19 #include "abg-reporter-priv.h"
114 for (string_enumerator_map::const_iterator i = enumerators_map.begin();
115 i != enumerators_map.end();
117 sorted.push_back(i->second);
119 std::sort(sorted.begin(), sorted.end(), comp);
131 for (string_changed_enumerator_map::const_iterator i =
132 enumerators_map.begin();
133 i != enumerators_map.end();
135 sorted.push_back(i->second);
138 std::sort(sorted.begin(), sorted.end(), comp);
148 vector<decl_base_sptr>& sorted)
150 sorted.reserve(data_members.size());
151 for (string_decl_base_sptr_map::const_iterator i = data_members.begin();
152 i != data_members.end();
154 sorted.push_back(i->second);
157 std::sort(sorted.begin(), sorted.end(), comp);
167 std::sort(to_sort.begin(), to_sort.end(), comp);
178 vector<function_decl*>& sorted)
180 sorted.reserve(map.size());
181 for (string_function_ptr_map::const_iterator i = map.begin();
184 sorted.push_back(i->second);
187 std::sort(sorted.begin(), sorted.end(), comp);
201 sorted.reserve(map.size());
202 for (string_member_function_sptr_map::const_iterator i = map.begin();
205 sorted.push_back(i->second);
208 std::sort(sorted.begin(), sorted.end(), comp);
224 sorted.reserve(map.size());
225 for (string_function_decl_diff_sptr_map::const_iterator i = map.begin();
228 sorted.push_back(i->second);
230 std::sort(sorted.begin(), sorted.end(), comp);
243 sorted.reserve(map.size());
244 for (string_var_diff_sptr_map::const_iterator i = map.begin();
247 sorted.push_back(i->second);
250 std::sort(sorted.begin(), sorted.end(), comp);
264 vector<elf_symbol_sptr>& sorted)
266 for (string_elf_symbol_map::const_iterator i = map.begin();
269 sorted.push_back(i->second);
272 std::sort(sorted.begin(), sorted.end(), comp);
285 vector<var_decl*>& sorted)
287 for (string_var_ptr_map::const_iterator i = map.begin();
290 sorted.push_back(i->second);
293 std::sort(sorted.begin(), sorted.end(), comp);
306 sorted.reserve(map.size());
307 for (string_var_diff_sptr_map::const_iterator i = map.begin();
310 sorted.push_back(i->second);
312 std::sort(sorted.begin(), sorted.end(), comp);
325 sorted.reserve(map.size());
326 for (unsigned_var_diff_sptr_map::const_iterator i = map.begin();
329 sorted.push_back(i->second);
331 std::sort(sorted.begin(), sorted.end(), comp);
347 sorted.reserve(map.size());
348 for (string_function_decl_diff_sptr_map::const_iterator i = map.begin();
351 sorted.push_back(i->second);
354 sort(sorted.begin(), sorted.end(), comp);
368 sorted.reserve(map.size());
369 for (string_diff_sptr_map::const_iterator i = map.begin();
372 sorted.push_back(i->second);
375 sort(sorted.begin(), sorted.end(), comp);
389 sorted.reserve(map.size());
390 for (string_diff_ptr_map::const_iterator i = map.begin();
393 sorted.push_back(i->second);
396 sort(sorted.begin(), sorted.end(), comp);
410 for (string_base_diff_sptr_map::const_iterator i = map.begin();
413 sorted.push_back(i->second);
415 sort(sorted.begin(), sorted.end(), comp);
424 for (string_base_sptr_map::const_iterator i = m.begin();
427 sorted.push_back(i->second);
430 std::sort(sorted.begin(), sorted.end(), comp);
442 vector<fn_parm_diff_sptr>& sorted)
444 sorted.reserve(map.size());
445 for (unsigned_fn_parm_diff_sptr_map::const_iterator i = map.begin();
448 sorted.push_back(i->second);
451 std::sort(sorted.begin(), sorted.end(), comp);
463 vector<fn_parm_diff_sptr>& sorted)
465 sorted.reserve(map.size());
466 for (string_fn_parm_diff_sptr_map::const_iterator i = map.begin();
469 sorted.push_back(i->second);
472 std::sort(sorted.begin(), sorted.end(), comp);
483 vector<function_decl::parameter_sptr>& sorted)
485 for (string_parm_map::const_iterator i = map.begin();
488 sorted.push_back(i->second);
491 std::sort(sorted.begin(), sorted.end(), comp);
503 vector<type_or_decl_base_sptr>& sorted)
506 for (artifact_sptr_set_type::const_iterator it = set.begin();
509 sorted.push_back(*it);
512 std::sort(sorted.begin(), sorted.end(), comp);
527 vector<type_base_sptr>& sorted)
529 for (string_type_base_sptr_map::const_iterator i = map.begin();
532 sorted.push_back(i->second);
535 std::sort(sorted.begin(), sorted.end(), comp);
547 return type_base_sptr();
549 type_base_sptr ut = t->get_underlying_type();
550 qualified_type_def_sptr qut = dynamic_pointer_cast<qualified_type_def>(ut);
578 if (decl_base_sptr decl =
is_decl(first))
595 |
static_cast<unsigned>(r));}
602 &
static_cast<unsigned>(r));
608 {
return static_cast<visiting_kind>(~static_cast<unsigned>(l));}
682 if (dif->first_class_or_union()->get_is_anonymous())
738 if (d->has_local_changes())
912 diff_context::diff_context()
928 diff_context::~diff_context() =
default;
935 {
return priv_->do_log_;}
942 {priv_->do_log_ = f;}
949 {priv_->corpus_diff_ = d;}
956 {
return priv_->corpus_diff_;}
965 if (priv_->corpus_diff_)
966 return priv_->corpus_diff_->first_corpus();
967 return corpus_sptr();
978 if (priv_->corpus_diff_)
979 return priv_->corpus_diff_->second_corpus();
980 return corpus_sptr();
989 if (!priv_->reporter_)
997 return priv_->reporter_;
1005 {priv_->reporter_ = r;}
1019 types_or_decls_diff_map_type::const_iterator i =
1020 priv_->types_or_decls_diff_map.find(std::make_pair(first, second));
1021 if (i != priv_->types_or_decls_diff_map.end())
1035 diff_context::has_diff_for_types(
const type_base_sptr first,
1036 const type_base_sptr second)
const
1037 {
return has_diff_for(first, second);}
1045 diff_context::has_diff_for(
const diff* d)
const
1046 {
return has_diff_for(d->first_subject(), d->second_subject()).get();}
1054 diff_context::has_diff_for(
const diff_sptr d)
const
1055 {
return has_diff_for(d->first_subject(), d->second_subject());}
1064 {
return priv_->allowed_category_;}
1073 {priv_->allowed_category_ = c;}
1086 {priv_->allowed_category_ = priv_->allowed_category_ | c;}
1097 {priv_->allowed_category_ = priv_->allowed_category_ & ~c;}
1113 {priv_->types_or_decls_diff_map[std::make_pair(first, second)] = d;}
1119 diff_context::add_diff(
const diff* d)
1132 diff_context::add_diff(
const diff_sptr d)
1135 add_diff(d->first_subject(), d->second_subject(), d);
1152 {
return has_diff_for(first, second);}
1164 {
return has_diff_for(d);}
1180 if (!has_diff_for(first, second))
1182 add_diff(first, second, d);
1183 priv_->canonical_diffs.push_back(d);
1208 canonical = canonical_diff;
1209 set_canonical_diff_for(first, second, canonical);
1252 {priv_->live_diffs_.insert(d);}
1265 size_t ptr_value =
reinterpret_cast<size_t>(canonical);
1266 pointer_map::iterator it = priv_->visited_diff_nodes_.find(ptr_value);
1267 if (it != priv_->visited_diff_nodes_.end())
1268 return reinterpret_cast<diff*
>(it->second);
1301 size_t canonical_ptr_value =
reinterpret_cast<size_t>(canonical);
1302 size_t diff_ptr_value =
reinterpret_cast<size_t>(d);
1303 priv_->visited_diff_nodes_[canonical_ptr_value] = diff_ptr_value;
1309 {priv_->visited_diff_nodes_.clear();}
1319 {priv_->forbid_visiting_a_node_twice_ = f;}
1329 {priv_->reset_visited_diffs_for_each_interface_ = f;}
1337 {
return priv_->forbid_visiting_a_node_twice_;}
1351 return (priv_->forbid_visiting_a_node_twice_
1352 && priv_->reset_visited_diffs_for_each_interface_);
1360 {
return priv_->filters_;}
1368 {priv_->filters_.push_back(f);}
1389 for (filtering::filters::const_iterator i =
diff_filters().begin();
1396 std::cerr <<
"applying a filter to diff '"
1407 std::cerr <<
"filter applied!:" << t <<
"\n";
1409 std::cerr <<
"propagating categories for the same diff node ... \n";
1418 std::cerr <<
"category propagated!: " << t <<
"\n";
1439 for (filtering::filters::const_iterator i =
diff_filters().begin();
1454 {
return priv_->suppressions_;}
1465 priv_->negated_suppressions_.clear();
1466 priv_->direct_suppressions_.clear();
1467 return priv_->suppressions_;
1486 if (priv_->negated_suppressions_.empty())
1489 priv_->negated_suppressions_.push_back(s);
1491 return priv_->negated_suppressions_;
1509 if (priv_->direct_suppressions_.empty())
1513 priv_->direct_suppressions_.push_back(s);
1515 return priv_->direct_suppressions_;
1526 priv_->suppressions_.push_back(suppr);
1529 priv_->negated_suppressions_.clear();
1530 priv_->direct_suppressions_.clear();
1541 priv_->suppressions_.insert(priv_->suppressions_.end(),
1542 supprs.begin(), supprs.end());
1551 {
return priv_->perform_change_categorization_;}
1558 {priv_->perform_change_categorization_ = f;}
1572 priv_->leaf_changes_only_ = f;
1582 {
return priv_->leaf_changes_only_;}
1592 {
return priv_->hex_values_;}
1602 {priv_->hex_values_ = f;}
1611 {
return priv_->show_offsets_sizes_in_bits_;}
1620 {priv_->show_offsets_sizes_in_bits_ = f;}
1629 {priv_->show_relative_offset_changes_ = f;}
1638 {
return priv_->show_relative_offset_changes_;}
1646 {priv_->show_stats_only_ = f;}
1654 {
return priv_->show_stats_only_;}
1662 {priv_->show_soname_change_ = f;}
1670 {
return priv_->show_soname_change_;}
1678 {priv_->show_architecture_change_ = f;}
1686 {
return priv_->show_architecture_change_;}
1693 {priv_->show_deleted_fns_ = f;}
1699 {
return priv_->show_deleted_fns_;}
1706 {priv_->show_changed_fns_ = f;}
1711 {
return priv_->show_changed_fns_;}
1718 {priv_->show_added_fns_ = f;}
1724 {
return priv_->show_added_fns_;}
1731 {priv_->show_deleted_vars_ = f;}
1737 {
return priv_->show_deleted_vars_;}
1744 {priv_->show_changed_vars_ = f;}
1749 {
return priv_->show_changed_vars_;}
1756 {priv_->show_added_vars_ = f;}
1762 {
return priv_->show_added_vars_;}
1765 diff_context::show_linkage_names()
const
1766 {
return priv_->show_linkage_names_;}
1769 diff_context::show_linkage_names(
bool f)
1770 {priv_->show_linkage_names_= f;}
1777 {priv_->show_locs_= f;}
1783 {
return priv_->show_locs_;}
1792 {
return priv_->show_redundant_changes_;}
1801 {priv_->show_redundant_changes_ = f;}
1809 {
return priv_->show_syms_unreferenced_by_di_;}
1817 {priv_->show_syms_unreferenced_by_di_ = f;}
1826 {
return priv_->show_added_syms_unreferenced_by_di_;}
1835 {priv_->show_added_syms_unreferenced_by_di_ = f;}
1844 {priv_->show_unreachable_types_ = f;}
1853 {
return priv_->show_unreachable_types_;}
1864 {
return priv_->show_impacted_interfaces_;}
1875 {priv_->show_impacted_interfaces_ = f;}
1884 {priv_->default_output_stream_ = o;}
1893 {
return priv_->default_output_stream_;}
1901 {priv_->error_output_stream_ = o;}
1909 {
return priv_->error_output_stream_;}
1918 {
return priv_->dump_diff_tree_;}
1927 {priv_->dump_diff_tree_ = f;}
1966 : priv_(new priv(first_subject, second_subject,
1988 : priv_(new priv(first_subject, second_subject,
2027 if (priv_->canonical_diff_)
2028 priv_->canonical_diff_->priv_->traversing_ =
true;
2029 priv_->traversing_ =
true;
2046 if (priv_->canonical_diff_)
2047 return priv_->canonical_diff_->priv_->traversing_;
2048 return priv_->traversing_;
2062 if (priv_->canonical_diff_)
2063 priv_->canonical_diff_->priv_->traversing_ =
false;
2064 priv_->traversing_ =
false;
2080 if (diff::priv_->finished_)
2083 diff::priv_->finished_ =
true;
2091 {
return dynamic_pointer_cast<type_or_decl_base>(priv_->first_subject_);}
2098 {
return dynamic_pointer_cast<type_or_decl_base>(priv_->second_subject_);}
2103 const vector<diff*>&
2105 {
return priv_->children_;}
2112 {
return priv_->parent_;}
2125 {
return priv_->canonical_diff_;}
2133 {priv_->canonical_diff_ = d;}
2146 context()->keep_diff_alive(d);
2153 priv_->children_.push_back(d.get());
2155 d->priv_->parent_ =
this;
2163 {
return priv_->get_context();}
2180 if (priv_->canonical_diff_)
2181 return priv_->canonical_diff_->priv_->currently_reporting_;
2182 return priv_->currently_reporting_;
2193 if (priv_->canonical_diff_)
2194 priv_->canonical_diff_->priv_->currently_reporting_ = f;
2195 priv_->currently_reporting_ = f;
2206 return priv_->canonical_diff_->priv_->reported_once_;
2266 bool already_visited =
false;
2267 if (
context()->visiting_a_node_twice_is_forbidden()
2268 &&
context()->diff_has_been_visited(
this))
2269 already_visited =
true;
2271 bool mark_visited_nodes_as_traversed =
2274 if (!already_visited && !v.
visit(
this,
true))
2277 if (mark_visited_nodes_as_traversed)
2278 context()->mark_diff_as_visited(
this);
2284 && !already_visited)
2291 if (!(*i)->traverse(v))
2294 if (mark_visited_nodes_as_traversed)
2295 context()->mark_diff_as_visited(
this);
2303 if (!v.
visit(
this,
false))
2306 if (mark_visited_nodes_as_traversed)
2307 context()->mark_diff_as_visited(
this);
2312 if (!already_visited && mark_visited_nodes_as_traversed)
2313 context()->mark_diff_as_visited(
this);
2327 priv_->canonical_diff_->priv_->reported_once_ = f;
2328 priv_->reported_once_ = f;
2340 {
return priv_->local_category_;}
2366 {
return priv_->category_;}
2381 priv_->category_ = priv_->category_ | c;
2382 return priv_->category_;
2396 priv_->local_category_ = priv_->local_category_ | c;
2397 return priv_->local_category_;
2425 priv_->category_ = priv_->category_ & ~c;
2426 return priv_->category_;
2440 priv_->local_category_ = priv_->local_category_ & ~c;
2441 return priv_->local_category_;
2451 {priv_->category_ = c;}
2458 {priv_->local_category_ = c;}
2483 && !canonical->is_allowed_by_specific_negated_suppression()
2484 && !canonical->has_descendant_allowed_by_specific_negated_suppression()
2485 && !canonical->has_parent_allowed_by_specific_negated_suppression())
2526 return priv_->is_filtered_out(c);
2537 bool is_private =
false;
2566 bool do_suppress = !
context()->negated_suppressions().empty();
2570 for (
auto n :
context()->negated_suppressions())
2571 if (!n->suppresses_diff(
this))
2573 do_suppress =
false;
2580 for (
auto d :
context()->direct_suppressions())
2581 if (d->suppresses_diff(
this))
2585 is_private_type =
true;
2625 for (suppressions_type::const_iterator i = suppressions.begin();
2626 i != suppressions.end();
2630 && !(*i)->suppresses_diff(
this))
2670 if (priv_->pretty_representation_.empty())
2671 priv_->pretty_representation_ =
"empty_diff";
2672 return priv_->pretty_representation_;
2699 type_diff_base::type_diff_base(type_base_sptr first_subject,
2700 type_base_sptr second_subject,
2702 :
diff(first_subject, second_subject, ctxt),
2706 type_diff_base::~type_diff_base()
2722 decl_base_sptr second_subject,
2724 :
diff(first_subject, second_subject, ctxt),
2728 decl_diff_base::~decl_diff_base()
2739 if (diff::priv_->pretty_representation_.empty())
2741 std::ostringstream o;
2742 o <<
"distinct_diff[";
2753 diff::priv_->pretty_representation_ = o.str();
2755 return diff::priv_->pretty_representation_;
2788 :
diff(first, second, ctxt),
2822 if (!priv_->compatible_child_diff)
2834 return priv_->compatible_child_diff;
2859 return typeid(f) !=
typeid(s);
2877 return NO_CHANGE_KIND;
2888 context()->get_reporter()->report(*
this, out, indent);
2911 ctxt->initialize_canonical_diff(result);
2936 template<
typename DiffType>
2942 if (shared_ptr<DiffType> f =
2943 dynamic_pointer_cast<DiffType>(first))
2945 shared_ptr<DiffType> s =
2946 dynamic_pointer_cast<DiffType>(second);
2972 dynamic_pointer_cast<class_decl>(first))
2978 if (f->get_is_declaration_only())
2985 if (s->get_is_declaration_only())
3040 ((d = try_to_diff<type_decl>(f, s, ctxt))
3041 ||(d = try_to_diff<enum_type_decl>(f, s, ctxt))
3042 ||(d = try_to_diff<union_decl>(f, s,ctxt))
3044 ||(d = try_to_diff<pointer_type_def>(f, s, ctxt))
3045 ||(d = try_to_diff<reference_type_def>(f, s, ctxt))
3046 ||(d = try_to_diff<array_type_def::subrange_type>(f, s, ctxt))
3047 ||(d = try_to_diff<array_type_def>(f, s, ctxt))
3048 ||(d = try_to_diff<qualified_type_def>(f, s, ctxt))
3049 ||(d = try_to_diff<typedef_decl>(f, s, ctxt))
3050 ||(d = try_to_diff<function_type>(f, s, ctxt))
3051 ||(d = try_to_diff_distinct_kinds(f, s, ctxt)));
3060 {
return static_cast<diff_category>(
static_cast<unsigned>(c1)
3061 |
static_cast<unsigned>(c2));}
3079 {
return static_cast<diff_category>(
static_cast<unsigned>(c1)
3080 ^
static_cast<unsigned>(c2));}
3084 {
return static_cast<diff_category>(
static_cast<unsigned>(c1)
3085 &
static_cast<unsigned>(c2));}
3089 {
return static_cast<diff_category>(~static_cast<unsigned>(c));}
3141 bool emitted_a_category =
false;
3145 o <<
"NO_CHANGE_CATEGORY";
3146 emitted_a_category =
true;
3151 if (emitted_a_category)
3153 o <<
"ACCESS_CHANGE_CATEGORY";
3154 emitted_a_category |=
true;
3159 if (emitted_a_category)
3161 o <<
"COMPATIBLE_TYPE_CHANGE_CATEGORY";
3162 emitted_a_category |=
true;
3167 if (emitted_a_category)
3169 o <<
"HARMLESS_DECL_NAME_CHANGE_CATEGORY";
3170 emitted_a_category |=
true;
3175 if (emitted_a_category)
3177 o <<
"NON_VIRT_MEM_FUN_CHANGE_CATEGORY";
3178 emitted_a_category |=
true;
3183 if (emitted_a_category)
3185 o <<
"STATIC_DATA_MEMBER_CHANGE_CATEGORY";
3186 emitted_a_category |=
true;
3191 if (emitted_a_category)
3193 o <<
"HARMLESS_ENUM_CHANGE_CATEGORY";
3194 emitted_a_category |=
true;
3199 if (emitted_a_category)
3201 o <<
"HARMLESS_DATA_MEMBER_CHANGE_CATEGORY";
3202 emitted_a_category |=
true;
3207 if (emitted_a_category)
3209 o <<
"HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY";
3210 emitted_a_category |=
true;
3215 if (emitted_a_category)
3217 o <<
"HARMLESS_UNION_CHANGE_CATEGORY";
3218 emitted_a_category |=
true;
3223 if (emitted_a_category)
3225 o <<
"SUPPRESSED_CATEGORY";
3226 emitted_a_category |=
true;
3231 if (emitted_a_category)
3233 o <<
"PRIVATE_TYPE_CATEGORY";
3234 emitted_a_category |=
true;
3239 if (emitted_a_category)
3241 o <<
"SIZE_OR_OFFSET_CHANGE_CATEGORY";
3242 emitted_a_category |=
true;
3247 if (emitted_a_category)
3249 o <<
"VIRTUAL_MEMBER_CHANGE_CATEGORY";
3250 emitted_a_category |=
true;
3255 if (emitted_a_category)
3257 o <<
"REDUNDANT_CATEGORY";
3258 emitted_a_category |=
true;
3263 if (emitted_a_category)
3265 o <<
"TYPE_DECL_ONLY_DEF_CHANGE_CATEGORY";
3266 emitted_a_category |=
true;
3271 if (emitted_a_category)
3273 o <<
"FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY";
3274 emitted_a_category |=
true;
3279 if (emitted_a_category)
3281 o <<
"FN_PARM_TYPE_CV_CHANGE_CATEGORY";
3282 emitted_a_category |=
true;
3287 if (emitted_a_category)
3289 o <<
"FN_RETURN_TYPE_CV_CHANGE_CATEGORY";
3290 emitted_a_category |=
true;
3295 if (emitted_a_category)
3297 o <<
"FN_PARM_ADD_REMOVE_CHANGE_CATEGORY";
3298 emitted_a_category |=
true;
3303 if (emitted_a_category)
3305 o <<
"VAR_TYPE_CV_CHANGE_CATEGORY";
3306 emitted_a_category |=
true;
3311 if (emitted_a_category)
3313 o <<
"VOID_PTR_TO_PTR_CHANGE_CATEGORY";
3314 emitted_a_category |=
true;
3319 if (emitted_a_category)
3321 o <<
"BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY";
3322 emitted_a_category |=
true;
3327 if (emitted_a_category)
3329 o <<
"HAS_ALLOWED_CHANGE_CATEGORY";
3330 emitted_a_category |=
true;
3335 if (emitted_a_category)
3337 o <<
"HAS_DESCENDANT_WITH_ALLOWED_CHANGE_CATEGORY";
3338 emitted_a_category |=
true;
3343 if (emitted_a_category)
3345 o <<
"HAS_PARENT_WITH_ALLOWED_CHANGE_CATEGORY";
3346 emitted_a_category |=
true;
3369 compute_diff_for_decls(
const decl_base_sptr first,
3370 const decl_base_sptr second,
3376 ((d = try_to_diff<function_decl>(first, second, ctxt))
3377 || (d = try_to_diff<var_decl>(first, second, ctxt))
3378 || (d = try_to_diff_distinct_kinds(first, second, ctxt)));
3401 const decl_base_sptr second,
3404 if (!first || !second)
3409 d = compute_diff_for_types(first, second, ctxt);
3411 d = compute_diff_for_decls(first, second, ctxt);
3431 const type_base_sptr second,
3437 diff_sptr d = compute_diff_for_types(f,s, ctxt);
3452 string prefix=
"diff of ";
3472 if (diff::priv_->pretty_representation_.empty())
3474 std::ostringstream o;
3480 diff::priv_->pretty_representation_ = o.str();
3482 return diff::priv_->pretty_representation_;
3525 if (
diff_sptr result = priv_->type_diff_.lock())
3532 context()->keep_diff_alive(result);
3533 priv_->type_diff_ = result;
3554 return ir::NO_CHANGE_KIND;
3566 context()->get_reporter()->report(*
this, out, indent);
3587 ctxt->initialize_canonical_diff(d);
3617 priv_(new
priv(underlying))
3625 {
return dynamic_pointer_cast<pointer_type_def>(
first_subject());}
3632 {
return dynamic_pointer_cast<pointer_type_def>(
second_subject());}
3639 if (diff::priv_->pretty_representation_.empty())
3641 std::ostringstream o;
3642 o <<
"pointer_diff["
3647 diff::priv_->pretty_representation_ = o.str();
3649 return diff::priv_->pretty_representation_;
3668 return ir::NO_CHANGE_KIND;
3677 {
return priv_->underlying_type_diff_;}
3686 {priv_->underlying_type_diff_ = d;}
3697 context()->get_reporter()->report(*
this, out, indent);
3717 diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
3718 second->get_pointed_to_type(),
3721 ctxt->initialize_canonical_diff(result);
3746 priv_(new
priv(underlying_type_diff))
3774 {
return priv_->underlying_type_diff_;}
3783 if (diff::priv_->pretty_representation_.empty())
3785 std::ostringstream o;
3786 o <<
"subrange_diff["
3791 diff::priv_->pretty_representation_ = o.str();
3793 return diff::priv_->pretty_representation_;
3815 return ir::NO_CHANGE_KIND;
3825 {
context()->get_reporter()->report(*
this, out, indent);}
3853 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
3854 second->get_underlying_type(),
3858 ctxt->initialize_canonical_diff(result);
3891 priv_(new
priv(element_type_diff))
3899 {
return dynamic_pointer_cast<array_type_def>(
first_subject());}
3913 {
return priv_->element_type_diff_;}
3920 {priv_->element_type_diff_ = d;}
3927 if (diff::priv_->pretty_representation_.empty())
3929 std::ostringstream o;
3935 diff::priv_->pretty_representation_ = o.str();
3937 return diff::priv_->pretty_representation_;
3954 if (f->get_name() != s->get_name())
3956 if (f->get_size_in_bits() != s->get_size_in_bits())
3958 if (f->get_alignment_in_bits() != s->get_alignment_in_bits())
3978 return ir::NO_CHANGE_KIND;
3989 context()->get_reporter()->report(*
this, out, indent);
4007 diff_sptr d = compute_diff_for_types(first->get_element_type(),
4008 second->get_element_type(),
4011 ctxt->initialize_canonical_diff(result);
4039 priv_(new
priv(underlying))
4047 {
return dynamic_pointer_cast<reference_type_def>(
first_subject());}
4054 {
return dynamic_pointer_cast<reference_type_def>(
second_subject());}
4062 {
return priv_->underlying_type_diff_;}
4070 priv_->underlying_type_diff_ = d;
4071 return priv_->underlying_type_diff_;
4079 if (diff::priv_->pretty_representation_.empty())
4081 std::ostringstream o;
4082 o <<
"reference_diff["
4087 diff::priv_->pretty_representation_ = o.str();
4089 return diff::priv_->pretty_representation_;
4110 return ir::NO_CHANGE_KIND;
4121 context()->get_reporter()->report(*
this, out, indent);
4139 diff_sptr d = compute_diff_for_types(first->get_pointed_to_type(),
4140 second->get_pointed_to_type(),
4143 ctxt->initialize_canonical_diff(result);
4167 qualified_type_def_sptr second,
4171 priv_(new
priv(under))
4177 const qualified_type_def_sptr
4179 {
return dynamic_pointer_cast<qualified_type_def>(
first_subject());}
4184 const qualified_type_def_sptr
4186 {
return dynamic_pointer_cast<qualified_type_def>(
second_subject());}
4195 {
return priv_->underlying_type_diff;}
4205 if (!priv_->leaf_underlying_type_diff)
4206 priv_->leaf_underlying_type_diff
4211 return priv_->leaf_underlying_type_diff;
4221 {priv_->underlying_type_diff = d;}
4228 if (diff::priv_->pretty_representation_.empty())
4230 std::ostringstream o;
4231 o <<
"qualified_type_diff["
4236 diff::priv_->pretty_representation_ = o.str();
4238 return diff::priv_->pretty_representation_;
4257 return ir::NO_CHANGE_KIND;
4268 context()->get_reporter()->report(*
this, out, indent);
4281 qualified_type_diff_sptr
4283 const qualified_type_def_sptr second,
4286 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
4287 second->get_underlying_type(),
4291 ctxt->initialize_canonical_diff(result);
4304 enum_diff::clear_lookup_tables()
4306 priv_->deleted_enumerators_.clear();
4307 priv_->inserted_enumerators_.clear();
4308 priv_->changed_enumerators_.clear();
4315 enum_diff::lookup_tables_empty()
const
4317 return (priv_->deleted_enumerators_.empty()
4318 && priv_->inserted_enumerators_.empty()
4319 && priv_->changed_enumerators_.empty());
4325 enum_diff::ensure_lookup_tables_populated()
4327 if (!lookup_tables_empty())
4331 edit_script e = priv_->enumerators_changes_;
4333 for (vector<deletion>::const_iterator it = e.deletions().begin();
4334 it != e.deletions().end();
4337 unsigned i = it->index();
4338 const enum_type_decl::enumerator& n =
4340 const string& name = n.get_name();
4341 ABG_ASSERT(priv_->deleted_enumerators_.find(n.get_name())
4342 == priv_->deleted_enumerators_.end());
4343 priv_->deleted_enumerators_[name] = n;
4346 for (vector<insertion>::const_iterator it = e.insertions().begin();
4347 it != e.insertions().end();
4350 for (vector<unsigned>::const_iterator iit =
4351 it->inserted_indexes().begin();
4352 iit != it->inserted_indexes().end();
4356 const enum_type_decl::enumerator& n =
4358 const string& name = n.get_name();
4359 ABG_ASSERT(priv_->inserted_enumerators_.find(n.get_name())
4360 == priv_->inserted_enumerators_.end());
4361 string_enumerator_map::const_iterator j =
4362 priv_->deleted_enumerators_.find(name);
4363 if (j == priv_->deleted_enumerators_.end())
4364 priv_->inserted_enumerators_[name] = n;
4368 priv_->changed_enumerators_[j->first] =
4369 std::make_pair(j->second, n);
4370 priv_->deleted_enumerators_.erase(j);
4401 priv_(new
priv(underlying_type_diff))
4407 {
return dynamic_pointer_cast<enum_type_decl>(
first_subject());}
4417 {
return priv_->underlying_type_diff_;}
4422 {
return priv_->deleted_enumerators_;}
4427 {
return priv_->inserted_enumerators_;}
4432 {
return priv_->changed_enumerators_;}
4439 if (diff::priv_->pretty_representation_.empty())
4441 std::ostringstream o;
4447 diff::priv_->pretty_representation_ = o.str();
4449 return diff::priv_->pretty_representation_;
4468 return ir::NO_CHANGE_KIND;
4479 context()->get_reporter()->report(*
this, out, indent);
4501 diff_sptr ud = compute_diff_for_types(first->get_underlying_type(),
4502 second->get_underlying_type(),
4504 enum_diff_sptr d(
new enum_diff(first, second, ud, ctxt));
4505 if (first != second)
4508 first->get_enumerators().end(),
4509 second->get_enumerators().begin(),
4510 second->get_enumerators().end(),
4511 d->priv_->enumerators_changes_);
4512 d->ensure_lookup_tables_populated();
4514 ctxt->initialize_canonical_diff(d);
4536 string qname = d->get_qualified_name();
4537 string_diff_sptr_map::const_iterator it =
4538 changed_member_types_.find(qname);
4540 return ((it == changed_member_types_.end())
4542 : it->second->second_subject());
4559 string qname = d->get_qualified_name();
4560 string_var_diff_sptr_map::const_iterator it =
4561 subtype_changed_dm_.find(qname);
4563 if (it == subtype_changed_dm_.end())
4564 return decl_base_sptr();
4565 return it->second->second_var();
4583 string qname = d->get_qualified_name();
4584 string_diff_sptr_map::const_iterator it =
4585 changed_member_class_tmpls_.find(qname);
4587 return ((it == changed_member_class_tmpls_.end())
4589 : dynamic_pointer_cast<decl_base>(it->second->second_subject()));
4600 for (string_decl_base_sptr_map::const_iterator i =
4601 deleted_data_members_.begin();
4602 i != deleted_data_members_.end();
4619 for (string_decl_base_sptr_map::const_iterator i =
4620 inserted_data_members_.begin();
4621 i != inserted_data_members_.end();
4641 size_t num_filtered= 0;
4642 for (var_diff_sptrs_type::const_iterator i =
4643 sorted_subtype_changed_dm_.begin();
4644 i != sorted_subtype_changed_dm_.end();
4649 if ((*i)->has_changes()
4650 && !(*i)->has_local_changes_to_be_reported())
4655 if ((*i)->is_filtered_out())
4659 return num_filtered;
4673 size_t num_filtered= 0;
4675 for (unsigned_var_diff_sptr_map::const_iterator i = changed_dm_.begin();
4676 i != changed_dm_.end();
4692 return num_filtered;
4701 #define SKIP_MEM_FN_IF_VIRTUALITY_DISALLOWED \
4703 if (get_member_function_is_virtual(f) \
4704 || get_member_function_is_virtual(s)) \
4706 if (!(allowed_category | VIRTUAL_MEMBER_CHANGE_CATEGORY)) \
4711 if (!(allowed_category | NON_VIRT_MEM_FUN_CHANGE_CATEGORY)) \
4726 diff_category allowed_category = ctxt->get_allowed_category();
4728 for (function_decl_diff_sptrs_type::const_iterator i =
4729 sorted_changed_member_functions_.begin();
4730 i != sorted_changed_member_functions_.end();
4733 method_decl_sptr f =
4734 dynamic_pointer_cast<method_decl>
4735 ((*i)->first_function_decl());
4738 method_decl_sptr s =
4739 dynamic_pointer_cast<method_decl>
4740 ((*i)->second_function_decl());
4746 ctxt->maybe_apply_filters(
diff);
4765 diff_category allowed_category = ctxt->get_allowed_category();
4767 for (string_member_function_sptr_map::const_iterator i =
4768 inserted_member_functions_.begin();
4769 i != inserted_member_functions_.end();
4772 method_decl_sptr f = i->second,
4778 ctxt->maybe_apply_filters(
diff);
4798 diff_category allowed_category = ctxt->get_allowed_category();
4800 for (string_member_function_sptr_map::const_iterator i =
4801 deleted_member_functions_.begin();
4802 i != deleted_member_functions_.end();
4805 method_decl_sptr f = i->second,
4811 ctxt->maybe_apply_filters(
diff);
4828 priv_->deleted_member_types_.clear();
4829 priv_->inserted_member_types_.clear();
4830 priv_->changed_member_types_.clear();
4831 priv_->deleted_data_members_.clear();
4832 priv_->inserted_data_members_.clear();
4833 priv_->subtype_changed_dm_.clear();
4834 priv_->deleted_member_functions_.clear();
4835 priv_->inserted_member_functions_.clear();
4836 priv_->changed_member_functions_.clear();
4837 priv_->deleted_member_class_tmpls_.clear();
4838 priv_->inserted_member_class_tmpls_.clear();
4839 priv_->changed_member_class_tmpls_.clear();
4848 return (priv_->deleted_member_types_.empty()
4849 && priv_->inserted_member_types_.empty()
4850 && priv_->changed_member_types_.empty()
4851 && priv_->deleted_data_members_.empty()
4852 && priv_->inserted_data_members_.empty()
4853 && priv_->subtype_changed_dm_.empty()
4854 && priv_->inserted_member_functions_.empty()
4855 && priv_->deleted_member_functions_.empty()
4856 && priv_->changed_member_functions_.empty()
4857 && priv_->deleted_member_class_tmpls_.empty()
4858 && priv_->inserted_member_class_tmpls_.empty()
4859 && priv_->changed_member_class_tmpls_.empty());
4870 for (vector<deletion>::const_iterator it = e.deletions().begin();
4871 it != e.deletions().end();
4874 unsigned i = it->index();
4878 if (record_type && record_type->get_is_declaration_only())
4880 string name = d->get_name();
4881 priv_->deleted_member_types_[name] = d;
4884 for (vector<insertion>::const_iterator it = e.insertions().begin();
4885 it != e.insertions().end();
4888 for (vector<unsigned>::const_iterator iit =
4889 it->inserted_indexes().begin();
4890 iit != it->inserted_indexes().end();
4897 if (record_type && record_type->get_is_declaration_only())
4899 string name = d->get_name();
4900 string_decl_base_sptr_map::const_iterator j =
4901 priv_->deleted_member_types_.find(name);
4902 if (j != priv_->deleted_member_types_.end())
4904 if (*j->second != *d)
4905 priv_->changed_member_types_[name] =
4908 priv_->deleted_member_types_.erase(j);
4911 priv_->inserted_member_types_[name] = d;
4919 for (vector<deletion>::const_iterator it = e.deletions().begin();
4920 it != e.deletions().end();
4923 unsigned i = it->index();
4926 string name = data_member->get_anon_dm_reliable_name();
4928 ABG_ASSERT(priv_->deleted_data_members_.find(name)
4929 == priv_->deleted_data_members_.end());
4930 priv_->deleted_data_members_[name] = data_member;
4933 for (vector<insertion>::const_iterator it = e.insertions().begin();
4934 it != e.insertions().end();
4937 for (vector<unsigned>::const_iterator iit =
4938 it->inserted_indexes().begin();
4939 iit != it->inserted_indexes().end();
4946 string name = added_dm->get_anon_dm_reliable_name();
4947 ABG_ASSERT(priv_->inserted_data_members_.find(name)
4948 == priv_->inserted_data_members_.end());
4950 bool ignore_added_anonymous_data_member =
false;
4988 bool added_anon_dm_changes_dm =
false;
4991 vector<var_decl_sptr> dms_replaced_by_anon_dm;
5000 for (string_decl_base_sptr_map::const_iterator it =
5001 priv_->deleted_data_members_.begin();
5002 it != priv_->deleted_data_members_.end();
5011 string deleted_dm_name = it->second->get_name();
5027 size_t replaced_dm_offset =
5029 replacing_dm_offset =
5032 if (replaced_dm_offset != replacing_dm_offset)
5040 added_anon_dm_changes_dm =
true;
5044 if (replaced_dm->get_type()->get_size_in_bits()
5045 == replaced_dm->get_type()->get_size_in_bits())
5046 dms_replaced_by_anon_dm.push_back(replaced_dm);
5049 added_anon_dm_changes_dm =
true;
5058 if (!added_anon_dm_changes_dm
5059 && !dms_replaced_by_anon_dm.empty())
5062 type_base_sptr added_dm_type = added_dm->get_type();
5078 ignore_added_anonymous_data_member =
true;
5079 for (vector<var_decl_sptr>::const_iterator i =
5080 dms_replaced_by_anon_dm.begin();
5081 i != dms_replaced_by_anon_dm.end();
5084 string n = (*i)->get_name();
5085 priv_->dms_replaced_by_adms_[n] =
5087 priv_->deleted_data_members_.erase(n);
5093 if (!ignore_added_anonymous_data_member)
5106 string_decl_base_sptr_map::const_iterator j =
5107 priv_->deleted_data_members_.find(name);
5108 if (j != priv_->deleted_data_members_.end())
5110 if (*j->second != *d)
5113 priv_->subtype_changed_dm_[name]=
5116 priv_->deleted_data_members_.erase(j);
5119 priv_->inserted_data_members_[name] = d;
5127 for (string_decl_base_sptr_map::const_iterator i =
5128 priv_->deleted_data_members_.begin();
5129 i != priv_->deleted_data_members_.end();
5133 priv_->deleted_dm_by_offset_[offset] = i->second;
5136 for (string_decl_base_sptr_map::const_iterator i =
5137 priv_->inserted_data_members_.begin();
5138 i != priv_->inserted_data_members_.end();
5142 priv_->inserted_dm_by_offset_[offset] = i->second;
5145 for (unsigned_decl_base_sptr_map::const_iterator i =
5146 priv_->inserted_dm_by_offset_.begin();
5147 i != priv_->inserted_dm_by_offset_.end();
5150 unsigned_decl_base_sptr_map::const_iterator j =
5151 priv_->deleted_dm_by_offset_.find(i->first);
5152 if (j != priv_->deleted_dm_by_offset_.end())
5156 priv_->changed_dm_[i->first] =
5161 for (unsigned_var_diff_sptr_map::const_iterator i =
5162 priv_->changed_dm_.begin();
5163 i != priv_->changed_dm_.end();
5166 priv_->deleted_dm_by_offset_.erase(i->first);
5167 priv_->inserted_dm_by_offset_.erase(i->first);
5168 priv_->deleted_data_members_.erase
5169 (i->second->first_var()->get_anon_dm_reliable_name());
5170 priv_->inserted_data_members_.erase
5171 (i->second->second_var()->get_anon_dm_reliable_name());
5175 priv_->sorted_subtype_changed_dm_);
5177 priv_->sorted_changed_dm_);
5180 edit_script& e = priv_->member_class_tmpls_changes_;
5182 for (vector<deletion>::const_iterator it = e.deletions().begin();
5183 it != e.deletions().end();
5186 unsigned i = it->index();
5190 string name = d->get_name();
5191 ABG_ASSERT(priv_->deleted_member_class_tmpls_.find(name)
5192 == priv_->deleted_member_class_tmpls_.end());
5193 priv_->deleted_member_class_tmpls_[name] = d;
5196 for (vector<insertion>::const_iterator it = e.insertions().begin();
5197 it != e.insertions().end();
5200 for (vector<unsigned>::const_iterator iit =
5201 it->inserted_indexes().begin();
5202 iit != it->inserted_indexes().end();
5209 string name = d->get_name();
5210 ABG_ASSERT(priv_->inserted_member_class_tmpls_.find(name)
5211 == priv_->inserted_member_class_tmpls_.end());
5212 string_decl_base_sptr_map::const_iterator j =
5213 priv_->deleted_member_class_tmpls_.find(name);
5214 if (j != priv_->deleted_member_class_tmpls_.end())
5216 if (*j->second != *d)
5217 priv_->changed_member_types_[name]=
5219 priv_->deleted_member_class_tmpls_.erase(j);
5222 priv_->inserted_member_class_tmpls_[name] = d;
5227 priv_->sorted_changed_member_types_);
5236 priv_.reset(
new priv);
5247 class_or_union_sptr second_scope,
5265 const class_or_union_diff::priv_ptr&
5278 return canonical->priv_;
5300 {
return get_priv()->member_types_changes_;}
5306 {
return get_priv()->member_types_changes_;}
5312 {
return get_priv()->data_members_changes_;}
5318 {
return get_priv()->data_members_changes_;}
5325 {
return get_priv()->inserted_data_members_;}
5332 {
return get_priv()->deleted_data_members_;}
5338 {
return get_priv()->member_fns_changes_;}
5347 {
return get_priv()->sorted_changed_member_functions_;}
5353 {
return get_priv()->member_fns_changes_;}
5358 {
return get_priv()->deleted_member_functions_;}
5363 {
return get_priv()->inserted_member_functions_;}
5371 {
return get_priv()->sorted_changed_dm_;}
5379 {
return get_priv()->count_filtered_changed_dm(local);}
5386 {
return get_priv()->sorted_subtype_changed_dm_;}
5393 {
return get_priv()->count_filtered_subtype_changed_dm(local);}
5405 {
return get_priv()->dms_replaced_by_adms_;}
5417 if (priv_->dms_replaced_by_adms_ordered_.empty())
5419 for (string_decl_base_sptr_map::const_iterator it =
5420 priv_->dms_replaced_by_adms_.begin();
5421 it != priv_->dms_replaced_by_adms_.end();
5428 priv_->dms_replaced_by_adms_ordered_.push_back(changed_dm);
5433 return priv_->dms_replaced_by_adms_ordered_;
5440 {
return get_priv()->member_fn_tmpls_changes_;}
5446 {
return get_priv()->member_fn_tmpls_changes_;}
5452 {
return get_priv()->member_class_tmpls_changes_;}
5458 {
return get_priv()->member_class_tmpls_changes_;}
5474 return ir::NO_CHANGE_KIND;
5487 context()->get_reporter()->report(*
this, out, indent);
5499 for (var_diff_sptrs_type::const_iterator i =
5500 get_priv()->sorted_subtype_changed_dm_.begin();
5501 i !=
get_priv()->sorted_subtype_changed_dm_.end();
5506 for (var_diff_sptrs_type::const_iterator i =
5507 get_priv()->sorted_changed_dm_.begin();
5508 i !=
get_priv()->sorted_changed_dm_.end();
5514 for (diff_sptrs_type::const_iterator i =
5515 get_priv()->sorted_changed_member_types_.begin();
5516 i !=
get_priv()->sorted_changed_member_types_.end();
5522 for (function_decl_diff_sptrs_type::const_iterator i =
5523 get_priv()->sorted_changed_member_functions_.begin();
5524 i !=
get_priv()->sorted_changed_member_functions_.end();
5539 class_diff::clear_lookup_tables(
void)
5541 priv_->deleted_bases_.clear();
5542 priv_->inserted_bases_.clear();
5543 priv_->changed_bases_.clear();
5550 class_diff::lookup_tables_empty(
void)
const
5552 return (priv_->deleted_bases_.empty()
5553 && priv_->inserted_bases_.empty()
5554 && priv_->changed_bases_.empty());
5564 static string_member_function_sptr_map::const_iterator
5567 for (string_member_function_sptr_map::const_iterator i = map.begin();
5581 class_diff::ensure_lookup_tables_populated(
void)
const
5585 if (!lookup_tables_empty())
5589 edit_script& e = get_priv()->base_changes_;
5591 for (vector<deletion>::const_iterator it = e.deletions().begin();
5592 it != e.deletions().end();
5595 unsigned i = it->index();
5598 string name = b->get_base_class()->get_qualified_name();
5599 ABG_ASSERT(get_priv()->deleted_bases_.find(name)
5600 == get_priv()->deleted_bases_.end());
5601 get_priv()->deleted_bases_[name] = b;
5604 for (vector<insertion>::const_iterator it = e.insertions().begin();
5605 it != e.insertions().end();
5608 for (vector<unsigned>::const_iterator iit =
5609 it->inserted_indexes().begin();
5610 iit != it->inserted_indexes().end();
5616 string name = b->get_base_class()->get_qualified_name();
5617 ABG_ASSERT(get_priv()->inserted_bases_.find(name)
5618 == get_priv()->inserted_bases_.end());
5619 string_base_sptr_map::const_iterator j =
5620 get_priv()->deleted_bases_.find(name);
5621 if (j != get_priv()->deleted_bases_.end())
5624 get_priv()->changed_bases_[name] =
5630 get_priv()->moved_bases_.push_back(b);
5631 get_priv()->deleted_bases_.erase(j);
5634 get_priv()->inserted_bases_[name] = b;
5640 get_priv()->sorted_deleted_bases_);
5642 get_priv()->sorted_inserted_bases_);
5644 get_priv()->sorted_changed_bases_);
5649 edit_script& e = p->member_fns_changes_;
5651 for (vector<deletion>::const_iterator it = e.deletions().begin();
5652 it != e.deletions().end();
5655 unsigned i = it->index();
5656 method_decl_sptr mem_fn =
5658 string name = mem_fn->get_linkage_name();
5660 name = mem_fn->get_pretty_representation();
5662 if (p->deleted_member_functions_.find(name)
5663 != p->deleted_member_functions_.end())
5665 p->deleted_member_functions_[name] = mem_fn;
5668 for (vector<insertion>::const_iterator it = e.insertions().begin();
5669 it != e.insertions().end();
5672 for (vector<unsigned>::const_iterator iit =
5673 it->inserted_indexes().begin();
5674 iit != it->inserted_indexes().end();
5679 method_decl_sptr mem_fn =
5681 string name = mem_fn->get_linkage_name();
5683 name = mem_fn->get_pretty_representation();
5685 if (p->inserted_member_functions_.find(name)
5686 != p->inserted_member_functions_.end())
5688 string_member_function_sptr_map::const_iterator j =
5689 p->deleted_member_functions_.find(name);
5691 if (j != p->deleted_member_functions_.end())
5693 if (*j->second != *mem_fn)
5694 p->changed_member_functions_[name] =
5695 compute_diff(static_pointer_cast<function_decl>(j->second),
5696 static_pointer_cast<function_decl>(mem_fn),
5698 p->deleted_member_functions_.erase(j);
5701 p->inserted_member_functions_[name] = mem_fn;
5748 vector<string> to_delete;
5749 corpus_sptr f =
context()->get_first_corpus(),
5750 s =
context()->get_second_corpus();
5752 for (string_member_function_sptr_map::const_iterator i =
5771 find_virtual_dtor_in_map(p->inserted_member_functions_);
5772 if (it != p->inserted_member_functions_.end())
5780 (!i->second->get_linkage_name().empty())
5781 ? i->second->get_linkage_name()
5782 : i->second->get_pretty_representation();
5783 to_delete.push_back(name);
5784 p->inserted_member_functions_.erase(it);
5791 if (!i->second->get_symbol()
5792 || s->lookup_function_symbol(*i->second->get_symbol()))
5793 to_delete.push_back(i->first);
5797 for (vector<string>::const_iterator i = to_delete.begin();
5798 i != to_delete.end();
5800 p->deleted_member_functions_.erase(*i);
5805 for (string_member_function_sptr_map::const_iterator i =
5814 if (!i->second->get_symbol()
5815 || f->lookup_function_symbol(*i->second->get_symbol()))
5816 to_delete.push_back(i->first);
5819 for (vector<string>::const_iterator i = to_delete.begin();
5820 i != to_delete.end();
5822 p->inserted_member_functions_.erase(*i);
5825 p->sorted_deleted_member_functions_);
5828 p->sorted_inserted_member_functions_);
5831 (p->changed_member_functions_,
5832 p->sorted_changed_member_functions_);
5839 class_diff::allocate_priv_data()
5843 priv_.reset(
new priv);
5856 string qname = d->get_base_class()->get_qualified_name();
5857 string_base_diff_sptr_map::const_iterator it =
5858 changed_bases_.find(qname);
5860 return (it == changed_bases_.end())
5862 : it->second->second_base();
5873 size_t num_filtered = 0;
5874 for (base_diff_sptrs_type::const_iterator i = sorted_changed_bases_.begin();
5875 i != sorted_changed_bases_.end();
5882 return num_filtered;
5896 for (base_diff_sptrs_type::const_iterator i =
5897 get_priv()->sorted_changed_bases_.begin();
5898 i != get_priv()->sorted_changed_bases_.end();
5923 class_diff::~class_diff()
5937 const class_diff::priv_ptr&
5938 class_diff::get_priv()
const
5950 return canonical->priv_;
5958 if (diff::priv_->pretty_representation_.empty())
5960 std::ostringstream o;
5966 diff::priv_->pretty_representation_ = o.str();
5968 return diff::priv_->pretty_representation_;
5987 return ir::NO_CHANGE_KIND;
5991 shared_ptr<class_decl>
5998 shared_ptr<class_decl>
6005 {
return get_priv()->base_changes_;}
6013 {
return get_priv()->deleted_bases_;}
6021 {
return get_priv()->inserted_bases_;}
6028 {
return get_priv()->sorted_changed_bases_;}
6036 const vector<class_decl::base_spec_sptr>&
6038 {
return get_priv()->moved_bases_;}
6043 {
return get_priv()->base_changes_;}
6054 context()->get_reporter()->report(*
this, out, indent);
6079 ctxt->initialize_canonical_diff(changes);
6082 if (!ctxt->get_canonical_diff_for(first, second))
6086 diff_sptr canonical_diff = ctxt->get_canonical_diff_for(changes);
6088 ctxt->set_canonical_diff_for(first, second, canonical_diff);
6104 if (
is_class_diff(changes->get_canonical_diff()) == changes.get())
6107 changes->allocate_priv_data();
6119 f->get_base_specifiers().end(),
6120 s->get_base_specifiers().begin(),
6121 s->get_base_specifiers().end(),
6122 changes->base_changes());
6128 f->get_member_types().end(),
6129 s->get_member_types().begin(),
6130 s->get_member_types().end(),
6131 changes->member_types_changes());
6136 f->get_non_static_data_members().end(),
6137 s->get_non_static_data_members().begin(),
6138 s->get_non_static_data_members().end(),
6139 changes->data_members_changes());
6143 f->get_virtual_mem_fns().end(),
6144 s->get_virtual_mem_fns().begin(),
6145 s->get_virtual_mem_fns().end(),
6146 changes->member_fns_changes());
6149 compute_diff(f->get_member_function_templates().begin(),
6150 f->get_member_function_templates().end(),
6151 s->get_member_function_templates().begin(),
6152 s->get_member_function_templates().end(),
6153 changes->member_fn_tmpls_changes());
6158 f->get_member_class_templates().end(),
6159 s->get_member_class_templates().begin(),
6160 s->get_member_class_templates().end(),
6161 changes->member_class_tmpls_changes());
6164 changes->ensure_lookup_tables_populated();
6194 :
diff(first, second, ctxt),
6195 priv_(new
priv(underlying))
6203 {
return dynamic_pointer_cast<class_decl::base_spec>(
first_subject());}
6210 {
return dynamic_pointer_cast<class_decl::base_spec>(
second_subject());}
6219 {
return priv_->underlying_class_diff_;}
6228 {priv_->underlying_class_diff_ = d;}
6235 if (diff::priv_->pretty_representation_.empty())
6237 std::ostringstream o;
6243 diff::priv_->pretty_representation_ = o.str();
6245 return diff::priv_->pretty_representation_;
6264 return ir::NO_CHANGE_KIND;
6275 context()->get_reporter()->report(*
this, out, indent);
6297 second->get_base_class(),
6301 ctxt->initialize_canonical_diff(changes);
6316 union_diff::clear_lookup_tables(
void)
6323 union_diff::lookup_tables_empty(
void)
const
6329 union_diff::ensure_lookup_tables_populated(
void)
const
6335 union_diff::allocate_priv_data()
6348 union_decl_sptr second_union,
6371 if (diff::priv_->pretty_representation_.empty())
6373 std::ostringstream o;
6379 diff::priv_->pretty_representation_ = o.str();
6381 return diff::priv_->pretty_representation_;
6393 context()->get_reporter()->report(*
this, out, indent);
6408 const union_decl_sptr second,
6411 union_diff_sptr changes(
new union_diff(first, second, ctxt));
6413 ctxt->initialize_canonical_diff(changes);
6429 if (
is_union_diff(changes->get_canonical_diff()) == changes.get())
6432 changes->allocate_priv_data();
6443 compute_diff(first->get_non_static_data_members().begin(),
6444 first->get_non_static_data_members().end(),
6445 second->get_non_static_data_members().begin(),
6446 second->get_non_static_data_members().end(),
6447 changes->data_members_changes());
6452 first->get_mem_fns().end(),
6453 second->get_mem_fns().begin(),
6454 second->get_mem_fns().end(),
6455 changes->member_fns_changes());
6458 compute_diff(first->get_member_function_templates().begin(),
6459 first->get_member_function_templates().end(),
6460 second->get_member_function_templates().begin(),
6461 second->get_member_function_templates().end(),
6462 changes->member_fn_tmpls_changes());
6465 changes->ensure_lookup_tables_populated();
6479 scope_diff::clear_lookup_tables()
6481 priv_->deleted_types_.clear();
6482 priv_->deleted_decls_.clear();
6483 priv_->inserted_types_.clear();
6484 priv_->inserted_decls_.clear();
6485 priv_->changed_types_.clear();
6486 priv_->changed_decls_.clear();
6487 priv_->removed_types_.clear();
6488 priv_->removed_decls_.clear();
6489 priv_->added_types_.clear();
6490 priv_->added_decls_.clear();
6500 scope_diff::lookup_tables_empty()
const
6502 return (priv_->deleted_types_.empty()
6503 && priv_->deleted_decls_.empty()
6504 && priv_->inserted_types_.empty()
6505 && priv_->inserted_decls_.empty()
6506 && priv_->changed_types_.empty()
6507 && priv_->changed_decls_.empty()
6508 && priv_->removed_types_.empty()
6509 && priv_->removed_decls_.empty()
6510 && priv_->added_types_.empty()
6511 && priv_->added_decls_.empty());
6517 scope_diff::ensure_lookup_tables_populated()
6519 if (!lookup_tables_empty())
6522 edit_script& e = priv_->member_changes_;
6525 for (
const auto& deletion : e.deletions())
6527 unsigned i = deletion.index();
6529 string qname = decl->get_qualified_name();
6533 if (klass_decl && klass_decl->get_is_declaration_only())
6537 == priv_->deleted_types_.end());
6538 priv_->deleted_types_[qname] = decl;
6543 == priv_->deleted_decls_.end());
6544 priv_->deleted_decls_[qname] = decl;
6550 for (vector<insertion>::const_iterator it = e.insertions().begin();
6551 it != e.insertions().end();
6554 for (vector<unsigned>::const_iterator i = it->inserted_indexes().begin();
6555 i != it->inserted_indexes().end();
6559 string qname = decl->get_qualified_name();
6563 dynamic_pointer_cast<class_decl>(decl);
6564 if (klass_decl && klass_decl->get_is_declaration_only())
6567 ABG_ASSERT(priv_->inserted_types_.find(qname)
6568 == priv_->inserted_types_.end());
6569 string_decl_base_sptr_map::const_iterator j =
6570 priv_->deleted_types_.find(qname);
6571 if (j != priv_->deleted_types_.end())
6573 if (*j->second != *decl)
6574 priv_->changed_types_[qname] =
6576 priv_->deleted_types_.erase(j);
6579 priv_->inserted_types_[qname] = decl;
6583 ABG_ASSERT(priv_->inserted_decls_.find(qname)
6584 == priv_->inserted_decls_.end());
6585 string_decl_base_sptr_map::const_iterator j =
6586 priv_->deleted_decls_.find(qname);
6587 if (j != priv_->deleted_decls_.end())
6589 if (*j->second != *decl)
6590 priv_->changed_decls_[qname] =
6592 priv_->deleted_decls_.erase(j);
6595 priv_->inserted_decls_[qname] = decl;
6601 priv_->sorted_changed_decls_);
6603 priv_->sorted_changed_types_);
6606 for (string_decl_base_sptr_map::const_iterator i =
6607 priv_->deleted_types_.begin();
6608 i != priv_->deleted_types_.end();
6611 string_decl_base_sptr_map::const_iterator r =
6612 priv_->inserted_types_.find(i->first);
6613 if (r == priv_->inserted_types_.end())
6614 priv_->removed_types_[i->first] = i->second;
6616 for (string_decl_base_sptr_map::const_iterator i =
6617 priv_->deleted_decls_.begin();
6618 i != priv_->deleted_decls_.end();
6621 string_decl_base_sptr_map::const_iterator r =
6622 priv_->inserted_decls_.find(i->first);
6623 if (r == priv_->inserted_decls_.end())
6624 priv_->removed_decls_[i->first] = i->second;
6628 for (string_decl_base_sptr_map::const_iterator i =
6629 priv_->inserted_types_.begin();
6630 i != priv_->inserted_types_.end();
6633 string_decl_base_sptr_map::const_iterator r =
6634 priv_->deleted_types_.find(i->first);
6635 if (r == priv_->deleted_types_.end())
6636 priv_->added_types_[i->first] = i->second;
6638 for (string_decl_base_sptr_map::const_iterator i =
6639 priv_->inserted_decls_.begin();
6640 i != priv_->inserted_decls_.end();
6643 string_decl_base_sptr_map::const_iterator r =
6644 priv_->deleted_decls_.find(i->first);
6645 if (r == priv_->deleted_decls_.end())
6646 priv_->added_decls_[i->first] = i->second;
6658 for (diff_sptrs_type::const_iterator i =
changed_types().begin();
6664 for (diff_sptrs_type::const_iterator i =
changed_decls().begin();
6684 :
diff(first_scope, second_scope, ctxt),
6722 {
return priv_->member_changes_;}
6744 {
return priv_->member_changes_;}
6755 const decl_base_sptr
6759 return scope->get_member_decls()[i];
6772 const decl_base_sptr
6786 const decl_base_sptr
6790 return scope->get_member_decls()[i];
6803 const decl_base_sptr
6811 {
return priv_->sorted_changed_types_;}
6817 {
return priv_->sorted_changed_decls_;}
6820 scope_diff::removed_types()
const
6821 {
return priv_->removed_types_;}
6824 scope_diff::removed_decls()
const
6825 {
return priv_->removed_decls_;}
6828 scope_diff::added_types()
const
6829 {
return priv_->added_types_;}
6832 scope_diff::added_decls()
const
6833 {
return priv_->added_decls_;}
6840 if (diff::priv_->pretty_representation_.empty())
6842 std::ostringstream o;
6848 diff::priv_->pretty_representation_ = o.str();
6850 return diff::priv_->pretty_representation_;
6872 return ir::NO_CHANGE_KIND;
6883 context()->get_reporter()->report(*
this, out, indent);
6909 ABG_ASSERT(d->first_scope() == first && d->second_scope() == second);
6912 first->get_member_decls().end(),
6913 second->get_member_decls().begin(),
6914 second->get_member_decls().end(),
6915 d->member_changes());
6917 d->ensure_lookup_tables_populated();
6943 ctxt->initialize_canonical_diff(d);
6967 ABG_ASSERT(first->get_index() == second->get_index());
6980 {
return dynamic_pointer_cast<function_decl::parameter>(
first_subject());}
6988 {
return dynamic_pointer_cast<function_decl::parameter>(
second_subject());}
6998 {
return priv_->type_diff;}
7008 if (diff::priv_->pretty_representation_.empty())
7010 std::ostringstream o;
7011 o <<
"function_parameter_diff["
7016 diff::priv_->pretty_representation_ = o.str();
7018 return diff::priv_->pretty_representation_;
7039 return ir::NO_CHANGE_KIND;
7050 context()->get_reporter()->report(*
this, out, indent);
7084 if (!first || !second)
7088 ctxt->initialize_canonical_diff(result);
7097 function_type_diff::ensure_lookup_tables_populated()
7099 priv_->return_type_diff_ =
7106 for (vector<deletion>::const_iterator i =
7107 priv_->parm_changes_.deletions().begin();
7108 i != priv_->parm_changes_.deletions().end();
7113 parm_name = parm->get_name_id();
7117 priv_->deleted_parms_[parm_name] = parm;
7118 priv_->deleted_parms_by_id_[parm->get_index()] = parm;
7121 for (vector<insertion>::const_iterator i =
7122 priv_->parm_changes_.insertions().begin();
7123 i != priv_->parm_changes_.insertions().end();
7126 for (vector<unsigned>::const_iterator j =
7127 i->inserted_indexes().begin();
7128 j != i->inserted_indexes().end();
7132 parm_name = parm->get_name_id();
7137 string_parm_map::const_iterator k =
7138 priv_->deleted_parms_.find(parm_name);
7139 if (k != priv_->deleted_parms_.end())
7141 if (*k->second != *parm)
7142 priv_->subtype_changed_parms_[parm_name] =
7144 priv_->deleted_parms_.erase(parm_name);
7147 priv_->added_parms_[parm_name] = parm;
7150 unsigned_parm_map::const_iterator k =
7151 priv_->deleted_parms_by_id_.find(parm->get_index());
7152 if (k != priv_->deleted_parms_by_id_.end())
7154 if (*k->second != *parm
7155 && (k->second->get_name_id() != parm_name))
7156 priv_->changed_parms_by_id_[parm->get_index()] =
7158 priv_->added_parms_.erase(parm_name);
7159 priv_->deleted_parms_.erase(k->second->get_name_id());
7160 priv_->deleted_parms_by_id_.erase(parm->get_index());
7163 priv_->added_parms_by_id_[parm->get_index()] = parm;
7169 priv_->sorted_subtype_changed_parms_);
7171 priv_->sorted_changed_parms_by_id_);
7173 priv_->sorted_deleted_parms_);
7176 priv_->sorted_added_parms_);
7186 function_type_diff::deleted_parameter_at(
int i)
const
7192 const vector<function_decl::parameter_sptr>&
7194 {
return priv_->sorted_deleted_parms_;}
7199 const vector<function_decl::parameter_sptr>&
7201 {
return priv_->sorted_added_parms_;}
7210 function_type_diff::inserted_parameter_at(
int i)
const
7238 {
return dynamic_pointer_cast<function_type>(
first_subject());}
7254 {
return priv_->return_type_diff_;}
7261 {
return priv_->subtype_changed_parms_;}
7268 {
return priv_->deleted_parms_;}
7275 {
return priv_->added_parms_;}
7285 if (diff::priv_->pretty_representation_.empty())
7287 std::ostringstream o;
7288 o <<
"function_type_diff["
7293 diff::priv_->pretty_representation_ = o.str();
7295 return diff::priv_->pretty_representation_;
7319 return ir::NO_CHANGE_KIND;
7331 context()->get_reporter()->report(*
this, out, indent);
7345 for (vector<fn_parm_diff_sptr>::const_iterator i =
7346 priv_->sorted_subtype_changed_parms_.begin();
7347 i != priv_->sorted_subtype_changed_parms_.end();
7352 for (vector<fn_parm_diff_sptr>::const_iterator i =
7353 priv_->sorted_changed_parms_by_id_.begin();
7354 i != priv_->sorted_changed_parms_by_id_.end();
7377 if (!first || !second)
7386 first->get_parameters().end(),
7387 second->get_first_parm(),
7388 second->get_parameters().end(),
7389 result->priv_->parm_changes_);
7391 result->ensure_lookup_tables_populated();
7393 ctxt->initialize_canonical_diff(result);
7403 function_decl_diff::ensure_lookup_tables_populated()
7440 {
return dynamic_pointer_cast<function_decl>(
first_subject());}
7448 function_decl_diff::type_diff()
const
7449 {
return priv_->type_diff_;}
7456 if (diff::priv_->pretty_representation_.empty())
7458 std::ostringstream o;
7459 o <<
"function_diff["
7464 diff::priv_->pretty_representation_ = o.str();
7466 return diff::priv_->pretty_representation_;
7485 return ir::NO_CHANGE_KIND;
7497 context()->get_reporter()->report(*
this, out, indent);
7517 if (!first || !second)
7529 result->priv_->type_diff_ = type_diff;
7531 result->ensure_lookup_tables_populated();
7533 ctxt->initialize_canonical_diff(result);
7577 if (diff::priv_->pretty_representation_.empty())
7579 std::ostringstream o;
7580 o <<
"type_decl_diff["
7585 diff::priv_->pretty_representation_ = o.str();
7587 return diff::priv_->pretty_representation_;
7605 return ir::NO_CHANGE_KIND;
7616 context()->get_reporter()->report(*
this, out, indent);
7654 ctxt->initialize_canonical_diff(result);
7691 priv_(new
priv(underlying))
7699 {
return dynamic_pointer_cast<typedef_decl>(
first_subject());}
7715 {
return priv_->underlying_type_diff_;}
7724 {priv_->underlying_type_diff_ = d;}
7731 if (diff::priv_->pretty_representation_.empty())
7733 std::ostringstream o;
7734 o <<
"typedef_diff["
7739 diff::priv_->pretty_representation_ = o.str();
7741 return diff::priv_->pretty_representation_;
7763 return ir::NO_CHANGE_KIND;
7775 context()->get_reporter()->report(*
this, out, indent);
7795 diff_sptr d = compute_diff_for_types(first->get_underlying_type(),
7796 second->get_underlying_type(),
7800 ctxt->initialize_canonical_diff(result);
7852 priv_(new
priv(first, second))
7861 {
return priv_->first_;}
7868 {
return priv_->second_;}
7882 {
return ir::NO_CHANGE_KIND;}
7921 compute_diff(static_pointer_cast<scope_decl>(first->get_global_scope()),
7922 static_pointer_cast<scope_decl>(second->get_global_scope()),
7926 ctxt->initialize_canonical_diff(tu_diff);
7936 struct diff_maps::priv
7959 diff_maps::~diff_maps() =
default;
7966 {
return priv_->type_decl_diff_map_;}
7973 {
return priv_->type_decl_diff_map_;}
7980 {
return priv_->enum_diff_map_;}
7987 {
return priv_->enum_diff_map_;}
7994 {
return priv_->class_diff_map_;}
8001 {
return priv_->class_diff_map_;}
8008 {
return priv_->union_diff_map_;}
8015 {
return priv_->union_diff_map_;}
8022 {
return priv_->typedef_diff_map_;}
8029 {
return priv_->typedef_diff_map_;}
8036 {
return priv_->subrange_diff_map_;}
8043 {
return priv_->subrange_diff_map_;}
8050 {
return priv_->array_diff_map_;}
8057 {
return priv_->array_diff_map_;}
8064 {
return priv_->reference_diff_map_;}
8071 {{
return priv_->reference_diff_map_;}}
8078 {
return priv_->fn_parm_diff_map_;}
8085 {
return priv_->fn_parm_diff_map_;}
8092 {
return priv_->function_type_diff_map_;}
8099 {
return priv_->function_type_diff_map_;}
8106 {
return priv_->function_decl_diff_map_;}
8113 {
return priv_->function_decl_diff_map_;}
8120 {
return priv_->var_decl_diff_map_;}
8127 {
return priv_->var_decl_diff_map_;}
8134 {
return priv_->distinct_diff_map_;}
8141 {
return priv_->distinct_diff_map_;}
8199 diff_artifact_set_map_type::iterator i =
8200 priv_->impacted_artifacts_map_.find(dif);
8202 if (i == priv_->impacted_artifacts_map_.end())
8205 set.insert(impacted_iface);
8206 priv_->impacted_artifacts_map_[dif] = set;
8209 i->second.insert(impacted_iface);
8223 diff_artifact_set_map_type::iterator i =
8224 priv_->impacted_artifacts_map_.find(d);
8226 if (i == priv_->impacted_artifacts_map_.end())
8242 : priv_(new
priv(ctxt))
8250 {
return priv_->num_func_removed;}
8257 {priv_->num_func_removed = n;}
8267 if (priv_->ctxt() && !priv_->ctxt()->show_deleted_fns())
8268 return num_func_removed();
8269 return priv_->num_removed_func_filtered_out;
8278 {priv_->num_removed_func_filtered_out = t;}
8289 ABG_ASSERT(num_func_removed() >= num_removed_func_filtered_out());
8290 return num_func_removed() - num_removed_func_filtered_out();
8298 {
return priv_->num_func_added;}
8305 {priv_->num_func_added = n;}
8313 if (priv_->ctxt() && !priv_->ctxt()->show_added_fns())
8314 return num_func_added();
8315 return priv_->num_added_func_filtered_out;
8324 {priv_->num_added_func_filtered_out = n;}
8336 ABG_ASSERT(num_func_added() >= num_added_func_filtered_out());
8337 return num_func_added() - num_added_func_filtered_out();
8347 {
return priv_->num_func_changed;}
8356 {priv_->num_func_changed = n;}
8365 {
return priv_->num_changed_func_filtered_out;}
8374 {priv_->num_changed_func_filtered_out = n;}
8382 {
return priv_->num_func_with_virt_offset_changes;}
8391 {priv_->num_func_with_virt_offset_changes = n;}
8402 {
return num_func_changed() - num_changed_func_filtered_out();}
8409 {
return priv_->num_vars_removed;}
8416 {priv_->num_vars_removed = n;}
8425 if (priv_->ctxt() && !priv_->ctxt()->show_deleted_vars())
8426 return num_vars_removed();
8427 return priv_->num_removed_vars_filtered_out;
8436 {priv_->num_removed_vars_filtered_out = n;}
8448 ABG_ASSERT(num_vars_removed() >= num_removed_vars_filtered_out());
8449 return num_vars_removed() - num_removed_vars_filtered_out();
8457 {
return priv_->num_vars_added;}
8464 {priv_->num_vars_added = n;}
8473 if (priv_->ctxt() && !priv_->ctxt()->show_added_vars())
8474 return num_vars_added();
8475 return priv_->num_added_vars_filtered_out;
8484 {priv_->num_added_vars_filtered_out = n;}
8496 ABG_ASSERT(num_vars_added() >= num_added_vars_filtered_out());
8497 return num_vars_added() - num_added_vars_filtered_out();
8507 {
return priv_->num_vars_changed;}
8516 {priv_->num_vars_changed = n;}
8525 {
return priv_->num_changed_vars_filtered_out;}
8534 {priv_->num_changed_vars_filtered_out = n;}
8545 {
return num_vars_changed() - num_changed_vars_filtered_out();}
8554 {
return priv_->num_func_syms_removed;}
8563 {priv_->num_func_syms_removed = n;}
8574 && !priv_->ctxt()->show_symbols_unreferenced_by_debug_info())
8575 return num_func_syms_removed();
8576 return priv_->num_removed_func_syms_filtered_out;
8586 {priv_->num_removed_func_syms_filtered_out = n;}
8601 ABG_ASSERT(num_func_syms_removed() >= num_removed_func_syms_filtered_out());
8602 return num_func_syms_removed() - num_removed_func_syms_filtered_out();
8612 {
return priv_->num_func_syms_added;}
8621 {priv_->num_func_syms_added = n;}
8632 && !(priv_->ctxt()->show_added_symbols_unreferenced_by_debug_info()
8633 && priv_->ctxt()->show_symbols_unreferenced_by_debug_info()))
8634 return num_func_syms_added();
8635 return priv_->num_added_func_syms_filtered_out;
8645 {priv_->num_added_func_syms_filtered_out = n;}
8660 ABG_ASSERT(num_func_syms_added() >= num_added_func_syms_filtered_out());
8661 return num_func_syms_added()- num_added_func_syms_filtered_out();
8671 {
return priv_->num_var_syms_removed;}
8680 {priv_->num_var_syms_removed = n;}
8691 && !priv_->ctxt()->show_symbols_unreferenced_by_debug_info())
8692 return num_var_syms_removed();
8693 return priv_->num_removed_var_syms_filtered_out;
8703 {priv_->num_removed_var_syms_filtered_out = n;}
8718 ABG_ASSERT(num_var_syms_removed() >= num_removed_var_syms_filtered_out());
8719 return num_var_syms_removed() - num_removed_var_syms_filtered_out();
8729 {
return priv_->num_var_syms_added;}
8738 {priv_->num_var_syms_added = n;}
8749 && !(priv_->ctxt()->show_added_symbols_unreferenced_by_debug_info()
8750 && priv_->ctxt()->show_symbols_unreferenced_by_debug_info()))
8751 return num_var_syms_added();
8752 return priv_->num_added_var_syms_filtered_out;
8762 {priv_->num_added_var_syms_filtered_out = n;}
8777 ABG_ASSERT(num_var_syms_added() >= num_added_var_syms_filtered_out());
8778 return num_var_syms_added() - num_added_var_syms_filtered_out();
8786 {
return priv_->num_leaf_changes;}
8793 {priv_->num_leaf_changes = n;}
8801 {
return priv_->num_leaf_changes_filtered_out;}
8810 {priv_->num_leaf_changes_filtered_out = n;}
8823 ABG_ASSERT(num_leaf_changes() >= num_leaf_changes_filtered_out());
8824 return num_leaf_changes() - num_leaf_changes_filtered_out();
8832 {
return priv_->num_leaf_type_changes;}
8839 {priv_->num_leaf_type_changes = n;}
8846 {
return priv_->num_leaf_type_changes_filtered_out;}
8852 {priv_->num_leaf_type_changes_filtered_out = n;}
8862 {
return num_leaf_type_changes() - num_leaf_type_changes_filtered_out();}
8869 {
return priv_->num_leaf_func_changes;}
8876 {priv_->num_leaf_func_changes = n;}
8885 {
return priv_->num_leaf_func_changes_filtered_out;}
8894 {priv_->num_leaf_func_changes_filtered_out = n;}
8905 {
return num_leaf_func_changes() - num_leaf_func_changes_filtered_out();}
8912 {
return priv_->num_leaf_var_changes;}
8919 {priv_->num_leaf_var_changes = n;}
8931 {
return priv_->num_added_unreachable_types;}
8944 {priv_->num_added_unreachable_types = n;}
8955 {
return priv_->num_added_unreachable_types_filtered_out;}
8966 {priv_->num_added_unreachable_types_filtered_out = n;}
8980 num_added_unreachable_types_filtered_out());
8982 return (num_added_unreachable_types()
8984 num_added_unreachable_types_filtered_out());
8997 {
return priv_->num_removed_unreachable_types;}
9009 {priv_->num_removed_unreachable_types = n;}
9020 {
return priv_->num_removed_unreachable_types_filtered_out;}
9031 {priv_->num_removed_unreachable_types_filtered_out = n;}
9045 num_removed_unreachable_types_filtered_out());
9047 return (num_removed_unreachable_types()
9049 num_removed_unreachable_types_filtered_out());
9062 {
return priv_->num_changed_unreachable_types;}
9074 {priv_->num_changed_unreachable_types = n;}
9085 {
return priv_->num_changed_unreachable_types_filtered_out;}
9096 {priv_->num_changed_unreachable_types_filtered_out = n;}
9110 num_changed_unreachable_types_filtered_out());
9112 return (num_changed_unreachable_types()
9114 num_changed_unreachable_types_filtered_out());
9124 {
return priv_->num_leaf_var_changes_filtered_out;}
9133 {priv_->num_leaf_var_changes_filtered_out = n;}
9144 {
return num_leaf_var_changes() - num_leaf_var_changes_filtered_out();}
9154 {
return ctxt_.lock();}
9162 return (deleted_fns_.empty()
9163 && added_fns_.empty()
9164 && changed_fns_map_.empty()
9165 && deleted_vars_.empty()
9166 && added_vars_.empty()
9167 && changed_vars_map_.empty());
9174 deleted_fns_.clear();
9176 changed_fns_map_.clear();
9177 deleted_vars_.clear();
9178 added_vars_.clear();
9179 changed_vars_map_.clear();
9187 if (!lookup_tables_empty())
9195 for (vector<deletion>::const_iterator it = e.deletions().begin();
9196 it != e.deletions().end();
9199 unsigned i = it->index();
9200 ABG_ASSERT(i < first_->get_functions().size());
9209 deleted_fns_[n] = deleted_fn;
9212 for (vector<insertion>::const_iterator it = e.insertions().begin();
9213 it != e.insertions().end();
9216 for (vector<unsigned>::const_iterator iit =
9217 it->inserted_indexes().begin();
9218 iit != it->inserted_indexes().end();
9229 string_function_ptr_map::const_iterator j =
9230 deleted_fns_.find(n);
9231 if (j != deleted_fns_.end())
9236 if (*j->second != *added_fn)
9237 changed_fns_map_[j->first] = d;
9238 deleted_fns_.erase(j);
9241 added_fns_[n] = added_fn;
9250 vector<string> to_delete;
9251 for (string_function_ptr_map::const_iterator i = deleted_fns_.begin();
9252 i != deleted_fns_.end();
9254 if (second_->lookup_function_symbol(*i->second->get_symbol()))
9255 to_delete.push_back(i->first);
9257 for (vector<string>::const_iterator i = to_delete.begin();
9258 i != to_delete.end();
9260 deleted_fns_.erase(*i);
9265 for (string_function_ptr_map::const_iterator i = added_fns_.begin();
9266 i != added_fns_.end();
9269 if (first_->lookup_function_symbol(*i->second->get_symbol()))
9270 to_delete.push_back(i->first);
9271 else if (! i->second->get_symbol()->get_version().is_empty()
9272 && i->second->get_symbol()->get_version().is_default())
9280 if (first_->lookup_function_symbol(i->second->get_symbol()->get_name(),
9282 to_delete.push_back(i->first);
9286 for (vector<string>::const_iterator i = to_delete.begin();
9287 i != to_delete.end();
9289 added_fns_.erase(*i);
9295 for (vector<deletion>::const_iterator it = e.deletions().begin();
9296 it != e.deletions().end();
9299 unsigned i = it->index();
9300 ABG_ASSERT(i < first_->get_variables().size());
9302 var_decl* deleted_var = first_->get_variables()[i];
9303 string n = deleted_var->
get_id();
9305 ABG_ASSERT(deleted_vars_.find(n) == deleted_vars_.end());
9306 deleted_vars_[n] = deleted_var;
9309 for (vector<insertion>::const_iterator it = e.insertions().begin();
9310 it != e.insertions().end();
9313 for (vector<unsigned>::const_iterator iit =
9314 it->inserted_indexes().begin();
9315 iit != it->inserted_indexes().end();
9319 var_decl* added_var = second_->get_variables()[i];
9320 string n = added_var->
get_id();
9323 string_var_ptr_map::const_iterator k = added_vars_.find(n);
9324 if ( k != added_vars_.end())
9331 string_var_ptr_map::const_iterator j =
9332 deleted_vars_.find(n);
9333 if (j != deleted_vars_.end())
9335 if (*j->second != *added_var)
9341 deleted_vars_.erase(j);
9344 added_vars_[n] = added_var;
9348 sorted_changed_vars_);
9354 vector<string> to_delete;
9355 for (string_var_ptr_map::const_iterator i = deleted_vars_.begin();
9356 i != deleted_vars_.end();
9358 if (second_->lookup_variable_symbol(*i->second->get_symbol()))
9359 to_delete.push_back(i->first);
9361 for (vector<string>::const_iterator i = to_delete.begin();
9362 i != to_delete.end();
9364 deleted_vars_.erase(*i);
9369 for (string_var_ptr_map::const_iterator i = added_vars_.begin();
9370 i != added_vars_.end();
9372 if (first_->lookup_variable_symbol(*i->second->get_symbol()))
9373 to_delete.push_back(i->first);
9374 else if (! i->second->get_symbol()->get_version().is_empty()
9375 && i->second->get_symbol()->get_version().is_default())
9383 if (first_->lookup_variable_symbol(i->second->get_symbol()->get_name(),
9385 to_delete.push_back(i->first);
9388 for (vector<string>::const_iterator i = to_delete.begin();
9389 i != to_delete.end();
9391 added_vars_.erase(*i);
9399 for (vector<deletion>::const_iterator it = e.deletions().begin();
9400 it != e.deletions().end();
9403 unsigned i = it->index();
9404 ABG_ASSERT(i < first_->get_unreferenced_function_symbols().size());
9406 first_->get_unreferenced_function_symbols()[i];
9407 if (!second_->lookup_function_symbol(*deleted_sym))
9408 deleted_unrefed_fn_syms_[deleted_sym->get_id_string()] = deleted_sym;
9411 for (vector<insertion>::const_iterator it = e.insertions().begin();
9412 it != e.insertions().end();
9415 for (vector<unsigned>::const_iterator iit =
9416 it->inserted_indexes().begin();
9417 iit != it->inserted_indexes().end();
9421 ABG_ASSERT(i < second_->get_unreferenced_function_symbols().size());
9423 second_->get_unreferenced_function_symbols()[i];
9424 if ((deleted_unrefed_fn_syms_.find(added_sym->get_id_string())
9425 == deleted_unrefed_fn_syms_.end()))
9427 if (!first_->lookup_function_symbol(*added_sym))
9430 if (! added_sym->get_version().is_empty()
9431 && added_sym->get_version().is_default())
9439 if (first_->lookup_function_symbol(added_sym->get_name(),
9445 added_unrefed_fn_syms_[added_sym->get_id_string()] =
9450 deleted_unrefed_fn_syms_.erase(added_sym->get_id_string());
9460 for (vector<deletion>::const_iterator it = e.deletions().begin();
9461 it != e.deletions().end();
9464 unsigned i = it->index();
9465 ABG_ASSERT(i < first_->get_unreferenced_variable_symbols().size());
9467 first_->get_unreferenced_variable_symbols()[i];
9468 if (!second_->lookup_variable_symbol(*deleted_sym))
9469 deleted_unrefed_var_syms_[deleted_sym->get_id_string()] = deleted_sym;
9472 for (vector<insertion>::const_iterator it = e.insertions().begin();
9473 it != e.insertions().end();
9476 for (vector<unsigned>::const_iterator iit =
9477 it->inserted_indexes().begin();
9478 iit != it->inserted_indexes().end();
9482 ABG_ASSERT(i < second_->get_unreferenced_variable_symbols().size());
9484 second_->get_unreferenced_variable_symbols()[i];
9485 if (deleted_unrefed_var_syms_.find(added_sym->get_id_string())
9486 == deleted_unrefed_var_syms_.end())
9488 if (!first_->lookup_variable_symbol(*added_sym))
9491 if (! added_sym->get_version().is_empty()
9492 && added_sym->get_version().is_default())
9500 if (first_->lookup_variable_symbol(added_sym->get_name(),
9506 added_unrefed_var_syms_[added_sym->get_id_string()] =
9511 deleted_unrefed_var_syms_.erase(added_sym->get_id_string());
9522 for (vector<deletion>::const_iterator it = e.deletions().begin();
9523 it != e.deletions().end();
9526 unsigned i = it->index();
9528 (first_->get_types_not_reachable_from_public_interfaces()[i]);
9534 deleted_unreachable_types_[repr] = t;
9539 for (vector<insertion>::const_iterator it = e.insertions().begin();
9540 it != e.insertions().end();
9543 for (vector<unsigned>::const_iterator iit =
9544 it->inserted_indexes().begin();
9545 iit != it->inserted_indexes().end();
9550 (second_->get_types_not_reachable_from_public_interfaces()[i]);
9568 string_type_base_sptr_map::const_iterator j =
9569 deleted_unreachable_types_.find(repr);
9570 if (j != deleted_unreachable_types_.end())
9575 decl_base_sptr old_type =
is_decl(j->second);
9576 decl_base_sptr new_type =
is_decl(t);
9577 if (old_type != new_type)
9585 changed_unreachable_types_[repr]= d;
9591 deleted_unreachable_types_.erase(j);
9596 added_unreachable_types_[repr] = t;
9626 return fn_suppr->suppresses_function(fn, k, ctxt);
9645 variable_is_suppressed(
const var_decl* var,
9653 return var_suppr->suppresses_variable(var, k, ctxt);
9665 for (suppressions_type::const_iterator i = suppressions.begin();
9666 i != suppressions.end();
9673 for (string_function_ptr_map::const_iterator e = added_fns_.begin();
9674 e != added_fns_.end();
9676 if (function_is_suppressed(e->second, fn_suppr,
9679 suppressed_added_fns_[e->first] = e->second;
9682 for (string_function_ptr_map::const_iterator e = deleted_fns_.begin();
9683 e != deleted_fns_.end();
9685 if (function_is_suppressed(e->second, fn_suppr,
9688 suppressed_deleted_fns_[e->first] = e->second;
9691 for (string_elf_symbol_map::const_iterator e =
9692 added_unrefed_fn_syms_.begin();
9693 e != added_unrefed_fn_syms_.end();
9695 if (fn_suppr->suppresses_function_symbol(e->second,
9698 suppressed_added_unrefed_fn_syms_[e->first] = e->second;
9701 for (string_elf_symbol_map::const_iterator e =
9702 deleted_unrefed_fn_syms_.begin();
9703 e != deleted_unrefed_fn_syms_.end();
9705 if (fn_suppr->suppresses_function_symbol(e->second,
9708 suppressed_deleted_unrefed_fn_syms_[e->first] = e->second;
9716 for (string_function_ptr_map::const_iterator e = added_fns_.begin();
9717 e != added_fns_.end();
9726 if (type_suppr->suppresses_type(c, ctxt))
9727 suppressed_added_fns_[e->first] = e->second;
9730 for (string_function_ptr_map::const_iterator e = deleted_fns_.begin();
9731 e != deleted_fns_.end();
9740 if (type_suppr->suppresses_type(c, ctxt))
9741 suppressed_deleted_fns_[e->first] = e->second;
9746 for (string_type_base_sptr_map::const_iterator e =
9747 deleted_unreachable_types_.begin();
9748 e != deleted_unreachable_types_.end();
9750 if (type_suppr->suppresses_type(e->second, ctxt))
9751 suppressed_deleted_unreachable_types_[e->first] = e->second;
9755 for (string_type_base_sptr_map::const_iterator e =
9756 added_unreachable_types_.begin();
9757 e != added_unreachable_types_.end();
9759 if (type_suppr->suppresses_type(e->second, ctxt))
9760 suppressed_added_unreachable_types_[e->first] = e->second;
9767 for (string_var_ptr_map::const_iterator e = added_vars_.begin();
9768 e != added_vars_.end();
9770 if (variable_is_suppressed(e->second, var_suppr,
9773 suppressed_added_vars_[e->first] = e->second;
9776 for (string_var_ptr_map::const_iterator e = deleted_vars_.begin();
9777 e != deleted_vars_.end();
9779 if (variable_is_suppressed(e->second, var_suppr,
9782 suppressed_deleted_vars_[e->first] = e->second;
9785 for (string_elf_symbol_map::const_iterator e =
9786 added_unrefed_var_syms_.begin();
9787 e != added_unrefed_var_syms_.end();
9789 if (var_suppr->suppresses_variable_symbol(e->second,
9792 suppressed_added_unrefed_var_syms_[e->first] = e->second;
9795 for (string_elf_symbol_map::const_iterator e =
9796 deleted_unrefed_var_syms_.begin();
9797 e != deleted_unrefed_var_syms_.end();
9799 if (var_suppr->suppresses_variable_symbol(e->second,
9802 suppressed_deleted_unrefed_var_syms_[e->first] = e->second;
9820 string_function_ptr_map::const_iterator i =
9821 suppressed_deleted_fns_.find(fn->
get_id());
9823 return (i != suppressed_deleted_fns_.end());
9840 string_type_base_sptr_map::const_iterator i =
9841 suppressed_added_unreachable_types_.find(repr);
9842 if (i == suppressed_added_unreachable_types_.end())
9862 string_type_base_sptr_map::const_iterator i =
9863 suppressed_deleted_unreachable_types_.find(repr);
9864 if (i == suppressed_deleted_unreachable_types_.end())
9883 string_function_ptr_map::const_iterator i =
9884 suppressed_added_fns_.find(fn->
get_id());
9886 return (i != suppressed_added_fns_.end());
9902 string_var_ptr_map::const_iterator i =
9903 suppressed_deleted_vars_.find(var->
get_id());
9905 return (i != suppressed_deleted_vars_.end());
9921 string_var_ptr_map::const_iterator i =
9922 suppressed_added_vars_.find(var->
get_id());
9924 return (i != suppressed_added_vars_.end());
9940 string_elf_symbol_map::const_iterator i =
9941 suppressed_deleted_unrefed_fn_syms_.find(s->
get_id_string());
9943 return (i != suppressed_deleted_unrefed_fn_syms_.end());
9959 string_elf_symbol_map::const_iterator i =
9962 return (i != suppressed_added_unrefed_fn_syms_.end());
9978 string_elf_symbol_map::const_iterator i =
9979 suppressed_deleted_unrefed_var_syms_.find(s->
get_id_string());
9981 return (i != suppressed_deleted_unrefed_var_syms_.end());
9997 string_elf_symbol_map::const_iterator i =
9998 suppressed_added_unrefed_var_syms_.find(s->
get_id_string());
10000 return (i != suppressed_added_unrefed_var_syms_.end());
10003 #ifdef do_count_diff_map_changes
10004 #undef do_count_diff_map_changes
10006 #define do_count_diff_map_changes(diff_map, n_changes, n_filtered) \
10008 string_diff_ptr_map::const_iterator i; \
10009 for (i = diff_map.begin(); \
10010 i != diff_map.end(); \
10013 if (const var_diff* d = is_var_diff(i->second)) \
10014 if (is_data_member(d->first_var())) \
10017 if (i->second->has_local_changes()) \
10019 if (!i->second->get_canonical_diff()->to_be_reported()) \
10035 count_leaf_type_changes(num_changes, num_filtered);
10038 do_count_diff_map_changes(leaf_diffs_.get_function_decl_diff_map(),
10039 num_changes, num_filtered);
10040 do_count_diff_map_changes(leaf_diffs_.get_var_decl_diff_map(),
10041 num_changes, num_filtered);
10054 size_t &num_filtered)
10056 do_count_diff_map_changes(leaf_diffs_.get_type_decl_diff_map(),
10057 num_changes, num_filtered);
10058 do_count_diff_map_changes(leaf_diffs_.get_enum_diff_map(),
10059 num_changes, num_filtered);
10060 do_count_diff_map_changes(leaf_diffs_.get_class_diff_map(),
10061 num_changes, num_filtered);
10062 do_count_diff_map_changes(leaf_diffs_.get_union_diff_map(),
10063 num_changes, num_filtered);
10064 do_count_diff_map_changes(leaf_diffs_.get_typedef_diff_map(),
10065 num_changes, num_filtered);
10066 do_count_diff_map_changes(leaf_diffs_.get_subrange_diff_map(),
10067 num_changes, num_filtered);
10068 do_count_diff_map_changes(leaf_diffs_.get_array_diff_map(),
10069 num_changes, num_filtered);
10070 do_count_diff_map_changes(leaf_diffs_.get_distinct_diff_map(),
10071 num_changes, num_filtered);
10072 do_count_diff_map_changes(leaf_diffs_.get_fn_parm_diff_map(),
10073 num_changes, num_filtered);
10101 size_t &num_deleted,
10102 size_t &num_changed,
10103 size_t &num_filtered_added,
10104 size_t &num_filtered_deleted,
10105 size_t &num_filtered_changed)
10107 num_added = added_unreachable_types_.size();
10108 num_deleted = deleted_unreachable_types_.size();
10109 num_changed = changed_unreachable_types_.size();
10110 num_filtered_added = suppressed_added_unreachable_types_.size();
10111 num_filtered_deleted = suppressed_deleted_unreachable_types_.size();
10113 for (vector<diff_sptr>::const_iterator i =
10117 if (!(*i)->to_be_reported())
10118 ++num_filtered_changed;
10130 const vector<diff_sptr>&
10133 if (changed_unreachable_types_sorted_.empty())
10134 if (!changed_unreachable_types_.empty())
10136 changed_unreachable_types_sorted_);
10138 return changed_unreachable_types_sorted_;
10173 if (ctxt->perform_change_categorization())
10175 if (get_context()->
do_log())
10177 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10178 <<
"applying filters to "
10179 << changed_fns_.size()
10180 <<
" changed fns ...\n";
10186 for (function_decl_diff_sptrs_type::const_iterator i =
10187 changed_fns_.begin();
10188 i != changed_fns_.end();
10192 ctxt->maybe_apply_filters(
diff);
10195 if (get_context()->
do_log())
10198 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10199 <<
"filters to changed fn applied!:" << t <<
"\n";
10201 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10202 <<
"applying filters to "
10203 << sorted_changed_vars_.size()
10204 <<
" changed vars ...\n";
10210 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
10211 i != sorted_changed_vars_.end();
10215 ctxt->maybe_apply_filters(
diff);
10218 if (get_context()->
do_log())
10221 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10222 <<
"filters to changed vars applied!:" << t <<
"\n";
10224 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10225 <<
"applying filters to unreachable types ...\n";
10231 for (diff_sptrs_type::const_iterator i =
10237 ctxt->maybe_apply_filters(
diff);
10240 if (get_context()->do_log())
10243 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10244 <<
"filters to unreachable types applied!:" << t <<
"\n";
10246 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10247 <<
"categorizing redundant changed sub nodes ...\n";
10251 categorize_redundant_changed_sub_nodes();
10253 if (get_context()->
do_log())
10256 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10257 <<
"redundant changed sub nodes categorized!:" << t <<
"\n";
10259 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10260 <<
"count changed fns ...\n";
10268 for (function_decl_diff_sptrs_type::const_iterator i =
10269 changed_fns_.begin();
10270 i != changed_fns_.end();
10273 if ((*i)->is_filtered_out())
10278 if ((*i)->has_local_changes())
10289 if ((*i)->has_local_changes())
10294 if (get_context()->
do_log())
10297 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10298 <<
"changed fn counted!:" << t <<
"\n";
10300 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10301 <<
"count changed vars ...\n";
10307 for (var_diff_sptrs_type ::const_iterator i = sorted_changed_vars_.begin();
10308 i != sorted_changed_vars_.end();
10311 if ((*i)->is_filtered_out())
10316 if ((*i)->has_local_changes())
10320 if ((*i)->has_local_changes())
10325 if (get_context()->
do_log())
10328 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10329 <<
"changed vars counted!:" << t <<
"\n";
10331 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10332 <<
"count leaf changed types ...\n";
10347 size_t num_type_changes = 0, num_type_filtered = 0;
10348 count_leaf_type_changes(num_type_changes, num_type_filtered);
10354 if (get_context()->
do_log())
10357 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10358 <<
"changed leaf types counted!:" << t <<
"\n";
10360 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10361 <<
"count leaf changed artefacts ...\n";
10367 size_t num_changes = 0, num_filtered = 0;
10368 count_leaf_changes(num_changes, num_filtered);
10374 if (get_context()->
do_log())
10377 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10378 <<
"changed leaf artefacts counted!:" << t <<
"\n";
10380 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10381 <<
"count unreachable types ...\n";
10387 size_t num_added_unreachable_types = 0,
10388 num_changed_unreachable_types = 0,
10389 num_deleted_unreachable_types = 0,
10390 num_added_unreachable_types_filtered = 0,
10391 num_changed_unreachable_types_filtered = 0,
10392 num_deleted_unreachable_types_filtered = 0;
10394 count_unreachable_types(num_added_unreachable_types,
10395 num_deleted_unreachable_types,
10396 num_changed_unreachable_types,
10397 num_added_unreachable_types_filtered,
10398 num_deleted_unreachable_types_filtered,
10399 num_changed_unreachable_types_filtered);
10401 if (get_context()->
do_log())
10404 std::cerr <<
"in apply_filters_and_compute_diff_stats:"
10405 <<
"unreachable types counted!:" << t <<
"\n";
10412 (num_added_unreachable_types_filtered);
10414 (num_deleted_unreachable_types_filtered);
10416 (num_changed_unreachable_types_filtered);
10432 const string& indent)
10435 size_t net_num_leaf_changes =
10448 if (!sonames_equal_)
10449 out << indent <<
"ELF SONAME changed\n";
10451 if (!architectures_equal_)
10452 out << indent <<
"ELF architecture changed\n";
10456 if (ctxt->show_leaf_changes_only())
10458 out <<
"Leaf changes summary: ";
10459 out << net_num_leaf_changes <<
" artifact";
10460 if (net_num_leaf_changes > 1)
10465 out <<
" (" << num_filtered <<
" filtered out)";
10468 out << indent <<
"Changed leaf types summary: "
10472 <<
" filtered out)";
10473 out <<
" leaf type";
10476 out <<
" changed\n";
10479 out << indent <<
"Removed/Changed/Added functions summary: ";
10484 <<
" filtered out)";
10491 <<
" filtered out)";
10498 out <<
"functions";
10504 out << indent <<
"Removed/Changed/Added variables summary: ";
10508 <<
" filtered out)";
10515 <<
" filtered out)";
10522 out <<
"variables";
10525 <<
" filtered out)";
10534 out << indent <<
"Functions changes summary: ";
10539 <<
" filtered out)";
10550 if (total_nb_function_changes <= 1)
10551 out <<
" function";
10553 out <<
" functions";
10560 out << indent <<
"Variables changes summary: ";
10564 <<
" filtered out)";
10575 <<
" filtered out)";
10576 if (total_nb_variable_changes <= 1)
10577 out <<
" variable";
10579 out <<
" variables";
10585 if (ctxt->show_unreachable_types())
10587 size_t total_nb_unreachable_type_changes =
10593 out << indent <<
"Unreachable types summary: "
10598 <<
" filtered out)";
10605 <<
" filtered out)";
10612 <<
" filtered out)";
10613 if (total_nb_unreachable_type_changes <= 1)
10620 if (ctxt->show_symbols_unreferenced_by_debug_info()
10628 if (!ctxt->show_added_symbols_unreferenced_by_debug_info()
10638 <<
"Function symbols changes summary: "
10642 <<
" filtered out)";
10647 <<
" filtered out)";
10648 out <<
" function symbol";
10651 out <<
" not referenced by debug info\n";
10656 if (!ctxt->show_added_symbols_unreferenced_by_debug_info()
10666 <<
"Variable symbols changes summary: "
10670 <<
" filtered out)";
10675 <<
" filtered out)";
10676 out <<
" variable symbol";
10679 out <<
" not referenced by debug info\n";
10693 ctxt->forget_visited_diffs();
10694 for (function_decl_diff_sptrs_type::const_iterator i =
10695 changed_fns_.begin();
10696 i!= changed_fns_.end();
10703 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
10704 i!= sorted_changed_vars_.end();
10711 for (diff_sptrs_type::const_iterator i =
10727 for (function_decl_diff_sptrs_type::const_iterator i = changed_fns_.begin();
10728 i!= changed_fns_.end();
10735 for (var_diff_sptrs_type::const_iterator i = sorted_changed_vars_.begin();
10736 i!= sorted_changed_vars_.end();
10754 if (!ctxt->dump_diff_tree()
10755 || ctxt->error_output_stream() == 0)
10758 if (!changed_fns_.empty())
10760 *ctxt->error_output_stream() <<
"changed functions diff tree: \n\n";
10761 for (function_decl_diff_sptrs_type::const_iterator i =
10762 changed_fns_.begin();
10763 i != changed_fns_.end();
10771 if (!sorted_changed_vars_.empty())
10773 *ctxt->error_output_stream() <<
"\nchanged variables diff tree: \n\n";
10774 for (var_diff_sptrs_type::const_iterator i =
10775 sorted_changed_vars_.begin();
10776 i != sorted_changed_vars_.end();
10786 *ctxt->error_output_stream() <<
"\nchanged unreachable "
10787 "types diff tree: \n\n";
10788 for (vector<diff_sptr>::const_iterator i =
10806 for (function_decl_diff_sptrs_type::const_iterator i =
10825 corpus_sptr second,
10827 : priv_(new
priv(first, second, ctxt))
10830 corpus_diff::~corpus_diff() =
default;
10836 if (priv_->finished_)
10839 priv_->finished_ =
true;
10847 {
return context()->do_log();}
10859 {
return priv_->first_;}
10864 {
return priv_->second_;}
10867 const vector<diff*>&
10869 {
return priv_->children_;}
10887 bool inserted =
false;
10888 for (vector<diff*>::iterator i = priv_->children_.begin();
10889 i != priv_->children_.end();
10892 if (!is_less_than(d.get(), *i))
10894 context()->keep_diff_alive(d);
10895 priv_->children_.insert(i, d.get());
10904 context()->keep_diff_alive(d);
10908 priv_->children_.push_back(d.get());
10916 {
return priv_->fns_edit_script_;}
10922 {
return priv_->vars_edit_script_;}
10929 {
return !priv_->sonames_equal_;}
10936 {
return !priv_->architectures_equal_;}
10943 {
return priv_->deleted_fns_;}
10950 {
return priv_->added_fns_;}
10962 {
return priv_->changed_fns_map_;}
10971 {
return priv_->changed_fns_;}
10979 {
return priv_->deleted_vars_;}
10986 {
return priv_->added_vars_;}
10994 {
return priv_->changed_vars_map_;}
11002 {
return priv_->sorted_changed_vars_;}
11011 {
return priv_->deleted_unrefed_fn_syms_;}
11020 {
return priv_->added_unrefed_fn_syms_;}
11029 {
return priv_->deleted_unrefed_var_syms_;}
11038 {
return priv_->added_unrefed_var_syms_;}
11047 {
return priv_->deleted_unreachable_types_;}
11055 const vector<type_base_sptr>&
11058 if (priv_->deleted_unreachable_types_sorted_.empty())
11059 if (!priv_->deleted_unreachable_types_.empty())
11061 priv_->deleted_unreachable_types_sorted_);
11063 return priv_->deleted_unreachable_types_sorted_;
11073 {
return priv_->added_unreachable_types_;}
11081 const vector<type_base_sptr>&
11084 if (priv_->added_unreachable_types_sorted_.empty())
11085 if (!priv_->added_unreachable_types_.empty())
11087 priv_->added_unreachable_types_sorted_);
11089 return priv_->added_unreachable_types_sorted_;
11099 {
return priv_->changed_unreachable_types_;}
11107 const vector<diff_sptr>&
11109 {
return priv_->changed_unreachable_types_sorted();}
11116 {
return priv_->get_context();}
11123 if (priv_->pretty_representation_.empty())
11125 std::ostringstream o;
11126 o <<
"corpus_diff["
11131 priv_->pretty_representation_ = o.str();
11133 return priv_->pretty_representation_;
11144 || !(priv_->deleted_fns_.empty()
11145 && priv_->added_fns_.empty()
11146 && priv_->changed_fns_map_.empty()
11147 && priv_->deleted_vars_.empty()
11148 && priv_->added_vars_.empty()
11149 && priv_->changed_vars_map_.empty()
11150 && priv_->added_unrefed_fn_syms_.empty()
11151 && priv_->deleted_unrefed_fn_syms_.empty()
11152 && priv_->added_unrefed_var_syms_.empty()
11153 && priv_->deleted_unrefed_var_syms_.empty()
11154 && priv_->deleted_unreachable_types_.empty()
11155 && priv_->added_unreachable_types_.empty()
11156 && priv_->changed_unreachable_types_.empty()));
11228 {
return context()->get_reporter()->diff_has_net_changes(
this);}
11253 if (priv_->diff_stats_)
11254 return *priv_->diff_stats_;
11259 std::cerr <<
"Applying suppressions ...\n";
11268 std::cerr <<
"suppressions applied!:" << t <<
"\n";
11275 std::cerr <<
"Marking leaf nodes ...\n";
11284 std::cerr <<
"leaf nodes marked!:" << t <<
"\n";
11285 std::cerr <<
"Applying filters and computing diff stats ...\n";
11289 priv_->apply_filters_and_compute_diff_stats(*priv_->diff_stats_);
11294 std::cerr <<
"Filters applied and diff stats computed!: " << t <<
"\n";
11297 return *priv_->diff_stats_;
11319 visit_begin(
diff *d)
11364 const corpus_diff *corpus_diff_node = ctxt->get_corpus_diff().get();
11367 if (
diff *iface_diff = get_current_topmost_iface_diff())
11374 get_leaf_diffs().insert_diff_node(d, iface);
11392 if (!
context()->show_leaf_changes_only())
11395 leaf_diff_node_marker_visitor v;
11396 context()->forget_visited_diffs();
11397 bool s =
context()->visiting_a_node_twice_is_forbidden();
11398 context()->forbid_visiting_a_node_twice(
true);
11399 if (
context()->show_impacted_interfaces())
11400 context()->forbid_visiting_a_node_twice_per_interface(
true);
11402 context()->forbid_visiting_a_node_twice(s);
11403 context()->forbid_visiting_a_node_twice_per_interface(
false);
11413 {
return priv_->leaf_diffs_;}
11422 {
return priv_->leaf_diffs_;}
11433 context()->get_reporter()->report(*
this, out, indent);
11448 if (!v.
visit(
this,
true))
11454 for (function_decl_diff_sptrs_type::const_iterator i =
11462 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
11463 ctxt->forget_visited_diffs();
11476 for (var_diff_sptrs_type::const_iterator i =
11484 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
11485 ctxt->forget_visited_diffs();
11502 for (vector<diff_sptr>::const_iterator i =
11510 if (ctxt->visiting_a_node_twice_is_forbidden_per_interface())
11511 ctxt->forget_visited_diffs();
11539 const corpus_sptr s,
11542 typedef corpus::functions::const_iterator fns_it_type;
11543 typedef corpus::variables::const_iterator vars_it_type;
11544 typedef elf_symbols::const_iterator symbols_it_type;
11546 typedef vector<type_base_wptr>::const_iterator type_base_wptr_it_type;
11555 ctxt->set_corpus_diff(r);
11557 if(ctxt->show_soname_change())
11558 r->priv_->sonames_equal_ = f->get_soname() == s->get_soname();
11560 r->priv_->sonames_equal_ =
true;
11562 r->priv_->architectures_equal_ =
11563 f->get_architecture_name() == s->get_architecture_name();
11566 diff_utils::compute_diff<fns_it_type, eq_type>(f->get_functions().begin(),
11567 f->get_functions().end(),
11568 s->get_functions().begin(),
11569 s->get_functions().end(),
11570 r->priv_->fns_edit_script_);
11573 diff_utils::compute_diff<vars_it_type, eq_type>
11574 (f->get_variables().begin(), f->get_variables().end(),
11575 s->get_variables().begin(), s->get_variables().end(),
11576 r->priv_->vars_edit_script_);
11580 diff_utils::compute_diff<symbols_it_type, eq_type>
11581 (f->get_unreferenced_function_symbols().begin(),
11582 f->get_unreferenced_function_symbols().end(),
11583 s->get_unreferenced_function_symbols().begin(),
11584 s->get_unreferenced_function_symbols().end(),
11585 r->priv_->unrefed_fn_syms_edit_script_);
11589 diff_utils::compute_diff<symbols_it_type, eq_type>
11590 (f->get_unreferenced_variable_symbols().begin(),
11591 f->get_unreferenced_variable_symbols().end(),
11592 s->get_unreferenced_variable_symbols().begin(),
11593 s->get_unreferenced_variable_symbols().end(),
11594 r->priv_->unrefed_var_syms_edit_script_);
11596 if (ctxt->show_unreachable_types())
11599 diff_utils::compute_diff<type_base_wptr_it_type, eq_type>
11600 (f->get_types_not_reachable_from_public_interfaces().begin(),
11601 f->get_types_not_reachable_from_public_interfaces().end(),
11602 s->get_types_not_reachable_from_public_interfaces().begin(),
11603 s->get_types_not_reachable_from_public_interfaces().end(),
11604 r->priv_->unreachable_types_edit_script_);
11606 r->priv_->ensure_lookup_tables_populated();
11627 const corpus_group_sptr& s,
11631 corpus_sptr c1 = f;
11632 corpus_sptr c2 = s;
11643 struct diff_node_visitor::priv
11645 diff* topmost_interface_diff;
11649 : topmost_interface_diff(),
11654 : topmost_interface_diff(),
11664 diff_node_visitor::~diff_node_visitor() =
default;
11670 : priv_(new priv(k))
11680 {
return priv_->kind;}
11700 {priv_->kind = priv_->kind | v;}
11708 {priv_->topmost_interface_diff = d;}
11716 {
return priv_->topmost_interface_diff;}
11943 bool already_visited = d->
context()->diff_has_been_visited(d);
11951 bool update_canonical = !already_visited && canonical;
11953 for (vector<diff*>::const_iterator i = d->
children_nodes().begin();
11986 if (!already_visited && canonical)
11987 if (update_canonical)
11988 canonical->add_to_category(c);
12002 category_propagation_visitor v;
12003 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12004 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
12005 diff_tree->
context()->forget_visited_diffs();
12007 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12029 category_propagation_visitor v;
12030 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12031 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
12033 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12058 visit_begin(
diff* d)
12060 bool is_private_type =
false;
12071 if (canonical_diff != d)
12127 bool has_non_suppressed_child =
false;
12128 bool has_non_empty_child =
false;
12129 bool has_suppressed_child =
false;
12130 bool has_non_private_child =
false;
12131 bool has_private_child =
false;
12132 bool has_descendant_with_allowed_change =
false;
12165 && (!d->has_local_changes()
12190 for (vector<diff*>::const_iterator i = d->children_nodes().begin();
12191 i != d->children_nodes().end();
12195 if (child->has_changes())
12197 has_non_empty_child =
true;
12199 has_suppressed_child =
true;
12200 else if (child->get_class_of_equiv_category()
12206 has_non_suppressed_child =
true;
12208 if (child->get_class_of_equiv_category()
12210 has_private_child =
true;
12211 else if (child->get_class_of_equiv_category()
12217 has_non_private_child =
true;
12221 if (has_non_empty_child
12222 && has_suppressed_child
12223 && !has_non_suppressed_child)
12229 if (canonical_diff != d)
12245 if (has_non_empty_child
12246 && has_private_child
12247 && !has_non_private_child)
12253 if (canonical_diff != d)
12263 && has_private_child
12264 && has_non_empty_child)
12270 if (canonical_diff != d)
12287 if (fn_type_diff->is_suppressed())
12293 if (canonical_diff != d)
12302 for (
auto child_node : d->children_nodes())
12308 has_descendant_with_allowed_change =
true;
12310 if (has_descendant_with_allowed_change)
12313 d->add_to_category(c);
12314 d->get_canonical_diff()->add_to_category(c);
12328 if (diff_tree && !diff_tree->
context()->suppressions().empty())
12332 suppression_categorization_visitor v;
12333 diff_tree->
context()->forget_visited_diffs();
12334 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12335 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
12337 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12360 if (diff_tree && !diff_tree->
context()->suppressions().empty())
12365 suppression_categorization_visitor v;
12366 diff_tree->
context()->forget_visited_diffs();
12367 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12368 diff_tree->
context()->forbid_visiting_a_node_twice(
true);
12369 const_cast<corpus_diff*
>(diff_tree)->traverse(v);
12370 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12376 apply_supprs_to_added_removed_fns_vars_unreachable_types();
12406 do_indent(
unsigned level)
12408 for (
unsigned i = 0; i < level; ++i)
12412 diff_node_printer(ostream& out)
12431 visit_begin(corpus_diff*)
12437 visit_end(corpus_diff*)
12443 visit(diff* d,
bool pre)
12452 out_ << d->get_pretty_representation();
12456 do_indent(level_ + 1);
12457 out_ <<
"category: "<< d->get_category() <<
"\n";
12458 do_indent(level_ + 1);
12459 out_ <<
"@: " << std::hex << d << std::dec <<
"\n";
12460 do_indent(level_ + 1);
12461 out_ <<
"@-canonical: " << std::hex
12462 << d->get_canonical_diff()
12463 << std::dec <<
"\n";
12471 visit(corpus_diff* d,
bool pre)
12480 for (
unsigned i = 0; i < level_; ++i)
12482 out_ << d->get_pretty_representation();
12501 diff_node_printer p(out);
12502 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12503 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
12505 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12519 diff_node_printer p(out);
12520 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12521 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
12523 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12562 bool skip_children_nodes_;
12564 redundancy_marking_visitor()
12565 : skip_children_nodes_()
12569 visit_begin(diff* d)
12571 if (d->to_be_reported())
12577 if ((d->context()->diff_has_been_visited(d)
12578 || d->get_canonical_diff()->is_traversing())
12579 && d->has_changes())
12594 bool redundant_with_sibling_node =
false;
12599 if (p &&
dynamic_cast<const fn_parm_diff*
>(p))
12603 for (vector<diff*>::const_iterator s =
12604 p->children_nodes().begin();
12605 s != p->children_nodes().end();
12613 if (fn_parm_diff* f =
dynamic_cast<fn_parm_diff*
>(*s))
12614 sib = f->type_diff().get();
12617 if (sib->get_canonical_diff() == d->get_canonical_diff()
12622 redundant_with_sibling_node =
true;
12626 if (!redundant_with_sibling_node
12647 && (!d->get_canonical_diff()->is_filtered_out()
12648 || (d->get_canonical_diff()->get_category()
12655 && d->context()->diff_has_been_visited(d) != d
12677 skip_children_nodes_ =
true;
12685 skip_children_nodes_ =
true;
12690 visit_begin(corpus_diff*)
12697 if (skip_children_nodes_)
12704 skip_children_nodes_ =
false;
12712 && (!d->has_local_changes_to_be_reported()
12738 && (!(d->has_local_changes()
12749 && (!(d->has_local_changes()
12756 && (!(d->has_local_changes()
12760 bool has_non_redundant_child =
false;
12761 bool has_non_empty_child =
false;
12762 for (vector<diff*>::const_iterator i =
12763 d->children_nodes().begin();
12764 i != d->children_nodes().end();
12767 if ((*i)->has_changes())
12769 has_non_empty_child =
true;
12776 if ((*i)->to_be_reported()
12778 has_non_redundant_child =
true;
12780 if (has_non_redundant_child)
12787 if (has_non_empty_child
12788 && !has_non_redundant_child)
12795 visit_end(corpus_diff*)
12804 visit(corpus_diff*,
bool)
12812 struct redundancy_clearing_visitor :
public diff_node_visitor
12815 visit(corpus_diff*,
bool)
12819 visit(diff* d,
bool)
12824 d->set_category(c);
12836 if (diff_tree->
context()->show_redundant_changes())
12838 redundancy_marking_visitor v;
12839 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12840 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
12842 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12860 redundancy_marking_visitor v;
12861 diff_tree->
context()->forget_visited_diffs();
12862 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12863 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
12865 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12885 redundancy_clearing_visitor v;
12886 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12887 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
12889 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12890 diff_tree->
context()->forget_visited_diffs();
12908 redundancy_clearing_visitor v;
12909 bool s = diff_tree->
context()->visiting_a_node_twice_is_forbidden();
12910 diff_tree->
context()->forbid_visiting_a_node_twice(
false);
12912 diff_tree->
context()->forbid_visiting_a_node_twice(s);
12913 diff_tree->
context()->forget_visited_diffs();
12934 diff_tree->context()->maybe_apply_filters(diff_tree);
12952 if (t && t->get_environment().is_variadic_parameter_type(t))
12956 if (t && t->get_environment().is_variadic_parameter_type(t))
13021 if (allow_indirect_type)
13222 has_local_type_change_only(
const diff *d)
13250 return (has_local_type_change_only(v)
13253 return (has_local_type_change_only(p)
13257 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, diff_context_sptr ctxt=diff_context_sptr())
Constructor for array_diff.
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
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 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.
friend corpus_diff_sptr compute_diff(const corpus_sptr f, const corpus_sptr s, diff_context_sptr ctxt)
Compute the diff between two instances of corpus.
const vector< type_base_sptr > & deleted_unreachable_types_sorted() const
Getter of a sorted vector of deleted types that are not reachable from global functions/variables.
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.
virtual bool visit(distinct_diff *, bool)
Default visitor implementation.
virtual void visit_end(corpus_diff *)
This is called by the traversing code on a corpus_diff node just after visiting it....
void set_current_topmost_iface_diff(diff *)
Setter of the diff current topmost interface which is impacted by the current diff node being visited...
virtual void visit_begin(diff *)
This is called by the traversing code on a diff node just before visiting it. That is,...
visiting_kind get_visiting_kind() const
Getter for the visiting policy of the traversing code while invoking this visitor.
virtual void visit_end(diff *)
This is called by the traversing code on a diff node just after visiting it. That is after visiting i...
diff_node_visitor()
Default constructor of the diff_node_visitor type.
void set_visiting_kind(visiting_kind v)
Setter for the visiting policy of the traversing code while invoking this visitor.
diff * get_current_topmost_iface_diff() const
Getter of the diff current topmost interface which is impacted by the current diff node being visited...
virtual bool traverse(diff_node_visitor &v)
The default traverse function.
The abstraction of a change between two ABI artifacts, a.k.a an artifact change.
void begin_traversing()
Flag a given diff node as being traversed.
void set_category(diff_category c)
Set the category of the current diff node. This category includes the categories inherited from the c...
virtual void finish_diff_type()
Finish the insertion of a diff tree node into the diff graph.
virtual void chain_into_hierarchy()
This constructs the relation between this diff node and its detail diff nodes, in the generic view of...
diff_category remove_from_category(diff_category c)
Remove the current diff tree node from an a existing sef of categories. The categories include those ...
type_or_decl_base_sptr second_subject() const
Getter of the second subject of the diff.
bool is_traversing() const
Tell if a given node is being traversed or not.
type_or_decl_base_sptr first_subject() const
Getter of the first subject of the diff.
bool is_suppressed() const
Test if the current diff node has been suppressed by a user-provided suppression specification.
bool is_filtered_out_without_looking_at_allowed_changes() const
Test if this diff tree node is to be filtered out for reporting purposes, but without considering the...
diff * get_canonical_diff() const
Getter for the canonical diff of the current instance of diff.
bool has_parent_allowed_by_specific_negated_suppression() const
Test if the current diff node has a parent node which is specifically allowed by a negated suppressio...
bool has_local_changes_to_be_reported() const
Test if this diff tree node should be reported when considering the categories that were *NOT* inheri...
const vector< diff * > & children_nodes() const
Getter for the children nodes of the current diff node.
diff_category get_category() const
Getter for the category of the current diff tree node.
bool is_allowed_by_specific_negated_suppression() const
Test if this diff node is allowed (prevented from being suppressed) by at least one negated suppressi...
diff_category remove_from_local_category(diff_category c)
Remove the current diff tree node from the categories resulting from the local changes.
void add_to_local_and_inherited_categories(diff_category c)
Adds the current diff tree node to the categories resulting from the local and inherited changes of t...
bool do_log() const
Test if logging was requested.
diff_category get_local_category() const
Getter for the local category of the current diff tree node.
diff_category add_to_category(diff_category c)
Adds the current diff tree node to an additional set of categories. Note that the categories include ...
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.
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.
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.
Abstracts a variable declaration.
interned_string get_id() const
Return an ID that tries to uniquely identify the variable inside a program or a library.
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.
std::vector< filter_base_sptr > filters
Convenience typedef for a vector of filter_base_sptr.
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_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.
@ 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...
@ 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_DECL_NAME_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a harmless declaration name change....
@ EVERYTHING_CATEGORY
A special enumerator that is the logical 'or' all the enumerators above.
@ NO_CHANGE_CATEGORY
This means the diff node does not carry any (meaningful) change, or that it carries changes that have...
@ HARMLESS_UNION_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a harmless union change.
@ 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 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.
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_var_ptr_map(const string_var_ptr_map &map, vector< var_decl * > &sorted)
Sort a map of string -> pointer to var_decl.
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.
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.
unordered_map< string, function_decl * > string_function_ptr_map
Convenience typedef for a map which key is a string and which value is a pointer to decl_base.
shared_ptr< function_decl_diff > function_decl_diff_sptr
Convenience typedef for a shared pointer to a function_decl type.
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.
unordered_map< string, var_decl * > string_var_ptr_map
Convenience typedef for a map which key is a string and which value is a point to var_decl.
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.
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.
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.
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.
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.
const fn_parm_diff * is_fn_parm_diff(const diff *diff)
Test if a diff node is about differences between two function parameters.
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...
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 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...
shared_ptr< array_diff > array_diff_sptr
Convenience typedef for a shared pointer on a array_diff type.
const class_diff * is_class_diff(const diff *diff)
Test if a diff node is a class_diff node.
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>
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.
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...
void print_diff_tree(diff *diff_tree, ostream &out)
Emit a textual representation of a diff sub-tree to an output stream.
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.
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 sort_string_function_ptr_map(const string_function_ptr_map &map, vector< function_decl * > &sorted)
Sort an instance of string_function_ptr_map map and stuff a resulting sorted vector of pointers to fu...
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 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.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
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< 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.
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< 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.
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.
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 * 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.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
interned_string get_function_id_or_pretty_representation(function_decl *fn)
Get the ID of a function, or, if the ID can designate several different functions,...
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_private_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.
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 added_variable_is_suppressed(const var_decl *var) const
Test if the change reports for a given added variable have been suppressed.
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_variable_is_suppressed(const var_decl *var) const
Test if the change reports for a give given deleted variable has been deleted.
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 ...
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_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 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.