13#include "abg-internal.h"
16ABG_BEGIN_EXPORT_DECLARATIONS
23ABG_END_EXPORT_DECLARATIONS
38type_diff_has_typedef_cv_qual_change_only(
const diff *type_dif);
41type_diff_has_typedef_cv_qual_change_only(
const type_base_sptr& f,
42 const type_base_sptr& s);
45has_harmful_change(
const diff* d);
48has_harmful_enum_change(
const diff*
diff);
51is_harmless_enum_change(
const type_base_sptr& f,
52 const type_base_sptr& s,
56type_size_changed_with_impact(
const type_base* f,
60type_size_changed_with_impact(
const decl_base* f,
67is_void_ptr_to_ptr(
const type_base_sptr f,
const type_base_sptr s);
74class_diff_has_only_harmless_changes(
const class_diff* d);
76using std::dynamic_pointer_cast;
88 bool s = d->context()->visiting_a_node_twice_is_forbidden();
89 d->context()->forbid_visiting_a_node_twice(
true);
91 d->context()->forbid_visiting_a_node_twice(s);
109 bool s = d->context()->visiting_a_node_twice_is_forbidden();
110 d->context()->forbid_visiting_a_node_twice(
true);
111 d->context()->forget_visited_diffs();
113 d->context()->forbid_visiting_a_node_twice(s);
162{
return there_is_a_decl_only_class(class1.get(), class2.get());}
189diff_involves_decl_only_class(
const class_diff* diff)
191 if (diff && there_is_a_decl_only_class(diff->first_class_decl(),
192 diff->second_class_decl()))
205type_size_changed(
const type_base* f,
const type_base* s)
208 || f->get_size_in_bits() == 0
209 || s->get_size_in_bits() == 0
216 return f->get_size_in_bits() != s->get_size_in_bits();
227type_size_changed(
const type_base_sptr f,
const type_base_sptr s)
228{
return type_size_changed(f.get(), s.get());}
242type_has_offset_changes(
const type_base_sptr f,
const type_base_sptr s)
249 if (!first || !second)
258 if (has_offset_changes(f_data_members, s_data_members))
276type_has_offset_changes(
const type_base* f,
const type_base* s)
278 type_base_sptr first(
const_cast<type_base*
>(f), sptr_utils::noop_deleter());
279 type_base_sptr second(
const_cast<type_base*
>(s), sptr_utils::noop_deleter());
281 return type_has_offset_changes(first, second);
290has_type_size_change(
const diff* diff)
296 diff = fn_parm_d->type_diff().get();
298 type_base_sptr f =
is_type(diff->first_subject()),
299 s =
is_type(diff->second_subject());
304 return type_size_changed(f, s);
325type_size_changed_with_impact(
const type_base* f,
331 if (type_size_changed(f, s))
336 result = type_size_changed_with_impact (
is_type(fs).get(),
341 if (type_has_offset_changes(f, s))
355 && type_size_changed(f, s))
376type_size_changed_with_impact(
const type_base* f,
const type_base *s)
381 if (!first_type || !second_type)
384 auto fs = first_type->get_scope();
385 auto ss = second_type->get_scope();
387 return type_size_changed_with_impact(f, s, fs, ss);
407type_size_changed_with_impact(
const decl_base* f,
const decl_base *s)
418 if (!f_var || !s_var)
421 auto fs = f->get_scope();
422 auto ss = s->get_scope();
424 const type_base* first_type = f_var->get_type().get();
425 const type_base* second_type = s_var->get_type().get();
427 return type_size_changed_with_impact(first_type, second_type, fs, ss);
444type_size_changed_with_impact(
const type_base_sptr& f,
const type_base_sptr& s)
445{
return type_size_changed_with_impact(f.get(), s.get());}
463type_size_changed_with_impact(
const decl_base_sptr& f,
const decl_base_sptr& s)
464{
return type_size_changed_with_impact(f.get(), s.get());}
480has_type_size_change_with_impact(
const diff* d)
486 d = fn_parm_d->type_diff().get();
489 return type_size_changed_with_impact(
is_type(d->first_subject()),
492 return type_size_changed_with_impact(
is_decl(d->first_subject()),
508 for (
auto e : data_members)
536 for (
auto entry : f_data_members)
541 auto i = s_data_members.find(entry.first);
543 if (i == s_data_members.end())
545 s_member = find_data_member_at_offset(s_data_members, f_offset);
556 if (f_offset != s_offset)
561 if (
auto t1 = f_member->get_type())
562 if (
auto t2 = s_member->get_type())
566 if (t1->get_size_in_bits() != t2->get_size_in_bits())
568 if (is_void_ptr_to_ptr(t1, t2) || is_void_ptr_to_ptr(t2, t1))
602 if (f->get_qualified_name() != s->get_qualified_name())
605 if (f->get_size_in_bits() != s->get_size_in_bits())
614 if (has_offset_changes(f_data_members, s_data_members))
635class_diff_has_only_harmless_changes(
const class_diff* d)
637 if (!d || !d->has_changes())
642 return class_diff_has_only_harmless_changes(f, s);
659class_diff_has_only_harmless_changes(diff* d)
662 return class_diff_has_only_harmless_changes(class_dif);
676access_changed(
const decl_base_sptr& f,
const decl_base_sptr& s)
698template <
typename function_or_var_decl_sptr>
700crc_changed(
const function_or_var_decl_sptr& f,
701 const function_or_var_decl_sptr& s)
703 const auto& symbol_f = f->get_symbol();
704 const auto& symbol_s = s->get_symbol();
705 if (!symbol_f || !symbol_s)
707 return symbol_f->get_crc() != symbol_s->get_crc();
717crc_changed(
const diff* diff)
719 if (
const function_decl_diff* d =
720 dynamic_cast<const function_decl_diff*
>(diff))
721 return crc_changed(d->first_function_decl(), d->second_function_decl());
722 if (
const var_diff* d =
dynamic_cast<const var_diff*
>(diff))
723 return crc_changed(d->first_var(), d->second_var());
734template <
typename function_or_var_decl_sptr>
736namespace_changed(
const function_or_var_decl_sptr& f,
737 const function_or_var_decl_sptr& s)
739 const auto& symbol_f = f->get_symbol();
740 const auto& symbol_s = s->get_symbol();
741 if (!symbol_f || !symbol_s)
743 return symbol_f->get_namespace() != symbol_s->get_namespace();
753namespace_changed(
const diff* diff)
755 if (
const function_decl_diff* d =
756 dynamic_cast<const function_decl_diff*
>(diff))
757 return namespace_changed(d->first_function_decl(),
758 d->second_function_decl());
759 if (
const var_diff* d =
dynamic_cast<const var_diff*
>(diff))
760 return namespace_changed(d->first_var(), d->second_var());
781 string fn = f->get_qualified_name(),
782 sn = s->get_qualified_name();
792 s && !s->is_main_symbol();
793 s = s->get_next_alias())
810function_name_changed_but_not_symbol(
const diff* diff)
812 if (
const function_decl_diff* d =
813 dynamic_cast<const function_decl_diff*
>(diff))
814 return function_name_changed_but_not_symbol(d->first_function_decl(),
815 d->second_function_decl());
829data_member_offset_changed(decl_base_sptr f, decl_base_sptr s)
836 v1 = dynamic_pointer_cast<var_decl>(s);
853non_static_data_member_type_size_changed_with_impact(
const decl_base_sptr& f,
854 const decl_base_sptr& s)
861 sv = dynamic_pointer_cast<var_decl>(s);
868 return type_size_changed_with_impact(fv, sv);
878static_data_member_type_size_changed(
const decl_base_sptr& f,
879 const decl_base_sptr& s)
886 sv = dynamic_pointer_cast<var_decl>(s);
893 return type_size_changed(fv->get_type(), sv->get_type());
904is_compatible_change(
const decl_base_sptr& d1,
const decl_base_sptr& d2)
919is_compatible_type_change(
const diff* d)
924 if (type_base_sptr t1 =
is_type(d->first_subject()))
925 if (type_base_sptr t2 =
is_type(d->second_subject()))
943is_non_compatible_distinct_change(
const diff *d)
947 if (dd->compatible_child_diff()
948 || is_compatible_type_change(d)
950 || (!dd->first_subject() || !dd->second_subject()))
971decl_name_changed(
const diff *d)
972{
return decl_name_changed(d->first_subject(), d->second_subject());}
989 const decl_base_sptr& s,
1009template <
class FnVarOrParm>
1012 FnVarOrParm second_decl,
1015 if (!decl_name_changed(first_decl, second_decl))
1023 type_base_sptr t1 = first_decl->get_type();
1024 type_base_sptr t2 = second_decl->get_type();
1029 if (decl_base_sptr d1 =
is_decl(t1))
1030 if (decl_base_sptr d2 =
is_decl(t2))
1052 const decl_base_sptr& s,
1055 if (!decl_name_changed(f, s))
1062 || is_harmless_enum_change(t1, t2, ctxt)
1082 if (class_diff_has_only_harmless_changes(class1, class2))
1109 if (f->get_is_declaration_only() != s->get_is_declaration_only())
1110 if ((f->get_is_declaration_only()
1112 &&
is_type(f)->get_size_in_bits() == 0)
1114 (s->get_is_declaration_only()
1116 &&
is_type(s)->get_size_in_bits() == 0))
1152non_static_data_member_added_or_removed_with_impact(
const class_diff*
diff)
1154 if (
diff && !diff_involves_decl_only_class(
diff))
1156 for (string_decl_base_sptr_map::const_iterator i =
1157 diff->inserted_data_members().begin();
1158 i !=
diff->inserted_data_members().end();
1173 for (string_decl_base_sptr_map::const_iterator i =
1174 diff->deleted_data_members().begin();
1175 i !=
diff->deleted_data_members().end();
1191non_static_data_member_added_or_removed_with_impact(
const diff* diff)
1193 return non_static_data_member_added_or_removed_with_impact
1248 if (fat->get_subranges().size() != 1
1249 || sat->get_subranges().size() != 1
1250 || (!fat->is_non_finite() && !sat->is_non_finite()))
1259 if (!var1->get_symbol()
1260 || !var2->get_symbol()
1261 || var1->get_symbol()->get_size() != var2->get_symbol()->get_size())
1373 if (
diff && !diff_involves_decl_only_class(
diff))
1375 for (string_decl_base_sptr_map::const_iterator i =
1376 diff->inserted_data_members().begin();
1377 i !=
diff->inserted_data_members().end();
1382 for (string_decl_base_sptr_map::const_iterator i =
1383 diff->deleted_data_members().begin();
1384 i !=
diff->deleted_data_members().end();
1418class_diff_has_harmless_odr_violation_change(
const diff* dif)
1420 class_diff* d =
dynamic_cast<class_diff*
>(
const_cast<diff*
>(dif));
1421 if (!d || !d->has_changes())
1427 if (first->get_qualified_name() == second->get_qualified_name()
1429 && first->get_corpus() == second->get_corpus())
1443static_data_member_added_or_removed(
const diff* diff)
1445 return static_data_member_added_or_removed
1446 (
dynamic_cast<const class_diff*
>(diff));
1460has_virtual_mem_fn_change(
const class_diff* diff)
1462 if (!diff || diff_involves_decl_only_class(diff))
1465 for (string_member_function_sptr_map::const_iterator i =
1466 diff->deleted_member_fns().begin();
1467 i != diff->deleted_member_fns().end();
1475 string_member_function_sptr_map::const_iterator j =
1476 diff->inserted_member_fns().find(i->first);
1477 if (j != diff->inserted_member_fns().end()
1486 for (string_member_function_sptr_map::const_iterator i =
1487 diff->inserted_member_fns().begin();
1488 i != diff->inserted_member_fns().end();
1496 string_member_function_sptr_map::const_iterator j =
1497 diff->deleted_member_fns().find(i->first);
1498 if (j != diff->deleted_member_fns().end()
1507 for (function_decl_diff_sptrs_type::const_iterator i =
1508 diff->changed_member_fns().begin();
1509 i != diff->changed_member_fns().end();
1541 sf =
diff->second_function_decl();
1550 if (ff_is_virtual != sf_is_virtual)
1556 if (ff_vtable_offset != sf_vtable_offset)
1573has_virtual_mem_fn_change(
const diff*
diff)
1575 return (has_virtual_mem_fn_change(
dynamic_cast<const class_diff*
>(
diff))
1589 if (!
diff || diff_involves_decl_only_class(
diff))
1592 for (string_member_function_sptr_map::const_iterator i =
1593 diff->deleted_member_fns().begin();
1594 i !=
diff->deleted_member_fns().end();
1599 for (string_member_function_sptr_map::const_iterator i =
1600 diff->inserted_member_fns().begin();
1601 i !=
diff->inserted_member_fns().end();
1606 for (function_decl_diff_sptrs_type::const_iterator i =
1607 diff->changed_member_fns().begin();
1608 i !=
diff->changed_member_fns().end();
1625has_non_virtual_mem_fn_change(
const diff* diff)
1626{
return has_non_virtual_mem_fn_change(
dynamic_cast<const class_diff*
>(diff));}
1634base_classes_removed(
const class_diff* diff)
1638 return diff->deleted_bases().size();
1647base_classes_removed(
const diff* diff)
1648{
return base_classes_removed(
dynamic_cast<const class_diff*
>(diff));}
1677 return f_is_empty && s_is_empty;
1696 const class_or_union_sptr& second)
1698 if (!first || !second)
1727 class_or_union_sptr f =
1729 class_or_union_sptr s =
1746 const decl_base_sptr& second)
1748 if (!first || !second)
1756 if (f->get_qualified_name() != s->get_qualified_name())
1759 return f->get_is_declaration_only() != s->get_is_declaration_only();
1797 const class_or_union_sptr& second)
1799 if (!first || !second)
1802 class_or_union_sptr f =
1804 class_or_union_sptr s =
1807 if (f->get_qualified_name() != s->get_qualified_name())
1810 return f->get_is_declaration_only() != s->get_is_declaration_only();
1826 if (!first || !second)
1832 if (f->get_qualified_name() != s->get_qualified_name())
1835 return f->get_is_declaration_only() != s->get_is_declaration_only();
1854 class_or_union_sptr f =
1856 class_or_union_sptr s =
1893 if (decl_name_changed(dif))
1909 if (decl_name_changed(dif))
2013has_enumerator_insertion(
const diff*
diff)
2016 return !d->inserted_enumerators().empty();
2027has_enumerator_removal_or_value_change(
const diff*
diff)
2031 if (!d->deleted_enumerators().empty())
2034 for (
auto& entry : d->changed_enumerators())
2037 if (change.first.get_value() != change.second.get_value())
2051has_enumerator_change(
const diff* diff)
2053 if (
const enum_diff* d =
dynamic_cast<const enum_diff*
>(diff))
2054 return !d->changed_enumerators().empty();
2070has_harmful_enum_change(
const diff* diff)
2072 if (
const enum_diff* d =
dynamic_cast<const enum_diff*
>(diff))
2073 if (has_type_size_change(d) || has_enumerator_removal_or_value_change(d))
2141is_harmless_enum_change(
const type_base_sptr& t1,
2142 const type_base_sptr& t2,
2160 if (((has_enumerator_insertion(dyf.get()) || has_enumerator_change(dyf.get()))
2161 && !has_harmful_enum_change(dyf.get()))
2184is_harmless_enum_change(
const diff* d)
2189 if (((has_enumerator_insertion(d) || has_enumerator_change(d))
2190 && !has_harmful_enum_change(d))
2199 return is_harmless_enum_change(f, s, d->
context());
2211has_fn_parm_type_top_cv_qual_change(
const diff* diff)
2216 if (!parm_diff || !parm_diff->has_changes())
2224 type_base_sptr first_parm_type = first_parm->get_type();
2225 type_base_sptr second_parm_type = second_parm->get_type();
2234 type_base_sptr peeled_type_1 = first_parm_type;
2235 type_base_sptr peeled_type_2 = second_parm_type;
2239 cv_quals_1 = qtype1->get_cv_quals();
2245 cv_quals_2 = qtype2->get_cv_quals();
2252 && cv_quals_1 != cv_quals_2)
2268type_diff_has_typedef_cv_qual_change_only(
const diff *type_dif)
2273 type_base_sptr f =
is_type(type_dif->first_subject());
2274 type_base_sptr s =
is_type(type_dif->second_subject());
2276 return type_diff_has_typedef_cv_qual_change_only(f, s);
2290type_diff_has_typedef_cv_qual_change_only(
const type_base_sptr& f,
2291 const type_base_sptr& s)
2293 type_base_sptr a = f;
2294 type_base_sptr b = s;
2296 if (a && b && *a == *b)
2302 if (a && b && *a == *b)
2329has_fn_parm_type_cv_qual_change(
const diff* dif)
2334 if (!parm_diff || !parm_diff->has_changes())
2339 const diff *type_dif = parm_diff->type_diff().get();
2340 return type_diff_has_typedef_cv_qual_change_only(type_dif);
2353has_fn_return_type_cv_qual_change(
const diff* dif)
2358 fn_type_diff = fn_decl_diff->type_diff().get();
2363 const diff* return_type_diff = fn_type_diff->return_type_diff().get();
2364 return type_diff_has_typedef_cv_qual_change_only(return_type_diff);
2377has_added_or_removed_function_parameters(
const diff *dif)
2382 fn_type_diff = fn_decl_diff->type_diff().get();
2387 if (!(fn_type_diff->sorted_deleted_parms().empty()
2388 && fn_type_diff->sorted_added_parms().empty()))
2410 if (!fn_decl_diff && !fn_type_diff)
2421 fn_type_diff = fn_decl_diff->type_diff().get();
2428 category = return_type_diff->get_local_category();
2435 category = entry.second->get_local_category();
2496 cat = type_diff->get_local_category();
2592 const type_base_sptr& s)
2605 if (f->get_size_in_bits() != second_cou->get_size_in_bits()
2606 || f->get_alignment_in_bits() != second_cou->get_alignment_in_bits())
2611 non_anonymous_dms_in_second_class);
2612 for (
const auto& entry : non_anonymous_dms_in_second_class)
2614 if (type_base_sptr t = dm->get_type())
2668 const decl_base_sptr& s)
2686 for (
const auto& entry : non_anonymous_dms_in_second_dm)
2702has_var_type_cv_qual_change(
const diff* dif)
2712 return type_diff_has_typedef_cv_qual_change_only(type_dif);
2745is_void_ptr_to_ptr(
const type_base_sptr f,
const type_base_sptr s)
2746{
return is_void_ptr_to_ptr(f.get(), s.get());}
2759is_void_to_non_void(
const type_base* f,
const type_base* s)
2767 const environment& env = f->get_environment();
2768 if (env.is_void_type(f) && !env.is_void_type(s))
2785is_void_to_non_void(
const type_base_sptr& f,
const type_base_sptr s)
2786{
return is_void_to_non_void(f.get(), s.get());}
2804 return is_void_to_non_void(f, s);
2842 if (is_void_ptr_to_ptr(f, s) || is_void_ptr_to_ptr(s, f))
2853 if (is_void_ptr_to_ptr(f, s) || is_void_ptr_to_ptr(s, f))
2864 if (is_void_ptr_to_ptr(f, s) || is_void_ptr_to_ptr(s, f))
2922 const union_decl_sptr r)
2924 if (l && r && *l == *r)
2927 if (type_has_offset_changes(l, r) || type_size_changed(l, r))
2951has_harmful_change(
const diff* d)
2961 && (has_type_size_change_with_impact(d)
2963 || data_member_offset_changed(f, s)
2964 || non_static_data_member_type_size_changed_with_impact(f, s)
2965 || non_static_data_member_added_or_removed_with_impact(d)
2966 || base_classes_removed(d)
2967 || has_harmful_enum_change(d)
2969 || namespace_changed(d)))
2972 if (has_virtual_mem_fn_change(d))
2976 category |= REFERENCE_LVALUENESS_CHANGE_CATEGORY;
2978 if (has_added_or_removed_function_parameters(d))
2981 if (is_non_compatible_distinct_change(d))
3008categorize_harmless_diff_node(
diff *d,
bool pre)
3024 if (access_changed(f, s))
3027 if (is_compatible_change(f, s))
3031 || class_diff_has_harmless_odr_violation_change(d))
3035 || class_diff_has_only_harmless_changes(d))
3038 if (has_non_virtual_mem_fn_change(d))
3041 if (static_data_member_added_or_removed(d)
3042 || static_data_member_type_size_changed(f, s))
3048 if (is_harmless_enum_change(d))
3051 if (function_name_changed_but_not_symbol(d))
3054 if (has_fn_parm_type_top_cv_qual_change(d))
3057 if (has_fn_parm_type_cv_qual_change(d))
3060 if (has_fn_return_type_cv_qual_change(d))
3063 if (has_var_type_cv_qual_change(d))
3077 canonical->add_to_local_and_inherited_categories(category);
3110categorize_harmful_diff_node(diff *d,
bool pre)
3112 if (!d->has_changes())
3118 category = has_harmful_change(d);
3122 d->add_to_local_and_inherited_categories(category);
3124 if (diff * canonical = d->get_canonical_diff())
3125 canonical->add_to_local_and_inherited_categories(category);
3142harmless_harmful_filter::visit(diff* d,
bool pre)
3144 return (categorize_harmless_diff_node(d, pre)
3145 && categorize_harmful_diff_node(d, pre));
3158harmless_harmful_filter::visit_end(diff* d)
3160 if (d->context()->diff_has_been_visited(d))
3171 if (diff* c = d->get_canonical_diff())
3172 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 contains the private implementation of the suppression engine of libabigail.
Utilities to ease the wrapping of C types into std::shared_ptr.
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...
diff_category get_local_category() const
Getter for the local category of the current diff tree node.
const diff_context_sptr context() const
Getter of the context of the current diff.
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 function types.
const string_fn_parm_diff_sptr_map & subtype_changed_parms() const
Getter for the map of function parameter changes of the current diff.
const diff_sptr return_type_diff() const
Getter for the diff of the return types of the two function types of the current diff.
The abstraction of a diff between two pointers.
Abstraction of a diff between two qualified types.
The abstraction of a diff between two references.
reference_type_def_sptr first_reference() const
Getter for the first reference of the diff.
reference_type_def_sptr second_reference() const
Getter for the second reference of the diff.
Abstraction of a diff between two basic type declarations.
The base class of diff between types.
union_decl_sptr first_union_decl() const
union_decl_sptr second_union_decl() const
Abstracts a diff between two instances of var_decl.
var_decl_sptr first_var() const
Getter for the first var_decl of the diff.
diff_sptr type_diff() const
Getter for the diff of the types of the instances of var_decl.
var_decl_sptr second_var() const
Getter for the second var_decl of the diff.
Abstracts a class declaration.
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.
The base type of all declarations.
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.
Abstracts a declaration for an enum type.
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.
An abstraction helper for type declarations.
virtual size_t get_size_in_bits() const
Getter for the size of the type.
bool has_void_ptr_to_ptr_change(const diff *dif)
Test if a diff node carries a void* to pointer type change.
bool has_basic_type_name_change(const diff *d)
Test if a diff node carries a basic type name change.
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...
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 ...
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 union_diff_is_harmless_change(const diff *d)
Test if a union diff node does have changes that don't impact its size.
diff_category has_var_harmful_local_change(const diff *d)
Test if a diff node carries a harmful local change to a variable.
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_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).
bool decl_with_type_has_harmful_name_change(FnVarOrParm first_decl, FnVarOrParm second_decl, const diff_context_sptr &ctxt)
Test if a decl-with-type (either a function, a variable or a parameter) has a harmful name change.
bool is_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.
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 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_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_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_incompatible_fn_or_var_change(const diff *d)
Test if a diff node carries an incompatible ABI change.
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 has_anonymous_data_member_change(const diff *d)
Test if a diff node carries a non-anonymous data member to anonymous data member 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...
bool has_void_to_non_void_change(const diff *d)
Test if a diff node carries a "void-to-non-void" type 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 is_harmless_name_change(const decl_base_sptr &f, const decl_base_sptr &s, const diff_context_sptr &ctxt)
Test if two decls represent a harmless name change.
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...
bool is_harmful_category(diff_category c)
Test if an instance of diff_category (a category bit-field) is harmful or not.
shared_ptr< diff > diff_sptr
Convenience typedef for a shared_ptr for the diff class.
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...
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.
@ NON_COMPATIBLE_DISTINCT_CHANGE_CATEGORY
A change between two non-compatible types of different kinds.
@ NON_COMPATIBLE_NAME_CHANGE_CATEGORY
A non-compatible name change between two types.
@ 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 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 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...
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 array types 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.
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.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
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.
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 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.
bool enum_equals_modulo_name(const enum_type_decl &l, const enum_type_decl &r, change_kind *k)
Test if two enums are equal modulo their names. That is, the test compares the two enums as if they d...
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
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.
function_decl::parameter * is_function_parameter(const type_or_decl_base *tod)
Test whether a declaration is a function_decl.
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.
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.
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.
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_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
type_base_sptr peel_typedef_type(const type_base_sptr &type)
Return the leaf underlying type node of a typedef_decl node.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
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 or CV qualifiers.
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.
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
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.
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.