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 =
190 dynamic_pointer_cast<method_decl>(mem_fn);
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;
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 range '"
759 <<
"' change from '";
768 out << indent <<
"upper bound of range '"
770 <<
"' change from '";
780 if (dif && dif->to_be_reported())
783 out << indent <<
"underlying type of range '"
784 << oor <<
"' changed:\n";
785 dif->report(out, indent +
" ");
806 const string& indent)
808 type_base_sptr f = dynamic_pointer_cast<type_base>(first),
809 s = dynamic_pointer_cast<type_base>(second);
824 unsigned fs = f->get_size_in_bits(), ss = s->get_size_in_bits(),
825 fa = f->get_alignment_in_bits(), sa = s->get_alignment_in_bits();
828 unsigned fdc = first_array ? first_array->get_dimension_count(): 0,
829 sdc = second_array ? second_array->get_dimension_count(): 0;
833 if (fs != ss || fdc != sdc)
835 if (first_array && second_array)
839 out << indent <<
"array type size changed from ";
840 if (first_array->is_non_finite())
841 out <<
"\'unknown\'";
845 if (second_array->is_non_finite())
846 out <<
"\'unknown\'";
854 <<
"number of dimensions changed from "
860 array_type_def::subranges_type::const_iterator i, j;
861 for (i = first_array->get_subranges().begin(),
862 j = second_array->get_subranges().begin();
863 (i != first_array->get_subranges().end()
864 && j != second_array->get_subranges().end());
867 if ((*i)->get_length() != (*j)->get_length())
870 <<
"array type subrange "
871 << i - first_array->get_subranges().begin() + 1
872 <<
" changed length from ";
874 if ((*i)->is_non_finite())
875 out <<
"\'unknown\'";
877 out << (*i)->get_length();
881 if ((*j)->is_non_finite())
882 out <<
"\'unknown\'";
884 out << (*j)->get_length();
897 if (ctxt->show_relative_offset_changes())
899 out << indent <<
"type size hasn't changed\n";
927 decl_base_sptr decl =
is_decl(tod);
935 if (tu && (loc = decl->get_location()))
938 unsigned line, column;
940 loc.
expand(path, line, column);
942 path = basename(
const_cast<char*
>(path.c_str()));
944 out <<
" at " << path <<
":" << line <<
":" << column;
964 decl_base_sptr second,
967 const string& indent)
969 string fn = first->get_qualified_name(),
970 sn = second->get_qualified_name();
972 if (!(first->get_is_anonymous() && second->get_is_anonymous())
986 out <<
"declaration";
987 out <<
" name changed from '" << fn <<
"' to '" << sn <<
"'";
1017 size_t num_filtered,
1019 const string& section_name,
1020 const string& indent)
1022 size_t net_number = number - num_filtered;
1024 char colon_or_semi_colon =
':';
1029 change = (number > 1) ?
"deletions" :
"deletion";
1032 change = (number > 1) ?
"insertions" :
"insertion";
1034 case subtype_change_kind:
1036 change = (number > 1) ?
"changes" :
"change";
1040 if (net_number == 0)
1042 out << indent <<
"no " << section_name <<
" " << change;
1043 colon_or_semi_colon =
';';
1045 else if (net_number == 1)
1046 out << indent <<
"1 " << section_name <<
" " << change;
1048 out << indent << net_number <<
" " << section_name
1052 out <<
" (" << num_filtered <<
" filtered)";
1053 out << colon_or_semi_colon <<
"\n";
1073 const string& section_name,
1074 const string& indent)
1081 change =
"deletions";
1084 change =
"insertions";
1086 case subtype_change_kind:
1092 out << indent <<
"there are " << section_name <<
" " << change <<
":\n";
1109 const decl_base_sptr& decl2,
1112 const string& indent)
1115 bool reported =
false;
1119 string decl1_repr = decl1->get_pretty_representation(),
1120 decl2_repr = decl2->get_pretty_representation();
1125 out << indent <<
"'" << decl1_repr <<
"' ";
1129 out <<
"became non-static";
1131 out <<
"became static";
1139 out << indent <<
"'" << decl1_repr <<
"' access changed from '"
1164 const decl_base_sptr& decl2,
1167 const string& indent)
1169 bool reported =
false;
1179 uint64_t var_size_in_bits = var1->get_symbol()->get_size() * 8;
1183 var_size_in_bits, *ctxt, out);
1184 out <<
") hasn't changed\n"
1185 << indent <<
"but it does have a harmless type change\n";
1208 const string& indent)
1210 if (!symbol1 || !symbol2 || symbol1 == symbol2)
1213 if (symbol1->get_size() != symbol2->get_size())
1217 symbol1->get_size(),
1218 symbol2->get_size(),
1224 if (symbol1->get_name() != symbol2->get_name())
1226 out << indent <<
"symbol name changed from "
1227 << symbol1->get_name()
1229 << symbol2->get_name()
1233 if (symbol1->get_type() != symbol2->get_type())
1235 out << indent <<
"symbol type changed from '"
1236 << symbol1->get_type()
1238 << symbol2->get_type()
1242 if (symbol1->is_public() != symbol2->is_public())
1244 out << indent <<
"symbol became ";
1245 if (symbol2->is_public())
1248 out <<
"non-exported";
1252 if (symbol1->is_defined() != symbol2->is_defined())
1254 out << indent <<
"symbol became ";
1255 if (symbol2->is_defined())
1262 if (symbol1->get_version() != symbol2->get_version())
1264 out << indent <<
"symbol version changed from "
1265 << symbol1->get_version().str()
1267 << symbol2->get_version().str()
1275 const std::string none =
"(none)";
1276 out << indent <<
"CRC (modversions) changed from "
1277 << std::showbase << std::hex;
1278 if (crc1.has_value())
1279 out << crc1.value();
1283 if (crc2.has_value())
1284 out << crc2.value();
1287 out << std::noshowbase << std::dec
1295 const std::string none =
"(none)";
1296 out << indent <<
"namespace changed from ";
1297 if (ns1.has_value())
1298 out <<
"'" << ns1.value() <<
"'";
1302 if (ns2.has_value())
1303 out <<
"'" << ns2.value() <<
"'";
1324 const string& indent,
1332 if (!aliases.empty())
1333 out <<
", aliases " << aliases;
1352 const string& indent,
1357 if (!(ctxt->show_unreachable_types()
1358 && (!d.priv_->deleted_unreachable_types_.empty()
1359 || !d.priv_->added_unreachable_types_.empty()
1360 || !d.priv_->changed_unreachable_types_.empty())))
1368 <<
"1 removed type unreachable from any public interface:\n\n";
1372 <<
" removed types unreachable from any public interface:\n\n";
1374 vector<type_base_sptr> sorted_removed_unreachable_types;
1376 sorted_removed_unreachable_types);
1377 bool emitted =
false;
1378 for (vector<type_base_sptr>::const_iterator i =
1379 sorted_removed_unreachable_types.begin();
1380 i != sorted_removed_unreachable_types.end();
1383 if (d.priv_->deleted_unreachable_type_is_suppressed((*i).get()))
1397 <<
"1 changed type unreachable from any public interface:\n\n";
1401 <<
" changed types unreachable from any public interface:\n\n";
1406 for (diff_sptrs_type::const_iterator i = sorted_diff_sptrs.begin();
1407 i != sorted_diff_sptrs.end();
1416 out << indent <<
" [C] '" << repr <<
"' changed:\n";
1426 <<
"1 added type unreachable from any public interface:\n\n";
1430 <<
" added types unreachable from any public interface:\n\n";
1432 vector<type_base_sptr> sorted_added_unreachable_types;
1434 sorted_added_unreachable_types);
1436 for (vector<type_base_sptr>::const_iterator i =
1437 sorted_added_unreachable_types.begin();
1438 i != sorted_added_unreachable_types.end();
1441 if (d.priv_->added_unreachable_type_is_suppressed((*i).get()))
1464 const string &indent)
1471 if (!ctxt->show_impacted_interfaces())
1474 const diff_maps &maps = corp_diff->get_leaf_diffs();
1477 if (impacted_artifacts == 0)
1480 if (impacted_artifacts->empty())
1483 vector<type_or_decl_base_sptr> sorted_impacted_interfaces;
1486 size_t num_impacted_interfaces = impacted_artifacts->size();
1487 if (num_impacted_interfaces == 1)
1488 out << indent <<
"one impacted interface:\n";
1490 out << indent << num_impacted_interfaces <<
" impacted interfaces:\n";
1492 string cur_indent = indent +
" ";
1493 vector<type_or_decl_base_sptr>::const_iterator it;
1494 for (it = sorted_impacted_interfaces.begin();
1495 it != sorted_impacted_interfaces.end();
1513 const string &indent)
1537 const string &indent)
1547 for (changed_var_sptrs_type::const_iterator i =
1553 vector<var_decl_sptr> dms_replaced_by_same_anon_dm;
1554 dms_replaced_by_same_anon_dm.push_back(i->first);
1563 && *i->second == *anonymous_data_member;
1565 dms_replaced_by_same_anon_dm.push_back(i->first);
1567 bool several_data_members_replaced =
1568 dms_replaced_by_same_anon_dm.size() > 1;
1570 out << indent <<
"data member";
1571 if (several_data_members_replaced)
1574 bool first_data_member =
true;
1575 for (vector<var_decl_sptr>::const_iterator it =
1576 dms_replaced_by_same_anon_dm.begin();
1577 it != dms_replaced_by_same_anon_dm.end();
1580 string name = (*it)->get_qualified_name();
1581 if (!first_data_member)
1583 out <<
" '" << name <<
"'";
1584 first_data_member =
false;
1587 if (several_data_members_replaced)
1592 out <<
"replaced by anonymous data member:\n"
1595 << anonymous_data_member->get_pretty_representation()
1611 const string &indent)
1619 ABG_ASSERT(!first->get_base_specifiers().empty());
1620 ABG_ASSERT(!second->get_base_specifiers().empty());
1622 out << indent <<
"base classes of '"
1623 << first->get_pretty_representation()
1624 <<
"' are re-ordered from: ";
1626 vector<class_decl_sptr> classes = {first, second};
1627 unsigned nb_classes_seen = 0;
1628 for (
auto &klass : classes)
1630 if (nb_classes_seen >= 1)
1633 bool needs_comma =
false;
1634 for (
auto &b : klass->get_base_specifiers())
1638 if (b->get_is_virtual())
1640 out << b->get_base_class()->get_qualified_name();
1646 if (nb_classes_seen)
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,...
This type abstracts changes for a class_decl.
class_decl_sptr first_class_decl() const
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...
class_decl_sptr second_class_decl() const
Getter of the second class involved in the diff.
This is the base class of class_diff and union_diff.
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.
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.
This is a document class that aims to capture statistics about the changes carried by a corpus_diff t...
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_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_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.
const diff_context_sptr context() const
Getter of the diff context of this diff.
The context of the diff. This type holds various bits of information that is going to be used through...
bool show_offsets_sizes_in_bits() const
Get the flag that indicates if diff reports using this context should show sizes and offsets in bits,...
void show_relative_offset_changes(bool f)
Set a flag saying if offset changes should be reported in a relative way. That is,...
bool show_hex_values() const
Get the flag that indicates if the diff reports using this context should show sizes and offsets in a...
This type contains maps. Each map associates a type name to a diff of that type. Not all kinds of dif...
artifact_sptr_set_type * lookup_impacted_interfaces(const diff *d) const
Lookup the interfaces that are impacted by a given leaf diff node.
The abstraction of a change between two ABI artifacts, a.k.a an artifact change.
type_or_decl_base_sptr first_subject() const
Getter of the first subject of the diff.
virtual void report(ostream &out, const string &indent="") const =0
Pure interface to report the diff in a serialized form that is legible for the user.
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.
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.
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< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
Abstraction of an elf symbol.
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...
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
The source location of a token.
void expand(std::string &path, unsigned &line, unsigned &column) const
Expand the current location into a tripplet file path, line and column number.
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
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_harmless_name_change(const decl_base_sptr &f, const decl_base_sptr &s)
Test if two decls represents a harmless name change.
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...
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,...
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...
@ ACCESS_CHANGE_CATEGORY
This means the diff node (or at least one of its descendant nodes) carries access related changes,...
@ HARMLESS_DATA_MEMBER_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a harmless data member change....
@ SIZE_OR_OFFSET_CHANGE_CATEGORY
This means the diff node (or at least one of its descendant nodes) carries a change that modifies the...
@ HARMLESS_DECL_NAME_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a harmless declaration name change....
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_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...
uint64_t convert_bits_to_bytes(size_t bits)
Convert a number in bits into a number in bytes.
vector< diff_sptr > diff_sptrs_type
Convenience typedef for a vector of diff_sptr.
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.
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 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_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,...
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
diff_kind
Represent the kind of difference we want report_mem_header() to report.
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.
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_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.
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,...
void emit_num_value(uint64_t value, const diff_context &ctxt, ostream &out)
Emit a numerical value to an output stream.
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 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...
shared_ptr< corpus_diff > corpus_diff_sptr
A convenience typedef for a shared pointer to corpus_diff.
void represent(const diff_context &ctxt, method_decl_sptr mem_fn, ostream &out)
Stream a string representation for a member function.
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.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
unordered_set< type_or_decl_base_sptr, type_or_decl_hash, type_or_decl_equal > artifact_sptr_set_type
A convenience typedef for a hash set of type_or_decl_base_sptr.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
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 ...
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
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.
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
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_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.
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
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.
translation_unit * get_translation_unit(const decl_base &decl)
Return the translation unit a declaration belongs to.
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.
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.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Toplevel namespace for libabigail.