16 #include "abg-reporter-priv.h"
48 apply_filters_and_suppressions_before_reporting();
86 bool started_to_emit =
false;
87 for (diff_ptrs_type::const_iterator i = sorted_diffs.begin();
88 i != sorted_diffs.end();
100 string n = (*i)->first_subject()->get_pretty_representation();
102 out << indent <<
"'" << n;
105 *(*i)->context(), out);
107 out <<
"' changed:\n";
109 (*i)->get_canonical_diff()->report(out, indent +
" ");
110 started_to_emit =
true;
123 report_type_changes_from_diff_maps(
const leaf_reporter& reporter,
124 const diff_maps& maps,
126 const string& indent)
129 report_diffs(reporter, maps.get_type_decl_diff_map(), out, indent);
132 report_diffs(reporter, maps.get_enum_diff_map(), out, indent);
135 report_diffs(reporter, maps.get_class_diff_map(), out, indent);
138 report_diffs(reporter, maps.get_union_diff_map(), out, indent);
141 report_diffs(reporter, maps.get_typedef_diff_map(), out, indent);
144 report_diffs(reporter, maps.get_subrange_diff_map(), out, indent);
147 report_diffs(reporter, maps.get_array_diff_map(), out, indent);
153 report_diffs(reporter, maps.get_distinct_diff_map(), out, indent);
156 report_diffs(reporter, maps.get_fn_parm_diff_map(), out, indent);
169 const string& indent)
const
171 report_type_changes_from_diff_maps(*
this, maps, out, indent);
188 const string& indent)
const
195 default_reporter::report(d, out, indent);
207 const string& indent)
const
226 leaf_reporter::report(
const pointer_diff &d,
228 const string& indent)
const
236 <<
"pointer type changed from: '"
237 << d.first_pointer()->get_pretty_representation()
239 << d.second_pointer()->get_pretty_representation()
249 leaf_reporter::report(
const reference_diff& d,
251 const string& indent)
const
265 leaf_reporter::report(
const fn_parm_diff& d,
267 const string& indent)
const
277 <<
"parameter " << f->get_index();
282 << f->get_type_pretty_representation()
284 d.type_diff()->report(out, indent +
" ");
293 leaf_reporter::report(
const function_type_diff& d,
295 const string& indent)
const
304 out << indent <<
"return type changed:\n";
305 d.priv_->return_type_diff_->report(out, indent +
" ");
311 for (vector<fn_parm_diff_sptr>::const_iterator i =
312 d.priv_->sorted_subtype_changed_parms_.begin();
313 i != d.priv_->sorted_subtype_changed_parms_.end();
318 dif->report(out, indent);
328 leaf_reporter::report(
const scope_diff& d,
330 const string& indent)
const
332 if (!d.to_be_reported())
336 unsigned num_changed_types = d.changed_types().size();
337 if (num_changed_types)
338 out << indent <<
"changed types:\n";
340 for (diff_sptrs_type::const_iterator dif = d.changed_types().begin();
341 dif != d.changed_types().end();
347 out << indent <<
" '"
348 << (*dif)->first_subject()->get_pretty_representation()
350 (*dif)->report(out, indent +
" ");
354 unsigned num_changed_decls = d.changed_decls().size();
355 if (num_changed_decls)
356 out << indent <<
"changed declarations:\n";
358 for (diff_sptrs_type::const_iterator dif= d.changed_decls().begin();
359 dif != d.changed_decls().end ();
365 out << indent <<
" '"
366 << (*dif)->first_subject()->get_pretty_representation()
367 <<
"' was changed to '"
368 << (*dif)->second_subject()->get_pretty_representation() <<
"'";
372 (*dif)->report(out, indent +
" ");
376 for (string_decl_base_sptr_map::const_iterator i =
377 d.priv_->deleted_types_.begin();
378 i != d.priv_->deleted_types_.end();
382 << i->second->get_pretty_representation()
383 <<
"' was removed\n";
385 if (d.priv_->deleted_types_.size())
388 for (string_decl_base_sptr_map::const_iterator i =
389 d.priv_->deleted_decls_.begin();
390 i != d.priv_->deleted_decls_.end();
394 << i->second->get_pretty_representation()
395 <<
"' was removed\n";
397 if (d.priv_->deleted_decls_.size())
401 bool emitted =
false;
402 for (string_decl_base_sptr_map::const_iterator i =
403 d.priv_->inserted_types_.begin();
404 i != d.priv_->inserted_types_.end();
409 if (dynamic_pointer_cast<type_decl>(i->second))
413 << i->second->get_pretty_representation()
422 for (string_decl_base_sptr_map::const_iterator i =
423 d.priv_->inserted_decls_.begin();
424 i != d.priv_->inserted_decls_.end();
429 if (dynamic_pointer_cast<type_decl>(i->second))
433 << i->second->get_pretty_representation()
452 const std::string& indent)
const
457 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER3(d.
first_subrange(),
474 const string& indent)
const
479 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER3(d.
first_array(),
493 out << indent <<
"array element type '"
494 << fn <<
"' changed: \n";
495 dif->report(out, indent +
" ");
507 leaf_reporter::report(
const class_or_union_diff& d,
509 const string& indent)
const
514 class_or_union_sptr first = d.first_class_or_union(),
515 second = d.second_class_or_union();
524 first->get_is_declaration_only()
525 ?
" was a declaration-only type"
526 :
" was a defined type";
529 second->get_is_declaration_only()
530 ?
" and is now a declaration-only type"
531 :
" and is now a defined type";
533 out << indent <<
"type " << first->get_pretty_representation()
534 << was << is_now <<
"\n";
539 if (d.member_fns_changes())
542 int numdels = d.get_priv()->deleted_member_functions_.size();
543 size_t num_filtered =
544 d.get_priv()->count_filtered_deleted_mem_fns(ctxt);
547 "member function", indent);
548 for (string_member_function_sptr_map::const_iterator i =
549 d.get_priv()->deleted_member_functions_.begin();
550 i != d.get_priv()->deleted_member_functions_.end();
553 if (!(ctxt->get_allowed_category()
558 method_decl_sptr mem_fun = i->second;
559 out << indent <<
" ";
564 int numins = d.get_priv()->inserted_member_functions_.size();
565 num_filtered = d.get_priv()->count_filtered_inserted_mem_fns(ctxt);
568 "member function", indent);
569 for (string_member_function_sptr_map::const_iterator i =
570 d.get_priv()->inserted_member_functions_.begin();
571 i != d.get_priv()->inserted_member_functions_.end();
574 if (!(ctxt->get_allowed_category()
579 method_decl_sptr mem_fun = i->second;
580 out << indent <<
" ";
585 int numchanges = d.get_priv()->sorted_changed_member_functions_.size();
588 for (function_decl_diff_sptrs_type::const_iterator i =
589 d.get_priv()->sorted_changed_member_functions_.begin();
590 i != d.get_priv()->sorted_changed_member_functions_.end();
593 if (!(ctxt->get_allowed_category()
596 ((*i)->first_function_decl()))
598 ((*i)->second_function_decl())))
606 (*i)->first_function_decl()->get_pretty_representation();
607 out << indent <<
" '" << repr <<
"' has some changes:\n";
608 diff->report(out, indent +
" ");
613 if (d.data_members_changes())
616 int numdels = d.class_or_union_diff::get_priv()->
617 get_deleted_non_static_data_members_number();
621 "data member", indent);
622 vector<decl_base_sptr> sorted_dms;
624 (d.class_or_union_diff::get_priv()->deleted_data_members_,
626 for (vector<decl_base_sptr>::const_iterator i = sorted_dms.begin();
627 i != sorted_dms.end();
631 dynamic_pointer_cast<var_decl>(*i);
641 d.class_or_union_diff::get_priv()->inserted_data_members_.size();
645 "data member", indent);
646 vector<decl_base_sptr> sorted_dms;
648 (d.class_or_union_diff::get_priv()->inserted_data_members_,
650 for (vector<decl_base_sptr>::const_iterator i = sorted_dms.begin();
651 i != sorted_dms.end();
655 dynamic_pointer_cast<var_decl>(*i);
662 size_t numchanges = (d.sorted_changed_data_members().size()
663 + d.sorted_subtype_changed_data_members().size());
665 size_t num_filtered =
666 (d.count_filtered_changed_data_members(
true)
667 + d.count_filtered_subtype_changed_data_members(
true));
670 size_t net_numchanges = numchanges - num_filtered;
676 for (var_diff_sptrs_type::const_iterator it =
677 d.sorted_changed_data_members().begin();
678 it != d.sorted_changed_data_members().end();
681 represent(*it, ctxt, out, indent +
" ",
true);
683 for (var_diff_sptrs_type::const_iterator it =
684 d.sorted_subtype_changed_data_members().begin();
685 it != d.sorted_subtype_changed_data_members().end();
688 represent(*it, ctxt, out, indent +
" ",
true);
703 leaf_reporter::report(
const class_diff& d,
705 const string& indent)
const
710 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER(d.first_subject(),
713 string name = d.first_subject()->get_pretty_representation();
717 second = d.second_class_decl();
725 d.class_or_union_diff::report(out, indent);
731 d.reported_once(
true);
740 leaf_reporter::report(
const union_diff& d,
742 const string& indent)
const
747 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER(d.first_subject(),
751 union_decl_sptr first = d.first_union_decl(), second = d.second_union_decl();
758 d.class_or_union_diff::report(out, indent);
769 leaf_reporter::report(
const distinct_diff& d,
771 const string& indent)
const
778 string f_repr = f ? f->get_pretty_representation() :
"'void'";
779 string s_repr = s ? s->get_pretty_representation() :
"'void'";
781 diff_sptr diff = d.compatible_child_diff();
783 string compatible = diff ?
" to compatible type '":
" to '";
785 out << indent <<
"entity changed from '" << f_repr <<
"'"
786 << compatible << s_repr <<
"'";
800 leaf_reporter::report(
const function_decl_diff& d,
802 const string& indent)
const
808 d.second_function_decl(),
809 d.context(), out, indent);
815 corpus_sptr fc = ctxt->get_corpus_diff()->first_corpus();
816 corpus_sptr sc = ctxt->get_corpus_diff()->second_corpus();
818 string qn1 = ff->get_qualified_name(), qn2 = sf->get_qualified_name(),
819 linkage_names1, linkage_names2;
823 linkage_names1 = s1->get_id_string();
825 linkage_names2 = s2->get_id_string();
831 s1->get_aliases_id_string(fc->get_fun_symbol_map());
834 s2->get_aliases_id_string(sc->get_fun_symbol_map());
838 if (linkage_names1 != linkage_names2)
840 if (linkage_names1.empty())
842 out << indent << ff->get_pretty_representation()
843 <<
" didn't have any linkage name, and it now has: '"
844 << linkage_names2 <<
"'\n";
846 else if (linkage_names2.empty())
848 out << indent << ff->get_pretty_representation()
849 <<
" did have linkage names '" << linkage_names1
851 << indent <<
"but it doesn't have any linkage name anymore\n";
854 out << indent <<
"linkage names of "
855 << ff->get_pretty_representation()
856 <<
"\n" << indent <<
"changed from '"
857 << linkage_names1 <<
"' to '" << linkage_names2 <<
"'\n";
867 string frep1 = d.first_function_decl()->get_pretty_representation(),
868 frep2 = d.second_function_decl()->get_pretty_representation();
869 out << indent <<
"'" << frep1 <<
" {" << linkage_names1<<
"}"
871 << frep2 <<
" {" << linkage_names2 <<
"}" <<
"'\n";
879 if (ff->is_declared_inline() != sf->is_declared_inline())
882 if (ff->is_declared_inline())
883 out << sf->get_pretty_representation()
884 <<
" is not declared inline anymore\n";
886 out << sf->get_pretty_representation()
887 <<
" is now declared inline\n";
895 if (ff_is_virtual != sf_is_virtual)
899 out << ff->get_pretty_representation()
900 <<
" is no more declared virtual\n";
902 out << ff->get_pretty_representation()
903 <<
" is now declared virtual\n";
908 if (ff_is_virtual && sf_is_virtual
909 && (ff_vtable_offset != sf_vtable_offset))
912 <<
"the vtable offset of " << ff->get_pretty_representation()
913 <<
" changed from " << ff_vtable_offset
914 <<
" to " << sf_vtable_offset <<
"\n";
925 bool vtable_added =
false, vtable_removed =
false;
926 if (!fc->get_is_declaration_only() && !sc->get_is_declaration_only())
928 vtable_added = !fc->has_vtable() && sc->has_vtable();
929 vtable_removed = fc->has_vtable() && !sc->has_vtable();
931 bool vtable_changed = ((ff_is_virtual != sf_is_virtual)
932 || (ff_vtable_offset != sf_vtable_offset));
933 bool incompatible_change = (ff_vtable_offset != sf_vtable_offset);
937 <<
" note that a vtable was added to "
938 << fc->get_pretty_representation()
940 else if (vtable_removed)
942 <<
" note that the vtable was removed from "
943 << fc->get_pretty_representation()
945 else if (vtable_changed)
948 if (incompatible_change)
949 out <<
" note that this is an ABI incompatible "
950 "change to the vtable of ";
952 out <<
" note that this induces a change to the vtable of ";
953 out << fc->get_pretty_representation()
961 d.type_diff()->report(out, indent);
970 leaf_reporter::report(
const var_diff& d,
972 const string& indent)
const
977 decl_base_sptr first = d.first_var(), second = d.second_var();
978 string n = first->get_pretty_representation();
985 d.second_var()->get_symbol(),
986 d.context(), out, indent);
994 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2(dif,
"type");
995 out << indent <<
"type of variable changed:\n";
996 dif->report(out, indent +
" ");
1007 leaf_reporter::report(
const translation_unit_diff& d,
1009 const string& indent)
const
1011 if (!d.to_be_reported())
1014 static_cast<const scope_diff&
>(d).report(out, indent);
1023 leaf_reporter::report(
const corpus_diff& d,
1025 const string& indent)
const
1027 if (!d.has_changes())
1030 const corpus_diff::diff_stats &s =
1031 const_cast<corpus_diff&
>(d).
1032 apply_filters_and_suppressions_before_reporting();
1036 d.priv_->emit_diff_stats(s, out, indent);
1037 if (ctxt->show_stats_only())
1041 if (ctxt->show_soname_change()
1042 && !d.priv_->sonames_equal_)
1043 out << indent <<
"SONAME changed from '"
1044 << d.first_corpus()->get_soname() <<
"' to '"
1045 << d.second_corpus()->get_soname() <<
"'\n\n";
1047 if (ctxt->show_architecture_change()
1048 && !d.priv_->architectures_equal_)
1049 out << indent <<
"architecture changed from '"
1050 << d.first_corpus()->get_architecture_name() <<
"' to '"
1051 << d.second_corpus()->get_architecture_name() <<
"'\n\n";
1054 if (ctxt->show_deleted_fns())
1056 if (s.net_num_func_removed() == 1)
1057 out << indent <<
"1 Removed function:\n\n";
1058 else if (s.net_num_func_removed() > 1)
1059 out << indent << s.net_num_func_removed() <<
" Removed functions:\n\n";
1061 bool emitted =
false;
1062 vector<function_decl*>sorted_deleted_fns;
1064 for (vector<function_decl*>::const_iterator i =
1065 sorted_deleted_fns.begin();
1066 i != sorted_deleted_fns.end();
1069 if (d.priv_->deleted_function_is_suppressed(*i))
1075 out <<
"'" << (*i)->get_pretty_representation() <<
"'";
1076 if (ctxt->show_linkage_names())
1080 d.first_corpus()->get_fun_symbol_map());
1090 <<
"note that this removes an entry from the vtable of "
1091 << c->get_pretty_representation()
1100 if (ctxt->show_added_fns())
1102 if (s.net_num_func_added() == 1)
1103 out << indent <<
"1 Added function:\n\n";
1104 else if (s.net_num_func_added() > 1)
1105 out << indent << s.net_num_func_added()
1106 <<
" Added functions:\n\n";
1107 bool emitted =
false;
1108 vector<function_decl*> sorted_added_fns;
1110 for (vector<function_decl*>::const_iterator i = sorted_added_fns.begin();
1111 i != sorted_added_fns.end();
1114 if (d.priv_->added_function_is_suppressed(*i))
1122 << (*i)->get_pretty_representation()
1124 if (ctxt->show_linkage_names())
1128 (out,
"", *(*i)->get_symbol(),
1129 d.second_corpus()->get_fun_symbol_map());
1139 <<
"note that this adds a new entry to the vtable of "
1140 << c->get_pretty_representation()
1149 if (ctxt->show_changed_fns())
1152 size_t num_changed = s.net_num_leaf_func_changes();
1153 if (num_changed == 1)
1154 out << indent <<
"1 function with some sub-type change:\n\n";
1155 else if (num_changed > 1)
1156 out << indent << num_changed
1157 <<
" functions with some sub-type change:\n\n";
1159 vector<function_decl_diff_sptr> sorted_changed_fns;
1161 sorted_changed_fns);
1162 for (vector<function_decl_diff_sptr>::const_iterator i =
1163 sorted_changed_fns.begin();
1164 i != sorted_changed_fns.end();
1174 out << indent <<
" [C] '"
1175 << fn->get_pretty_representation() <<
"'";
1177 out <<
" has some sub-type changes:\n";
1178 if ((fn->get_symbol()->has_aliases()
1184 && fn->get_name() != fn->get_linkage_name()))
1186 int number_of_aliases =
1187 fn->get_symbol()->get_number_of_aliases();
1188 if (number_of_aliases == 0)
1190 out << indent <<
" "
1191 <<
"Please note that the exported symbol of "
1193 << fn->get_symbol()->get_id_string()
1198 out << indent <<
" "
1199 <<
"Please note that the symbol of this function is "
1200 << fn->get_symbol()->get_id_string()
1201 <<
"\n and it aliases symbol";
1202 if (number_of_aliases > 1)
1205 << fn->get_symbol()->get_aliases_id_string(
false)
1209 diff->report(out, indent +
" ");
1218 if (ctxt->show_deleted_vars())
1220 if (s.net_num_vars_removed() == 1)
1221 out << indent <<
"1 Removed variable:\n\n";
1222 else if (s.net_num_vars_removed() > 1)
1223 out << indent << s.net_num_vars_removed()
1224 <<
" Removed variables:\n\n";
1226 bool emitted =
false;
1227 vector<var_decl*> sorted_deleted_vars;
1229 for (vector<var_decl*>::const_iterator i =
1230 sorted_deleted_vars.begin();
1231 i != sorted_deleted_vars.end();
1234 if (d.priv_->deleted_variable_is_suppressed(*i))
1237 n = (*i)->get_pretty_representation();
1245 if (ctxt->show_linkage_names())
1249 d.first_corpus()->get_var_symbol_map());
1259 if (ctxt->show_added_vars())
1261 if (s.net_num_vars_added() == 1)
1262 out << indent <<
"1 Added variable:\n\n";
1263 else if (s.net_num_vars_added() > 1)
1264 out << indent << s.net_num_vars_added()
1265 <<
" Added variables:\n\n";
1267 bool emitted =
false;
1268 vector<var_decl*> sorted_added_vars;
1270 for (vector<var_decl*>::const_iterator i =
1271 sorted_added_vars.begin();
1272 i != sorted_added_vars.end();
1275 if (d.priv_->added_variable_is_suppressed(*i))
1278 n = (*i)->get_pretty_representation();
1283 out <<
"'" << n <<
"'";
1284 if (ctxt->show_linkage_names())
1288 d.second_corpus()->get_var_symbol_map());
1298 if (ctxt->show_changed_vars())
1300 size_t num_changed = s.net_num_leaf_var_changes();
1301 if (num_changed == 1)
1302 out << indent <<
"1 Changed variable:\n\n";
1303 else if (num_changed > 1)
1304 out << indent << num_changed
1305 <<
" Changed variables:\n\n";
1307 for (var_diff_sptrs_type::const_iterator i =
1308 d.priv_->sorted_changed_vars_.begin();
1309 i != d.priv_->sorted_changed_vars_.end();
1320 n1 = diff->first_subject()->get_pretty_representation();
1321 n2 = diff->second_subject()->get_pretty_representation();
1323 out << indent <<
" [C] '" << n1 <<
"' was changed";
1325 out <<
" to '" << n2 <<
"'";
1328 diff->report(out, indent +
" ");
1336 if (ctxt->show_symbols_unreferenced_by_debug_info()
1337 && d.priv_->deleted_unrefed_fn_syms_.size())
1339 if (s.net_num_removed_func_syms() == 1)
1341 <<
"1 Removed function symbol not referenced by debug info:\n\n";
1342 else if (s.net_num_removed_func_syms() > 0)
1344 << s.net_num_removed_func_syms()
1345 <<
" Removed function symbols not referenced by debug info:\n\n";
1347 bool emitted =
false;
1348 vector<elf_symbol_sptr> sorted_deleted_unrefed_fn_syms;
1350 sorted_deleted_unrefed_fn_syms);
1351 for (vector<elf_symbol_sptr>::const_iterator i =
1352 sorted_deleted_unrefed_fn_syms.begin();
1353 i != sorted_deleted_unrefed_fn_syms.end();
1356 if (d.priv_->deleted_unrefed_fn_sym_is_suppressed((*i).get()))
1359 out << indent <<
" ";
1363 d.first_corpus()->get_fun_symbol_map());
1372 if (ctxt->show_symbols_unreferenced_by_debug_info()
1373 && ctxt->show_added_symbols_unreferenced_by_debug_info()
1374 && d.priv_->added_unrefed_fn_syms_.size())
1376 if (s.net_num_added_func_syms() == 1)
1378 <<
"1 Added function symbol not referenced by debug info:\n\n";
1379 else if (s.net_num_added_func_syms() > 0)
1381 << s.net_num_added_func_syms()
1382 <<
" Added function symbols not referenced by debug info:\n\n";
1384 bool emitted =
false;
1385 vector<elf_symbol_sptr> sorted_added_unrefed_fn_syms;
1387 sorted_added_unrefed_fn_syms);
1388 for (vector<elf_symbol_sptr>::const_iterator i =
1389 sorted_added_unrefed_fn_syms.begin();
1390 i != sorted_added_unrefed_fn_syms.end();
1393 if (d.priv_->added_unrefed_fn_sym_is_suppressed((*i).get()))
1396 out << indent <<
" ";
1400 d.second_corpus()->get_fun_symbol_map());
1409 if (ctxt->show_symbols_unreferenced_by_debug_info()
1410 && d.priv_->deleted_unrefed_var_syms_.size())
1412 if (s.net_num_removed_var_syms() == 1)
1414 <<
"1 Removed variable symbol not referenced by debug info:\n\n";
1415 else if (s.net_num_removed_var_syms() > 0)
1417 << s.net_num_removed_var_syms()
1418 <<
" Removed variable symbols not referenced by debug info:\n\n";
1420 bool emitted =
false;
1421 vector<elf_symbol_sptr> sorted_deleted_unrefed_var_syms;
1423 sorted_deleted_unrefed_var_syms);
1424 for (vector<elf_symbol_sptr>::const_iterator i =
1425 sorted_deleted_unrefed_var_syms.begin();
1426 i != sorted_deleted_unrefed_var_syms.end();
1429 if (d.priv_->deleted_unrefed_var_sym_is_suppressed((*i).get()))
1432 out << indent <<
" ";
1437 d.first_corpus()->get_fun_symbol_map());
1447 if (ctxt->show_symbols_unreferenced_by_debug_info()
1448 && ctxt->show_added_symbols_unreferenced_by_debug_info()
1449 && d.priv_->added_unrefed_var_syms_.size())
1451 if (s.net_num_added_var_syms() == 1)
1453 <<
"1 Added variable symbol not referenced by debug info:\n\n";
1454 else if (s.net_num_added_var_syms() > 0)
1456 << s.net_num_added_var_syms()
1457 <<
" Added variable symbols not referenced by debug info:\n\n";
1459 bool emitted =
false;
1460 vector<elf_symbol_sptr> sorted_added_unrefed_var_syms;
1462 sorted_added_unrefed_var_syms);
1463 for (vector<elf_symbol_sptr>::const_iterator i =
1464 sorted_added_unrefed_var_syms.begin();
1465 i != sorted_added_unrefed_var_syms.end();
1468 if (d.priv_->added_unrefed_var_sym_is_suppressed((*i).get()))
1471 out << indent <<
" ";
1474 d.second_corpus()->get_fun_symbol_map());
1483 const diff_maps& leaf_diffs = d.get_leaf_diffs();
1484 report_type_changes_from_diff_maps(*
this, leaf_diffs, out, indent);
1490 d.priv_->maybe_dump_diff_tree();
The private data and functions of the abigail::ir::comparison types.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
The declaration of the reporting types of libabigail's diff engine.
The abstraction of a diff between two arrays.
const diff_sptr & element_type_diff() const
Getter for the diff between the two types of array elements.
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.
This is a document class that aims to capture statistics about the changes carried by a corpus_diff t...
size_t net_num_leaf_var_changes() const
Getter for the net number of leaf variable change diff nodes.
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 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 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 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_type_changes() const
Getter for the net number of leaf type change diff nodes.
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 net_num_vars_added() const
Getter for the net number of added variables.
size_t net_num_leaf_func_changes() const
Getter for the net 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*...
An abstraction of a diff between between two abi corpus.
bool soname_changed() const
Test if the soname of the underlying corpus has changed.
bool architecture_changed() const
Test if the architecture of the underlying corpus has changed.
bool report_local_qualified_type_changes(const qualified_type_diff &d, std::ostream &out, const std::string &indent) const
For a qualified_type_diff node, report the changes that are local.
void report_local_function_type_changes(const function_type_diff &d, std::ostream &out, const std::string &indent) const
For a function_type_diff node, report the local changes carried by the diff node.
void report_underlying_changes_of_qualified_type(const qualified_type_diff &d, ostream &out, const string &indent) const
For a qualified_type_diff node, report the changes of its underlying type.
void report_local_reference_type_changes(const reference_diff &d, std::ostream &out, const std::string &indent) const
For a @reference_diff node, report the local changes carried by the diff node.
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.
The abstraction of a change between two ABI artifacts, a.k.a an artifact change.
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...
bool to_be_reported() const
Test if this diff tree node should be reported.
virtual bool diff_has_net_changes(const corpus_diff *d) const
Test if a given instance of corpus_diff carries changes whose reports are not suppressed by any suppr...
void report_changes_from_diff_maps(const diff_maps &, std::ostream &out, const std::string &indent) const
Report the changes carried by an instance of diff_maps.
virtual bool diff_to_be_reported(const diff *d) const
Test if a diff node is to be reported by the current instance of leaf_reporter.
Abstraction of a diff between two qualified types.
The base class of all the reporting classes.
virtual bool diff_to_be_reported(const diff *d) const
Tests if the diff node is to be reported.
The abstraction of the diff between two subrange types.
const array_type_def::subrange_sptr second_subrange() const
Getter of the second subrange of the current instance subrange_diff.
const array_type_def::subrange_sptr first_subrange() const
Getter of the first subrange of the current instance subrange_diff.
Abstraction of a diff between two typedef_decl.
Abstracts a diff between two instances of var_decl.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
bool has_class_decl_only_def_change(const class_or_union_sptr &first, const class_or_union_sptr &second)
Test if two class_or_union_sptr are different just by the fact that one is decl-only and the other on...
shared_ptr< diff > diff_sptr
Convenience typedef for a shared_ptr for the diff class.
void show_linkage_name_and_aliases(ostream &out, const string &indent, const elf_symbol &symbol, const string_elf_symbols_map_type &sym_map)
For a given symbol, emit a string made of its name and version. The string also contains the list of ...
vector< diff * > diff_ptrs_type
Convenience typedef for a vector of diff*.
void maybe_report_interfaces_impacted_by_diff(const diff *d, ostream &out, const string &indent)
If a given diff node impacts some public interfaces, then report about those impacted interfaces on a...
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...
@ 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...
@ 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 ...
void maybe_report_diff_for_symbol(const elf_symbol_sptr &symbol1, const elf_symbol_sptr &symbol2, const diff_context_sptr &ctxt, ostream &out, const string &indent)
Report the difference between two ELF symbols, if there is any.
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 maybe_report_unreachable_type_changes(const corpus_diff &d, const corpus_diff::diff_stats &s, const string &indent, ostream &out)
Report changes about types that are not reachable from global functions and variables,...
shared_ptr< diff_context > diff_context_sptr
Convenience typedef for a shared pointer of diff_context.
void report_size_and_alignment_changes(type_or_decl_base_sptr first, type_or_decl_base_sptr second, diff_context_sptr ctxt, ostream &out, const string &indent)
Report the size and alignment changes of a type.
bool report_loc_info(const type_or_decl_base_sptr &tod, const diff_context &ctxt, ostream &out)
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.
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...
void maybe_report_base_class_reordering(const class_diff &d, ostream &out, const string &indent)
Report about the base classes of a class having been re-ordered.
void represent_data_member(var_decl_sptr d, const diff_context_sptr &ctxt, ostream &out, const string &indent)
Stream a string representation for a data member.
void maybe_report_data_members_replaced_by_anon_dm(const class_or_union_diff &d, ostream &out, const string &indent)
Report about data members replaced by an anonymous data member without changing the overall bit-layou...
bool maybe_report_diff_for_member(const decl_base_sptr &decl1, const decl_base_sptr &decl2, const diff_context_sptr &ctxt, ostream &out, const string &indent)
Report the differences in access specifiers and static-ness for class members.
void report_mem_header(ostream &out, size_t number, size_t num_filtered, diff_kind k, const string §ion_name, const string &indent)
Output the header preceding the the report for insertion/deletion/change of a part of a class....
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.
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...
const var_diff * is_var_diff(const diff *diff)
Test if a diff node is about differences between variables.
void report_name_size_and_alignment_changes(decl_base_sptr first, decl_base_sptr second, diff_context_sptr ctxt, ostream &out, const string &indent)
Report the name, size and alignment changes of a type.
void represent(const diff_context &ctxt, method_decl_sptr mem_fn, ostream &out)
Stream a string representation for a member function.
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...
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.
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
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...
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
translation_unit * get_translation_unit(const decl_base &decl)
Return the translation unit a declaration belongs to.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Toplevel namespace for libabigail.