13 #include "abg-internal.h"
16 ABG_BEGIN_EXPORT_DECLARATIONS
21 ABG_END_EXPORT_DECLARATIONS
35 using std::dynamic_pointer_cast;
47 bool s = d->context()->visiting_a_node_twice_is_forbidden();
48 d->context()->forbid_visiting_a_node_twice(
true);
50 d->context()->forbid_visiting_a_node_twice(s);
68 bool s = d->context()->visiting_a_node_twice_is_forbidden();
69 d->context()->forbid_visiting_a_node_twice(
true);
70 d->context()->forget_visited_diffs();
72 d->context()->forbid_visiting_a_node_twice(s);
104 if ((class1 && class1->get_is_declaration_only())
105 || (class2 && class2->get_is_declaration_only()))
123 if ((enum1 && enum1->get_is_declaration_only())
124 || (enum2 && enum2->get_is_declaration_only()))
137 if (
diff && there_is_a_decl_only_class(
diff->first_class_decl(),
138 diff->second_class_decl()))
151 type_size_changed(
const type_base_sptr f,
const type_base_sptr s)
154 || f->get_size_in_bits() == 0
155 || s->get_size_in_bits() == 0
162 return f->get_size_in_bits() != s->get_size_in_bits();
177 type_has_offset_changes(
const type_base_sptr f,
const type_base_sptr s)
184 if (!first || !second)
193 if (has_offset_changes(f_data_members, s_data_members))
211 type_has_offset_changes(
const decl_base_sptr f,
const decl_base_sptr s)
224 type_size_changed(
const decl_base_sptr f,
const decl_base_sptr s)
233 has_type_size_change(
const diff* diff)
239 diff = fn_parm_d->type_diff().get();
241 type_base_sptr f =
is_type(diff->first_subject()),
242 s =
is_type(diff->second_subject());
247 return type_size_changed(f, s);
262 for (
auto e : data_members)
290 for (
auto entry : f_data_members)
295 auto i = s_data_members.find(entry.first);
297 if (i == s_data_members.end())
299 s_member = find_data_member_at_offset(s_data_members, f_offset);
310 if (f_offset != s_offset)
334 for (
auto entry : f_data_members)
340 auto i = s_data_members.find(entry.first);
341 if (i == s_data_members.end())
344 s_member = find_data_member_at_offset(s_data_members, offset);
355 if (d->has_changes())
376 class_diff_has_only_harmless_changes(
const class_diff* d)
378 if (!d || !d->has_changes())
383 if (f->get_qualified_name() != s->get_qualified_name())
386 if (f->get_size_in_bits() != s->get_size_in_bits())
395 if (has_offset_changes(f_data_members, s_data_members))
399 if (has_subtype_changes(f_data_members, s_data_members, d->context()))
420 class_diff_has_only_harmless_changes(diff* d)
423 return class_diff_has_only_harmless_changes(class_dif);
437 access_changed(
const decl_base_sptr& f,
const decl_base_sptr& s)
459 template <
typename function_or_var_decl_sptr>
461 crc_changed(
const function_or_var_decl_sptr& f,
462 const function_or_var_decl_sptr& s)
464 const auto& symbol_f = f->get_symbol();
465 const auto& symbol_s = s->get_symbol();
466 if (!symbol_f || !symbol_s)
468 return symbol_f->get_crc() != symbol_s->get_crc();
478 crc_changed(
const diff* diff)
480 if (
const function_decl_diff* d =
481 dynamic_cast<const function_decl_diff*
>(diff))
482 return crc_changed(d->first_function_decl(), d->second_function_decl());
483 if (
const var_diff* d =
dynamic_cast<const var_diff*
>(diff))
484 return crc_changed(d->first_var(), d->second_var());
495 template <
typename function_or_var_decl_sptr>
497 namespace_changed(
const function_or_var_decl_sptr& f,
498 const function_or_var_decl_sptr& s)
500 const auto& symbol_f = f->get_symbol();
501 const auto& symbol_s = s->get_symbol();
502 if (!symbol_f || !symbol_s)
504 return symbol_f->get_namespace() != symbol_s->get_namespace();
514 namespace_changed(
const diff* diff)
516 if (
const function_decl_diff* d =
517 dynamic_cast<const function_decl_diff*
>(diff))
518 return namespace_changed(d->first_function_decl(),
519 d->second_function_decl());
520 if (
const var_diff* d =
dynamic_cast<const var_diff*
>(diff))
521 return namespace_changed(d->first_var(), d->second_var());
542 string fn = f->get_qualified_name(),
543 sn = s->get_qualified_name();
553 s && !s->is_main_symbol();
554 s = s->get_next_alias())
571 function_name_changed_but_not_symbol(
const diff* diff)
573 if (
const function_decl_diff* d =
574 dynamic_cast<const function_decl_diff*
>(diff))
575 return function_name_changed_but_not_symbol(d->first_function_decl(),
576 d->second_function_decl());
590 data_member_offset_changed(decl_base_sptr f, decl_base_sptr s)
597 v1 = dynamic_pointer_cast<var_decl>(s);
614 non_static_data_member_type_size_changed(
const decl_base_sptr& f,
615 const decl_base_sptr& s)
622 sv = dynamic_pointer_cast<var_decl>(s);
629 return type_size_changed(fv->get_type(), sv->get_type());
639 static_data_member_type_size_changed(
const decl_base_sptr& f,
640 const decl_base_sptr& s)
647 sv = dynamic_pointer_cast<var_decl>(s);
654 return type_size_changed(fv->get_type(), sv->get_type());
665 is_compatible_change(
const decl_base_sptr& d1,
const decl_base_sptr& d2)
682 decl_name_changed(
const type_or_decl_base* a1,
const type_or_decl_base *a2)
684 string d1_name, d2_name;
686 const decl_base *d1 =
dynamic_cast<const decl_base*
>(a1);
690 const decl_base *d2 =
dynamic_cast<const decl_base*
>(a2);
695 d1_name = d1->get_qualified_name();
697 d2_name = d2->get_qualified_name();
699 return d1_name != d2_name;
712 {
return decl_name_changed(d1.get(), d2.get());}
722 decl_name_changed(
const diff *d)
723 {
return decl_name_changed(d->first_subject(), d->second_subject());}
739 return (decl_name_changed(f, s)
742 (f->get_is_anonymous() && s->get_is_anonymous())
746 ((f->get_is_anonymous_or_has_anonymous_parent()
747 && s->get_is_anonymous_or_has_anonymous_parent())
749 s->get_qualified_name()))
816 if (
diff && !diff_involves_decl_only_class(
diff))
818 for (string_decl_base_sptr_map::const_iterator i =
819 diff->inserted_data_members().begin();
820 i !=
diff->inserted_data_members().end();
825 for (string_decl_base_sptr_map::const_iterator i =
826 diff->deleted_data_members().begin();
827 i !=
diff->deleted_data_members().end();
842 non_static_data_member_added_or_removed(
const diff* diff)
844 return non_static_data_member_added_or_removed
845 (
dynamic_cast<const class_diff*
>(diff));
899 if (fat->get_subranges().size() != 1
900 || sat->get_subranges().size() != 1
901 || (!fat->is_non_finite() && !sat->is_non_finite()))
910 if (!var1->get_symbol()
911 || !var2->get_symbol()
912 || var1->get_symbol()->get_size() != var2->get_symbol()->get_size())
1004 if (
diff && !diff_involves_decl_only_class(
diff))
1006 for (string_decl_base_sptr_map::const_iterator i =
1007 diff->inserted_data_members().begin();
1008 i !=
diff->inserted_data_members().end();
1013 for (string_decl_base_sptr_map::const_iterator i =
1014 diff->deleted_data_members().begin();
1015 i !=
diff->deleted_data_members().end();
1049 class_diff_has_harmless_odr_violation_change(
const diff* dif)
1051 class_diff* d =
dynamic_cast<class_diff*
>(
const_cast<diff*
>(dif));
1052 if (!d || !d->has_changes())
1058 if (first->get_qualified_name() == second->get_qualified_name()
1060 && first->get_corpus() == second->get_corpus())
1074 static_data_member_added_or_removed(
const diff* diff)
1076 return static_data_member_added_or_removed
1077 (
dynamic_cast<const class_diff*
>(diff));
1091 has_virtual_mem_fn_change(
const class_diff* diff)
1093 if (!diff || diff_involves_decl_only_class(diff))
1096 for (string_member_function_sptr_map::const_iterator i =
1097 diff->deleted_member_fns().begin();
1098 i != diff->deleted_member_fns().end();
1106 string_member_function_sptr_map::const_iterator j =
1107 diff->inserted_member_fns().find(i->first);
1108 if (j != diff->inserted_member_fns().end()
1117 for (string_member_function_sptr_map::const_iterator i =
1118 diff->inserted_member_fns().begin();
1119 i != diff->inserted_member_fns().end();
1127 string_member_function_sptr_map::const_iterator j =
1128 diff->deleted_member_fns().find(i->first);
1129 if (j != diff->deleted_member_fns().end()
1138 for (function_decl_diff_sptrs_type::const_iterator i =
1139 diff->changed_member_fns().begin();
1140 i != diff->changed_member_fns().end();
1172 sf =
diff->second_function_decl();
1181 if (ff_is_virtual != sf_is_virtual)
1187 if (ff_vtable_offset != sf_vtable_offset)
1204 has_virtual_mem_fn_change(
const diff*
diff)
1206 return (has_virtual_mem_fn_change(
dynamic_cast<const class_diff*
>(
diff))
1220 if (!
diff || diff_involves_decl_only_class(
diff))
1223 for (string_member_function_sptr_map::const_iterator i =
1224 diff->deleted_member_fns().begin();
1225 i !=
diff->deleted_member_fns().end();
1230 for (string_member_function_sptr_map::const_iterator i =
1231 diff->inserted_member_fns().begin();
1232 i !=
diff->inserted_member_fns().end();
1237 for (function_decl_diff_sptrs_type::const_iterator i =
1238 diff->changed_member_fns().begin();
1239 i !=
diff->changed_member_fns().end();
1256 has_non_virtual_mem_fn_change(
const diff* diff)
1257 {
return has_non_virtual_mem_fn_change(
dynamic_cast<const class_diff*
>(diff));}
1265 base_classes_removed(
const class_diff* diff)
1269 return diff->deleted_bases().size();
1278 base_classes_removed(
const diff* diff)
1279 {
return base_classes_removed(
dynamic_cast<const class_diff*
>(diff));}
1308 return f_is_empty && s_is_empty;
1327 const class_or_union_sptr& second)
1329 if (!first || !second)
1358 class_or_union_sptr f =
1360 class_or_union_sptr s =
1377 const decl_base_sptr& second)
1379 if (!first || !second)
1387 if (f->get_qualified_name() != s->get_qualified_name())
1390 return f->get_is_declaration_only() != s->get_is_declaration_only();
1428 const class_or_union_sptr& second)
1430 if (!first || !second)
1433 class_or_union_sptr f =
1435 class_or_union_sptr s =
1438 if (f->get_qualified_name() != s->get_qualified_name())
1441 return f->get_is_declaration_only() != s->get_is_declaration_only();
1457 if (!first || !second)
1463 if (f->get_qualified_name() != s->get_qualified_name())
1466 return f->get_is_declaration_only() != s->get_is_declaration_only();
1485 class_or_union_sptr f =
1487 class_or_union_sptr s =
1524 if (decl_name_changed(dif))
1540 if (decl_name_changed(dif))
1642 has_enumerator_insertion(
const diff*
diff)
1645 return !d->inserted_enumerators().empty();
1655 has_enumerator_removal_or_change(
const diff*
diff)
1658 return (!d->deleted_enumerators().empty()
1659 || !d->changed_enumerators().empty());
1669 has_harmful_enum_change(
const diff* diff)
1671 if (
const enum_diff* d =
dynamic_cast<const enum_diff*
>(diff))
1672 return (has_enumerator_removal_or_change(d)
1673 || has_type_size_change(d));
1687 has_harmless_enum_to_int_change(
const diff* diff)
1696 const enum_type_decl *enum_type = 0;
1697 const type_base *integer_type = 0;
1699 type_base *first_type =
1701 type_base *second_type =
1704 if (
const enum_type_decl *e =
is_enum_type(first_type))
1706 else if (
const enum_type_decl *e =
is_enum_type(second_type))
1711 else if (
const type_base *i =
is_type_decl(second_type))
1716 && enum_type->get_size_in_bits() == integer_type->get_size_in_bits())
1732 has_fn_parm_type_top_cv_qual_change(
const diff* diff)
1737 if (!parm_diff || !parm_diff->has_changes())
1745 type_base_sptr first_parm_type = first_parm->get_type();
1746 type_base_sptr second_parm_type = second_parm->get_type();
1755 type_base_sptr peeled_type_1 = first_parm_type;
1756 type_base_sptr peeled_type_2 = second_parm_type;
1760 cv_quals_1 = qtype1->get_cv_quals();
1766 cv_quals_2 = qtype2->get_cv_quals();
1773 && cv_quals_1 != cv_quals_2)
1789 type_diff_has_cv_qual_change_only(
const diff *type_dif)
1799 const type_base *f = 0;
1800 const type_base *s = 0;
1807 f =
is_type(d->first()).get();
1808 s =
is_type(d->second()).get();
1813 f =
is_type(d->first_qualified_type()).get();
1814 s =
is_type(d->second_qualified_type()).get();
1843 has_fn_parm_type_cv_qual_change(
const diff* dif)
1848 if (!parm_diff || !parm_diff->has_changes())
1853 const diff *type_dif = parm_diff->type_diff().get();
1854 return type_diff_has_cv_qual_change_only(type_dif);
1867 has_fn_return_type_cv_qual_change(
const diff* dif)
1872 fn_type_diff = fn_decl_diff->type_diff().get();
1877 const diff* return_type_diff = fn_type_diff->return_type_diff().get();
1878 return type_diff_has_cv_qual_change_only(return_type_diff);
1891 has_added_or_removed_function_parameters(
const diff *dif)
1896 fn_type_diff = fn_decl_diff->type_diff().get();
1901 if (!(fn_type_diff->sorted_deleted_parms().empty()
1902 && fn_type_diff->sorted_added_parms().empty()))
1916 has_var_type_cv_qual_change(
const diff* dif)
1922 diff *type_dif = var_dif->type_diff().get();
1926 return type_diff_has_cv_qual_change_only(type_dif);
1938 has_void_ptr_to_ptr_change(
const diff* dif)
1944 const type_base *f =
is_type(d->first().get());
1945 const type_base *s =
is_type(d->second().get());
1958 const type_base *f =
is_type(d->first_pointer()).get();
1959 const type_base *s =
is_type(d->second_pointer()).get();
1972 const type_base *f =
is_type(d->first_qualified_type()).get();
1973 const type_base *s =
is_type(d->second_qualified_type()).get();
2001 has_benign_array_of_unknown_size_change(
const diff* dif)
2018 && !has_type_size_change(d))
2035 categorize_harmless_diff_node(
diff *d,
bool pre)
2051 if (access_changed(f, s))
2054 if (is_compatible_change(f, s))
2058 || class_diff_has_harmless_odr_violation_change(d))
2062 || class_diff_has_only_harmless_changes(d))
2065 if (has_non_virtual_mem_fn_change(d))
2068 if (static_data_member_added_or_removed(d)
2069 || static_data_member_type_size_changed(f, s))
2075 if ((has_enumerator_insertion(d)
2076 && !has_harmful_enum_change(d))
2077 || has_harmless_enum_to_int_change(d))
2080 if (function_name_changed_but_not_symbol(d))
2083 if (has_fn_parm_type_top_cv_qual_change(d))
2086 if (has_fn_parm_type_cv_qual_change(d))
2089 if (has_fn_return_type_cv_qual_change(d))
2092 if (has_var_type_cv_qual_change(d))
2095 if (has_void_ptr_to_ptr_change(d))
2098 if (has_benign_array_of_unknown_size_change(d))
2106 canonical->add_to_local_and_inherited_categories(category);
2124 categorize_harmful_diff_node(diff *d,
bool pre)
2126 if (!d->has_changes())
2132 decl_base_sptr f =
is_decl(d->first_subject()),
2133 s =
is_decl(d->second_subject());
2141 && (type_size_changed(f, s)
2142 || type_has_offset_changes(f, s)
2143 || data_member_offset_changed(f, s)
2144 || non_static_data_member_type_size_changed(f, s)
2145 || non_static_data_member_added_or_removed(d)
2146 || base_classes_removed(d)
2147 || has_harmful_enum_change(d)
2149 || namespace_changed(d)))
2152 if (has_virtual_mem_fn_change(d))
2155 if (has_added_or_removed_function_parameters(d))
2160 d->add_to_local_and_inherited_categories(category);
2162 if (diff * canonical = d->get_canonical_diff())
2163 canonical->add_to_local_and_inherited_categories(category);
2180 harmless_harmful_filter::visit(diff* d,
bool pre)
2182 return (categorize_harmless_diff_node(d, pre)
2183 && categorize_harmful_diff_node(d, pre));
2196 harmless_harmful_filter::visit_end(diff* d)
2198 if (d->context()->diff_has_been_visited(d))
2209 if (diff* c = d->get_canonical_diff())
2210 d->add_to_local_and_inherited_categories(c->get_local_category());
This header declares filters for the diff trees resulting from comparing ABI Corpora.
#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
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.
class_or_union_sptr first_class_or_union() const
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.
class_or_union_sptr second_class_or_union() const
The abstraction of a change between two ABI artifacts, a.k.a an artifact change.
type_or_decl_base_sptr second_subject() const
Getter of the second subject of the diff.
type_or_decl_base_sptr first_subject() const
Getter of the first subject of the diff.
diff * get_canonical_diff() const
Getter for the canonical diff of the current instance of diff.
void add_to_local_and_inherited_categories(diff_category c)
Adds the current diff tree node to the categories resulting from the local and inherited changes of t...
virtual bool has_changes() const =0
Pure interface to get the length of the changes encapsulated by this diff. A length of zero means tha...
An abstraction of a diff between entities that are of a different kind (disctinct).
static bool entities_are_of_distinct_kinds(type_or_decl_base_sptr first, type_or_decl_base_sptr second)
Test if the two arguments are of different kind, or that are both NULL.
Abstraction of a diff between two enums.
const enum_type_decl_sptr first_enum() const
const enum_type_decl_sptr second_enum() const
Abstraction of a diff between two function parameters.
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_decl.
Abstraction of a diff between two basic type declarations.
The base class of diff between types.
Abstracts a diff between two instances of var_decl.
var_decl_sptr first_var() const
Getter for the first var_decl of the diff.
var_decl_sptr second_var() const
Getter for the second var_decl of the diff.
The base type of class_decl and union_decl.
const data_members & get_data_members() const
Get the data members of this class_or_union.
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
CV
Bit field values representing the cv qualifiers of the underlying type.
virtual size_t get_size_in_bits() const
Getter for the size of the type.
bool has_basic_type_name_change(const diff *d)
Test if a diff node carries a basic type name change.
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_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_data_member_replaced_by_anon_dm(const diff *diff)
Test if a class_or_union_diff has a data member replaced by an anonymous data member in a harmless wa...
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 is_decl_only_class_with_size_change(const class_or_union &first, const class_or_union &second)
Test if two classes that are decl-only (have the decl-only flag and carry no data members) but are di...
shared_ptr< filter_base > filter_base_sptr
Convenience typedef for a shared pointer to filter_base.
bool has_harmful_name_change(const decl_base_sptr &f, const decl_base_sptr &s)
Test if two decls represents a harmful name change.
bool has_class_or_union_type_name_change(const diff *d)
Test if a diff node carries a class or union type name change.
bool has_decl_only_def_change(const decl_base_sptr &first, const decl_base_sptr &second)
Test if two decl_base_sptr are different just by the fact that one is decl-only and the other one is ...
bool has_basic_or_class_type_name_change(const diff *d)
Test if a diff node carries a basic or class type name change.
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,...
void apply_filter(filter_base &filter, corpus_diff_sptr d)
Walk the diff sub-trees of a a corpus_diff and apply a filter to the nodes visted....
bool is_mostly_distinct_diff(const diff *d)
Test if a diff node carries a distinct type change or a pointer/reference/typedef to distinct type ch...
bool union_diff_has_harmless_changes(const diff *d)
Test if a union diff node does have changes that don't impact its size.
bool has_strict_fam_conversion(const class_decl_sptr &first, const class_decl_sptr &second)
Test if a class with a fake flexible data member got changed into a class with a real fexible data me...
shared_ptr< diff > diff_sptr
Convenience typedef for a shared_ptr for the diff class.
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,...
@ HARMLESS_DATA_MEMBER_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries a harmless data member change....
@ VIRTUAL_MEMBER_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an incompatible change to a vtable.
@ SIZE_OR_OFFSET_CHANGE_CATEGORY
This means the diff node (or at least one of its descendant nodes) carries a change that modifies 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...
@ HARMLESS_ENUM_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an addition of enumerator to an enum type.
@ FN_PARM_ADD_REMOVE_CHANGE_CATEGORY
A diff node in this category is a function (or function type) with at least one parameter added or re...
@ VOID_PTR_TO_PTR_CHANGE_CATEGORY
A diff node in this category carries a change from void pointer to non-void pointer.
@ COMPATIBLE_TYPE_CHANGE_CATEGORY
This means the diff node (or at least one of its descendant nodes) carries a change involving two com...
@ 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 ...
@ STATIC_DATA_MEMBER_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an addition or removal of a static data member.
@ 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....
@ NO_CHANGE_CATEGORY
This means the diff node does not carry any (meaningful) change, or that it carries changes that have...
@ BENIGN_INFINITE_ARRAY_CHANGE_CATEGORY
A diff node in this category carries a change in the size of the array type of a global variable,...
@ VAR_TYPE_CV_CHANGE_CATEGORY
A diff node in this category is for a variable which type holds a cv-qualifier change.
@ FN_PARM_TYPE_CV_CHANGE_CATEGORY
A diff node in this category has a function parameter type with a cv-qualifiers change.
@ FN_PARM_TYPE_TOP_CV_CHANGE_CATEGORY
A diff node in this category is a function parameter type which top cv-qualifiers change.
@ FN_RETURN_TYPE_CV_CHANGE_CATEGORY
A diff node in this category is a function return type with a cv-qualifier change.
@ HARMLESS_SYMBOL_ALIAS_CHANGE_CATEGORY
This means that a diff node in the sub-tree carries an a symbol alias change that is harmless.
const class_or_union_diff * is_diff_of_class_or_union_type(const diff *d)
Test if a diff node represents a diff between two class or union types.
const pointer_diff * is_pointer_diff(const diff *diff)
Test if a diff node is about differences between two pointers.
shared_ptr< diff_context > diff_context_sptr
Convenience typedef for a shared pointer of diff_context.
const diff * peel_typedef_diff(const diff *dif)
If a diff node is about changes between two typedef types, get the diff node about changes between th...
const function_decl_diff * is_function_decl_diff(const diff *diff)
Test if a diff node is about differences between functions.
const function_type_diff * is_function_type_diff(const diff *diff)
Test if a diff node is a function_type_diff node.
const distinct_diff * is_distinct_diff(const diff *diff)
Test if a diff node is about differences between two diff nodes of different kinds.
const diff * peel_reference_diff(const diff *dif)
If a diff node is about changes between two reference types, get the diff node about changes between ...
const fn_parm_diff * is_fn_parm_diff(const diff *diff)
Test if a diff node is about differences between two function parameters.
const union_diff * is_union_diff(const diff *diff)
Test if a diff node is a union_diff node.
const diff * peel_pointer_diff(const diff *dif)
If a diff node is about changes between two pointer types, get the diff node about changes between th...
const class_or_union_diff * is_class_or_union_diff(const diff *d)
Test if a diff node is a class_or_union_diff node.
const class_diff * is_class_diff(const diff *diff)
Test if a diff node is a class_diff node.
const type_decl_diff * is_diff_of_basic_type(const diff *d)
Test if a diff node represents a diff between two basic types.
const qualified_type_diff * is_qualified_type_diff(const diff *diff)
Test if a diff node is about differences between two qualified types.
diff_sptr compute_diff(const decl_base_sptr first, const decl_base_sptr second, diff_context_sptr ctxt)
Compute the difference between two decls. The decls can represent either type declarations,...
const var_diff * is_var_diff(const diff *diff)
Test if a diff node is about differences between variables.
const type_diff_base * is_type_diff(const diff *diff)
Test if a diff node is about differences between types.
const reference_diff * is_reference_diff(const diff *diff)
Test if a diff node is about differences between two references.
shared_ptr< corpus_diff > corpus_diff_sptr
A convenience typedef for a shared pointer to corpus_diff.
const diff * peel_typedef_or_qualified_type_diff(const diff *dif)
If a diff node is about changes between two typedefs or qualified types, get the diff node about chan...
bool enum_has_non_name_change(const enum_type_decl &l, const enum_type_decl &r, change_kind *k)
Test if two enums differ, but not by a name change.
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
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.
access_specifier
Access specifier for class members.
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
bool equals_modulo_cv_qualifier(const array_type_def *l, const array_type_def *r)
Test if two variables are equals modulo CV qualifiers.
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.
class_decl_sptr is_compatible_with_class_type(const type_base_sptr &t)
Test if a type is a class. This function looks through typedefs.
bool collect_non_anonymous_data_members(const class_or_union *cou, string_decl_base_sptr_map &dms)
Collect all the non-anonymous data members of a class or union type.
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.
type_base_sptr peel_typedef_pointer_or_reference_type(const type_base_sptr type)
Return the leaf underlying or pointed-to type node of a typedef_decl, pointer_type_def,...
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
decl_base_sptr look_through_decl_only(const decl_base &d)
If a decl is decl-only get its definition. Otherwise, just return nil.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
bool var_equals_modulo_types(const var_decl &l, const var_decl &r, change_kind *k)
Compares two instances of var_decl without taking their type into account.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
const type_base * is_void_pointer_type_equivalent(const type_base *type)
Test if a type is equivalent to a pointer to void type.
unordered_map< string, decl_base_sptr > string_decl_base_sptr_map
Convenience typedef for a map which key is a string and which value is a decl_base_sptr.
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
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.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
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.
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
var_decl_sptr has_fake_flexible_array_data_member(const class_decl &klass)
Test if the last data member of a class is an array with one element.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
var_decl_sptr has_flexible_array_data_member(const class_decl &klass)
Test if the last data member of a class is an array with non-finite 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.
bool types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
Test if two types are equal modulo a typedef.
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.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
enum_type_decl_sptr look_through_decl_only_enum(const enum_type_decl &the_enum)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum.
enum_type_decl_sptr is_compatible_with_enum_type(const type_base_sptr &t)
Test if a type is an enum. This function looks through typedefs.
type_base * peel_qualified_or_typedef_type(const type_base *type)
Return the leaf underlying type of a qualified or typedef type.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Toplevel namespace for libabigail.
The base class for the diff tree node filter.