11 #include "abg-reporter-priv.h"
42 out << std::hex << std::showbase ;
45 out << value << std::dec << std::noshowbase;
101 bool show_bits_or_byte)
103 bool can_convert_bits_to_bytes = (old_bits % 8 == 0 && new_bits % 8 == 0);
104 uint64_t o = can_convert_bits_to_bytes
107 uint64_t n = can_convert_bits_to_bytes
110 string bits_or_bytes =
115 out << what <<
" changed from ";
119 if (show_bits_or_byte)
122 out << bits_or_bytes;
145 bool can_convert_bits_to_bytes = (value % 8 == 0);
146 if (can_convert_bits_to_bytes)
148 string bits_or_bytes =
156 out <<
" (in " << bits_or_bytes <<
")";
183 method_decl_sptr mem_fn,
189 method_decl_sptr meth =
193 out <<
"'" << mem_fn->get_pretty_representation() <<
"'";
199 ssize_t biggest_voffset =
201 get_biggest_vtable_offset();
204 out <<
", virtual at voffset ";
212 if (ctxt.show_linkage_names()
213 && (mem_fn->get_symbol()))
216 << mem_fn->get_symbol()->get_id_string()
235 const string& indent)
243 << d->get_pretty_representation(
false,
294 if (first_offset < second_offset)
297 change = second_offset - first_offset;
299 else if (first_offset > second_offset)
302 change = first_offset - second_offset;
314 out <<
" (by " << sign;
316 out <<
" " << bits_or_bytes <<
")";
353 if (first_size < second_size)
356 change = second_size - first_size;
358 else if (first_size > second_size)
361 change = first_size - second_size;
373 out <<
" (by " << sign;
375 out <<
" " << bits_or_bytes <<
")";
394 const string& indent,
397 if (!ctxt->get_reporter()->diff_to_be_reported(diff.get()))
404 const bool is_strict_anonymous_data_member_change = o_anon && n_anon;
407 : o->get_qualified_name());
410 : n->get_qualified_name());
415 const string o_pretty_representation =
416 o->get_pretty_representation(
false,
false);
418 const bool show_size_offset_changes = ctxt->get_allowed_category()
422 bool emitted =
false;
424 bool begin_with_and =
false;
426 bool size_reported =
false;
441 if (is_strict_anonymous_data_member_change)
443 const string n_pretty_representation =
444 n->get_pretty_representation(
false,
446 const type_base_sptr o_type = o->get_type(), n_type = n->get_type();
447 if (o_pretty_representation != n_pretty_representation)
450 o_offset, *ctxt, out);
452 out <<
" changed from:\n"
453 << indent <<
" " << o_pretty_representation <<
"\n"
455 << indent <<
" " << n_pretty_representation <<
"\n";
457 begin_with_and =
true;
462 &&
is_decl(o_type)->get_is_anonymous()
463 &&
is_decl(n_type)->get_is_anonymous())
465 out << indent <<
"while looking at anonymous data member '"
466 << o_pretty_representation <<
"':\n"
467 << indent <<
"the internal name of that anonymous data member"
472 << indent <<
" This is usually due to "
473 <<
"an anonymous member type being added or removed from "
474 <<
"the containing type\n";
476 begin_with_and =
true;
485 const string n_pretty_representation =
486 n->get_pretty_representation(
false,
488 out << indent << (o_anon ?
"anonymous " :
"")
489 <<
"data member " << o_pretty_representation;
491 out <<
" became " << (n_anon ?
"anonymous " :
"")
492 <<
"data member '" << n_pretty_representation <<
"'\n";
494 begin_with_and =
true;
507 if (
const diff_sptr d = diff->type_diff())
509 if (ctxt->get_reporter()->diff_to_be_reported(d.get()))
512 out << indent <<
"type '"
516 string(
"anonymous data member")
517 : o->get_qualified_name())
521 <<
"type of '"<< (o_anon ?
"anonymous data member ":
"")
522 << o_pretty_representation <<
"' changed";
524 if (d->currently_reporting())
525 out <<
", as being reported\n";
526 else if (d->reported_once())
527 out <<
", as reported earlier\n";
531 d->report(out, indent +
" ");
534 begin_with_and =
true;
536 size_reported =
true;
548 && !(ctxt->get_allowed_category()
555 out << indent <<
"and ";
556 begin_with_and =
false;
562 out <<
"name of '" << o_name <<
"' changed to '" << n_name <<
"'";
573 out << indent <<
"and ";
574 begin_with_and =
false;
577 out << indent <<
"'" << o_pretty_representation <<
"' ";
581 out <<
"is no more laid out";
583 out <<
"now becomes laid out";
586 if (show_size_offset_changes)
588 if (o_offset != n_offset)
592 out << indent <<
"and ";
593 begin_with_and =
false;
598 if (is_strict_anonymous_data_member_change)
599 out <<
"anonymous data member ";
600 out <<
"'" << o_pretty_representation <<
"' ";
610 if (!size_reported && o_size != n_size)
614 out << indent <<
"and ";
615 begin_with_and =
false;
620 if (is_strict_anonymous_data_member_change)
621 out <<
"anonymous data member ";
622 out <<
"'" << o_pretty_representation <<
"' ";
632 if (o->get_binding() != n->get_binding())
636 out << indent <<
"and ";
637 begin_with_and =
false;
640 out << indent <<
"'" << o_pretty_representation <<
"' ";
643 out <<
"elf binding changed from " << o->get_binding()
644 <<
" to " << n->get_binding();
647 if (o->get_visibility() != n->get_visibility())
651 out << indent <<
"and ";
652 begin_with_and =
false;
655 out << indent <<
"'" << o_pretty_representation <<
"' ";
658 out <<
"visibility changed from " << o->get_visibility()
659 <<
" to " << n->get_visibility();
668 out << indent <<
"and ";
669 begin_with_and =
false;
672 out << indent <<
"'" << o_pretty_representation <<
"' ";
676 out <<
"access changed from '"
687 out << indent <<
"and ";
688 begin_with_and =
false;
691 out << indent <<
"'" << o_pretty_representation <<
"' ";
696 out <<
"is no more static";
698 out <<
"now becomes static";
707 out << indent <<
"'" << o_pretty_representation
708 <<
"' has *some* difference - please report as a bug";
735 const string& indent,
740 string oor = o->get_pretty_representation();
741 string nr = n->get_pretty_representation();
742 string on = o->get_name();
743 string nn = n->get_name();
744 int64_t olb = o->get_lower_bound();
745 int64_t nlb = n->get_lower_bound();
746 int64_t oub = o->get_upper_bound();
747 int64_t nub = n->get_upper_bound();
751 out << indent <<
"name of range changed from '"
752 << on <<
"' to '" << nn <<
"'\n";
757 out << indent <<
"lower bound of '" << oor <<
"' change from '";
766 out << indent <<
"upper bound of '" << oor <<
"' change from '";
773 if (o->is_non_finite() != n->is_non_finite())
776 << (o->is_non_finite()
777 ? string(
"unknown sized")
778 : string(
"known sized"))
779 <<
string(
" range '")
781 << string(
"' changed to ")
782 << (n->is_non_finite()
783 ? string(
"unknown sized")
784 : string(
"known sized"))
785 <<
string(
" range '")
793 if (dif && dif->to_be_reported())
796 out << indent <<
"underlying type of range '"
797 << oor <<
"' changed:\n";
798 dif->report(out, indent +
" ");
819 const string& indent)
821 type_base_sptr f = dynamic_pointer_cast<
type_base>(first),
822 s = dynamic_pointer_cast<type_base>(second);
837 unsigned fs = f->get_size_in_bits(), ss = s->get_size_in_bits(),
838 fa = f->get_alignment_in_bits(), sa = s->get_alignment_in_bits();
841 unsigned fdc = first_array ? first_array->get_dimension_count(): 0,
842 sdc = second_array ? second_array->get_dimension_count(): 0;
846 if (fs != ss || fdc != sdc)
848 if (first_array && second_array)
852 out << indent <<
"array type size changed from ";
853 if (first_array->is_non_finite())
854 out <<
"\'unknown\'";
858 if (second_array->is_non_finite())
859 out <<
"\'unknown\'";
867 <<
"number of dimensions changed from "
873 array_type_def::subranges_type::const_iterator i, j;
874 for (i = first_array->get_subranges().begin(),
875 j = second_array->get_subranges().begin();
876 (i != first_array->get_subranges().end()
877 && j != second_array->get_subranges().end());
880 if ((*i)->get_length() != (*j)->get_length())
883 <<
"array type subrange "
884 << i - first_array->get_subranges().begin() + 1
885 <<
" changed length from ";
887 if ((*i)->is_non_finite())
888 out <<
"\'unknown\'";
890 out << (*i)->get_length();
894 if ((*j)->is_non_finite())
895 out <<
"\'unknown\'";
897 out << (*j)->get_length();
910 if (ctxt->show_relative_offset_changes())
912 out << indent <<
"type size hasn't changed\n";
940 decl_base_sptr decl =
is_decl(tod);
948 if (tu && (loc = decl->get_location()))
951 unsigned line, column;
953 loc.
expand(path, line, column);
955 path = basename(const_cast<char*>(path.c_str()));
957 out <<
" at " << path <<
":" << line <<
":" << column;
977 decl_base_sptr second,
980 const string& indent)
982 string fn = first->get_qualified_name(),
983 sn = second->get_qualified_name();
985 if (!(first->get_is_anonymous() && second->get_is_anonymous())
999 out <<
"declaration";
1000 out <<
" name changed from '" << fn <<
"' to '" << sn <<
"'";
1030 size_t num_filtered,
1032 const string& section_name,
1033 const string& indent)
1035 size_t net_number = number - num_filtered;
1037 char colon_or_semi_colon =
':';
1042 change = (number > 1) ?
"deletions" :
"deletion";
1045 change = (number > 1) ?
"insertions" :
"insertion";
1047 case subtype_change_kind:
1049 change = (number > 1) ?
"changes" :
"change";
1053 if (net_number == 0)
1055 out << indent <<
"no " << section_name <<
" " << change;
1056 colon_or_semi_colon =
';';
1058 else if (net_number == 1)
1059 out << indent <<
"1 " << section_name <<
" " << change;
1061 out << indent << net_number <<
" " << section_name
1065 out <<
" (" << num_filtered <<
" filtered)";
1066 out << colon_or_semi_colon <<
"\n";
1086 const string& section_name,
1087 const string& indent)
1094 change =
"deletions";
1097 change =
"insertions";
1099 case subtype_change_kind:
1105 out << indent <<
"there are " << section_name <<
" " << change <<
":\n";
1127 ostream& out,
const string indent,
1128 bool indirect_changed_subtypes,
1129 bool emit_redundant_fn_changes)
1131 bool saved_show_redundant_changes = ctxt->show_redundant_changes();
1132 ctxt->show_redundant_changes(emit_redundant_fn_changes);
1134 if (fn_diff->to_be_reported())
1137 out << indent <<
" [C] '"
1138 << fn->get_pretty_representation() <<
"'";
1142 if (indirect_changed_subtypes)
1144 out <<
" sub-type changes:\n";
1146 if ((fn->get_symbol()->has_aliases()
1152 && fn->get_name() != fn->get_linkage_name()))
1154 int number_of_aliases =
1155 fn->get_symbol()->get_number_of_aliases();
1156 if (number_of_aliases == 0)
1158 out << indent <<
" "
1159 <<
"Please note that the exported symbol of "
1161 << fn->get_symbol()->get_id_string()
1166 out << indent <<
" "
1167 <<
"Please note that the symbol of this function is "
1168 << fn->get_symbol()->get_id_string()
1169 <<
"\n and it aliases symbol";
1170 if (number_of_aliases > 1)
1173 << fn->get_symbol()->get_aliases_id_string(
false)
1177 fn_diff->report(out, indent +
" ");
1182 ctxt->show_redundant_changes(saved_show_redundant_changes);
1204 ostream& out,
const string indent,
1205 bool emit_redundant_var_changes)
1211 bool saved_show_redundant_changes = ctxt->show_redundant_changes();
1212 ctxt->show_redundant_changes(emit_redundant_var_changes);
1214 if (diff->to_be_reported())
1216 string n1 = diff->
first_subject()->get_pretty_representation();
1217 string n2 = diff->second_subject()->get_pretty_representation();
1219 out << indent <<
" [C] '" << n1 <<
"' was changed";
1221 out <<
" to '" << n2 <<
"'";
1224 diff->report(out, indent +
" ");
1229 ctxt->show_redundant_changes(saved_show_redundant_changes);
1246 const decl_base_sptr& decl2,
1249 const string& indent)
1252 bool reported =
false;
1256 string decl1_repr = decl1->get_pretty_representation(),
1257 decl2_repr = decl2->get_pretty_representation();
1262 out << indent <<
"'" << decl1_repr <<
"' ";
1266 out <<
"became non-static";
1268 out <<
"became static";
1276 out << indent <<
"'" << decl1_repr <<
"' access changed from '"
1301 const decl_base_sptr& decl2,
1304 const string& indent)
1306 bool reported =
false;
1316 uint64_t var_size_in_bits = var1->get_symbol()->get_size() * 8;
1320 var_size_in_bits, *ctxt, out);
1321 out <<
") hasn't changed\n"
1322 << indent <<
"but it does have a harmless type change\n";
1345 const string& indent)
1347 if (!symbol1 || !symbol2 || symbol1 == symbol2)
1350 if (symbol1->get_size() != symbol2->get_size())
1354 symbol1->get_size(),
1355 symbol2->get_size(),
1361 if (symbol1->get_name() != symbol2->get_name())
1363 out << indent <<
"symbol name changed from "
1364 << symbol1->get_name()
1366 << symbol2->get_name()
1370 if (symbol1->get_type() != symbol2->get_type())
1372 out << indent <<
"symbol type changed from '"
1373 << symbol1->get_type()
1375 << symbol2->get_type()
1379 if (symbol1->is_public() != symbol2->is_public())
1381 out << indent <<
"symbol became ";
1382 if (symbol2->is_public())
1385 out <<
"non-exported";
1389 if (symbol1->is_defined() != symbol2->is_defined())
1391 out << indent <<
"symbol became ";
1392 if (symbol2->is_defined())
1399 if (symbol1->get_version() != symbol2->get_version())
1401 out << indent <<
"symbol version changed from "
1402 << symbol1->get_version().str()
1404 << symbol2->get_version().str()
1412 const std::string none =
"(none)";
1413 out << indent <<
"CRC (modversions) changed from "
1414 << std::showbase << std::hex;
1415 if (crc1.has_value())
1416 out << crc1.value();
1420 if (crc2.has_value())
1421 out << crc2.value();
1424 out << std::noshowbase << std::dec
1432 const std::string none =
"(none)";
1433 out << indent <<
"namespace changed from ";
1434 if (ns1.has_value())
1435 out <<
"'" << ns1.value() <<
"'";
1439 if (ns2.has_value())
1440 out <<
"'" << ns2.value() <<
"'";
1461 const string& indent,
1469 if (!aliases.empty())
1470 out <<
", aliases " << aliases;
1489 const string& indent,
1494 if (!(ctxt->show_unreachable_types()
1495 && (!d.priv_->deleted_unreachable_types_.empty()
1496 || !d.priv_->added_unreachable_types_.empty()
1497 || !d.priv_->changed_unreachable_types_.empty())))
1505 <<
"1 removed type unreachable from any public interface:\n\n";
1509 <<
" removed types unreachable from any public interface:\n\n";
1511 vector<type_base_sptr> sorted_removed_unreachable_types;
1513 sorted_removed_unreachable_types);
1514 bool emitted =
false;
1515 for (vector<type_base_sptr>::const_iterator i =
1516 sorted_removed_unreachable_types.begin();
1517 i != sorted_removed_unreachable_types.end();
1520 if (d.priv_->deleted_unreachable_type_is_suppressed((*i).get()))
1534 <<
"1 changed type unreachable from any public interface:\n\n";
1538 <<
" changed types unreachable from any public interface:\n\n";
1543 for (diff_sptrs_type::const_iterator i = sorted_diff_sptrs.begin();
1544 i != sorted_diff_sptrs.end();
1548 if (!diff || !diff->to_be_reported())
1551 string repr = diff->
first_subject()->get_pretty_representation();
1553 out << indent <<
" [C] '" << repr <<
"' changed:\n";
1554 diff->report(out, indent +
" ");
1563 <<
"1 added type unreachable from any public interface:\n\n";
1567 <<
" added types unreachable from any public interface:\n\n";
1569 vector<type_base_sptr> sorted_added_unreachable_types;
1571 sorted_added_unreachable_types);
1573 for (vector<type_base_sptr>::const_iterator i =
1574 sorted_added_unreachable_types.begin();
1575 i != sorted_added_unreachable_types.end();
1578 if (d.priv_->added_unreachable_type_is_suppressed((*i).get()))
1601 const string &indent)
1608 if (!ctxt->show_impacted_interfaces())
1611 const diff_maps &maps = corp_diff->get_leaf_diffs();
1614 if (impacted_artifacts == 0)
1617 if (impacted_artifacts->empty())
1620 vector<type_or_decl_base_sptr> sorted_impacted_interfaces;
1623 size_t num_impacted_interfaces = impacted_artifacts->size();
1624 if (num_impacted_interfaces == 1)
1625 out << indent <<
"one impacted interface:\n";
1627 out << indent << num_impacted_interfaces <<
" impacted interfaces:\n";
1629 string cur_indent = indent +
" ";
1630 vector<type_or_decl_base_sptr>::const_iterator it;
1631 for (it = sorted_impacted_interfaces.begin();
1632 it != sorted_impacted_interfaces.end();
1650 const string &indent)
1674 const string &indent)
1684 for (changed_var_sptrs_type::const_iterator i =
1690 vector<var_decl_sptr> dms_replaced_by_same_anon_dm;
1691 dms_replaced_by_same_anon_dm.push_back(i->first);
1700 && *i->second == *anonymous_data_member;
1702 dms_replaced_by_same_anon_dm.push_back(i->first);
1704 bool several_data_members_replaced =
1705 dms_replaced_by_same_anon_dm.size() > 1;
1707 out << indent <<
"data member";
1708 if (several_data_members_replaced)
1711 bool first_data_member =
true;
1712 for (vector<var_decl_sptr>::const_iterator it =
1713 dms_replaced_by_same_anon_dm.begin();
1714 it != dms_replaced_by_same_anon_dm.end();
1717 string name = (*it)->get_qualified_name();
1718 if (!first_data_member)
1720 out <<
" '" << name <<
"'";
1721 first_data_member =
false;
1724 if (several_data_members_replaced)
1729 out <<
"replaced by anonymous data member:\n"
1732 << anonymous_data_member->get_pretty_representation()
1748 const string &indent)
1756 ABG_ASSERT(!first->get_base_specifiers().empty());
1757 ABG_ASSERT(!second->get_base_specifiers().empty());
1759 out << indent <<
"base classes of '"
1760 << first->get_pretty_representation()
1761 <<
"' are re-ordered from: ";
1763 vector<class_decl_sptr> classes = {first, second};
1764 unsigned nb_classes_seen = 0;
1765 for (
auto &klass : classes)
1767 if (nb_classes_seen >= 1)
1770 bool needs_comma =
false;
1771 for (
auto &b : klass->get_base_specifiers())
1775 if (b->get_is_virtual())
1777 out << b->get_base_class()->get_qualified_name();
1783 if (nb_classes_seen)
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...
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool show_offsets_sizes_in_bits() const
Get the flag that indicates if diff reports using this context should show sizes and offsets in bits...
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
The abstraction of a change between two ABI artifacts, a.k.a an artifact change.
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.
class_decl_sptr second_class_decl() const
Getter of the second class involved in the diff.
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*...
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
An abstraction helper for type declarations.
This means the diff node (or at least one of its descendant nodes) carries a change that modifies the...
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
uint64_t maybe_convert_bits_to_bytes(uint64_t bits, const diff_context &ctxt)
Convert a bits value into a byte value if the current diff context instructs us to do so...
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 show_numerical_change(const string &what, uint64_t old_bits, uint64_t new_bits, const diff_context &ctxt, ostream &out, bool show_bits_or_byte)
Emit a message showing the numerical change between two values, to a given output stream...
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 represent(const diff_context &ctxt, method_decl_sptr mem_fn, ostream &out)
Stream a string representation for a member function.
This type abstracts changes for a class_decl.
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 ...
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
type_or_decl_base_sptr first_subject() const
Getter of the first subject of the diff.
This is the abstraction of the set of relevant artefacts (types, variable declarations, functions, templates, etc) bundled together into a translation unit.
shared_ptr< diff_context > diff_context_sptr
Convenience typedef for a shared pointer of diff_context.
void maybe_show_relative_offset_change(const var_diff_sptr &diff, diff_context &ctxt, ostream &out)
If a given var_diff node carries a data member change in which the offset of the data member actually...
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
This means the diff node (or at least one of its descendant nodes) carries access related changes...
virtual bool diff_to_be_reported(const diff *d) const
Tests if the diff node is to be reported.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Abstraction of the declaration of a method.
void show_offset_or_size(const string &what, uint64_t value, const diff_context &ctxt, ostream &out)
Emit a message showing the value of a numerical value representing a size or an offset, preceded by a string. The message is ended by a part which says if the value is in bits or bytes.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
void sort_string_diff_sptr_map(const string_diff_sptr_map &map, diff_sptrs_type &sorted)
Sort a map ofg string -> diff_sptr into a vector of diff_sptr. The diff_sptr are sorted lexicographic...
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
void emit_changed_var_report(const diff_context_sptr &ctxt, const var_diff_sptr &var_diff, ostream &out, const string indent, bool emit_redundant_var_changes)
Emit a report about a changed variable.
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.
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
bool has_anonymous_data_member_change(const diff *d)
Test if a diff node carries a non-anonymous data member to anonymous data member change, or vice-versa.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
This is the base class of class_diff and union_diff.
string get_aliases_id_string(const string_elf_symbols_map_type &symtab, bool include_symbol_itself=true) const
Return a comma separated list of the id of the current symbol as well as the id string of its aliases...
The abstraction of the diff between two subrange types.
bool is_data_member_of_anonymous_class_or_union(const var_decl &d)
Test if a var_decl is a data member belonging to an anonymous type.
An abstraction of a diff between between two abi corpus.
diff_kind
Represent the kind of difference we want report_mem_header() to report.
void expand(std::string &path, unsigned &line, unsigned &column) const
Expand the current location into a tripplet file path, line and column number.
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...
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Toplevel namespace for libabigail.
unordered_set< type_or_decl_base_sptr, type_or_decl_hash, type_or_decl_equal > artifact_sptr_set_type
A convenience typedef for a hash set of type_or_decl_base_sptr.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
std::unordered_map< string, elf_symbols > string_elf_symbols_map_type
Convenience typedef for a map which key is a string and which value is a vector of elf_symbol...
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 show_relative_offset_changes(bool f)
Set a flag saying if offset changes should be reported in a relative way. That is, if the report should say how of many bits a class/struct data member did move.
This means that a diff node in the sub-tree carries a harmless declaration name change. This is set only for name changes for data members and typedefs.
const array_type_def::subrange_sptr first_subrange() const
Getter of the first subrange of the current instance subrange_diff.
This means that a diff node in the sub-tree carries a harmless data member change. An example of harmless data member change is an anonymous data member that replaces a given data member without locally changing the layout.
void emit_changed_fn_report(const diff_context_sptr &ctxt, const function_decl_diff_sptr &fn_diff, ostream &out, const string indent, bool indirect_changed_subtypes, bool emit_redundant_fn_changes)
Emit a report about a changed function.
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...
class_decl_sptr first_class_decl() const
The context of the diff. This type holds various bits of information that is going to be used through...
const diff_sptr underlying_type_diff() const
Getter of the diff node of the underlying types of the current subrange_diff diff node...
shared_ptr< function_decl_diff > function_decl_diff_sptr
Convenience typedef for a shared pointer to a function_decl type.
The source location of a token.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
Abstraction of an elf symbol.
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.
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...
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
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.
void emit_num_value(uint64_t value, const diff_context &ctxt, ostream &out)
Emit a numerical value to an output stream.
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
This type contains maps. Each map associates a type name to a diff of that type. Not all kinds of dif...
const array_type_def::subrange_sptr second_subrange() const
Getter of the second subrange of the current instance subrange_diff.
const vector< class_decl::base_spec_sptr > & moved_bases() const
Getter for the vector of bases that "moved". That is, the vector of base types which position changed...
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
const string_decl_base_sptr_map & data_members_replaced_by_adms() const
Get the map of data members that got replaced by anonymous data members.
bool to_be_reported() const
Test if this diff tree node should be reported.
void maybe_show_relative_size_change(const var_diff_sptr &diff, diff_context &ctxt, ostream &out)
If a given var_diff node carries a hange in which the size of the variable actually changed...
Abstracts a diff between two instances of var_decl.
uint64_t convert_bits_to_bytes(size_t bits)
Convert a number in bits into a number in bytes.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
The private data and functions of the abigail::ir::comparison types.
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...
vector< diff_sptr > diff_sptrs_type
Convenience typedef for a vector of diff_sptr.
bool show_hex_values() const
Get the flag that indicates if the diff reports using this context should show sizes and offsets in a...
shared_ptr< corpus_diff > corpus_diff_sptr
A convenience typedef for a shared pointer to corpus_diff.
const diff_context_sptr context() const
Getter of the diff context of this diff.
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.
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
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.
bool is_var_1_dim_unknown_size_array_change(const var_decl_sptr &var1, const var_decl_sptr &var2)
Test if we are looking at two variables which types are both one dimension array, with one of them be...
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, in a given.
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
artifact_sptr_set_type * lookup_impacted_interfaces(const diff *d) const
Lookup the interfaces that are impacted by a given leaf diff node.
This is a document class that aims to capture statistics about the changes carried by a corpus_diff t...
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.
shared_ptr< diff > diff_sptr
Convenience typedef for a shared_ptr for the diff class.
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.
void sort_artifacts_set(const artifact_sptr_set_type &set, vector< type_or_decl_base_sptr > &sorted)
Sort the set of ABI artifacts contained in a artifact_sptr_set_type.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
const diff_context_sptr context() const
Getter of the context of the current diff.