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 void_pointer_type_;
395 type_base_sptr variadic_marker_type_;
412 vector<type_base_sptr> extra_live_types_;
455 vector<const type_base*> left_type_comp_operands_;
456 vector<const type_base*> right_type_comp_operands_;
462 pointer_set types_with_non_confirmed_propagated_ct_;
464#ifdef WITH_DEBUG_CT_PROPAGATION
470 mutable pointer_set types_with_cleared_propagated_ct_;
472#ifdef WITH_DEBUG_SELF_COMPARISON
487 unordered_map<string, uintptr_t> type_id_canonical_type_map_;
490 unordered_map<uintptr_t, string> pointer_type_id_map_;
492 bool canonicalization_is_done_;
493 bool do_on_the_fly_canonicalization_;
494 bool decl_only_class_equals_definition_;
495 bool use_enum_binary_only_equality_;
496 bool allow_type_comparison_results_caching_;
499#ifdef WITH_DEBUG_SELF_COMPARISON
500 bool self_comparison_debug_on_;
502#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
507 bool use_canonical_type_comparison_;
515 bool debug_type_canonicalization_;
516 bool debug_die_canonicalization_;
520 : canonicalization_is_done_(),
521 do_on_the_fly_canonicalization_(
true),
522 decl_only_class_equals_definition_(
false),
523 use_enum_binary_only_equality_(
true),
524 allow_type_comparison_results_caching_(
false),
526#ifdef WITH_DEBUG_SELF_COMPARISON
528 self_comparison_debug_on_(
false)
530#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
532 use_canonical_type_comparison_(
true),
533 debug_type_canonicalization_(
false),
534 debug_die_canonicalization_(
false)
545 {allow_type_comparison_results_caching_ = f;}
556 {
return allow_type_comparison_results_caching_;}
586 && !
is_type(&first)->priv_->depends_on_recursive_type()
587 && !
is_type(&second)->priv_->depends_on_recursive_type())))
589 type_comparison_results_cache_.emplace
590 (std::make_pair(
reinterpret_cast<uint64_t
>(&first),
591 reinterpret_cast<uint64_t
>(&second)),
622 type_comparison_result_type::const_iterator it =
623 type_comparison_results_cache_.find
624 (std::make_pair(
reinterpret_cast<uint64_t
>(&first),
625 reinterpret_cast<uint64_t
>(&second)));
626 if (it == type_comparison_results_cache_.end())
636 {type_comparison_results_cache_.clear();}
653 left_type_comp_operands_.push_back(left);
654 right_type_comp_operands_.push_back(right);
674 const type_base *t = left_type_comp_operands_.back();
676 t = right_type_comp_operands_.back();
679 left_type_comp_operands_.pop_back();
680 right_type_comp_operands_.pop_back();
697 vector<const type_base*>& types)
703 && (
reinterpret_cast<uintptr_t
>(t)
704 ==
reinterpret_cast<uintptr_t
>(type)))
710 t->priv_->set_depends_on_recursive_type(type);
777 right_type_comp_operands_);
778 recursive_types_.insert(
reinterpret_cast<uintptr_t
>(right));
790 return (recursive_types_.find(
reinterpret_cast<uintptr_t
>(t))
791 != recursive_types_.end());
800 {recursive_types_.erase(
reinterpret_cast<uintptr_t
>(t));}
815 dest.priv_->canonical_type = canonical;
816 dest.priv_->naked_canonical_type = canonical.get();
818#ifdef WITH_DEBUG_CT_PROPAGATION
821 erase_type_with_cleared_propagated_canonical_type(&dest);
838 for (
auto i : types_with_non_confirmed_propagated_ct_)
846#ifdef WITH_DEBUG_SELF_COMPARISON
847 check_abixml_canonical_type_propagation_during_self_comp(t);
852 for (
auto i : to_remove)
853 types_with_non_confirmed_propagated_ct_.erase(i);
875 env.priv_->confirm_ct_propagation_for_types_dependant_on(t);
877 env.priv_->remove_from_types_with_non_confirmed_propagated_ct(t);
878 env.priv_->set_is_not_recursive(t);
880#ifdef WITH_DEBUG_SELF_COMPARISON
881 check_abixml_canonical_type_propagation_during_self_comp(t);
896 for (
auto i : types_with_non_confirmed_propagated_ct_)
901#ifdef WITH_DEBUG_SELF_COMPARISON
902 check_abixml_canonical_type_propagation_during_self_comp(t);
905 types_with_non_confirmed_propagated_ct_.clear();
908#ifdef WITH_DEBUG_CT_PROPAGATION
918 types_with_cleared_propagated_ct()
const
919 {
return types_with_cleared_propagated_ct_;}
930 types_with_cleared_propagated_ct()
931 {
return types_with_cleared_propagated_ct_;}
938 record_type_with_cleared_propagated_canonical_type(
const type_base* t)
940 uintptr_t ptr =
reinterpret_cast<uintptr_t
>(t);
941 types_with_cleared_propagated_ct_.insert(ptr);
951 erase_type_with_cleared_propagated_canonical_type(
const type_base* t)
953 uintptr_t ptr =
reinterpret_cast<uintptr_t
>(t);
954 types_with_cleared_propagated_ct_.erase(ptr);
976 for (
const auto i : types)
980 if (collected.find(i) != collected.end())
1014 types_with_non_confirmed_propagated_ct_,
1017 for (
auto i : to_remove)
1022 type_base_sptr canonical = t->priv_->canonical_type.lock();
1030 for (
auto i : to_remove)
1031 types_with_non_confirmed_propagated_ct_.erase(i);
1058 env.priv_->cancel_ct_propagation_for_types_dependant_on(t);
1065 env.priv_->remove_from_types_with_non_confirmed_propagated_ct(t);
1066 env.priv_->clear_type_comparison_results_cache();
1084#ifdef WITH_DEBUG_CT_PROPAGATION
1087 record_type_with_cleared_propagated_canonical_type(t)
1101 uintptr_t v =
reinterpret_cast<uintptr_t
>(t);
1102 types_with_non_confirmed_propagated_ct_.insert(v);
1113 uintptr_t i =
reinterpret_cast<uintptr_t
>(dependant);
1114 types_with_non_confirmed_propagated_ct_.erase(i);
1122 vector<uintptr_t> to_erase;
1123 for (
auto i : types_with_non_confirmed_propagated_ct_)
1124 to_erase.push_back(i);
1126 for (
auto i : to_erase)
1133#ifdef WITH_DEBUG_SELF_COMPARISON
1135 const unordered_map<string, uintptr_t>&
1136 get_type_id_canonical_type_map()
const
1137 {
return type_id_canonical_type_map_;}
1139 unordered_map<string, uintptr_t>&
1140 get_type_id_canonical_type_map()
1141 {
return type_id_canonical_type_map_;}
1143 const unordered_map<uintptr_t, string>&
1144 get_pointer_type_id_map()
const
1145 {
return pointer_type_id_map_;}
1147 unordered_map<uintptr_t, string>&
1148 get_pointer_type_id_map()
1149 {
return pointer_type_id_map_;}
1152 get_type_id_from_pointer(uintptr_t ptr)
const
1154 auto it = get_pointer_type_id_map().find(ptr);
1155 if (it != get_pointer_type_id_map().end())
1161 get_type_id_from_type(
const type_base *t)
const
1162 {
return get_type_id_from_pointer(
reinterpret_cast<uintptr_t
>(t));}
1165 get_canonical_type_from_type_id(
const char* type_id)
const
1169 auto it = get_type_id_canonical_type_map().find(type_id);
1170 if (it != get_type_id_canonical_type_map().end())
1188 check_canonical_type_from_abixml_during_self_comp(
const type_base* t,
1191 if (!t || !t->get_corpus() || !c)
1194 if (!(t->get_corpus()->get_origin() == ir::corpus::NATIVE_XML_ORIGIN))
1200 unordered_map<uintptr_t, string>::const_iterator it =
1201 pointer_type_id_map_.find(
reinterpret_cast<uintptr_t
>(t));
1202 if (it == pointer_type_id_map_.end())
1206 type_id = it->second;
1211 type_base *original_canonical_type =
nullptr;
1212 if (!type_id.empty())
1214 unordered_map<string, uintptr_t>::const_iterator it =
1215 type_id_canonical_type_map_.find(type_id);
1216 if (it == type_id_canonical_type_map_.end())
1218 original_canonical_type =
reinterpret_cast<type_base*
>(it->second);
1227 if (original_canonical_type == c)
1243 check_abixml_canonical_type_propagation_during_self_comp(
const type_base* t)
1246 && t->get_corpus()->get_origin() == ir::corpus::NATIVE_XML_ORIGIN)
1248 type_base* c = t->get_naked_canonical_type();
1249 if (c && !check_canonical_type_from_abixml_during_self_comp(t, c))
1251 string repr = t->get_pretty_representation(
true,
true);
1252 string type_id = get_type_id_from_type(t);
1253 std::cerr <<
"error: canonical type propagation error for '"
1255 <<
"' of type-id: '"
1262 <<
", should have had canonical type: "
1264 << get_canonical_type_from_type_id(type_id.c_str())
1284 check_canonical_type_from_abixml_during_self_comp(
const type_base_sptr& t,
1285 const type_base_sptr& c)
1287 return check_canonical_type_from_abixml_during_self_comp(t.get(), c.get());
1323template<
typename input_iterator,
1324 typename deref_lambda>
1327 const input_iterator& end,
1336 for (t = begin,i = 0; t != end; ++t, ++i)
1338 if (deref(t)->get_environment().priv_->do_log())
1339 std::cerr <<
"#" << std::dec << i <<
" ";
1344#ifdef WITH_DEBUG_CT_PROPAGATION
1349 const environment& env = deref(begin)->get_environment();
1351 env.priv_->types_with_cleared_propagated_ct();
1369 member_function_templates member_function_templates_;
1370 member_class_templates member_class_templates_;
1377 : data_members_(data_mbrs),
1378 member_functions_(mbr_fns)
1380 for (data_members::const_iterator i = data_members_.begin();
1381 i != data_members_.end();
1384 non_static_data_members_.push_back(*i);
1407 env.priv_->left_classes_being_compared_.insert(&first);
1408 env.priv_->right_classes_being_compared_.insert(&second);
1446 const class_or_union_sptr& second)
const
1469 env.priv_->left_classes_being_compared_.erase(&first);
1470 env.priv_->right_classes_being_compared_.erase(&second);
1491 if (!first || !second)
1510 return (env.priv_->left_classes_being_compared_.count(&first)
1511 || env.priv_->right_classes_being_compared_.count(&second)
1512 || env.priv_->right_classes_being_compared_.count(&first)
1513 || env.priv_->left_classes_being_compared_.count(&second));
1528 if (first && second)
1549 type_base_sptr return_type)
1551 return_type_(return_type)
1554 priv(type_base_sptr return_type)
1555 : return_type_(return_type)
1571 env.priv_->left_fn_types_being_compared_.insert(&first);
1572 env.priv_->right_fn_types_being_compared_.insert(&second);
1588 env.priv_->left_fn_types_being_compared_.erase(&first);
1589 env.priv_->right_fn_types_being_compared_.erase(&second);
1603 return (env.priv_->left_fn_types_being_compared_.count(&first)
1605 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.