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_;
400 class_set_type left_classes_being_compared_;
401 class_set_type right_classes_being_compared_;
406 fn_set_type left_fn_types_being_compared_;
407 fn_set_type right_fn_types_being_compared_;
411 type_comparison_result_type type_comparison_results_cache_;
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);
956 #endif //WITH_DEBUG_CT_PROPAGATION
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());
1323 template<
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();
1354 #endif // WITH_DEBUG_CT_PROPAGATION
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));
1615 #endif // __ABG_IR_PRIV_H__
bool is_recursive_type(const type_base *t)
Test if a type is a recursive one.
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...
string to_string(bool internal=false) const
Return the string representation of the current instance of integral_type.
The type of the private data of the function_type type.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
void set_is_not_recursive(const type_base *t)
Unflag a type as being recursive.
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...
friend bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
integral_type()
Default constructor of the integral_type.
bool propagated_canonical_type_confirmed() const
Getter of the property propagated-canonical-type-confirmed.
bool propagate_ct(const type_base &src, const type_base &dest)
Propagate the canonical type of a type to another one.
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...
The internal representation of an integral type.
comparison_result
The result of structural comparison of type ABI artifacts.
An abstraction helper for type declarations.
The "long long" modifier.
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...
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition of the private data of type_base.
weak_ptr< typedef_decl > typedef_decl_wptr
Convenience typedef for a weak pointer on a typedef_decl.
unordered_set< const function_type * > fn_set_type
A convenience typedef for a set of pointer to function_type.
base_type
The possible base types of integral types. We might have forgotten many of these, so do not hesitate ...
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.
shared_ptr< scope_decl > global_scope_sptr
Convenience typedef for a shared pointer on a global_scope.
base_type get_base_type() const
Getter of the base type of the integral_type.
unordered_set< const class_or_union * > class_set_type
A convenience typedef for a set of pointer to class_or_union.
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 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...
unordered_set< uintptr_t > pointer_set
A convenience typedef for an unordered set of pointer values.
void unmark_as_being_compared(const function_type &first, const function_type &second) const
Mark a given pair of function_type as being compared.
The "char32_t" base type.
unordered_map< string, method_decl_sptr > string_mem_fn_sptr_map_type
Convenience typedef.
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_modifiers(modifiers_type)
Setter of the modifiers bitmap of the integral_type.
The private data of the environment type.
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.
Simplified implementation of std::optional just enough to be used as a replacement for our purposes a...
weak_ptr< type_base > type_base_wptr
Convenience typedef for a weak pointer on a type_base.
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
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...
Private type to hold private members of translation_unit.
Toplevel namespace for libabigail.
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
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 mark_as_being_compared(const function_type &first, const function_type &second) const
Mark a given pair of function_type as being compared.
Types of the main internal representation of libabigail.
modifiers_type
The modifiers of the base types above. Several modifiers can be combined for a given base type...
The base type of class_decl and union_decl.
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...
This is a type that aggregates maps of all the kinds of types that are supported by libabigail...
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
vector< method_decl_sptr > member_functions
Convenience typedef.
weak_ptr< corpus > corpus_wptr
Convenience typedef for a weak pointer to a corpus.
The "bool" base type in C++ or "_Bool" in C11.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
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 ...
void cache_type_comparison_result(T &first, T &second, bool r)
Cache the result of comparing two sub-types.
bool canonical_type_propagated()
Test if the type carries a canonical type that is the result of maybe_propagate_canonical_type(), aka, "canonical type propagation optimization".
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...
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
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.
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
bool clear_propagated_canonical_type()
If the current canonical type was set as the result of the "canonical type propagation optimization"...
bool comparison_started(const function_type &first, const function_type &second) const
Tests if a function_type is currently being compared.
modifiers_type get_modifiers() const
Getter of the modifiers bitmap of the integral_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...
language
The language of the translation unit.
bool mark_dependant_types_compared_until(const type_base *right)
In the stack of the current types being compared (as part of type canonicalization), mark all the types that comes after a certain one as NOT being eligible to the canonical type propagation optimization.
uint64_t operator()(const std::pair< uint64_t, uint64_t > &p) const
Hashing function for a pair of uint64_t.
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
integral_type::modifiers_type operator~(integral_type::modifiers_type l)
Bitwise one's complement operator for integral_type::modifiers_type.
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...
bool allow_type_comparison_results_caching() const
Check whether if caching of the sub-types comparison results during the invocation of the equal overl...
unordered_map< string, method_decl * > string_mem_fn_ptr_map_type
Convenience typedef.
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...
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.
The abstraction of an interned string.
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...
void clear_type_comparison_results_cache()
Clear the cache type comparison results.
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...
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...
The interned string pool.
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...
This type abstracts the configuration information of the library.
vector< var_decl_sptr > data_members
Convenience typedef.
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.
void clear_propagated_canonical_type(const type_base *t)
Clear the propagated canonical type of a given type.
void set_does_not_depend_on_recursive_type()
Flag the current type as not being dependant on any recursive type.
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
The hashing functor for a pair of uint64_t.
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...
bool parse_integral_type(const string &type_name, integral_type &type)
Parse an integral type from a string.
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 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. ...
bool depends_on_recursive_type(const type_base *dependant) const
Test if the current type depends on a given recursive type.
bool depends_on_recursive_type() const
Test if the current type depends on recursive type comparison.
void set_propagated_canonical_type_confirmed(bool f)
Setter of the property propagated-canonical-type-confirmed.
bool operator==(const integral_type &) const
Equality operator for the integral_type.
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.
Abstraction of a function type.
The entry point to manage locations.
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...