11 #include "abg-internal.h"
15 ABG_BEGIN_EXPORT_DECLARATIONS
44 char_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';
71 int_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())
196 hash(uint64_t v, uint64_t seed)
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());
243 const uint32_t prime = 0x01000193;
244 const uint32_t offset_basis = 0x811c9dc5;
245 uint32_t
hash = offset_basis;
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);
309 result = d->type_or_decl_base::priv_->is_recursive_artefact();
312 result = t.type_or_decl_base::priv_->is_recursive_artefact();
333 d->type_or_decl_base::priv_->is_recursive_artefact(f);
336 t.priv_->is_recursive_artefact(f);
349 #define MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(type) \
352 if (hashing::get_hashing_state(type) == hashing::HASHING_STARTED_STATE \
353 || hashing::get_hashing_state(type) == hashing::HASHING_SUBTYPE_STATE) \
355 hashing::set_hashing_state(t, hashing::HASHING_CYCLED_TYPE_STATE); \
356 hashing::is_recursive_artefact(type, true); \
359 else if (hashing::get_hashing_state(type) == hashing::HASHING_CYCLED_TYPE_STATE) \
361 else if (hashing::get_hashing_state(type) == hashing::HASHING_FINISHED_STATE) \
362 return peek_hash_value(type); \
366 #define MAYBE_FLAG_TYPE_AS_RECURSIVE(type, underlying, h) \
369 if (!h || hashing::is_recursive_artefact(*underlying)) \
370 hashing::is_recursive_artefact(type, true); \
374 #define MAYBE_RETURN_EARLY_IF_HASH_EXISTS(type) \
377 if (hashing::get_hashing_state(type) == hashing::HASHING_FINISHED_STATE) \
378 return peek_hash_value(type); \
391 type_base::hash::operator()(
const type_base& t)
const
404 type_base::hash::operator()(
const type_base* t)
const
405 {
return operator()(*t);}
413 type_base::hash::operator()(
const type_base_sptr t)
const
414 {
return operator()(*t);}
422 decl_base::hash::operator()(
const decl_base& d)
const
447 decl_base::hash::operator()(
const decl_base* d)
const
451 return operator()(*d);
460 type_decl::hash::operator()(
const type_decl& t)
const
462 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
485 type_decl::hash::operator()(
const type_decl* t)
const
489 return operator()(*t);
498 typedef_decl::hash::operator()(
const typedef_decl& t)
const
500 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
509 hash_t v = u->hash_value();
511 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, u, v);
524 typedef_decl::hash::operator()(
const typedef_decl* t)
const
528 return operator()(*t);
539 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
549 hash_t v = u->hash_value();
551 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, u, v);
571 return operator()(*t);
582 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
592 hash_t v = u->hash_value();
594 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, u, v);
613 return operator()(*t);
624 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
634 hash_t v = u->hash_value();
636 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, u, v);
656 return operator()(*t);
688 return operator()(*s);
699 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
706 hash_t v = hash_as_type_base(t), h = 0;
709 for (vector<array_type_def::subrange_sptr >::const_iterator i =
716 h = (*i)->hash_value();
718 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, *i, h);
727 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, e, h);
745 return operator()(*t);
756 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
763 hash_t v = hash_as_type_base(t);
768 hash_t h = e->hash_value();
770 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, e, h);
796 return operator()(*t);
806 {
return operator()(t.get());}
816 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
823 hash_t v = e->hash_value();
825 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, e, v);
834 hash_t v = hash_as_type(t);
840 hash_t h = u->hash_value();
842 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, u, h);
845 for (enum_type_decl::enumerators::const_iterator i =
869 return operator()(*t);
878 function_type::hash::operator()(
const function_type& t)
const
880 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
886 hash_t v = hash_as_type_base(t), h = 0;
892 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, r, h);
899 type_base_sptr parm_type = (*parm)->get_type();
902 h = parm_type->hash_value();
904 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, parm_type, h);
919 function_type::hash::operator()(
const function_type* t)
const
923 return operator()(*t);
933 {
return operator()(t.get());}
941 method_type::hash::operator()(
const method_type& t)
const
943 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
949 hash_t v = hash_as_type_base(t), h = 0;
963 type_base_sptr ty = parm->get_type();
966 h = ty->hash_value();
968 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, ty, h);
983 method_type::hash::operator()(
const method_type* t)
const
984 {
return operator()(*t);}
993 {
return operator()(t.get());}
1012 class_decl::base_spec::hash::operator()(
const base_spec& t)
const
1014 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
1020 hash_t v = hash_member(t), h = 0;;
1023 type_base_sptr b = t.get_base_class();
1026 h = b->hash_value();
1028 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, t.get_base_class(), h);
1042 class_decl::base_spec::hash::operator()(
const base_spec* t)
const
1046 return operator()(*t);
1065 hash_t v = cou->hash_value();
1074 hash_t v = hash_as_type_base(t);
1083 ty = (*d)->get_type();
1086 hash_t h = ty->hash_value();
1088 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, ty, h);
1103 {
return t ? operator()(*t) : 0;}
1111 class_decl::hash::operator()(
const class_decl& t)
const
1113 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
1123 hash_t v = c->hash_value();
1125 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, c, v);
1133 hash_t v = hash_as_class_or_union(t);
1142 hash_t h = (*b)->hash_value();
1144 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, *b, h);
1171 const_cast<class_decl&
>(t).sort_virtual_mem_fns();
1178 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, method_type, h);
1194 class_decl::hash::operator()(
const class_decl* t)
const
1195 {
return t ? operator()(*t) : 0;}
1203 union_decl::hash::operator()(
const union_decl& t)
const
1205 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
1215 hash_t v = u->hash_value();
1217 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, u, v);
1225 hash_t v = hash_as_class_or_union(t);
1238 union_decl::hash::operator()(
const union_decl*t)
const
1242 return operator()(*t);
The abstraction of an array type.
The base type of all declarations.
Hashing started but is not yet finished.
hash_t operator()(const member_base &m) const
Hashing function for a member_base IR node.
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
hash_t do_hash_value(const T &tod)
Compute the hash value of an IR node and return it.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
An abstraction helper for type declarations.
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
The base class of both types and declarations.
Hasher for the class_or_union type.
Abstracts a reference type.
The abstraction of a qualified type.
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
hashing::hashing_state get_hashing_state(const type_or_decl_base &tod)
Get the hashing state of an IR node.
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Abstracts the type of a class member function.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
const type_base_sptr & get_containing_type() const
Getter of the type containing the member pointed-to by the current ptr_to_mbr_type.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
Abstracts a class declaration.
virtual const interned_string & get_name() const
Getter for the name of the current decl.
type_base_sptr get_underlying_type() const
Getter of the underlying type.
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
hash_t combine_hashes(hash_t val1, hash_t val2)
Combine two hash values to produce a third hash value.
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
bool is_recursive_artefact(const type_or_decl_base &t)
Test if an artifact is recursive.
const data_members & get_non_static_data_members() const
Get the non-static data members of this class_or_union.
Abstracts a declaration for an enum type.
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
Toplevel namespace for libabigail.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
No hashing has been done/started.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
uint32_t fnv_hash(const std::string &str)
Compute a stable string hash.
Abstracts a union type declaration.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
virtual size_t get_size_in_bits() const
Getter for the size of the type.
The abstraction of a pointer-to-member type.
This contains the private implementation of the suppression engine of libabigail. ...
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.
Types of the main internal representation of libabigail.
The base type of class_decl and union_decl.
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...
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
decl_base_sptr look_through_decl_only(const decl_base &d)
If a decl is decl-only get its definition. Otherwise, just return nil.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
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 ...
Hash functor for instances of type_base.
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
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...
The abstraction of a pointer type.
A basic type declaration that introduces no scope.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Hashing a sub-type while hashing another type.
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
const enumerators & get_enumerators() const
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
bool get_is_anonymous() const
Test if the current declaration is anonymous.
Abstraction for an array range type, like in Ada, or just for an array dimension like in C or C++...
The hashing functor for member_base.
The abstraction of a typedef declaration.
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
void set_hashing_state(const type_or_decl_base &tod, hashing::hashing_state s)
Set the hashing state of an IR node.
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
The namespace of the internal representation of ABI artifacts like types and decls.
hashing_state
Enumeration of the different hashing states of an IR node being hashed.
const decl_base_sptr get_definition_of_declaration() const
If this decl_base is declaration-only, get its definition, if any.
Abstraction of a function type.
hash_t hash(uint64_t v, uint64_t seed)
Hash an integer value and combine it with a hash previously computed.
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.