13 #ifndef __ABG_IR_PRIV_H__
14 #define __ABG_IR_PRIV_H__
34 COMPARISON_RESULT_DIFFERENT = 0,
35 COMPARISON_RESULT_EQUAL = 1,
36 COMPARISON_RESULT_CYCLE_DETECTED = 2,
37 COMPARISON_RESULT_UNKNOWN = 3,
119 operator string()
const;
146 bool is_constructed_;
150 std::string comp_dir_path_;
151 std::string abs_path_;
154 mutable vector<type_base_sptr> synthesized_types_;
155 vector<function_type_sptr> live_fn_types_;
164 language_(LANG_UNKNOWN)
181 size_t alignment_in_bits;
201 unordered_set<uintptr_t> depends_on_recursive_type_;
202 bool canonical_type_propagated_;
203 bool propagated_canonical_type_confirmed_;
208 naked_canonical_type(),
209 canonical_type_propagated_(
false),
210 propagated_canonical_type_confirmed_(
false)
215 type_base_sptr c = type_base_sptr())
217 alignment_in_bits(a),
219 naked_canonical_type(c.get()),
220 canonical_type_propagated_(
false),
221 propagated_canonical_type_confirmed_(
false)
235 {
return !depends_on_recursive_type_.empty();}
254 (depends_on_recursive_type_.find(
reinterpret_cast<uintptr_t
>(dependant))
255 != depends_on_recursive_type_.end());
270 {depends_on_recursive_type_.insert(
reinterpret_cast<uintptr_t
>(t));}
285 {depends_on_recursive_type_.erase(
reinterpret_cast<uintptr_t
>(t));}
290 {depends_on_recursive_type_.clear();}
300 {
return canonical_type_propagated_;}
310 {canonical_type_propagated_ = f;}
323 {
return propagated_canonical_type_confirmed_;}
336 {propagated_canonical_type_confirmed_ = f;}
343 if (canonical_type_propagated_ && !propagated_canonical_type_confirmed_)
345 canonical_type.reset();
346 naked_canonical_type =
nullptr;
364 {
return abigail::hashing::combine_hashes(p.first, p.second);}
392 mutable vector<type_base_sptr> sorted_canonical_types_;
393 type_base_sptr void_type_;
394 type_base_sptr variadic_marker_type_;
411 vector<type_base_sptr> extra_live_types_;
454 vector<const type_base*> left_type_comp_operands_;
455 vector<const type_base*> right_type_comp_operands_;
461 pointer_set types_with_non_confirmed_propagated_ct_;
463 #ifdef WITH_DEBUG_CT_PROPAGATION
469 mutable pointer_set types_with_cleared_propagated_ct_;
471 #ifdef WITH_DEBUG_SELF_COMPARISON
486 unordered_map<string, uintptr_t> type_id_canonical_type_map_;
489 unordered_map<uintptr_t, string> pointer_type_id_map_;
491 bool canonicalization_is_done_;
492 bool do_on_the_fly_canonicalization_;
493 bool decl_only_class_equals_definition_;
494 bool use_enum_binary_only_equality_;
495 bool allow_type_comparison_results_caching_;
497 #ifdef WITH_DEBUG_SELF_COMPARISON
498 bool self_comparison_debug_on_;
500 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
505 bool use_canonical_type_comparison_;
513 bool debug_type_canonicalization_;
514 bool debug_die_canonicalization_;
518 : canonicalization_is_done_(),
519 do_on_the_fly_canonicalization_(
true),
520 decl_only_class_equals_definition_(
false),
521 use_enum_binary_only_equality_(
true),
522 allow_type_comparison_results_caching_(
false)
523 #ifdef WITH_DEBUG_SELF_COMPARISON
525 self_comparison_debug_on_(
false)
527 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
529 use_canonical_type_comparison_(
true),
530 debug_type_canonicalization_(
false),
531 debug_die_canonicalization_(
false)
542 {allow_type_comparison_results_caching_ = f;}
553 {
return allow_type_comparison_results_caching_;}
575 && !
is_type(&first)->priv_->depends_on_recursive_type()
576 && !
is_type(&second)->priv_->depends_on_recursive_type())))
578 type_comparison_results_cache_.emplace
579 (std::make_pair(
reinterpret_cast<uint64_t
>(&first),
580 reinterpret_cast<uint64_t
>(&second)),
611 type_comparison_result_type::const_iterator it =
612 type_comparison_results_cache_.find
613 (std::make_pair(
reinterpret_cast<uint64_t
>(&first),
614 reinterpret_cast<uint64_t
>(&second)));
615 if (it == type_comparison_results_cache_.end())
625 {type_comparison_results_cache_.clear();}
642 left_type_comp_operands_.push_back(left);
643 right_type_comp_operands_.push_back(right);
663 const type_base *t = left_type_comp_operands_.back();
665 t = right_type_comp_operands_.back();
668 left_type_comp_operands_.pop_back();
669 right_type_comp_operands_.pop_back();
686 vector<const type_base*>& types)
692 && (
reinterpret_cast<uintptr_t
>(t)
693 ==
reinterpret_cast<uintptr_t
>(type)))
699 t->priv_->set_depends_on_recursive_type(type);
766 right_type_comp_operands_);
767 recursive_types_.insert(
reinterpret_cast<uintptr_t
>(right));
779 return (recursive_types_.find(
reinterpret_cast<uintptr_t
>(t))
780 != recursive_types_.end());
789 {recursive_types_.erase(
reinterpret_cast<uintptr_t
>(t));}
804 dest.priv_->canonical_type = canonical;
805 dest.priv_->naked_canonical_type = canonical.get();
807 #ifdef WITH_DEBUG_CT_PROPAGATION
810 erase_type_with_cleared_propagated_canonical_type(&dest);
827 for (
auto i : types_with_non_confirmed_propagated_ct_)
835 #ifdef WITH_DEBUG_SELF_COMPARISON
836 check_abixml_canonical_type_propagation_during_self_comp(t);
841 for (
auto i : to_remove)
842 types_with_non_confirmed_propagated_ct_.erase(i);
864 env.priv_->confirm_ct_propagation_for_types_dependant_on(t);
866 env.priv_->remove_from_types_with_non_confirmed_propagated_ct(t);
867 env.priv_->set_is_not_recursive(t);
869 #ifdef WITH_DEBUG_SELF_COMPARISON
870 check_abixml_canonical_type_propagation_during_self_comp(t);
885 for (
auto i : types_with_non_confirmed_propagated_ct_)
890 #ifdef WITH_DEBUG_SELF_COMPARISON
891 check_abixml_canonical_type_propagation_during_self_comp(t);
894 types_with_non_confirmed_propagated_ct_.clear();
897 #ifdef WITH_DEBUG_CT_PROPAGATION
907 types_with_cleared_propagated_ct()
const
908 {
return types_with_cleared_propagated_ct_;}
919 types_with_cleared_propagated_ct()
920 {
return types_with_cleared_propagated_ct_;}
927 record_type_with_cleared_propagated_canonical_type(
const type_base* t)
929 uintptr_t ptr =
reinterpret_cast<uintptr_t
>(t);
930 types_with_cleared_propagated_ct_.insert(ptr);
940 erase_type_with_cleared_propagated_canonical_type(
const type_base* t)
942 uintptr_t ptr =
reinterpret_cast<uintptr_t
>(t);
943 types_with_cleared_propagated_ct_.erase(ptr);
965 for (
const auto i : types)
969 if (collected.find(i) != collected.end())
1003 types_with_non_confirmed_propagated_ct_,
1006 for (
auto i : to_remove)
1011 type_base_sptr canonical = t->priv_->canonical_type.lock();
1019 for (
auto i : to_remove)
1020 types_with_non_confirmed_propagated_ct_.erase(i);
1047 env.priv_->cancel_ct_propagation_for_types_dependant_on(t);
1054 env.priv_->remove_from_types_with_non_confirmed_propagated_ct(t);
1072 #ifdef WITH_DEBUG_CT_PROPAGATION
1075 record_type_with_cleared_propagated_canonical_type(t)
1089 uintptr_t v =
reinterpret_cast<uintptr_t
>(t);
1090 types_with_non_confirmed_propagated_ct_.insert(v);
1101 uintptr_t i =
reinterpret_cast<uintptr_t
>(dependant);
1102 types_with_non_confirmed_propagated_ct_.erase(i);
1110 vector<uintptr_t> to_erase;
1111 for (
auto i : types_with_non_confirmed_propagated_ct_)
1112 to_erase.push_back(i);
1114 for (
auto i : to_erase)
1121 #ifdef WITH_DEBUG_SELF_COMPARISON
1123 const unordered_map<string, uintptr_t>&
1124 get_type_id_canonical_type_map()
const
1125 {
return type_id_canonical_type_map_;}
1127 unordered_map<string, uintptr_t>&
1128 get_type_id_canonical_type_map()
1129 {
return type_id_canonical_type_map_;}
1131 const unordered_map<uintptr_t, string>&
1132 get_pointer_type_id_map()
const
1133 {
return pointer_type_id_map_;}
1135 unordered_map<uintptr_t, string>&
1136 get_pointer_type_id_map()
1137 {
return pointer_type_id_map_;}
1140 get_type_id_from_pointer(uintptr_t ptr)
const
1142 auto it = get_pointer_type_id_map().find(ptr);
1143 if (it != get_pointer_type_id_map().end())
1149 get_type_id_from_type(
const type_base *t)
const
1150 {
return get_type_id_from_pointer(
reinterpret_cast<uintptr_t
>(t));}
1153 get_canonical_type_from_type_id(
const char* type_id)
const
1157 auto it = get_type_id_canonical_type_map().find(type_id);
1158 if (it != get_type_id_canonical_type_map().end())
1176 check_canonical_type_from_abixml_during_self_comp(
const type_base* t,
1179 if (!t || !t->get_corpus() || !c)
1182 if (!(t->get_corpus()->get_origin() == ir::corpus::NATIVE_XML_ORIGIN))
1188 unordered_map<uintptr_t, string>::const_iterator it =
1189 pointer_type_id_map_.find(
reinterpret_cast<uintptr_t
>(t));
1190 if (it == pointer_type_id_map_.end())
1194 type_id = it->second;
1199 type_base *original_canonical_type =
nullptr;
1200 if (!type_id.empty())
1202 unordered_map<string, uintptr_t>::const_iterator it =
1203 type_id_canonical_type_map_.find(type_id);
1204 if (it == type_id_canonical_type_map_.end())
1206 original_canonical_type =
reinterpret_cast<type_base*
>(it->second);
1215 if (original_canonical_type == c)
1231 check_abixml_canonical_type_propagation_during_self_comp(
const type_base* t)
1234 && t->get_corpus()->get_origin() == ir::corpus::NATIVE_XML_ORIGIN)
1236 type_base* c = t->get_naked_canonical_type();
1237 if (c && !check_canonical_type_from_abixml_during_self_comp(t, c))
1239 string repr = t->get_pretty_representation(
true,
true);
1240 string type_id = get_type_id_from_type(t);
1241 std::cerr <<
"error: canonical type propagation error for '"
1243 <<
"' of type-id: '"
1250 <<
", should have had canonical type: "
1252 << get_canonical_type_from_type_id(type_id.c_str())
1272 check_canonical_type_from_abixml_during_self_comp(
const type_base_sptr& t,
1273 const type_base_sptr& c)
1275 return check_canonical_type_from_abixml_during_self_comp(t.get(), c.get());
1311 template<
typename input_iterator,
1312 typename deref_lambda>
1315 const input_iterator& end,
1322 for (
auto t = begin; t != end; ++t)
1325 #ifdef WITH_DEBUG_CT_PROPAGATION
1330 const environment& env = deref(begin)->get_environment();
1332 env.priv_->types_with_cleared_propagated_ct();
1350 member_function_templates member_function_templates_;
1351 member_class_templates member_class_templates_;
1358 : data_members_(data_mbrs),
1359 member_functions_(mbr_fns)
1361 for (data_members::const_iterator i = data_members_.begin();
1362 i != data_members_.end();
1365 non_static_data_members_.push_back(*i);
1388 env.priv_->left_classes_being_compared_.insert(&first);
1389 env.priv_->right_classes_being_compared_.insert(&second);
1427 const class_or_union_sptr& second)
const
1450 env.priv_->left_classes_being_compared_.erase(&first);
1451 env.priv_->right_classes_being_compared_.erase(&second);
1472 if (!first || !second)
1491 return (env.priv_->left_classes_being_compared_.count(&first)
1492 || env.priv_->right_classes_being_compared_.count(&second)
1493 || env.priv_->right_classes_being_compared_.count(&first)
1494 || env.priv_->left_classes_being_compared_.count(&second));
1509 if (first && second)
1530 type_base_sptr return_type)
1532 return_type_(return_type)
1535 priv(type_base_sptr return_type)
1536 : return_type_(return_type)
1552 env.priv_->left_fn_types_being_compared_.insert(&first);
1553 env.priv_->right_fn_types_being_compared_.insert(&second);
1569 env.priv_->left_fn_types_being_compared_.erase(&first);
1570 env.priv_->right_fn_types_being_compared_.erase(&second);
1584 return (env.priv_->left_fn_types_being_compared_.count(&first)
1586 env.priv_->right_fn_types_being_compared_.count(&second));
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
Types of the main internal representation of libabigail.
Simplified implementation of std::optional just enough to be used as a replacement for our purposes a...
This type abstracts the configuration information of the library.
The interned string pool.
The abstraction of an interned string.
The base type of class_decl and union_decl.
vector< method_decl_sptr > member_functions
Convenience typedef.
unordered_map< string, method_decl * > string_mem_fn_ptr_map_type
Convenience typedef.
vector< var_decl_sptr > data_members
Convenience typedef.
unordered_map< string, method_decl_sptr > string_mem_fn_sptr_map_type
Convenience typedef.
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
friend bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
std::unordered_map< string, std::vector< type_base_sptr > > canonical_types_map_type
A convenience typedef for a map of canonical types. The key is the pretty representation string of a ...
Abstraction of a function type.
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
The internal representation of an integral type.
void set_modifiers(modifiers_type)
Setter of the modifiers bitmap of the integral_type.
string to_string(bool internal=false) const
Return the string representation of the current instance of integral_type.
base_type get_base_type() const
Getter of the base type of the integral_type.
modifiers_type
The modifiers of the base types above. Several modifiers can be combined for a given base type....
@ LONG_LONG_MODIFIER
The "long long" modifier.
@ LONG_MODIFIER
The "long" modifier.
@ SIGNED_MODIFIER
The "signed" modifier.
@ UNSIGNED_MODIFIER
The "unsigned" modier.
@ SHORT_MODIFIER
The "short" modifier.
bool operator==(const integral_type &) const
Equality operator for the integral_type.
base_type
The possible base types of integral types. We might have forgotten many of these, so do not hesitate ...
@ WCHAR_T_BASE_TYPE
The "wchar_t" base type.
@ CHAR32_T_BASE_TYPE
The "char32_t" base type.
@ FLOAT_BASE_TYPE
The "float" base type.
@ BOOL_BASE_TYPE
The "bool" base type in C++ or "_Bool" in C11.
@ CHAR_BASE_TYPE
The "char" base type.
@ CHAR16_T_BASE_TYPE
The "char16_t base type.
@ INT_BASE_TYPE
The "int" base type.
@ DOUBLE_BASE_TYPE
The "double" base type.
modifiers_type get_modifiers() const
Getter of the modifiers bitmap of the integral_type.
integral_type()
Default constructor of the integral_type.
The entry point to manage locations.
language
The language of the translation unit.
shared_ptr< scope_decl > global_scope_sptr
Convenience typedef for a shared pointer on a global_scope.
An abstraction helper for type declarations.
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
This is a type that aggregates maps of all the kinds of types that are supported by libabigail.
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
weak_ptr< typedef_decl > typedef_decl_wptr
Convenience typedef for a weak pointer on a typedef_decl.
unordered_map< uint64_t_pair_type, bool, uint64_t_pair_hash > type_comparison_result_type
A convenience typedef for a map which key is a pair of uint64_t and which value is a boolean....
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
weak_ptr< type_base > type_base_wptr
Convenience typedef for a weak pointer on a type_base.
unordered_set< const class_or_union * > class_set_type
A convenience typedef for a set of pointer to class_or_union.
integral_type::modifiers_type operator~(integral_type::modifiers_type l)
Bitwise one's complement operator for integral_type::modifiers_type.
unordered_set< const function_type * > fn_set_type
A convenience typedef for a set of pointer to function_type.
comparison_result
The result of structural comparison of type ABI artifacts.
void canonicalize_types(const input_iterator &begin, const input_iterator &end, deref_lambda deref)
Compute the canonical type for all the IR types of the system.
weak_ptr< corpus > corpus_wptr
Convenience typedef for a weak pointer to a corpus.
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
bool parse_integral_type(const string &type_name, integral_type &type)
Parse an integral type from a string.
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
unordered_set< uintptr_t > pointer_set
A convenience typedef for an unordered set of pointer values.
unordered_set< uint64_t_pair_type, uint64_t_pair_hash > uint64_t_pairs_set_type
A convenience typedef for a set of uint64_t_pair.
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
std::pair< uint64_t, uint64_t > uint64_t_pair_type
A convenience typedef for a pair of uint64_t which is initially intended to store a pair of pointer v...
Toplevel namespace for libabigail.
bool comparison_started(const class_or_union &first, const class_or_union &second) const
Test if a pair of class_or_union is being currently compared.
bool comparison_started(const class_or_union *first, const class_or_union *second) const
Test if a pair of class_or_union is being currently compared.
void mark_as_being_compared(const class_or_union_sptr &first, const class_or_union_sptr &second) const
Mark a pair of classes or unions as being currently compared using the class_or_union== operator.
void mark_as_being_compared(const class_or_union &first, const class_or_union &second) const
Mark a pair of classes or unions as being currently compared using the class_or_union== operator.
void mark_as_being_compared(const class_or_union *first, const class_or_union *second) const
Mark a pair of classes or unions as being currently compared using the class_or_union== operator.
void unmark_as_being_compared(const class_or_union *first, const class_or_union *second) const
If a pair of class_or_union has been previously marked as being compared – via an invocation of mark_...
void unmark_as_being_compared(const class_or_union &first, const class_or_union &second) const
If a pair of class_or_union has been previously marked as being compared – via an invocation of mark_...
The private data of the environment type.
void confirm_ct_propagation()
Mark all the types that have been the target of canonical type propagation and that are not yet confi...
bool is_type_comparison_cached(T &first, T &second, bool &r)
Retrieve the result of comparing two sub-types from the cache, if it was previously stored.
bool collect_types_that_depends_on(const type_base *target, const pointer_set &types, pointer_set &collected)
Collect the types that depends on a given "target" type.
void confirm_ct_propagation_for_types_dependant_on(const type_base *dependant_type)
Mark a set of types that have been the target of canonical type propagation and that depend on a recu...
void set_is_not_recursive(const type_base *t)
Unflag a type as being recursive.
void clear_type_comparison_results_cache()
Clear the cache type comparison results.
void push_composite_type_comparison_operands(const type_base *left, const type_base *right)
Push a pair of operands on the stack of operands of the current type comparison, during type canonica...
void remove_from_types_with_non_confirmed_propagated_ct(const type_base *dependant)
Remove a given type from the set of types that have been non-confirmed subjects of the canonical type...
void confirm_ct_propagation(const type_base *t)
Mark a type that has been the target of canonical type propagation as being permanently canonicalized...
void add_to_types_with_non_confirmed_propagated_ct(const type_base *t)
Add a given type to the set of types that have been non-confirmed subjects of the canonical type prop...
bool mark_dependant_types_compared_until(const type_base *right)
In the stack of the current types being compared (as part of type canonicalization),...
void cancel_all_non_confirmed_propagated_canonical_types()
Cancel the propagated canonical types of all the types which propagated canonical type have not yet b...
void cancel_ct_propagation_for_types_dependant_on(const type_base *target)
Reset the canonical type (set it nullptr) of a set of types that have been the target of canonical ty...
void clear_propagated_canonical_type(const type_base *t)
Clear the propagated canonical type of a given type.
void pop_composite_type_comparison_operands(const type_base *left, const type_base *right)
Pop a pair of operands from the stack of operands to the current type comparison.
void allow_type_comparison_results_caching(bool f)
Allow caching of the sub-types comparison results during the invocation of the equal overloads for cl...
bool allow_type_comparison_results_caching() const
Check whether if caching of the sub-types comparison results during the invocation of the equal overl...
bool mark_dependant_types(const type_base *type, vector< const type_base * > &types)
Mark all the types that comes after a certain one as NOT being eligible for the canonical type propag...
bool propagate_ct(const type_base &src, const type_base &dest)
Propagate the canonical type of a type to another one.
void cache_type_comparison_result(T &first, T &second, bool r)
Cache the result of comparing two sub-types.
void cancel_ct_propagation(const type_base *t)
Reset the canonical type (set it nullptr) of a type that has been the target of canonical type propag...
bool is_recursive_type(const type_base *t)
Test if a type is a recursive one.
The type of the private data of the function_type type.
void mark_as_being_compared(const function_type &first, const function_type &second) const
Mark a given pair of function_type as being compared.
bool comparison_started(const function_type &first, const function_type &second) const
Tests if a function_type is currently being compared.
void unmark_as_being_compared(const function_type &first, const function_type &second) const
Mark a given pair of function_type as being compared.
Private type to hold private members of translation_unit.
Definition of the private data of type_base.
void set_does_not_depend_on_recursive_type(const type_base *t)
Unset the flag that tells if the current type depends on a given recursive type.
void set_propagated_canonical_type_confirmed(bool f)
Setter of the property propagated-canonical-type-confirmed.
void set_does_not_depend_on_recursive_type()
Flag the current type as not being dependant on any recursive type.
bool depends_on_recursive_type(const type_base *dependant) const
Test if the current type depends on a given recursive type.
bool propagated_canonical_type_confirmed() const
Getter of the property propagated-canonical-type-confirmed.
void set_depends_on_recursive_type(const type_base *t)
Set the flag that tells if the current type depends on a given recursive type.
bool canonical_type_propagated()
Test if the type carries a canonical type that is the result of maybe_propagate_canonical_type(),...
bool clear_propagated_canonical_type()
If the current canonical type was set as the result of the "canonical type propagation optimization",...
void set_canonical_type_propagated(bool f)
Set the flag that says if the type carries a canonical type that is the result of maybe_propagate_can...
bool depends_on_recursive_type() const
Test if the current type depends on recursive type comparison.
The hashing functor for a pair of uint64_t.
uint64_t operator()(const std::pair< uint64_t, uint64_t > &p) const
Hashing function for a pair of uint64_t.