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 = XXH64(data, data_size, seed);
221 hash_t h = XXH64(str.c_str(), str.size(), 0);
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);
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) \
354 hashing::set_hashing_state(t, hashing::HASHING_CYCLED_TYPE_STATE); \
355 hashing::is_recursive_artefact(type, true); \
358 else if (hashing::get_hashing_state(type) == hashing::HASHING_CYCLED_TYPE_STATE) \
360 else if (hashing::get_hashing_state(type) == hashing::HASHING_FINISHED_STATE) \
361 return peek_hash_value(type); \
365#define MAYBE_FLAG_TYPE_AS_RECURSIVE(type, underlying, h) \
368 if (!h || hashing::is_recursive_artefact(*underlying)) \
369 hashing::is_recursive_artefact(type, true); \
373#define MAYBE_RETURN_EARLY_IF_HASH_EXISTS(type) \
376 if (hashing::get_hashing_state(type) == hashing::HASHING_FINISHED_STATE) \
377 return peek_hash_value(type); \
404{
return operator()(*t);}
412type_base::hash::operator()(
const type_base_sptr t)
const
413{
return operator()(*t);}
450 return operator()(*d);
461 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
488 return operator()(*t);
499 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
507 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, u, v);
524 return operator()(*t);
535 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
544 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, u, v);
564 return operator()(*t);
575 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
584 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, u, v);
603 return operator()(*t);
614 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
623 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, u, v);
643 return operator()(*t);
675 return operator()(*s);
686 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
693 hash_t v = hash_as_type_base(t), h = 0;
696 for (vector<array_type_def::subrange_sptr >::const_iterator i =
702 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, *i, h);
725 return operator()(*t);
736 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
743 hash_t v = hash_as_type_base(t);
767 return operator()(*t);
777{
return operator()(t.get());}
787 MAYBE_RETURN_EARLY_IF_HASH_EXISTS(t);
801 hash_t v = hash_as_type(t);
808 for (enum_type_decl::enumerators::const_iterator i =
832 return operator()(*t);
843 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
849 hash_t v = hash_as_type_base(t), h = 0;
858 type_base_sptr parm_type = (*parm)->get_type();
860 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, parm_type, h);
879 return operator()(*t);
889{
return operator()(t.get());}
899 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
905 hash_t v = hash_as_type_base(t), h = 0;
916 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, parm->get_type(), h);
932{
return operator()(*t);}
941{
return operator()(t.get());}
960class_decl::base_spec::hash::operator()(
const base_spec& t)
const
962 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
968 hash_t v = hash_member(t), h = 0;;
986class_decl::base_spec::hash::operator()(
const base_spec* t)
const
990 return operator()(*t);
1014 hash_t v = hash_as_type_base(t);
1023 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, (*d)->get_type(), h);
1038{
return t ? operator()(*t) : 0;}
1048 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
1064 hash_t v = hash_as_class_or_union(t);
1072 MAYBE_FLAG_TYPE_AS_RECURSIVE(t, *b, h);
1099 const_cast<class_decl&
>(t).sort_virtual_mem_fns();
1123{
return t ? operator()(*t) : 0;}
1131union_decl::hash::operator()(
const union_decl& t)
const
1133 MAYBE_RETURN_EARLY_FROM_HASHING_TO_AVOID_CYCLES(t);
1149 hash_t v = hash_as_class_or_union(t);
1162union_decl::hash::operator()(
const union_decl*t)
const
1166 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.
The abstraction of an interned string.
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.
bool get_is_anonymous() const
Test if the current declaration is anonymous.
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.
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.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Abstraction of a function type.
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
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.
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.
The abstraction of a typedef declaration.
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
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.
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.
@ HASHING_STARTED_STATE
Hashing started but is not yet finished.
@ HASHING_NOT_DONE_STATE
No hashing has been done/started.
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.
bool is_recursive_artefact(const type_or_decl_base &t)
Test if an artifact is recursive.
The namespace of the internal representation of ABI artifacts like types and decls.
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_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.
decl_base_sptr look_through_decl_only(const decl_base &d)
If a decl is decl-only get its definition. Otherwise, just return nil.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
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.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
hash_t do_hash_value(const T &tod)
Compute the hash value of an IR node and return it.
Toplevel namespace for libabigail.
Hasher for the class_or_union type.
The hashing functor for member_base.
Hash functor for instances of type_base.