16#include "abg-reporter-priv.h"
38 apply_filters_and_suppressions_before_reporting();
69 const string& indent)
const
76 string name = f->get_pretty_representation();
81 if (f->get_visibility() != s->get_visibility())
84 <<
"visibility changed from '"
85 << f->get_visibility() <<
"' to '" << s->get_visibility()
89 if (f->get_linkage_name() != s->get_linkage_name())
92 <<
"mangled name changed from '"
93 << f->get_linkage_name() <<
"' to "
94 << s->get_linkage_name()
107default_reporter::report(
const enum_diff& d, ostream& out,
108 const string& indent)
const
110 if (!d.to_be_reported())
113 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER3(d.first_subject(),
117 string name = d.first_enum()->get_pretty_representation();
128 first->get_is_declaration_only()
129 ?
" was a declaration-only enum type"
130 :
" was a defined enum type";
133 second->get_is_declaration_only()
134 ?
" and is now a declaration-only enum type"
135 :
" and is now a defined enum type";
137 out << indent <<
"enum type " << name << was << is_now <<
"\n";
146 d.underlying_type_diff()->report(out, indent);
149 unsigned numdels = d.deleted_enumerators().size();
150 unsigned numins = d.inserted_enumerators().size();
151 unsigned numchanges = d.changed_enumerators().size();
158 for (enum_type_decl::enumerators::const_iterator i =
159 sorted_deleted_enumerators.begin();
160 i != sorted_deleted_enumerators.end();
165 << (first->get_is_anonymous()
167 : i->get_qualified_name())
179 for (enum_type_decl::enumerators::const_iterator i =
180 sorted_inserted_enumerators.begin();
181 i != sorted_inserted_enumerators.end();
186 << (second->get_is_anonymous()
188 :i->get_qualified_name())
200 sorted_changed_enumerators);
201 for (changed_enumerators_type::const_iterator i =
202 sorted_changed_enumerators.begin();
203 i != sorted_changed_enumerators.end();
207 if (i->first.get_value() != i->second.get_value())
210 << (first->get_is_anonymous()
211 ? i->first.get_name()
212 : i->first.get_qualified_name())
214 << i->first.get_value() <<
"' to '"
215 << i->second.get_value() <<
"'";
217 else if (i->first.get_name() != i->second.get_name())
220 << (first->get_is_anonymous()
221 ? i->first.get_name()
222 : i->first.get_qualified_name())
223 <<
" = " << i->first.get_value()
225 << (second->get_is_anonymous()
226 ? i->second.get_name()
227 : i->second.get_qualified_name())
228 <<
" = " << i->second.get_value()
233 out <<
"enumerator change from '"
234 << i->first.get_name()
236 << i->first.get_value()
238 << i->second.get_name()
240 << i->second.get_value()
241 <<
"' could not be determined - please report as a bug";
248 if (ctxt->show_leaf_changes_only())
251 d.reported_once(
true);
268 const string& indent)
const
278 && ((d.
context()->get_allowed_category()
280 || d.
context()->show_leaf_changes_only()))
281 || f->get_qualified_name() != s->get_qualified_name())
283 out << indent <<
"typedef name changed from "
284 << f->get_qualified_name()
286 << s->get_qualified_name();
303 const string& indent)
const
314 if (dif && dif->has_changes())
316 if (dif->to_be_reported())
318 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2(dif,
321 <<
"underlying type '"
322 << dif->first_subject()->get_pretty_representation() <<
"'";
324 out <<
" changed:\n";
325 dif->report(out, indent +
" ");
340 <<
"underlying type '"
341 << dif->first_subject()->get_pretty_representation() <<
"'";
343 out <<
" changed:\n";
346 dif->report(out, indent +
" ");
370 const string& indent)
const
380 out << indent <<
"'" << fname <<
"' changed to '" << sname <<
"'\n";
407 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2(dif,
411 string fltname = dif->first_subject()->get_pretty_representation();
412 out << indent <<
"in unqualified underlying type '" << fltname <<
"'";
415 dif->report(out, indent +
" ");
427 const string& indent)
const
454default_reporter::report(
const pointer_diff& d, ostream& out,
455 const string& indent)
const
462 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2(dif,
"pointed to type");
463 string repr = dif->first_subject()
464 ? dif->first_subject()->get_pretty_representation()
468 <<
"in pointed to type '" << repr <<
"'";
471 dif->report(out, indent +
" ");
486 const string& indent)
const
494 string f_repr = f->get_pretty_representation(),
495 s_repr = s->get_pretty_representation();
497 if (f->is_lvalue() != s->is_lvalue())
501 out <<
"lvalue reference type '" << f_repr
502 <<
" became an rvalue reference type: '"
506 out <<
"rvalue reference type '" << f_repr
507 <<
" became an lvalue reference type: '"
512 s->get_pointed_to_type().get()))
514 <<
"reference type changed from: '"
515 << f_repr <<
"' to: '" << s_repr <<
"'\n";
527 const string& indent)
const
542 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2(dif,
546 <<
"in referenced type '"
547 << dif->first_subject()->get_pretty_representation() <<
"'";
550 dif->report(out, indent +
" ");
571 const std::string& indent)
const
584 string f_repr = f->get_pretty_representation(),
585 s_repr = s->get_pretty_representation();
588 out <<
"pointer-to-member type changed from: '"
589 << f_repr <<
" to: '"<< s_repr <<
"'\n";
605 const std::string& indent)
const
614 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2
615 (dif,
"data member type of pointer-to-member");
616 if (dif->to_be_reported())
619 <<
"in data member type '"
620 << dif->first_subject()->get_pretty_representation()
621 <<
"' of pointed-to-member type '"
626 dif->report(out, indent +
" ");
631 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2
632 (dif,
"containing type of pointer-to-member");
633 if (dif->to_be_reported())
636 <<
"in containing type '"
637 << dif->first_subject()->get_pretty_representation()
638 <<
"' of pointed-to-member type '"
643 dif->report(out, indent +
" ");
656default_reporter::report(
const fn_parm_diff& d, ostream& out,
657 const string& indent)
const
669 bool has_sub_type_change =
677 if (f->get_is_artificial())
679 out <<
"parameter " << f->get_index();
682 << f->get_type_pretty_representation();
684 if (has_sub_type_change)
685 out <<
"' has sub-type changes:\n";
687 out <<
"' changed:\n";
689 type_diff->report(out, indent +
" ");
703 const string& indent)
const
715 if (fft->get_size_in_bits() != sft->get_size_in_bits())
717 out << indent <<
"address size of function changed from "
718 << fft->get_size_in_bits()
720 << sft->get_size_in_bits()
725 if (fft->get_alignment_in_bits()
726 != sft->get_alignment_in_bits())
728 out << indent <<
"address alignment of function changed from "
729 << fft->get_alignment_in_bits()
731 << sft->get_alignment_in_bits()
739 for (vector<function_decl::parameter_sptr>::const_iterator i =
740 d.priv_->sorted_deleted_parms_.begin();
741 i != d.priv_->sorted_deleted_parms_.end();
744 out << indent <<
"parameter " << (*i)->get_index()
745 <<
" of type '" << (*i)->get_type_pretty_representation()
746 <<
"' was removed\n";
750 for (vector<function_decl::parameter_sptr>::const_iterator i =
751 d.priv_->sorted_added_parms_.begin();
752 i != d.priv_->sorted_added_parms_.end();
755 out << indent <<
"parameter " << (*i)->get_index()
756 <<
" of type '" << (*i)->get_type_pretty_representation()
770 const string& indent)
const
779 corpus_sptr fc = ctxt->get_first_corpus();
780 corpus_sptr sc = ctxt->get_second_corpus();
783 if (d.priv_->return_type_diff_
784 && d.priv_->return_type_diff_->to_be_reported())
786 out << indent <<
"return type changed:\n";
787 d.priv_->return_type_diff_->report(out, indent +
" ");
791 for (vector<fn_parm_diff_sptr>::const_iterator i =
792 d.priv_->sorted_subtype_changed_parms_.begin();
793 i != d.priv_->sorted_subtype_changed_parms_.end();
797 if (dif && dif->to_be_reported())
798 dif->report(out, indent);
815 const std::string& indent)
const
820 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER3(d.
first_subrange(),
835default_reporter::report(
const array_diff& d, ostream& out,
836 const string& indent)
const
841 string name = d.
first_array()->get_pretty_representation();
842 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER3(d.
first_array(),
847 if (dif->to_be_reported())
851 out << indent <<
"array element type '"
852 << fn <<
"' changed:\n";
853 dif->report(out, indent +
" ");
864 int subrange_index = 0;
870 out << indent <<
"array subrange ";
872 out << subrange_index <<
" ";
873 out <<
"changed: \n";
889default_reporter::report(
const base_diff& d, ostream& out,
890 const string& indent)
const
892 if (!d.to_be_reported())
896 string repr = f->get_base_class()->get_pretty_representation();
897 bool emitted =
false;
899 if (!d.is_filtered_out_without_looking_at_allowed_changes())
901 if (f->get_is_static() != s->get_is_static())
903 if (f->get_is_static())
904 out << indent <<
"is no more static";
906 out << indent <<
"now becomes static";
911 && (f->get_access_specifier() != s->get_access_specifier()))
916 out <<
"has access changed from '"
917 << f->get_access_specifier()
919 << s->get_access_specifier()
927 if (dif->to_be_reported())
931 dif->report(out, indent);
944default_reporter::report(
const scope_diff& d, ostream& out,
945 const string& indent)
const
947 if (!d.to_be_reported())
951 unsigned num_changed_types = d.changed_types().size();
952 if (num_changed_types == 0)
954 else if (num_changed_types == 1)
955 out << indent <<
"1 changed type:\n";
957 out << indent << num_changed_types <<
" changed types:\n";
959 for (diff_sptrs_type::const_iterator dif = d.changed_types().begin();
960 dif != d.changed_types().end();
966 out << indent <<
" '"
967 << (*dif)->first_subject()->get_pretty_representation()
969 (*dif)->report(out, indent +
" ");
973 unsigned num_changed_decls = d.changed_decls().size();
974 if (num_changed_decls == 0)
976 else if (num_changed_decls == 1)
977 out << indent <<
"1 changed declaration:\n";
979 out << indent << num_changed_decls <<
" changed declarations:\n";
981 for (diff_sptrs_type::const_iterator dif= d.changed_decls().begin();
982 dif != d.changed_decls().end ();
988 out << indent <<
" '"
989 << (*dif)->first_subject()->get_pretty_representation()
990 <<
"' was changed to '"
991 << (*dif)->second_subject()->get_pretty_representation() <<
"'";
995 (*dif)->report(out, indent +
" ");
999 for (string_decl_base_sptr_map::const_iterator i =
1000 d.priv_->deleted_types_.begin();
1001 i != d.priv_->deleted_types_.end();
1005 << i->second->get_pretty_representation()
1006 <<
"' was removed\n";
1008 if (d.priv_->deleted_types_.size())
1011 for (string_decl_base_sptr_map::const_iterator i =
1012 d.priv_->deleted_decls_.begin();
1013 i != d.priv_->deleted_decls_.end();
1017 << i->second->get_pretty_representation()
1018 <<
"' was removed\n";
1020 if (d.priv_->deleted_decls_.size())
1024 bool emitted =
false;
1025 for (string_decl_base_sptr_map::const_iterator i =
1026 d.priv_->inserted_types_.begin();
1027 i != d.priv_->inserted_types_.end();
1032 if (dynamic_pointer_cast<type_decl>(i->second))
1036 << i->second->get_pretty_representation()
1045 for (string_decl_base_sptr_map::const_iterator i =
1046 d.priv_->inserted_decls_.begin();
1047 i != d.priv_->inserted_decls_.end();
1052 if (dynamic_pointer_cast<type_decl>(i->second))
1056 << i->second->get_pretty_representation()
1074default_reporter::report(
const class_or_union_diff& d,
1076 const string& indent)
const
1078 if (!d.to_be_reported())
1081 class_or_union_sptr first = d.first_class_or_union(),
1082 second = d.second_class_or_union();
1091 first->get_is_declaration_only()
1092 ?
" was a declaration-only type"
1093 :
" was a defined type";
1096 second->get_is_declaration_only()
1097 ?
" and is now a declaration-only type"
1098 :
" and is now a defined type";
1100 out << indent <<
"type " << first->get_pretty_representation()
1101 << was << is_now <<
"\n";
1106 if (d.member_fns_changes())
1109 int numdels = d.get_priv()->deleted_member_functions_.size();
1110 size_t num_filtered =
1111 d.get_priv()->count_filtered_deleted_mem_fns(ctxt);
1114 "member function", indent);
1115 for (class_or_union::member_functions::const_iterator i =
1116 d.get_priv()->sorted_deleted_member_functions_.begin();
1117 i != d.get_priv()->sorted_deleted_member_functions_.end();
1120 if (!(ctxt->get_allowed_category()
1125 method_decl_sptr mem_fun = *i;
1126 out << indent <<
" ";
1131 int numins = d.get_priv()->inserted_member_functions_.size();
1132 num_filtered = d.get_priv()->count_filtered_inserted_mem_fns(ctxt);
1135 "member function", indent);
1136 for (class_or_union::member_functions::const_iterator i =
1137 d.get_priv()->sorted_inserted_member_functions_.begin();
1138 i != d.get_priv()->sorted_inserted_member_functions_.end();
1141 if (!(ctxt->get_allowed_category()
1146 method_decl_sptr mem_fun = *i;
1147 out << indent <<
" ";
1152 int numchanges = d.get_priv()->sorted_changed_member_functions_.size();
1153 num_filtered = d.get_priv()->count_filtered_changed_mem_fns(ctxt);
1156 "member function", indent);
1157 for (function_decl_diff_sptrs_type::const_iterator i =
1158 d.get_priv()->sorted_changed_member_functions_.begin();
1159 i != d.get_priv()->sorted_changed_member_functions_.end();
1162 if (!(ctxt->get_allowed_category()
1165 ((*i)->first_function_decl()))
1167 ((*i)->second_function_decl())))
1171 if (!diff || !diff->to_be_reported())
1175 (*i)->first_function_decl()->get_pretty_representation();
1176 out << indent <<
" '" << repr <<
"' has some sub-type changes:\n";
1177 diff->report(out, indent +
" ");
1182 if (d.data_members_changes())
1185 int numdels = d.class_or_union_diff::get_priv()->
1186 get_deleted_non_static_data_members_number();
1190 "data member", indent);
1191 vector<decl_base_sptr> sorted_dms;
1193 (d.class_or_union_diff::get_priv()->deleted_data_members_,
1195 for (vector<decl_base_sptr>::const_iterator i = sorted_dms.begin();
1196 i != sorted_dms.end();
1200 dynamic_pointer_cast<var_decl>(*i);
1210 d.class_or_union_diff::get_priv()->inserted_data_members_.size();
1214 "data member", indent);
1215 vector<decl_base_sptr> sorted_dms;
1217 (d.class_or_union_diff::get_priv()->inserted_data_members_,
1219 for (vector<decl_base_sptr>::const_iterator i = sorted_dms.begin();
1220 i != sorted_dms.end();
1224 dynamic_pointer_cast<var_decl>(*i);
1231 size_t num_changes =
1232 (d.sorted_subtype_changed_data_members().size()
1233 + d.sorted_changed_data_members().size());
1235 size_t num_changes_filtered =
1236 (d.count_filtered_subtype_changed_data_members()
1237 + d.count_filtered_changed_data_members());
1242 change_kind,
"data member", indent);
1244 for (var_diff_sptrs_type::const_iterator it =
1245 d.sorted_changed_data_members().begin();
1246 it != d.sorted_changed_data_members().end();
1248 if ((*it)->to_be_reported())
1249 represent(*it, ctxt, out, indent +
" ");
1251 for (var_diff_sptrs_type::const_iterator it =
1252 d.sorted_subtype_changed_data_members().begin();
1253 it != d.sorted_subtype_changed_data_members().end();
1255 if ((*it)->to_be_reported())
1256 represent(*it, ctxt, out, indent +
" ");
1265 if (
const edit_script& e = d.member_types_changes())
1268 d.class_or_union_diff::get_priv()->sorted_changed_member_types_.size();
1270 d.class_or_union_diff::get_priv()->deleted_member_types_.size();
1276 "member type", indent);
1278 for (string_decl_base_sptr_map::const_iterator i =
1279 d.class_or_union_diff::get_priv()->deleted_member_types_.begin();
1280 i != d.class_or_union_diff::get_priv()->deleted_member_types_.end();
1283 decl_base_sptr mem_type = i->second;
1284 out << indent <<
" '"
1285 << mem_type->get_pretty_representation()
1294 "member type", indent);
1296 for (diff_sptrs_type::const_iterator it =
1297 d.class_or_union_diff::get_priv()->sorted_changed_member_types_.begin();
1298 it != d.class_or_union_diff::get_priv()->sorted_changed_member_types_.end();
1301 if (!(*it)->to_be_reported())
1306 out << indent <<
" '"
1307 << o->get_pretty_representation()
1311 (*it)->report(out, indent +
" ");
1317 int numins = e.num_insertions();
1319 numins -= numchanges;
1324 "member type", indent);
1326 for (vector<insertion>::const_iterator i = e.insertions().begin();
1327 i != e.insertions().end();
1330 type_base_sptr mem_type;
1331 for (vector<unsigned>::const_iterator j =
1332 i->inserted_indexes().begin();
1333 j != i->inserted_indexes().end();
1336 mem_type = second->get_member_types()[*j];
1337 if (!d.class_or_union_diff::get_priv()->
1340 out << indent <<
" '"
1352 if (
const edit_script& e = d.member_fn_tmpls_changes())
1355 int numdels = e.num_deletions();
1358 "member function template", indent);
1359 for (vector<deletion>::const_iterator i = e.deletions().begin();
1360 i != e.deletions().end();
1363 member_function_template_sptr mem_fn_tmpl =
1364 first->get_member_function_templates()[i->index()];
1365 out << indent <<
" '"
1366 << mem_fn_tmpl->as_function_tdecl()->get_pretty_representation()
1371 int numins = e.num_insertions();
1374 "member function template", indent);
1375 for (vector<insertion>::const_iterator i = e.insertions().begin();
1376 i != e.insertions().end();
1379 member_function_template_sptr mem_fn_tmpl;
1380 for (vector<unsigned>::const_iterator j =
1381 i->inserted_indexes().begin();
1382 j != i->inserted_indexes().end();
1385 mem_fn_tmpl = second->get_member_function_templates()[*j];
1386 out << indent <<
" '"
1387 << mem_fn_tmpl->as_function_tdecl()->
1395 if (
const edit_script& e = d.member_class_tmpls_changes())
1398 int numdels = e.num_deletions();
1401 "member class template", indent);
1402 for (vector<deletion>::const_iterator i = e.deletions().begin();
1403 i != e.deletions().end();
1406 member_class_template_sptr mem_cls_tmpl =
1407 first->get_member_class_templates()[i->index()];
1408 out << indent <<
" '"
1409 << mem_cls_tmpl->as_class_tdecl()->get_pretty_representation()
1414 int numins = e.num_insertions();
1417 "member class template", indent);
1418 for (vector<insertion>::const_iterator i = e.insertions().begin();
1419 i != e.insertions().end();
1422 member_class_template_sptr mem_cls_tmpl;
1423 for (vector<unsigned>::const_iterator j =
1424 i->inserted_indexes().begin();
1425 j != i->inserted_indexes().end();
1428 mem_cls_tmpl = second->get_member_class_templates()[*j];
1429 out << indent <<
" '"
1430 << mem_cls_tmpl->as_class_tdecl()
1431 ->get_pretty_representation()
1448default_reporter::report(
const class_diff& d, ostream& out,
1449 const string& indent)
const
1451 if (!d.to_be_reported())
1454 string name = d.first_subject()->get_pretty_representation();
1456 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER(d.first_subject(),
1457 d.second_subject());
1459 d.currently_reporting(
true);
1463 second = d.second_class_decl();
1472 if (d.base_changes())
1475 int numdels = d.get_priv()->deleted_bases_.size();
1476 size_t numchanges = d.get_priv()->sorted_changed_bases_.size();
1481 "base class", indent);
1483 for (class_decl::base_specs::const_iterator i
1484 = d.get_priv()->sorted_deleted_bases_.begin();
1485 i != d.get_priv()->sorted_deleted_bases_.end();
1488 if (i != d.get_priv()->sorted_deleted_bases_.begin())
1493 if (d.get_priv()->base_has_changed(base))
1495 out << indent <<
" "
1496 << base->get_base_class()->get_pretty_representation();
1503 size_t num_filtered = d.get_priv()->count_filtered_bases();
1507 "base class", indent);
1508 for (base_diff_sptrs_type::const_iterator it =
1509 d.get_priv()->sorted_changed_bases_.begin();
1510 it != d.get_priv()->sorted_changed_bases_.end();
1514 if (!diff || !diff->to_be_reported())
1518 out << indent <<
" '"
1519 << o->get_base_class()->get_pretty_representation() <<
"'";
1521 out <<
" changed:\n";
1522 diff->report(out, indent +
" ");
1527 int numins = d.get_priv()->inserted_bases_.size();
1531 "base class", indent);
1533 for (class_decl::base_specs::const_iterator i =
1534 d.get_priv()->sorted_inserted_bases_.begin();
1535 i != d.get_priv()->sorted_inserted_bases_.end();
1539 out << indent <<
" " << b->get_pretty_representation();
1549 d.class_or_union_diff::report(out, indent);
1551 d.currently_reporting(
false);
1553 d.reported_once(
true);
1566default_reporter::report(
const union_diff& d, ostream& out,
1567 const string& indent)
const
1569 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER(d.first_subject(),
1570 d.second_subject());
1572 d.currently_reporting(
true);
1575 union_decl_sptr first = d.first_union_decl(), second = d.second_union_decl();
1582 d.class_or_union_diff::report(out, indent);
1590 out << indent <<
"type changed from:\n"
1596 << indent <<
"to:\n"
1604 d.currently_reporting(
false);
1606 d.reported_once(
true);
1618default_reporter::report(
const distinct_diff& d, ostream& out,
1619 const string& indent)
const
1621 if (!d.to_be_reported())
1626 string f_repr = f ? f->get_pretty_representation() :
"'void'";
1627 string s_repr = s ? s->get_pretty_representation() :
"'void'";
1629 diff_sptr diff = d.compatible_child_diff();
1631 string compatible = diff ?
" to compatible type '":
" to '";
1633 out << indent <<
"entity changed from '" << f_repr <<
"'"
1634 << compatible << s_repr <<
"'";
1642 diff->report(out, indent +
" ");
1656default_reporter::report(
const function_decl_diff& d, ostream& out,
1657 const string& indent)
const
1659 if (!d.to_be_reported())
1663 d.second_function_decl(),
1664 d.context(), out, indent);
1670 corpus_sptr fc = ctxt->get_first_corpus();
1671 corpus_sptr sc = ctxt->get_second_corpus();
1674 string qn1 = ff->get_qualified_name(), qn2 = sf->get_qualified_name(),
1675 linkage_names1, linkage_names2;
1679 linkage_names1 = s1->get_id_string();
1681 linkage_names2 = s2->get_id_string();
1687 s1->get_aliases_id_string(fc->get_fun_symbol_map());
1690 s2->get_aliases_id_string(sc->get_fun_symbol_map());
1692 if (!d.is_filtered_out_without_looking_at_allowed_changes())
1696 if (linkage_names1 != linkage_names2)
1698 if (linkage_names1.empty())
1700 out << indent << ff->get_pretty_representation()
1701 <<
" didn't have any linkage name, and it now has: '"
1702 << linkage_names2 <<
"'\n";
1704 else if (linkage_names2.empty())
1706 out << indent << ff->get_pretty_representation()
1707 <<
" did have linkage names '" << linkage_names1
1709 << indent <<
"but it doesn't have any linkage name anymore\n";
1712 out << indent <<
"linkage names of "
1713 << ff->get_pretty_representation()
1714 <<
"\n" << indent <<
"changed from '"
1715 << linkage_names1 <<
"' to '" << linkage_names2 <<
"'\n";
1720 && d.type_diff()->to_be_reported())
1726 string frep1 = d.first_function_decl()->get_pretty_representation(),
1727 frep2 = d.second_function_decl()->get_pretty_representation();
1728 out << indent <<
"'" << frep1 <<
" {" << linkage_names1<<
"}"
1729 <<
"' now becomes '"
1730 << frep2 <<
" {" << linkage_names2 <<
"}" <<
"'\n";
1735 d.context(), out, indent);
1738 if (ff->is_declared_inline() != sf->is_declared_inline())
1741 if (ff->is_declared_inline())
1742 out << sf->get_pretty_representation()
1743 <<
" is not declared inline anymore\n";
1745 out << sf->get_pretty_representation()
1746 <<
" is now declared inline\n";
1754 if (ff_is_virtual != sf_is_virtual)
1758 out << ff->get_pretty_representation()
1759 <<
" is no more declared virtual\n";
1761 out << ff->get_pretty_representation()
1762 <<
" is now declared virtual\n";
1767 if (ff_is_virtual && sf_is_virtual
1768 && (ff_vtable_offset != sf_vtable_offset))
1771 <<
"the vtable offset of " << ff->get_pretty_representation()
1772 <<
" changed from " << ff_vtable_offset
1773 <<
" to " << sf_vtable_offset <<
"\n";
1778 class_or_union_sptr f =
1780 class_or_union_sptr s =
1788 bool vtable_added =
false, vtable_removed =
false;
1789 if (!f->get_is_declaration_only() && !s->get_is_declaration_only())
1793 vtable_added = !fc->has_vtable() && sc->has_vtable();
1794 vtable_removed = fc->has_vtable() && !sc->has_vtable();
1797 bool vtable_changed = ((ff_is_virtual != sf_is_virtual)
1798 || (ff_vtable_offset != sf_vtable_offset));
1799 bool incompatible_change = (ff_vtable_offset != sf_vtable_offset);
1803 <<
" note that a vtable was added to "
1804 << fc->get_pretty_representation()
1806 else if (vtable_removed)
1808 <<
" note that the vtable was removed from "
1809 << fc->get_pretty_representation()
1811 else if (vtable_changed)
1814 if (incompatible_change)
1815 out <<
" note that this is an ABI incompatible "
1816 "change to the vtable of ";
1818 out <<
" note that this induces a change to the vtable of ";
1819 out << fc->get_pretty_representation()
1827 if (d.type_diff() && d.type_diff()->to_be_reported())
1828 d.type_diff()->report(out, indent);
1841default_reporter::report(
const var_diff& d, ostream& out,
1842 const string& indent)
const
1844 if (!d.to_be_reported())
1847 decl_base_sptr first = d.first_var(), second = d.second_var();
1848 string n = first->get_pretty_representation();
1850 if (!d.is_filtered_out_without_looking_at_allowed_changes())
1857 d.second_var()->get_symbol(),
1858 d.context(), out, indent);
1867 if (dif->to_be_reported())
1869 RETURN_IF_BEING_REPORTED_OR_WAS_REPORTED_EARLIER2(dif,
"type");
1870 out << indent <<
"type of variable changed:\n";
1871 dif->report(out, indent +
" ");
1885default_reporter::report(
const translation_unit_diff& d,
1887 const string& indent)
const
1889 static_cast<const scope_diff&
>(d).report(out, indent);
1911 ostream& out,
const string indent,
1912 bool indirect_changed_subtypes =
false,
1913 bool emit_redundant_fn_changes =
true)
1915 bool saved_show_redundant_changes = ctxt->show_redundant_changes();
1916 ctxt->show_redundant_changes(emit_redundant_fn_changes);
1918 if (fn_diff->to_be_reported())
1921 out << indent <<
" [C] '"
1922 << fn->get_pretty_representation() <<
"'";
1926 if (indirect_changed_subtypes)
1928 out <<
" sub-type changes:\n";
1933 (fn->get_symbol()->has_aliases()
1945 && fn->get_name() != fn->get_symbol()->get_name()))
1951 int number_of_aliases =
1952 fn->get_symbol()->get_number_of_aliases();
1953 if (number_of_aliases == 0)
1955 out << indent <<
" "
1956 <<
"Please note that the exported symbol of "
1958 << fn->get_symbol()->get_id_string()
1963 out << indent <<
" "
1964 <<
"Please note that the symbol of this function is "
1965 << fn->get_symbol()->get_id_string()
1966 <<
"\n and it aliases symbol";
1967 if (number_of_aliases > 1)
1970 << fn->get_symbol()->get_aliases_id_string(
false)
1974 fn_diff->report(out, indent +
" ");
1979 ctxt->show_redundant_changes(saved_show_redundant_changes);
2001 ostream& out,
const string indent,
2002 bool emit_redundant_var_changes =
true)
2008 bool saved_show_redundant_changes = ctxt->show_redundant_changes();
2009 ctxt->show_redundant_changes(emit_redundant_var_changes);
2011 if (diff->to_be_reported())
2013 string n1 = diff->first_subject()->get_pretty_representation();
2014 string n2 = diff->second_subject()->get_pretty_representation();
2016 out << indent <<
" [C] '" << n1 <<
"' was changed";
2018 out <<
" to '" << n2 <<
"'";
2021 diff->report(out, indent +
" ");
2026 ctxt->show_redundant_changes(saved_show_redundant_changes);
2038default_reporter::report(
const corpus_diff& d, ostream& out,
2039 const string& indent)
const
2041 const corpus_diff::diff_stats &s =
2042 const_cast<corpus_diff&
>(d).
2043 apply_filters_and_suppressions_before_reporting();
2047 d.priv_->emit_diff_stats(s, out, indent);
2048 if (ctxt->show_stats_only())
2052 if (ctxt->show_soname_change()
2053 && !d.priv_->sonames_equal_)
2054 out << indent <<
"SONAME changed from '"
2055 << d.first_corpus()->get_soname() <<
"' to '"
2056 << d.second_corpus()->get_soname() <<
"'\n\n";
2058 if (ctxt->show_architecture_change()
2059 && !d.priv_->architectures_equal_)
2060 out << indent <<
"architecture changed from '"
2061 << d.first_corpus()->get_architecture_name() <<
"' to '"
2062 << d.second_corpus()->get_architecture_name() <<
"'\n\n";
2065 if (ctxt->show_deleted_fns())
2067 if (s.net_num_func_removed() == 1)
2068 out << indent <<
"1 Removed function:\n\n";
2069 else if (s.net_num_func_removed() > 1)
2070 out << indent << s.net_num_func_removed() <<
" Removed functions:\n\n";
2072 bool emitted =
false;
2075 for (
auto f : sorted_deleted_fns)
2077 if (d.priv_->deleted_function_is_suppressed(f))
2084 if (ctxt->show_linkage_names())
2088 d.first_corpus()->get_fun_symbol_map());
2098 <<
"note that this removes an entry from the vtable of "
2099 << c->get_pretty_representation()
2108 if (
size_t num_changed = s.num_func_with_incompatible_changes())
2110 if (num_changed == 1)
2111 out << indent <<
"1 function with incompatible sub-type changes:\n\n";
2112 else if (num_changed > 1)
2113 out << indent << num_changed
2114 <<
" functions with incompatible sub-type changes:\n\n";
2117 incompatible_changed_functions());
2118 for (
auto& fn_diff : d.incompatible_changed_functions())
2120 emit_changed_fn_report(ctxt, fn_diff, out, indent);
2123 if (ctxt->show_added_fns())
2125 if (s.net_num_func_added() == 1)
2126 out << indent <<
"1 Added function:\n\n";
2127 else if (s.net_num_func_added() > 1)
2128 out << indent << s.net_num_func_added()
2129 <<
" Added functions:\n\n";
2130 bool emitted =
false;
2133 for (
auto f : sorted_added_fns)
2135 if (d.priv_->added_function_is_suppressed(f))
2143 << f->get_pretty_representation()
2145 if (ctxt->show_linkage_names())
2149 (out,
"", *f->get_symbol(),
2150 d.second_corpus()->get_fun_symbol_map());
2160 <<
"note that this adds a new entry to the vtable of "
2161 << c->get_pretty_representation()
2170 if (ctxt->show_changed_fns())
2171 if (
size_t num_changed = s.net_num_non_incompatible_func_changed())
2173 if (num_changed == 1)
2174 out << indent <<
"1 function with some indirect sub-type change:\n\n";
2175 else if (num_changed > 1)
2176 out << indent << num_changed
2177 <<
" functions with some indirect sub-type change:\n\n";
2179 vector<function_decl_diff_sptr> sorted_changed_fns;
2181 sorted_changed_fns);
2182 for (
auto& fn_diff : sorted_changed_fns)
2184 emit_changed_fn_report(ctxt, fn_diff, out, indent,
2191 if (ctxt->show_deleted_vars())
2193 if (s.net_num_vars_removed() == 1)
2194 out << indent <<
"1 Removed variable:\n\n";
2195 else if (s.net_num_vars_removed() > 1)
2196 out << indent << s.net_num_vars_removed()
2197 <<
" Removed variables:\n\n";
2199 bool emitted =
false;
2202 for (
auto v : sorted_deleted_vars)
2204 if (d.priv_->deleted_variable_is_suppressed(v))
2207 n = v->get_pretty_representation();
2215 if (ctxt->show_linkage_names())
2219 d.first_corpus()->get_var_symbol_map());
2229 if (
size_t num_changed = s.num_var_with_incompatible_changes())
2231 if (num_changed == 1)
2232 out << indent <<
"1 variable with incompatible sub-type changes:\n\n";
2233 else if (num_changed > 1)
2234 out << indent << num_changed
2235 <<
" variables with incompatible sub-type changes:\n\n";
2238 incompatible_changed_variables());
2239 for (
auto& var_diff : d.incompatible_changed_variables())
2241 emit_changed_var_report(ctxt, var_diff, out, indent);
2244 if (ctxt->show_added_vars())
2246 if (s.net_num_vars_added() == 1)
2247 out << indent <<
"1 Added variable:\n\n";
2248 else if (s.net_num_vars_added() > 1)
2249 out << indent << s.net_num_vars_added()
2250 <<
" Added variables:\n\n";
2252 bool emitted =
false;
2255 for (
auto v : sorted_added_vars)
2257 if (d.priv_->added_variable_is_suppressed(v))
2260 n = v->get_pretty_representation();
2265 out <<
"'" << n <<
"'";
2266 if (ctxt->show_linkage_names())
2270 d.second_corpus()->get_var_symbol_map());
2280 if (ctxt->show_changed_vars())
2281 if (
size_t num_changed = s.net_num_non_incompatible_var_changed())
2283 if (num_changed == 1)
2284 out << indent <<
"1 Changed variable:\n\n";
2285 else if (num_changed > 1)
2286 out << indent << num_changed
2287 <<
" Changed variables:\n\n";
2290 for (
auto& var_diff : d.priv_->sorted_changed_vars_)
2293 emit_changed_var_report(ctxt, var_diff, out, indent);
2298 if (ctxt->show_symbols_unreferenced_by_debug_info()
2299 && d.priv_->deleted_unrefed_fn_syms_.size())
2301 if (s.net_num_removed_func_syms() == 1)
2303 <<
"1 Removed function symbol not referenced by debug info:\n\n";
2304 else if (s.net_num_removed_func_syms() > 0)
2306 << s.net_num_removed_func_syms()
2307 <<
" Removed function symbols not referenced by debug info:\n\n";
2309 bool emitted =
false;
2310 vector<elf_symbol_sptr> sorted_deleted_unrefed_fn_syms;
2312 sorted_deleted_unrefed_fn_syms);
2313 for (vector<elf_symbol_sptr>::const_iterator i =
2314 sorted_deleted_unrefed_fn_syms.begin();
2315 i != sorted_deleted_unrefed_fn_syms.end();
2318 if (d.priv_->deleted_unrefed_fn_sym_is_suppressed((*i).get()))
2321 out << indent <<
" ";
2325 d.first_corpus()->get_fun_symbol_map());
2334 if (ctxt->show_symbols_unreferenced_by_debug_info()
2335 && ctxt->show_added_symbols_unreferenced_by_debug_info()
2336 && d.priv_->added_unrefed_fn_syms_.size())
2338 if (s.net_num_added_func_syms() == 1)
2340 <<
"1 Added function symbol not referenced by debug info:\n\n";
2341 else if (s.net_num_added_func_syms() > 0)
2343 << s.net_num_added_func_syms()
2344 <<
" Added function symbols not referenced by debug info:\n\n";
2346 bool emitted =
false;
2347 vector<elf_symbol_sptr> sorted_added_unrefed_fn_syms;
2349 sorted_added_unrefed_fn_syms);
2350 for (vector<elf_symbol_sptr>::const_iterator i =
2351 sorted_added_unrefed_fn_syms.begin();
2352 i != sorted_added_unrefed_fn_syms.end();
2355 if (d.priv_->added_unrefed_fn_sym_is_suppressed((*i).get()))
2358 out << indent <<
" ";
2362 d.second_corpus()->get_fun_symbol_map());
2371 if (ctxt->show_symbols_unreferenced_by_debug_info()
2372 && d.priv_->deleted_unrefed_var_syms_.size())
2374 if (s.net_num_removed_var_syms() == 1)
2376 <<
"1 Removed variable symbol not referenced by debug info:\n\n";
2377 else if (s.net_num_removed_var_syms() > 0)
2379 << s.net_num_removed_var_syms()
2380 <<
" Removed variable symbols not referenced by debug info:\n\n";
2382 bool emitted =
false;
2383 vector<elf_symbol_sptr> sorted_deleted_unrefed_var_syms;
2385 sorted_deleted_unrefed_var_syms);
2386 for (vector<elf_symbol_sptr>::const_iterator i =
2387 sorted_deleted_unrefed_var_syms.begin();
2388 i != sorted_deleted_unrefed_var_syms.end();
2391 if (d.priv_->deleted_unrefed_var_sym_is_suppressed((*i).get()))
2394 out << indent <<
" ";
2399 d.first_corpus()->get_fun_symbol_map());
2409 if (ctxt->show_symbols_unreferenced_by_debug_info()
2410 && ctxt->show_added_symbols_unreferenced_by_debug_info()
2411 && d.priv_->added_unrefed_var_syms_.size())
2413 if (s.net_num_added_var_syms() == 1)
2415 <<
"1 Added variable symbol not referenced by debug info:\n\n";
2416 else if (s.net_num_added_var_syms() > 0)
2418 << s.net_num_added_var_syms()
2419 <<
" Added variable symbols not referenced by debug info:\n\n";
2421 bool emitted =
false;
2422 vector<elf_symbol_sptr> sorted_added_unrefed_var_syms;
2424 sorted_added_unrefed_var_syms);
2425 for (vector<elf_symbol_sptr>::const_iterator i =
2426 sorted_added_unrefed_var_syms.begin();
2427 i != sorted_added_unrefed_var_syms.end();
2430 if (d.priv_->added_unrefed_var_sym_is_suppressed((*i).get()))
2433 out << indent <<
" ";
2436 d.second_corpus()->get_fun_symbol_map());
2448 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.
bool any_subrange_diff_to_be_reported() const
Test if any subrange diff is to be reported.
const array_type_def_sptr second_array() const
Getter for the second array of the diff.
const array_type_def_sptr first_array() const
Getter for the first array of the diff.
const vector< subrange_diff_sptr > & subrange_diffs() const
Getter for the diffs between the array subranges.
This is a document class that aims to capture statistics about the changes carried by a corpus_diff t...
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 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_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_changed_unreachable_types() const
Getter of the number of changed types that are unreachable from public interfaces and that have *NOT*...
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 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_ptr_to_mbr_type_changes(const ptr_to_mbr_diff &d, std::ostream &out, const std::string &indent="") const
Report the local changes carried by a ptr_to_mbr_diff diff node.
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.
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_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.
void report_non_type_typedef_changes(const typedef_diff &d, std::ostream &out, const std::string &indent) const
For a typedef_diff node, report the local changes to the typedef rather the changes to its underlying...
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...
const diff_context_sptr context() const
Getter of the context of the current diff.
bool to_be_reported() const
Test if this diff tree node should be reported.
bool reported_once() const
Tests if a report has already been emitted for the current diff.
Abstraction of a diff between two function parameters.
const function_decl::parameter_sptr first_parameter() const
Getter for the first subject of this diff node.
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...
Abstraction of a diff between two function types.
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.
The abstraction of a diff between two pointers.
diff_sptr underlying_type_diff() const
Getter for the diff between the pointed-to types of the pointers of this diff.
The abstraction of a diff between two ptr_to_mbr_type.
ptr_to_mbr_type_sptr first_ptr_to_mbr_type() const
Getter of the first pointer-to-member subject of the current diff node.
const diff_sptr containing_type_diff() const
Getter of the diff node carrying changes to the containing type of first subject of the current diff ...
const diff_sptr member_type_diff() const
Getter of the diff node carrying changes to the member type of first subject of the current diff node...
ptr_to_mbr_type_sptr second_ptr_to_mbr_type() const
Getter of the second pointer-to-member subject of the current diff node.
Abstraction of a diff between two qualified types.
diff_sptr leaf_underlying_type_diff() const
Getter for the diff between the most underlying non-qualified types of two qualified types.
const qualified_type_def_sptr second_qualified_type() const
Getter for the second qualified type of the diff.
const qualified_type_def_sptr first_qualified_type() const
Getter for the first qualified type of the diff.
The abstraction of a diff between two references.
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.
const diff_sptr & underlying_type_diff() const
Getter for the diff between the two referred-to types.
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.
virtual void report(ostream &, const string &indent="") const
Report about the changes carried by this node.
Abstraction of a diff between two basic type declarations.
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.
Abstraction of a diff between two typedef_decl.
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.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
vector< var_decl_sptr > variables
Convenience typedef for std::vector<abigail::ir::var_decl*>
vector< const function_decl * > functions
Convenience typedef for std::vector<abigail::ir::function_decl*>
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
bool has_enum_decl_only_def_change(const enum_type_decl_sptr &first, const enum_type_decl_sptr &second)
Test if two enum_sptr are different just by the fact that one is decl-only and the other one is defin...
bool has_harmless_name_change(const decl_base_sptr &f, const decl_base_sptr &s, const diff_context_sptr &ctxt)
Test if two decls represents a harmless name change.
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...
bool has_incompatible_fn_or_var_change(const diff *d)
Test if a diff node carries an incompatible ABI change.
bool union_diff_has_harmless_changes(const diff *d)
Test if a union diff node does have changes that don't impact its size.
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 ...
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...
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,...
@ SUPPRESSED_CATEGORY
This means that a diff node was marked as suppressed by a user-provided suppression specification.
@ REDUNDANT_CATEGORY
A diff node in this category is redundant. That means it's present as a child of a other nodes in 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...
@ 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...
@ 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 ...
@ HARMLESS_UNION_OR_CLASS_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a harmless union or class change.
@ HARMLESS_DECL_NAME_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a harmless declaration name change....
void sort_string_function_ptr_map(const string_function_ptr_map &map, vector< const function_decl * > &sorted)
Sort an instance of string_function_ptr_map map and stuff a resulting sorted vector of pointers to fu...
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 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)
shared_ptr< var_diff > var_diff_sptr
Convenience typedef for a shared pointer to a var_diff type.
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.
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...
bool maybe_report_diff_for_variable(const decl_base_sptr &decl1, const decl_base_sptr &decl2, const diff_context_sptr &ctxt, ostream &out, const string &indent)
Report the differences between two generic variables.
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 sort_function_decl_diffs(function_decl_diff_sptrs_type &fn_diffs)
Sort a vector of function_decl_diff_sptr.
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.
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
shared_ptr< base_diff > base_diff_sptr
Convenience typedef for a shared pointer to a base_diff type.
shared_ptr< class_diff > class_diff_sptr
Convenience typedef for a shared pointer on a class_diff type.
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 sort_string_var_ptr_map(const string_var_ptr_map &map, vector< var_decl_sptr > &sorted)
Sort a map of string -> pointer to var_decl.
void 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.
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.
void sort_var_diffs(var_diff_sptrs_type &var_diffs)
Sort a vector of var_diff_sptr.
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_enumerators(const string_enumerator_map &enumerators_map, enum_type_decl::enumerators &sorted)
Sort a map of enumerators by their value.
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.
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.
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
@ SUBTYPE_CHANGE_KIND
This means that a given IR artifact has changes in some of its sub-types, with respect to the other a...
@ ALL_LOCAL_CHANGES_MASK
Testing (anding) against this mask means that a given IR artifact has local differences,...
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...
bool types_have_similar_structure(const type_base_sptr &first, const type_base_sptr &second, bool indirect_type)
Test if two types have similar structures, even though they are (or can be) different.
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.
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.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of 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.
string get_class_or_union_flat_representation(const class_or_union &cou, const string &indent, bool one_line, bool internal, bool qualified_names)
Get the flat representation of an instance of class_or_union type.
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 ...
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
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.
bool type_has_sub_type_changes(const type_base_sptr t_v1, const type_base_sptr t_v2)
Tests if the change of a given type effectively comes from just its sub-types. That is,...
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.