13 #include "abg-internal.h"
16 ABG_BEGIN_EXPORT_DECLARATIONS
38 type_diff_has_typedef_cv_qual_change_only(
const diff *type_dif);
41 type_diff_has_typedef_cv_qual_change_only(
const type_base_sptr& f,
42 const type_base_sptr& s);
45 has_harmful_change(
const diff* d);
48 has_harmful_enum_change(
const diff*
diff);
51 has_harmless_enum_change(
const type_base_sptr& f,
52 const type_base_sptr& s,
56 type_size_changed_with_impact(
const type_base* f,
60 type_size_changed_with_impact(
const decl_base* f,
63 using std::dynamic_pointer_cast;
75 bool s = d->context()->visiting_a_node_twice_is_forbidden();
76 d->context()->forbid_visiting_a_node_twice(
true);
78 d->context()->forbid_visiting_a_node_twice(s);
96 bool s = d->context()->visiting_a_node_twice_is_forbidden();
97 d->context()->forbid_visiting_a_node_twice(
true);
98 d->context()->forget_visited_diffs();
100 d->context()->forbid_visiting_a_node_twice(s);
149 {
return there_is_a_decl_only_class(class1.get(), class2.get());}
161 there_is_a_decl_only_enum(
const enum_type_decl* enum1,
162 const enum_type_decl* enum2)
164 if ((enum1 && enum1->get_is_declaration_only())
165 || (enum2 && enum2->get_is_declaration_only()))
176 diff_involves_decl_only_class(
const class_diff* diff)
178 if (diff && there_is_a_decl_only_class(diff->first_class_decl(),
179 diff->second_class_decl()))
192 type_size_changed(
const type_base* f,
const type_base* s)
195 || f->get_size_in_bits() == 0
196 || s->get_size_in_bits() == 0
203 return f->get_size_in_bits() != s->get_size_in_bits();
214 type_size_changed(
const type_base_sptr f,
const type_base_sptr s)
215 {
return type_size_changed(f.get(), s.get());}
229 type_has_offset_changes(
const type_base_sptr f,
const type_base_sptr s)
236 if (!first || !second)
245 if (has_offset_changes(f_data_members, s_data_members))
263 type_has_offset_changes(
const type_base* f,
const type_base* s)
265 type_base_sptr first(const_cast<type_base*>(f), sptr_utils::noop_deleter());
266 type_base_sptr second(const_cast<type_base*>(s), sptr_utils::noop_deleter());
268 return type_has_offset_changes(first, second);
283 type_has_offset_changes(
const decl_base_sptr f,
const decl_base_sptr s)
292 has_type_size_change(
const diff* diff)
298 diff = fn_parm_d->type_diff().get();
300 type_base_sptr f =
is_type(diff->first_subject()),
301 s =
is_type(diff->second_subject());
306 return type_size_changed(f, s);
327 type_size_changed_with_impact(
const type_base* f,
const type_base *s,
328 const scope_decl* fs,
const scope_decl* ss)
331 if (type_size_changed(f, s))
336 result = type_size_changed_with_impact (
is_type(fs),
is_type(ss));
340 if (type_has_offset_changes(f, s))
354 && type_size_changed(f, s))
375 type_size_changed_with_impact(
const type_base* f,
const type_base *s)
380 if (!first_type || !second_type)
383 scope_decl* fs = first_type->get_scope();
384 scope_decl* ss = second_type->get_scope();
386 return type_size_changed_with_impact(f, s, fs, ss);
406 type_size_changed_with_impact(
const decl_base* f,
const decl_base *s)
417 if (!f_var || !s_var)
420 scope_decl* fs = f->get_scope();
421 scope_decl* ss = s->get_scope();
423 const type_base* first_type = f_var->get_type().get();
424 const type_base* second_type = s_var->get_type().get();
426 return type_size_changed_with_impact(first_type, second_type, fs, ss);
443 type_size_changed_with_impact(
const type_base_sptr& f,
const type_base_sptr& s)
444 {
return type_size_changed_with_impact(f.get(), s.get());}
462 type_size_changed_with_impact(
const decl_base_sptr& f,
const decl_base_sptr& s)
463 {
return type_size_changed_with_impact(f.get(), s.get());}
479 has_type_size_change_with_impact(
const diff* d)
485 d = fn_parm_d->type_diff().get();
488 return type_size_changed_with_impact(
is_type(d->first_subject()),
491 return type_size_changed_with_impact(
is_decl(d->first_subject()),
507 for (
auto e : data_members)
535 for (
auto entry : f_data_members)
540 auto i = s_data_members.find(entry.first);
542 if (i == s_data_members.end())
544 s_member = find_data_member_at_offset(s_data_members, f_offset);
555 if (f_offset != s_offset)
576 class_diff_has_only_harmless_changes(
const class_diff* d)
578 if (!d || !d->has_changes())
583 if (f->get_qualified_name() != s->get_qualified_name())
586 if (f->get_size_in_bits() != s->get_size_in_bits())
595 if (has_offset_changes(f_data_members, s_data_members))
615 class_diff_has_only_harmless_changes(diff* d)
618 return class_diff_has_only_harmless_changes(class_dif);
632 access_changed(
const decl_base_sptr& f,
const decl_base_sptr& s)
654 template <
typename function_or_var_decl_sptr>
656 crc_changed(
const function_or_var_decl_sptr& f,
657 const function_or_var_decl_sptr& s)
659 const auto& symbol_f = f->get_symbol();
660 const auto& symbol_s = s->get_symbol();
661 if (!symbol_f || !symbol_s)
663 return symbol_f->get_crc() != symbol_s->get_crc();
673 crc_changed(
const diff* diff)
675 if (
const function_decl_diff* d =
676 dynamic_cast<const function_decl_diff*>(diff))
677 return crc_changed(d->first_function_decl(), d->second_function_decl());
678 if (
const var_diff* d = dynamic_cast<const var_diff*>(diff))
679 return crc_changed(d->first_var(), d->second_var());
690 template <
typename function_or_var_decl_sptr>
692 namespace_changed(
const function_or_var_decl_sptr& f,
693 const function_or_var_decl_sptr& s)
695 const auto& symbol_f = f->get_symbol();
696 const auto& symbol_s = s->get_symbol();
697 if (!symbol_f || !symbol_s)
699 return symbol_f->get_namespace() != symbol_s->get_namespace();
709 namespace_changed(
const diff* diff)
711 if (
const function_decl_diff* d =
712 dynamic_cast<const function_decl_diff*>(diff))
713 return namespace_changed(d->first_function_decl(),
714 d->second_function_decl());
715 if (
const var_diff* d = dynamic_cast<const var_diff*>(diff))
716 return namespace_changed(d->first_var(), d->second_var());
737 string fn = f->get_qualified_name(),
738 sn = s->get_qualified_name();
748 s && !s->is_main_symbol();
749 s = s->get_next_alias())
766 function_name_changed_but_not_symbol(
const diff* diff)
768 if (
const function_decl_diff* d =
769 dynamic_cast<const function_decl_diff*>(diff))
770 return function_name_changed_but_not_symbol(d->first_function_decl(),
771 d->second_function_decl());
785 data_member_offset_changed(decl_base_sptr f, decl_base_sptr s)
792 v1 = dynamic_pointer_cast<var_decl>(s);
809 non_static_data_member_type_size_changed_with_impact(
const decl_base_sptr& f,
810 const decl_base_sptr& s)
817 sv = dynamic_pointer_cast<var_decl>(s);
824 return type_size_changed_with_impact(fv, sv);
834 static_data_member_type_size_changed(
const decl_base_sptr& f,
835 const decl_base_sptr& s)
842 sv = dynamic_pointer_cast<var_decl>(s);
849 return type_size_changed(fv->get_type(), sv->get_type());
860 is_compatible_change(
const decl_base_sptr& d1,
const decl_base_sptr& d2)
875 is_compatible_type_change(
const diff* d)
880 if (type_base_sptr t1 =
is_type(d->first_subject()))
881 if (type_base_sptr t2 =
is_type(d->second_subject()))
899 is_non_compatible_distinct_change(
const diff *d)
903 if (dd->compatible_child_diff()
904 || is_compatible_type_change(d)
906 || (!dd->first_subject() || !dd->second_subject()))
927 decl_name_changed(
const diff *d)
928 {
return decl_name_changed(d->first_subject(), d->second_subject());}
945 const decl_base_sptr& s,
949 return (decl_name_changed(f, s)
952 (f->get_is_anonymous() && s->get_is_anonymous())
956 ((f->get_is_anonymous_or_has_anonymous_parent()
957 && s->get_is_anonymous_or_has_anonymous_parent())
959 s->get_qualified_name()))
1000 const decl_base_sptr& s,
1032 non_static_data_member_added_or_removed_with_impact(
const class_diff* diff)
1034 if (diff && !diff_involves_decl_only_class(diff))
1036 for (string_decl_base_sptr_map::const_iterator i =
1053 for (string_decl_base_sptr_map::const_iterator i =
1071 non_static_data_member_added_or_removed_with_impact(
const diff* diff)
1073 return non_static_data_member_added_or_removed_with_impact
1128 if (fat->get_subranges().size() != 1
1129 || sat->get_subranges().size() != 1
1130 || (!fat->is_non_finite() && !sat->is_non_finite()))
1139 if (!var1->get_symbol()
1140 || !var2->get_symbol()
1141 || var1->get_symbol()->get_size() != var2->get_symbol()->get_size())
1251 static_data_member_added_or_removed(
const class_diff* diff)
1253 if (diff && !diff_involves_decl_only_class(diff))
1255 for (string_decl_base_sptr_map::const_iterator i =
1262 for (string_decl_base_sptr_map::const_iterator i =
1298 class_diff_has_harmless_odr_violation_change(
const diff* dif)
1300 class_diff* d =
dynamic_cast<class_diff*
>(
const_cast<diff*
>(dif));
1301 if (!d || !d->has_changes())
1307 if (first->get_qualified_name() == second->get_qualified_name()
1309 && first->get_corpus() == second->get_corpus())
1323 static_data_member_added_or_removed(
const diff* diff)
1325 return static_data_member_added_or_removed
1326 (dynamic_cast<const class_diff*>(diff));
1340 has_virtual_mem_fn_change(
const class_diff* diff)
1342 if (!diff || diff_involves_decl_only_class(diff))
1345 for (string_member_function_sptr_map::const_iterator i =
1346 diff->deleted_member_fns().begin();
1347 i != diff->deleted_member_fns().end();
1355 string_member_function_sptr_map::const_iterator j =
1356 diff->inserted_member_fns().find(i->first);
1357 if (j != diff->inserted_member_fns().end()
1366 for (string_member_function_sptr_map::const_iterator i =
1367 diff->inserted_member_fns().begin();
1368 i != diff->inserted_member_fns().end();
1376 string_member_function_sptr_map::const_iterator j =
1377 diff->deleted_member_fns().find(i->first);
1378 if (j != diff->deleted_member_fns().end()
1387 for (function_decl_diff_sptrs_type::const_iterator i =
1388 diff->changed_member_fns().begin();
1389 i != diff->changed_member_fns().end();
1430 if (ff_is_virtual != sf_is_virtual)
1436 if (ff_vtable_offset != sf_vtable_offset)
1453 has_virtual_mem_fn_change(
const diff* diff)
1455 return (has_virtual_mem_fn_change(dynamic_cast<const class_diff*>(diff))
1456 || has_virtual_mem_fn_change(dynamic_cast<const function_decl_diff*>(diff)));
1467 has_non_virtual_mem_fn_change(
const class_diff* diff)
1469 if (!diff || diff_involves_decl_only_class(diff))
1472 for (string_member_function_sptr_map::const_iterator i =
1479 for (string_member_function_sptr_map::const_iterator i =
1486 for (function_decl_diff_sptrs_type::const_iterator i =
1505 has_non_virtual_mem_fn_change(
const diff* diff)
1506 {
return has_non_virtual_mem_fn_change(dynamic_cast<const class_diff*>(diff));}
1514 base_classes_removed(
const class_diff* diff)
1518 return diff->deleted_bases().size();
1527 base_classes_removed(
const diff* diff)
1528 {
return base_classes_removed(dynamic_cast<const class_diff*>(diff));}
1557 return f_is_empty && s_is_empty;
1576 const class_or_union_sptr& second)
1578 if (!first || !second)
1607 class_or_union_sptr f =
1609 class_or_union_sptr s =
1626 const decl_base_sptr& second)
1628 if (!first || !second)
1636 if (f->get_qualified_name() != s->get_qualified_name())
1639 return f->get_is_declaration_only() != s->get_is_declaration_only();
1677 const class_or_union_sptr& second)
1679 if (!first || !second)
1682 class_or_union_sptr f =
1684 class_or_union_sptr s =
1687 if (f->get_qualified_name() != s->get_qualified_name())
1690 return f->get_is_declaration_only() != s->get_is_declaration_only();
1706 if (!first || !second)
1712 if (f->get_qualified_name() != s->get_qualified_name())
1715 return f->get_is_declaration_only() != s->get_is_declaration_only();
1734 class_or_union_sptr f =
1736 class_or_union_sptr s =
1773 if (decl_name_changed(dif))
1789 if (decl_name_changed(dif))
1893 has_enumerator_insertion(
const diff* diff)
1895 if (
const enum_diff* d = dynamic_cast<const enum_diff*>(diff))
1896 return !d->inserted_enumerators().empty();
1907 has_enumerator_removal_or_value_change(
const diff* diff)
1909 if (
const enum_diff* d = dynamic_cast<const enum_diff*>(diff))
1911 if (!d->deleted_enumerators().empty())
1914 for (
auto& entry : d->changed_enumerators())
1917 if (change.first.get_value() != change.second.get_value())
1931 has_enumerator_change(
const diff* diff)
1933 if (
const enum_diff* d = dynamic_cast<const enum_diff*>(diff))
1934 return !d->changed_enumerators().empty();
1950 has_harmful_enum_change(
const diff* diff)
1952 if (
const enum_diff* d = dynamic_cast<const enum_diff*>(diff))
1953 if (has_type_size_change(d) || has_enumerator_removal_or_value_change(d))
2021 has_harmless_enum_change(
const type_base_sptr& t1,
2022 const type_base_sptr& t2,
2034 if (((has_enumerator_insertion(dyf.get()) || has_enumerator_change(dyf.get()))
2035 && !has_harmful_enum_change(dyf.get()))
2058 has_harmless_enum_change(
const diff* d)
2063 if (((has_enumerator_insertion(d) || has_enumerator_change(d))
2064 && !has_harmful_enum_change(d))
2073 return has_harmless_enum_change(f, s, d->
context());
2085 has_fn_parm_type_top_cv_qual_change(
const diff* diff)
2090 if (!parm_diff || !parm_diff->has_changes())
2098 type_base_sptr first_parm_type = first_parm->get_type();
2099 type_base_sptr second_parm_type = second_parm->get_type();
2108 type_base_sptr peeled_type_1 = first_parm_type;
2109 type_base_sptr peeled_type_2 = second_parm_type;
2113 cv_quals_1 = qtype1->get_cv_quals();
2119 cv_quals_2 = qtype2->get_cv_quals();
2126 && cv_quals_1 != cv_quals_2)
2142 type_diff_has_typedef_cv_qual_change_only(
const diff *type_dif)
2147 type_base_sptr f =
is_type(type_dif->first_subject());
2148 type_base_sptr s =
is_type(type_dif->second_subject());
2150 return type_diff_has_typedef_cv_qual_change_only(f, s);
2164 type_diff_has_typedef_cv_qual_change_only(
const type_base_sptr& f,
2165 const type_base_sptr& s)
2167 type_base_sptr a = f;
2168 type_base_sptr b = s;
2173 if (a && b && *a == *b)
2200 has_fn_parm_type_cv_qual_change(
const diff* dif)
2205 if (!parm_diff || !parm_diff->has_changes())
2210 const diff *type_dif = parm_diff->type_diff().get();
2211 return type_diff_has_typedef_cv_qual_change_only(type_dif);
2224 has_fn_return_type_cv_qual_change(
const diff* dif)
2229 fn_type_diff = fn_decl_diff->type_diff().get();
2234 const diff* return_type_diff = fn_type_diff->return_type_diff().get();
2235 return type_diff_has_typedef_cv_qual_change_only(return_type_diff);
2248 has_added_or_removed_function_parameters(
const diff *dif)
2253 fn_type_diff = fn_decl_diff->type_diff().get();
2258 if (!(fn_type_diff->sorted_deleted_parms().empty()
2259 && fn_type_diff->sorted_added_parms().empty()))
2281 if (!fn_decl_diff && !fn_type_diff)
2292 fn_type_diff = fn_decl_diff->type_diff().get();
2299 category = return_type_diff->get_local_category();
2306 category = entry.second->get_local_category();
2367 cat = type_diff->get_local_category();
2463 const type_base_sptr& s)
2476 if (f->get_size_in_bits() != second_cou->get_size_in_bits()
2477 || f->get_alignment_in_bits() != second_cou->get_alignment_in_bits())
2482 non_anonymous_dms_in_second_class);
2483 for (
const auto& entry : non_anonymous_dms_in_second_class)
2485 if (type_base_sptr t = dm->get_type())
2539 const decl_base_sptr& s)
2557 for (
const auto& entry : non_anonymous_dms_in_second_dm)
2573 has_var_type_cv_qual_change(
const diff* dif)
2579 diff *type_dif = var_dif->
type_diff().get();
2583 return type_diff_has_typedef_cv_qual_change_only(type_dif);
2618 is_void_to_non_void(
const type_base* f,
const type_base* s)
2626 const environment& env = f->get_environment();
2627 if (env.is_void_type(f) && !env.is_void_type(s))
2644 is_void_to_non_void(
const type_base_sptr& f,
const type_base_sptr s)
2645 {
return is_void_to_non_void(f.get(), s.get());}
2663 return is_void_to_non_void(f, s);
2701 if (is_void_ptr_to_ptr(f, s) || is_void_ptr_to_ptr(s, f))
2712 if (is_void_ptr_to_ptr(f, s) || is_void_ptr_to_ptr(s, f))
2723 if (is_void_ptr_to_ptr(f, s) || is_void_ptr_to_ptr(s, f))
2760 && !has_type_size_change(d))
2784 has_harmful_change(
const diff* d)
2794 && (has_type_size_change_with_impact(d)
2795 || type_has_offset_changes(f, s)
2796 || data_member_offset_changed(f, s)
2797 || non_static_data_member_type_size_changed_with_impact(f, s)
2798 || non_static_data_member_added_or_removed_with_impact(d)
2799 || base_classes_removed(d)
2800 || has_harmful_enum_change(d)
2802 || namespace_changed(d)))
2805 if (has_virtual_mem_fn_change(d))
2809 category |= REFERENCE_LVALUENESS_CHANGE_CATEGORY;
2811 if (has_added_or_removed_function_parameters(d))
2814 if (is_non_compatible_distinct_change(d))
2841 categorize_harmless_diff_node(diff *d,
bool pre)
2857 if (access_changed(f, s))
2860 if (is_compatible_change(f, s))
2864 || class_diff_has_harmless_odr_violation_change(d))
2868 || class_diff_has_only_harmless_changes(d))
2871 if (has_non_virtual_mem_fn_change(d))
2874 if (static_data_member_added_or_removed(d)
2875 || static_data_member_type_size_changed(f, s))
2881 if (has_harmless_enum_change(d))
2884 if (function_name_changed_but_not_symbol(d))
2887 if (has_fn_parm_type_top_cv_qual_change(d))
2890 if (has_fn_parm_type_cv_qual_change(d))
2893 if (has_fn_return_type_cv_qual_change(d))
2896 if (has_var_type_cv_qual_change(d))
2910 canonical->add_to_local_and_inherited_categories(category);
2943 categorize_harmful_diff_node(diff *d,
bool pre)
2945 if (!d->has_changes())
2951 category = has_harmful_change(d);
2955 d->add_to_local_and_inherited_categories(category);
2957 if (diff * canonical = d->get_canonical_diff())
2958 canonical->add_to_local_and_inherited_categories(category);
2975 harmless_harmful_filter::visit(diff* d,
bool pre)
2977 return (categorize_harmless_diff_node(d, pre)
2978 && categorize_harmful_diff_node(d, pre));
2991 harmless_harmful_filter::visit_end(diff* d)
2993 if (d->context()->diff_has_been_visited(d))
3004 if (diff* c = d->get_canonical_diff())
3005 d->add_to_local_and_inherited_categories(c->get_local_category());
bool has_harmless_enum_to_int_change(const diff *diff)
Test if a diff node carries a harmless change of an enum into an integer (or vice-versa).
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...
The base type of all declarations.
const string_member_function_sptr_map & deleted_member_fns() const
This header declares filters for the diff trees resulting from comparing ABI Corpora.
The abstraction of a change between two ABI artifacts, a.k.a an artifact change.
const pointer_diff * is_pointer_diff(const diff *diff)
Test if a diff node is about differences between two pointers.
diff_category has_fn_return_or_parm_harmful_change(const diff *d)
Test if a diff node is a function diff node that carries either a return or a parameter type change t...
Abstraction of a diff between two qualified types.
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).
const string_fn_parm_diff_sptr_map & subtype_changed_parms() const
Getter for the map of function parameter changes of the current diff.
var_decl_sptr first_var() const
Getter for the first var_decl of the diff.
diff_category get_local_category() const
Getter for the local category of the current diff tree node.
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).
Utilities to ease the wrapping of C types into std::shared_ptr.
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...
An abstraction helper for type declarations.
This means the diff node (or at least one of its descendant nodes) carries a change that modifies the...
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.
A non-compatible name change between two types.
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 ...
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.
Abstracts a class declaration.
Abstraction of a diff between two function_decl.
A diff node in this category is a function parameter type which top cv-qualifiers change...
bool has_void_to_non_void_change(const diff *d)
Test if a diff node carries a "void-to-non-void" type change.
bool is_type_to_compatible_anonymous_type_change(const diff_sptr &d)
Test if a diff node carries a change where a type T is modified into an anonymous type T' of the same...
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.
bool has_void_ptr_to_ptr_change(const diff *dif)
Test if a diff node carries a void* to pointer type change.
class_or_union * anonymous_data_member_to_class_or_union(const var_decl *d)
Get the class_or_union type of a given anonymous data member.
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.
diff_category has_var_harmful_local_change(const diff *d)
Test if a diff node carries a harmful local change to a variable.
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.
Abstracts a declaration for an enum type.
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_benign_array_of_unknown_size_change(const diff *dif)
Test if a diff node carries a benign change to the size of a variable of type array.
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.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
virtual size_t get_size_in_bits() const
Getter for the size of the type.
var_decl_sptr second_var() const
Getter for the second var_decl of the diff.
This contains the private implementation of the suppression engine of libabigail. ...
Abstraction of a diff between two function parameters.
const enum_type_decl * is_compatible_with_enum_type(const type_base *t)
Test if a type is an enum. This function looks through typedefs.
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.
The abstraction of a diff between two references.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
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 has_lvalue_reference_ness_change(const diff *dif)
Test if a diff node carries a change where an lvalue reference changed into a rvalue reference...
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.
The abstraction of a diff between two pointers.
bool is_data_member_to_compatible_anonymous_dm_change(const diff *d)
Test if a diff node carries a change where a data member F is modified into an anonymous data member ...
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
std::pair< enum_type_decl::enumerator, enum_type_decl::enumerator > changed_enumerator
Convenience typedef for a changed enumerator. The first element of the pair is the old enumerator and...
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
diff_sptr type_diff() const
Getter for the diff representing the changes on the type of the function parameter involved in the cu...
bool has_fn_with_virtual_offset_change(const diff *d)
Test if a diff node carries a change to the offset of a virtual function.
bool has_incompatible_fn_or_var_change(const diff *d)
Test if a diff node carries an incompatible ABI change.
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.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
bool is_harmful_category(diff_category c)
Test if an instance of diff_category (a category bit-field) is harmful or not.
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.
diff_sptr type_diff() const
Getter for the diff of the types of the 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.
bool has_harmful_name_change(const decl_base_sptr &f, const decl_base_sptr &s, const diff_context_sptr &ctxt)
Test if two decls represent a harmful name change.
This means that a diff node in the sub-tree carries an addition or removal of a non-virtual member fu...
reference_type_def_sptr second_reference() const
Getter for the second reference of the diff.
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...
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.
const class_decl * is_compatible_with_class_type(const type_base *t)
Test if a type is a class. This function looks through typedefs.
bool types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
Test if two types are equal modulo a typedef or CV qualifiers.
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.
reference_type_def_sptr first_reference() const
Getter for the first reference of the diff.
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...
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.
const distinct_diff * is_distinct_diff(const diff *diff)
Test if a diff node is about differences between two diff nodes of different kinds.
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.
A change between two non-compatible types of different kinds.
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 array types 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.
Abstraction of a diff between two function types.
type_base_sptr peel_typedef_type(const type_base_sptr &type)
Return the leaf underlying type node of a typedef_decl node.
shared_ptr< filter_base > filter_base_sptr
Convenience typedef for a shared pointer to filter_base.
const diff_sptr return_type_diff() const
Getter for the diff of the return types of the two function types of the current diff.
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 diff_context_sptr context() const
Getter of the context of the current diff.
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...