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 '" << 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";
1122 const decl_base_sptr& decl2,
1125 const string& indent)
1128 bool reported =
false;
1132 string decl1_repr = decl1->get_pretty_representation(),
1133 decl2_repr = decl2->get_pretty_representation();
1138 out << indent <<
"'" << decl1_repr <<
"' ";
1142 out <<
"became non-static";
1144 out <<
"became static";
1152 out << indent <<
"'" << decl1_repr <<
"' access changed from '"
1177 const decl_base_sptr& decl2,
1180 const string& indent)
1182 bool reported =
false;
1192 uint64_t var_size_in_bits = var1->get_symbol()->get_size() * 8;
1196 var_size_in_bits, *ctxt, out);
1197 out <<
") hasn't changed\n"
1198 << indent <<
"but it does have a harmless type change\n";
1221 const string& indent)
1223 if (!symbol1 || !symbol2 || symbol1 == symbol2)
1226 if (symbol1->get_size() != symbol2->get_size())
1230 symbol1->get_size(),
1231 symbol2->get_size(),
1237 if (symbol1->get_name() != symbol2->get_name())
1239 out << indent <<
"symbol name changed from "
1240 << symbol1->get_name()
1242 << symbol2->get_name()
1246 if (symbol1->get_type() != symbol2->get_type())
1248 out << indent <<
"symbol type changed from '"
1249 << symbol1->get_type()
1251 << symbol2->get_type()
1255 if (symbol1->is_public() != symbol2->is_public())
1257 out << indent <<
"symbol became ";
1258 if (symbol2->is_public())
1261 out <<
"non-exported";
1265 if (symbol1->is_defined() != symbol2->is_defined())
1267 out << indent <<
"symbol became ";
1268 if (symbol2->is_defined())
1275 if (symbol1->get_version() != symbol2->get_version())
1277 out << indent <<
"symbol version changed from "
1278 << symbol1->get_version().str()
1280 << symbol2->get_version().str()
1288 const std::string none =
"(none)";
1289 out << indent <<
"CRC (modversions) changed from "
1290 << std::showbase << std::hex;
1291 if (crc1.has_value())
1292 out << crc1.value();
1296 if (crc2.has_value())
1297 out << crc2.value();
1300 out << std::noshowbase << std::dec
1308 const std::string none =
"(none)";
1309 out << indent <<
"namespace changed from ";
1310 if (ns1.has_value())
1311 out <<
"'" << ns1.value() <<
"'";
1315 if (ns2.has_value())
1316 out <<
"'" << ns2.value() <<
"'";
1337 const string& indent,
1345 if (!aliases.empty())
1346 out <<
", aliases " << aliases;
1365 const string& indent,
1370 if (!(ctxt->show_unreachable_types()
1371 && (!d.priv_->deleted_unreachable_types_.empty()
1372 || !d.priv_->added_unreachable_types_.empty()
1373 || !d.priv_->changed_unreachable_types_.empty())))
1381 <<
"1 removed type unreachable from any public interface:\n\n";
1385 <<
" removed types unreachable from any public interface:\n\n";
1387 vector<type_base_sptr> sorted_removed_unreachable_types;
1389 sorted_removed_unreachable_types);
1390 bool emitted =
false;
1391 for (vector<type_base_sptr>::const_iterator i =
1392 sorted_removed_unreachable_types.begin();
1393 i != sorted_removed_unreachable_types.end();
1396 if (d.priv_->deleted_unreachable_type_is_suppressed((*i).get()))
1410 <<
"1 changed type unreachable from any public interface:\n\n";
1414 <<
" changed types unreachable from any public interface:\n\n";
1419 for (diff_sptrs_type::const_iterator i = sorted_diff_sptrs.begin();
1420 i != sorted_diff_sptrs.end();
1429 out << indent <<
" [C] '" << repr <<
"' changed:\n";
1439 <<
"1 added type unreachable from any public interface:\n\n";
1443 <<
" added types unreachable from any public interface:\n\n";
1445 vector<type_base_sptr> sorted_added_unreachable_types;
1447 sorted_added_unreachable_types);
1449 for (vector<type_base_sptr>::const_iterator i =
1450 sorted_added_unreachable_types.begin();
1451 i != sorted_added_unreachable_types.end();
1454 if (d.priv_->added_unreachable_type_is_suppressed((*i).get()))
1477 const string &indent)
1484 if (!ctxt->show_impacted_interfaces())
1487 const diff_maps &maps = corp_diff->get_leaf_diffs();
1490 if (impacted_artifacts == 0)
1493 if (impacted_artifacts->empty())
1496 vector<type_or_decl_base_sptr> sorted_impacted_interfaces;
1499 size_t num_impacted_interfaces = impacted_artifacts->size();
1500 if (num_impacted_interfaces == 1)
1501 out << indent <<
"one impacted interface:\n";
1503 out << indent << num_impacted_interfaces <<
" impacted interfaces:\n";
1505 string cur_indent = indent +
" ";
1506 vector<type_or_decl_base_sptr>::const_iterator it;
1507 for (it = sorted_impacted_interfaces.begin();
1508 it != sorted_impacted_interfaces.end();
1526 const string &indent)
1550 const string &indent)
1560 for (changed_var_sptrs_type::const_iterator i =
1566 vector<var_decl_sptr> dms_replaced_by_same_anon_dm;
1567 dms_replaced_by_same_anon_dm.push_back(i->first);
1576 && *i->second == *anonymous_data_member;
1578 dms_replaced_by_same_anon_dm.push_back(i->first);
1580 bool several_data_members_replaced =
1581 dms_replaced_by_same_anon_dm.size() > 1;
1583 out << indent <<
"data member";
1584 if (several_data_members_replaced)
1587 bool first_data_member =
true;
1588 for (vector<var_decl_sptr>::const_iterator it =
1589 dms_replaced_by_same_anon_dm.begin();
1590 it != dms_replaced_by_same_anon_dm.end();
1593 string name = (*it)->get_qualified_name();
1594 if (!first_data_member)
1596 out <<
" '" << name <<
"'";
1597 first_data_member =
false;
1600 if (several_data_members_replaced)
1605 out <<
"replaced by anonymous data member:\n"
1608 << anonymous_data_member->get_pretty_representation()
1624 const string &indent)
1632 ABG_ASSERT(!first->get_base_specifiers().empty());
1633 ABG_ASSERT(!second->get_base_specifiers().empty());
1635 out << indent <<
"base classes of '"
1636 << first->get_pretty_representation()
1637 <<
"' are re-ordered from: ";
1639 vector<class_decl_sptr> classes = {first, second};
1640 unsigned nb_classes_seen = 0;
1641 for (
auto &klass : classes)
1643 if (nb_classes_seen >= 1)
1646 bool needs_comma =
false;
1647 for (
auto &b : klass->get_base_specifiers())
1651 if (b->get_is_virtual())
1653 out << b->get_base_class()->get_qualified_name();
1659 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_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 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.
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
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.
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.