13 #include "abg-internal.h"
16 ABG_BEGIN_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()))
135 diff_involves_decl_only_class(
const class_diff* diff)
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()))
814 non_static_data_member_added_or_removed(
const class_diff* diff)
816 if (diff && !diff_involves_decl_only_class(diff))
818 for (string_decl_base_sptr_map::const_iterator i =
825 for (string_decl_base_sptr_map::const_iterator i =
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())
1002 static_data_member_added_or_removed(
const class_diff* diff)
1004 if (diff && !diff_involves_decl_only_class(diff))
1006 for (string_decl_base_sptr_map::const_iterator i =
1013 for (string_decl_base_sptr_map::const_iterator i =
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();
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))
1207 || has_virtual_mem_fn_change(dynamic_cast<const function_decl_diff*>(diff)));
1218 has_non_virtual_mem_fn_change(
const class_diff* diff)
1220 if (!diff || diff_involves_decl_only_class(diff))
1223 for (string_member_function_sptr_map::const_iterator i =
1230 for (string_member_function_sptr_map::const_iterator i =
1237 for (function_decl_diff_sptrs_type::const_iterator i =
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)
1644 if (
const enum_diff* d = dynamic_cast<const enum_diff*>(diff))
1645 return !d->inserted_enumerators().empty();
1655 has_enumerator_removal_or_change(
const diff* diff)
1657 if (
const enum_diff* d = dynamic_cast<const enum_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());
const string_decl_base_sptr_map & inserted_data_members() const
Getter for the data members that got inserted.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
This means the diff node (or at least one of its descendant nodes) carries a change involving two com...
const string_member_function_sptr_map & deleted_member_fns() const
This header declares filters for the diff trees resulting from comparing ABI Corpora.
const pointer_diff * is_pointer_diff(const diff *diff)
Test if a diff node is about differences between two pointers.
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.
class_decl_sptr second_class_decl() const
Getter of the second class involved in the diff.
const function_decl_sptr first_function_decl() const
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
var_decl_sptr first_var() const
Getter for the first var_decl of the diff.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
An abstraction of a diff between entities that are of a different kind (disctinct).
const qualified_type_diff * is_qualified_type_diff(const diff *diff)
Test if a diff node is about differences between two qualified types.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
A diff node in this category is a function (or function type) with at least one parameter added or re...
This means the diff node (or at least one of its descendant nodes) carries a change that modifies the...
This type abstracts changes for a class_decl.
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 means the diff node does not carry any (meaningful) change, or that it carries changes that have...
shared_ptr< diff_context > diff_context_sptr
Convenience typedef for a shared pointer of diff_context.
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
const var_diff * is_var_diff(const diff *diff)
Test if a diff node is about differences between variables.
This means that a diff node in the sub-tree carries an addition of enumerator to an enum type...
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...
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...
This means the diff node (or at least one of its descendant nodes) carries access related changes...
A diff node in this category carries a change from void pointer to non-void pointer.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
class_or_union_sptr first_class_or_union() const
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
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 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 fn_parm_diff * is_fn_parm_diff(const diff *diff)
Test if a diff node is about differences between two function parameters.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
const type_decl_diff * is_diff_of_basic_type(const diff *d)
Test if a diff node represents a diff between two basic types.
Abstraction of a diff between two function_decl.
A diff node in this category is a function parameter type which top cv-qualifiers change...
This means that a diff node in the sub-tree carries an incompatible change to a vtable.
const enum_type_decl_sptr first_enum() const
const class_diff * is_class_diff(const diff *diff)
Test if a diff node is a class_diff node.
Abstraction of a diff between two enums.
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.
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.
The base class of diff between types.
Abstraction of a diff between two basic type declarations.
const function_decl_sptr second_function_decl() const
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.
const string_decl_base_sptr_map & deleted_data_members() const
Getter for the data members that got deleted.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
class_or_union_sptr second_class_or_union() const
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
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...
diff_category
An enum for the different categories that a diff tree node falls into, regarding the kind of changes ...
Toplevel namespace for libabigail.
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 has_harmless_name_change(const decl_base_sptr &f, const decl_base_sptr &s)
Test if two decls represents a harmless name change.
bool has_basic_type_name_change(const diff *d)
Test if a diff node carries a basic type name change.
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.
bool has_harmful_name_change(const decl_base_sptr &f, const decl_base_sptr &s)
Test if two decls represents a harmful name change.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
virtual size_t get_size_in_bits() const
Getter for the size of the type.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
var_decl_sptr second_var() const
Getter for the second var_decl of the diff.
Abstraction of a diff between two function parameters.
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.
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.
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...
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, or non-type declaration.
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...
class_decl_sptr first_class_decl() const
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.
The base type of class_decl and union_decl.
This means that a diff node in the sub-tree carries a type that was declaration-only and that is now ...
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
diff * get_canonical_diff() const
Getter for the canonical diff of the current instance of diff.
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.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
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. The filter categorizes each node, assigning it into one or several categories.
const function_decl_diff * is_function_decl_diff(const diff *diff)
Test if a diff node is about differences between functions.
decl_base_sptr look_through_decl_only(const decl_base &d)
If a decl is decl-only get its definition. Otherwise, just return nil.
A diff node in this category is for a variable which type holds a cv-qualifier change.
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 union_diff_has_harmless_changes(const diff *d)
Test if a union diff node does have changes that don't impact its size.
A diff node in this category has a function parameter type with a cv-qualifiers change.
type_base * peel_qualified_or_typedef_type(const type_base *type)
Return the leaf underlying type of a qualified or typedef type.
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...
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.
const type_base_sptr get_type() const
Getter of the type of the variable.
const string_member_function_sptr_map & inserted_member_fns() const
diff_sptr type_diff() const
Getter for the diff representing the changes on the type of the function parameter involved in the cu...
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< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the 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.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
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.
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.
Abstracts a diff between two instances of var_decl.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
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.
This means that a diff node in the sub-tree carries an addition or removal of a non-virtual member fu...
const reference_diff * is_reference_diff(const diff *diff)
Test if a diff node is about differences between two references.
This means that a diff node in the sub-tree carries an a symbol alias change that is harmless...
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 ...
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, reference_type_def, or array_type_def node.
const type_diff_base * is_type_diff(const diff *diff)
Test if a diff node is about differences between types.
shared_ptr< corpus_diff > corpus_diff_sptr
A convenience typedef for a shared pointer to corpus_diff.
bool types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
Test if two types are equal modulo a typedef.
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...
const data_members & get_data_members() const
Get the data members of this class_or_union.
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.
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
access_specifier
Access specifier for class members.
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...
const function_type_diff * is_function_type_diff(const diff *diff)
Test if a diff node is a function_type_diff node.
const function_decl_diff_sptrs_type & changed_member_fns() const
Getter for the virtual members functions that have had a change in a sub-type, without having a chang...
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...
A diff node in this category carries a change in the size of the array type of a global variable...
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 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...
The base class for the diff tree node filter.
This means that a diff node in the sub-tree carries a harmless union or class change.
type_or_decl_base_sptr second_subject() const
Getter of the second subject of the diff.
bool has_basic_or_class_type_name_change(const diff *d)
Test if a diff node carries a basic or class type name change.
const union_diff * is_union_diff(const diff *diff)
Test if a diff node is a union_diff node.
A diff node in this category is a function return type with a cv-qualifier change.
shared_ptr< diff > diff_sptr
Convenience typedef for a shared_ptr for the diff class.
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...
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_pointer_diff(const diff *dif)
If a diff node is about changes between two pointer types, get the diff node about changes between th...
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.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
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_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...
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.
shared_ptr< filter_base > filter_base_sptr
Convenience typedef for a shared pointer to filter_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.
const enum_type_decl_sptr second_enum() const
CV
Bit field values representing the cv qualifiers of the underlying type.
This means that a diff node in the sub-tree carries an addition or removal of a static data member...