11#include "abg-internal.h"
15ABG_BEGIN_EXPORT_DECLARATIONS
20ABG_END_EXPORT_DECLARATIONS
44char_to_int(
char c,
unsigned char& integer)
46 if (c >=
'0' && c <=
'9')
48 else if (c >=
'a' && c <=
'z')
49 integer = 10 + c -
'a';
50 else if (c >=
'A' && c <=
'Z')
51 integer = 10 + c -
'A';
71int_to_char(
unsigned char integer,
unsigned char& c)
75 else if (integer >= 0xA && integer <= 0xF)
76 c =
'a' + (integer - 0xA);
101 unsigned char byte = 0;
102 string xxh64_canonical_form;
103 for (
size_t i = 0; i + 1 < input.size(); i += 2)
105 unsigned char first_nibble = 0, second_nibble = 0;
106 ABG_ASSERT(char_to_int(input[i], first_nibble));
107 ABG_ASSERT(char_to_int(input[i+1], second_nibble));
108 byte = (first_nibble << 4) | second_nibble;
109 xxh64_canonical_form.push_back(
byte);
112 XXH64_canonical_t canonical_hash = {};
113 size_t size =
sizeof(canonical_hash.digest);
114 memcpy(canonical_hash.digest,
115 xxh64_canonical_form.c_str(),
117 hash = XXH64_hashFromCanonical(&canonical_hash);
140 XXH64_canonical_t canonical_output = {};
141 XXH64_canonicalFromHash(&canonical_output,
hash);
142 for (
unsigned i = 0; i <
sizeof(canonical_output.digest); ++i)
144 unsigned char first_nibble = 0, second_nibble = 0;
145 unsigned char byte = canonical_output.digest[i];
146 first_nibble = (0xf0 & byte) >> 4;
147 second_nibble = 0xf & byte;
149 int_to_char(first_nibble, c);
151 int_to_char(second_nibble, c);
175 if (val1.has_value() && val2.has_value())
176 result =
hash(*val2, *val1);
177 else if (val1.has_value())
179 else if (val2.has_value())
201 unsigned char data[
sizeof(uint64_t)] = {};
203 size_t data_size =
sizeof(data);
204 for (
unsigned i = 0; i < data_size; ++i)
206 data[data_size - i - 1] = t & 0xff;
209 hash_t h = XXH3_64bits_withSeed(data, data_size, seed);
221 hash_t h = XXH3_64bits(str.c_str(), str.size());
244 const uint32_t offset_basis = 0x811c9dc5;
246 for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
267 return d->type_or_decl_base::priv_->get_hashing_state();
270 return tod.priv_->get_hashing_state();
287 d->type_or_decl_base::priv_->set_hashing_state(s);
290 tod.priv_->set_hashing_state(s);
396#define MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(type) \
399 if (hashing::get_hashing_state(type) == hashing::HASHING_FINISHED_STATE) \
400 return peek_hash_value(type); \
401 else if (hashing::get_hashing_state(type) & hashing::HASHING_CYCLED_TYPE_STATE) \
423 std::unordered_set<uint32_t> native_offsets,
428 if (native_offsets.find(*o) != native_offsets.end())
430 std::cerr <<
"hash of '"
431 << artifact.get_pretty_representation()
464 hash_t h = hash_as_type(t);
484hash_as_basic_type(
const type_base_sptr t)
488 return hash_as_basic_type(*t);
498hash_as_ptr_ref_or_typedef_type(
const type_base* t)
506 h = hash_pointer(*p);
508 h = hash_reference(*r);
510 h = hash_typedef(*ty);
522hash_as_basic_then_ptr_ref_or_typedef_type(
const type_base* t)
524 hash_t h = hash_as_basic_type(*t);
536hash_as_basic_then_ptr_ref_or_typedef_type(
const type_base_sptr t)
537{
return hash_as_basic_then_ptr_ref_or_typedef_type(t.get());}
562{
return operator()(*t);}
571{
return operator()(*t);}
607 return operator()(*d);
618 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
645 return operator()(*t);
656 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
662 hash_t h = hash_as_basic_then_ptr_ref_or_typedef_type(
is_type(u));
679 return operator()(*t);
690 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
719 return operator()(*t);
731 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
738 hash_t v = type_base_hash(t);
760 return operator()(*t);
771 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
775 hash_t v = hash_as_basic_type(t);
795 return operator()(*t);
827 return operator()(*s);
838 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
845 hash_t v = hash_as_type_base(t), h = 0;
848 for (vector<array_type_def::subrange_sptr >::const_iterator i =
854 h = hash_as_type_base(*type);
882 return operator()(*t);
893 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
900 hash_t v = hash_as_type_base(t);
904 hash_t h = hash_as_basic_then_ptr_ref_or_typedef_type(e);
909 h = hash_as_basic_then_ptr_ref_or_typedef_type(e);
927 return operator()(*t);
937{
return operator()(t.get());}
947 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
953 hash_t v = hash_as_basic_then_ptr_ref_or_typedef_type(e);
962 hash_t v = hash_as_type(t);
967 hash_t h = hash_as_basic_then_ptr_ref_or_typedef_type(u);
970 for (enum_type_decl::enumerators::const_iterator i =
994 return operator()(*t);
1005 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
1009 hash_t h = hash_as_basic_type(t);
1018 (h, hash_as_basic_then_ptr_ref_or_typedef_type(type));
1036 return operator()(*t);
1046{
return operator()(t.get());}
1056 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
1060 hash_t v = hash_as_basic_type(t);
1079 (v, hash_as_basic_then_ptr_ref_or_typedef_type(ty));
1094{
return operator()(*t);}
1103{
return operator()(t.get());}
1124 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
1130 hash_t v = hash_member(t), h = 0;;
1135 h = hash_as_basic_then_ptr_ref_or_typedef_type(b);
1153 return operator()(*t);
1170 hash_t v = operator()(*cou);
1177 hash_t v = hash_as_type_base(t);
1187 hash_t h = hash_as_basic_type(ty);
1202{
return t ? operator()(*t) : 0;}
1212 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
1220 hash_t v = operator()(*c);
1229 hash_t v = hash_as_class_or_union(t);
1235 h = hash_as_basic_then_ptr_ref_or_typedef_type(b->get_base_class());
1265 const_cast<class_decl&
>(t).sort_virtual_mem_fns();
1295{
return t ? operator()(*t) : 0;}
1303union_decl::hash::operator()(
const union_decl& t)
const
1305 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
1313 hash_t v = operator()(*u);
1322 hash_t v = hash_as_class_or_union(t);
1335union_decl::hash::operator()(
const union_decl*t)
const
1339 return operator()(*t);
#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.
Types of the main internal representation of libabigail.
Abstraction for an array range type, like in Ada, or just for an array dimension like in C or C++.
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
The abstraction of an array type.
const type_base_sptr get_element_type() const
Getter of the type of an array element.
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Abstraction of a base specifier in a class declaration.
class_decl_sptr get_base_class() const
Get the base class referred to by the current base class specifier.
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
long get_offset_in_bits() const
Getter of the offset of the base.
Abstracts a class declaration.
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
The base type of class_decl and union_decl.
const data_members & get_non_static_data_members() const
Get the non-static data members of this class_or_union.
The base type of all declarations.
virtual const interned_string & get_name() const
Getter for the name of the current decl.
const decl_base_sptr get_definition_of_declaration() const
If this decl_base is declaration-only, get its definition, if any.
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
const interned_string & get_linkage_name() const
Getter for the mangled name.
Abstracts a declaration for an enum type.
const enumerators & get_enumerators() const
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Abstraction of a function type.
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Abstracts the type of a class member function.
bool get_is_const() const
Getter of the "is-const" property of method_type.
The abstraction of a pointer type.
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
The abstraction of a pointer-to-member type.
const type_base_sptr & get_containing_type() const
Getter of the type containing the member pointed-to by the current ptr_to_mbr_type.
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
The abstraction of a qualified type.
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
type_base_sptr get_underlying_type() const
Getter of the underlying type.
Abstracts a reference type.
An abstraction helper for type declarations.
virtual size_t get_size_in_bits() const
Getter for the size of the type.
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
A basic type declaration that introduces no scope.
The base class of both types and declarations.
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current decl.
offset_t get_native_offset() const
Get the native offset of a given artifact.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
The abstraction of a typedef declaration.
Abstracts a union type declaration.
hash_t combine_hashes(hash_t val1, hash_t val2)
Combine two hash values to produce a third hash value.
void add_to_hashing_state(const ir::type_or_decl_base &tod, hashing::hashing_state s)
Add a state to the hashing state of a given IR node.
hashing::hashing_state get_hashing_state(const type_or_decl_base &tod)
Get the hashing state of an IR node.
void set_hashing_state(const type_or_decl_base &tod, hashing::hashing_state s)
Set the hashing state of an IR node.
hash_t hash(uint64_t v, uint64_t seed)
Hash an integer value and combine it with a hash previously computed.
hashing_state
Enumeration of the different hashing states of an IR node being hashed. This is a bitfield.
@ HASHING_STARTED_STATE
Hashing started but is not yet finished.
@ HASHING_FINISHED_STATE
Hashing of the given IR node started, is done and a hash value has been stored onto the node....
@ HASHING_CYCLED_TYPE_STATE
A cycle has been detected in the graph on the current node.
@ HASHING_NOT_DONE_STATE
No hashing has been done/started.
void remove_from_hashing_state(const ir::type_or_decl_base &tod, hashing::hashing_state s)
Remove a state to the hashing state of a given IR node.
bool deserialize_hash(const string &input, uint64_t &hash)
Read a string of characters representing a string of hexadecimal digits which itself represents a has...
bool serialize_hash(uint64_t hash, string &output)
Serialiaze a hash value computed using the XH64 algorithm (from the xxhash project) into a string of ...
uint32_t fnv_hash(const std::string &str)
Compute a stable string hash.
The namespace of the internal representation of ABI artifacts like types and decls.
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
hash_t peek_hash_value(const type_or_decl_base &artefact)
Get the hash value associated to an IR node.
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
type_base * look_through_decl_only_type(type_base *t)
If a type is is decl-only, then get its definition. Otherwise, just return the initial type.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
decl_base_sptr look_through_decl_only(const decl_base &d)
If a decl is decl-only get its definition. Otherwise, just return nil.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
abg_compat::optional< uint64_t > hash_t
The abstraction for an 8 bytes hash value.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
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 * 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.
hash_t get_subtype_hash(const type_or_decl_base *t)
Compute (or get) the hash of a sub-type of the type for which we are currently computing the hash....
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Toplevel namespace for libabigail.
hash_t operator()(const array_type_def &t) const
Hashing function for a array_type_def IR node.
hash_t operator()(const base_spec &t) const
Hashing function for a class_decl::base_spec IR node.
hash_t operator()(const class_decl &t) const
Compute a hash for a class_decl.
Hasher for the class_or_union type.
hash_t operator()(const class_or_union &t) const
Compute a hash for a class_or_union.
hash_t operator()(const decl_base &d) const
Hash function for an instance of decl_base.
hash_t operator()(const enum_type_decl &t) const
Hashing function for a enum_type_decl IR node.
hash_t operator()(const function_type &t) const
Hashing function for function_type.
The hashing functor for member_base.
hash_t operator()(const member_base &m) const
Hashing function for a member_base IR node.
hash_t operator()(const method_type &t) const
Hashing function for a method_type IR node.
Hash functor for instances of pointer_type_def.
hash_t operator()(const pointer_type_def &t) const
Hashing function for a pointer_type_def IR node.
hash_t operator()(const ptr_to_mbr_type &t) const
Hashing function for a ptr_to_mbr_type IR node.
Hash functor for instances of qualified_type_def.
hash_t operator()(const qualified_type_def &t) const
Hashing function for a qualified_type_def IR node.
Hash functor for instances of reference_type_def.
hash_t operator()(const reference_type_def &t) const
Hashing function for a reference_type_def IR node.
Hash functor for instances of type_base.
hash_t operator()(const type_base &t) const
The hashing functor for using instances of type_or_decl_base as values in a hash map or set.
hash_t operator()(const type_decl &t) const
Hashing function for a type_decl IR node.
Hash functor for instances of typedef_decl.
hash_t operator()(const typedef_decl &t) const
Hashing function for a typedef_decl IR node.