libabigail
abg-hash.cc
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2// -*- mode: C++ -*-
3//
4// Copyright (C) 2013-2024 Red Hat, Inc.
5
6/// @file
7
8#include <functional>
9#include "abg-internal.h"
10// <headers defining libabigail's API go under here>
11ABG_BEGIN_EXPORT_DECLARATIONS
12
13#include "abg-hash.h"
14#include "abg-ir.h"
15
16ABG_END_EXPORT_DECLARATIONS
17// </headers defining libabigail's API>
18
19namespace abigail
20{
21
22namespace hashing
23{
24
25// Mix 3 32 bits values reversibly. Borrowed from hashtab.c in gcc tree.
26#define abigail_hash_mix(a, b, c) \
27{ \
28 a -= b; a -= c; a ^= (c>>13); \
29 b -= c; b -= a; b ^= (a<< 8); \
30 c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \
31 a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \
32 b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \
33 c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \
34 a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \
35 b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \
36 c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \
37}
38
39size_t
40combine_hashes(size_t val1, size_t val2)
41{
42 /* the golden ratio; an arbitrary value. */
43 size_t a = 0x9e3779b9;
44 abigail_hash_mix(a, val1, val2);
45 return val2;
46}
47
48/// Compute a stable string hash.
49///
50/// std::hash has no portability or stability guarantees so is
51/// unsuitable where reproducibility is a requirement such as in XML
52/// output.
53///
54/// This is the 32-bit FNV-1a algorithm. The algorithm, reference code
55/// and constants are all unencumbered. It is fast and has reasonable
56/// distribution properties.
57///
58/// https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
59///
60/// @param str the string to hash.
61///
62/// @return an unsigned 32 bit hash value.
64fnv_hash(const std::string& str)
65{
66 const uint32_t prime = 0x01000193;
67 const uint32_t offset_basis = 0x811c9dc5;
68 uint32_t hash = offset_basis;
69 for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
70 {
71 uint8_t byte = *i;
72 hash = hash ^ byte;
73 hash = hash * prime;
74 }
75 return hash;
76}
77
78}//end namespace hashing
79
80using std::list;
81using std::vector;
82
83using namespace abigail::ir;
84
85// See forward declarations in abg-ir.h.
86
87// Definitions.
88
89/// Hash function for an instance of @ref type_base.
90///
91/// @param t the type to hash.
92///
93/// @return the type value.
94size_t
95type_base::hash::operator()(const type_base& t) const
96{
97 std::hash<size_t> size_t_hash;
98 std::hash<string> str_hash;
99
100 size_t v = str_hash(typeid(t).name());
101 v = hashing::combine_hashes(v, size_t_hash(t.get_size_in_bits()));
102 v = hashing::combine_hashes(v, size_t_hash(t.get_alignment_in_bits()));
103
104 return v;
105}
106
107/// Hash function for an instance of @ref type_base.
108///
109/// @param t the type to hash.
110///
111/// @return the type value.
112size_t
113type_base::hash::operator()(const type_base* t) const
114{return operator()(*t);}
115
116/// Hash function for an instance of @ref type_base.
117///
118/// @param t the type to hash.
119///
120/// @return the type value.
121size_t
122type_base::hash::operator()(const type_base_sptr t) const
123{return operator()(*t);}
124
125struct decl_base::hash
126{
127 size_t
128 operator()(const decl_base& d) const
129 {
130 std::hash<string> str_hash;
131
132 size_t v = str_hash(typeid(d).name());
133 if (!d.get_linkage_name().empty())
134 v = hashing::combine_hashes(v, str_hash(d.get_linkage_name()));
135 if (!d.get_name().empty())
136 v = hashing::combine_hashes(v, str_hash(d.get_qualified_name()));
137 if (is_member_decl(d))
138 {
139 v = hashing::combine_hashes(v, get_member_access_specifier(d));
140 v = hashing::combine_hashes(v, get_member_is_static(d));
141 }
142 return v;
143 }
144}; // end struct decl_base::hash
145
146struct type_decl::hash
147{
148 size_t
149 operator()(const type_decl& t) const
150 {
151 decl_base::hash decl_hash;
152 type_base::hash type_hash;
153 std::hash<string> str_hash;
154
155 size_t v = str_hash(typeid(t).name());
156 v = hashing::combine_hashes(v, decl_hash(t));
157 v = hashing::combine_hashes(v, type_hash(t));
158
159 return v;
160 }
161};
162
163/// Hashing operator for the @ref scope_decl type.
164///
165/// @param d the scope_decl to hash.
166///
167/// @return the hash value.
168size_t
169scope_decl::hash::operator()(const scope_decl& d) const
170{
171 std::hash<string> hash_string;
172 size_t v = hash_string(typeid(d).name());
173 for (scope_decl::declarations::const_iterator i =
174 d.get_member_decls().begin();
175 i != d.get_member_decls().end();
176 ++i)
177 v = hashing::combine_hashes(v, (*i)->get_hash());
178
179 return v;
180}
181
182/// Hashing operator for the @ref scope_decl type.
183///
184/// @param d the scope_decl to hash.
185///
186/// @return the hash value.
187size_t
188scope_decl::hash::operator()(const scope_decl* d) const
189{return d? operator()(*d) : 0;}
190
192{
193 size_t
194 operator()(const scope_type_decl& t) const
195 {
196 decl_base::hash decl_hash;
197 type_base::hash type_hash;
198 std::hash<string> str_hash;
199
200 size_t v = str_hash(typeid(t).name());
201 v = hashing::combine_hashes(v, decl_hash(t));
202 v = hashing::combine_hashes(v, type_hash(t));
203
204 return v;
205 }
206};
207
209{
210 size_t
211 operator()(const qualified_type_def& t) const
212 {
213 type_base::hash type_hash;
214 decl_base::hash decl_hash;
215 std::hash<string> str_hash;
216
217 size_t v = str_hash(typeid(t).name());
218 v = hashing::combine_hashes(v, type_hash(t));
219 v = hashing::combine_hashes(v, decl_hash(t));
220 v = hashing::combine_hashes(v, t.get_cv_quals());
221 return v;
222 }
223};
224
226{
227 size_t
228 operator()(const pointer_type_def& t) const
229 {
230 std::hash<string> str_hash;
231 type_base::hash type_base_hash;
232 decl_base::hash decl_hash;
233 type_base::shared_ptr_hash hash_type_ptr;
234
235 size_t v = str_hash(typeid(t).name());
236 v = hashing::combine_hashes(v, decl_hash(t));
237 v = hashing::combine_hashes(v, type_base_hash(t));
238 v = hashing::combine_hashes(v, hash_type_ptr(t.get_pointed_to_type()));
239 return v ;
240 }
241};
242
244{
245 size_t
246 operator()(const reference_type_def& t)
247 {
248 std::hash<string> hash_str;
249 type_base::hash hash_type_base;
250 decl_base::hash hash_decl;
251 type_base::shared_ptr_hash hash_type_ptr;
252
253 size_t v = hash_str(typeid(t).name());
254 v = hashing::combine_hashes(v, hash_str(t.is_lvalue()
255 ? "lvalue"
256 : "rvalue"));
257 v = hashing::combine_hashes(v, hash_type_base(t));
258 v = hashing::combine_hashes(v, hash_decl(t));
259 v = hashing::combine_hashes(v, hash_type_ptr(t.get_pointed_to_type()));
260 return v;
261 }
262};
263
265{
266 size_t
267 operator()(const array_type_def::subrange_type& s) const
268 {
269 std::hash<int> hash_size_t;
270 size_t v = hash_size_t(hash_size_t(s.get_lower_bound()));
271 v = hashing::combine_hashes(v, hash_size_t(s.get_upper_bound()));
272 return v;
273 }
274};
275
277{
278 size_t
279 operator()(const array_type_def& t)
280 {
281 std::hash<string> hash_str;
282 type_base::hash hash_type_base;
283 decl_base::hash hash_decl;
284 type_base::shared_ptr_hash hash_type_ptr;
286
287 size_t v = hash_str(typeid(t).name());
288
289 v = hashing::combine_hashes(v, hash_type_base(t));
290 v = hashing::combine_hashes(v, hash_decl(t));
291 v = hashing::combine_hashes(v, hash_type_ptr(t.get_element_type()));
292
293 for (vector<array_type_def::subrange_sptr >::const_iterator i =
294 t.get_subranges().begin();
295 i != t.get_subranges().end();
296 ++i)
297 v = hashing::combine_hashes(v, hash_subrange(**i));
298
299 return v;
300 }
301};
302
304{
305 size_t
306 operator()(const enum_type_decl& t) const
307 {
308 std::hash<string> str_hash;
309 decl_base::hash decl_hash;
310 type_base::shared_ptr_hash type_ptr_hash;
311 std::hash<size_t> size_t_hash;
312
313 size_t v = str_hash(typeid(t).name());
314 v = hashing::combine_hashes(v, decl_hash(t));
315 v = hashing::combine_hashes(v, type_ptr_hash(t.get_underlying_type()));
316 for (enum_type_decl::enumerators::const_iterator i =
317 t.get_enumerators().begin();
318 i != t.get_enumerators().end();
319 ++i)
320 {
321 v = hashing::combine_hashes(v, str_hash(i->get_name()));
322 v = hashing::combine_hashes(v, size_t_hash(i->get_value()));
323 }
324 return v;
325 }
326};
327
329{
330 size_t
331 operator()(const typedef_decl& t) const
332 {
333 std::hash<string> str_hash;
335 decl_base::hash decl_hash;
336 type_base::shared_ptr_hash type_ptr_hash;
337
338 size_t v = str_hash(typeid(t).name());
339 v = hashing::combine_hashes(v, hash_type(t));
340 v = hashing::combine_hashes(v, decl_hash(t));
341 v = hashing::combine_hashes(v, type_ptr_hash(t.get_underlying_type()));
342 return v;
343 }
344 };
345
346/// Compute a hash for an instance @ref var_decl.
347///
348/// Note that this function caches the hashing value the
349/// decl_base::hash_ data member of the input instance and re-uses it
350/// when it is already calculated.
351///
352/// @param t the instance of @ref var_decl to compute the hash for.
353///
354/// @return the calculated hash value, or the one that was previously
355/// calculated.
356size_t
357var_decl::hash::operator()(const var_decl& t) const
358{
359 std::hash<string> hash_string;
360 decl_base::hash hash_decl;
361 type_base::shared_ptr_hash hash_type_ptr;
362 std::hash<size_t> hash_size_t;
363
364 size_t v = hash_string(typeid(t).name());
365 v = hashing::combine_hashes(v, hash_decl(t));
366 v = hashing::combine_hashes(v, hash_type_ptr(t.get_type()));
367
369 {
370 v = hashing::combine_hashes(v, hash_decl(*t.get_scope()));
371 v = hashing::combine_hashes(v, hash_size_t(get_data_member_offset(t)));
372 }
373
374 return v;
375}
376
377/// Compute a hash for a pointer to @ref var_decl.
378///
379/// @param t the pointer to @ref var_decl to compute the hash for.
380///
381/// @return the calculated hash value
382size_t
383var_decl::hash::operator()(const var_decl* t) const
384{return operator()(*t);}
385
386/// Compute a hash value for an instance of @ref function_decl.
387///
388/// Note that this function caches the resulting hash in the
389/// decl_base::hash_ data member of the instance of @ref
390/// function_decl, and just returns if it is already calculated.
391///
392/// @param t the function to calculate the hash for.
393///
394/// @return the hash value.
395size_t
397{
398 std::hash<int> hash_int;
399 std::hash<size_t> hash_size_t;
400 std::hash<bool> hash_bool;
401 std::hash<string> hash_string;
402 decl_base::hash hash_decl_base;
403 type_base::shared_ptr_hash hash_type_ptr;
404
405 size_t v = hash_string(typeid(t).name());
406 v = hashing::combine_hashes(v, hash_decl_base(t));
407 v = hashing::combine_hashes(v, hash_type_ptr(t.get_type()));
408 v = hashing::combine_hashes(v, hash_bool(t.is_declared_inline()));
409 v = hashing::combine_hashes(v, hash_int(t.get_binding()));
410 if (is_member_function(t))
411 {
412 bool is_ctor = get_member_function_is_ctor(t),
413 is_dtor = get_member_function_is_dtor(t),
414 is_static = get_member_is_static(t),
415 is_const = get_member_function_is_const(t);
416 size_t voffset = get_member_function_vtable_offset(t);
417
418 v = hashing::combine_hashes(v, hash_bool(is_ctor));
419 v = hashing::combine_hashes(v, hash_bool(is_dtor));
420 v = hashing::combine_hashes(v, hash_bool(is_static));
421 v = hashing::combine_hashes(v, hash_bool(is_const));
422 if (!is_static && !is_ctor)
423 v = hashing::combine_hashes(v, hash_size_t(voffset));
424 }
425
426 return v;
427}
428
429/// Compute a hash for a pointer to @ref function_decl.
430///
431/// @param t the pointer to @ref function_decl to compute the hash for.
432///
433/// @return the calculated hash value
434size_t
436{return operator()(*t);}
437
438size_t
439function_decl::parameter::hash::operator()
440 (const function_decl::parameter& p) const
441{
442 type_base::shared_ptr_hash hash_type_ptr;
443 std::hash<bool> hash_bool;
444 std::hash<unsigned> hash_unsigned;
445 size_t v = hash_type_ptr(p.get_type());
446 v = hashing::combine_hashes(v, hash_unsigned(p.get_index()));
447 v = hashing::combine_hashes(v, hash_bool(p.get_variadic_marker()));
448 return v;
449}
450
451size_t
452function_decl::parameter::hash::operator()
453 (const function_decl::parameter* p) const
454{return operator()(*p);}
455
456size_t
457function_decl::parameter::hash::operator()
458 (const function_decl::parameter_sptr p) const
459{return operator()(p.get());}
460
461/// Hashing functor for the @ref method_type type.
463{
464 size_t
465 operator()(const method_type& t) const
466 {
467 std::hash<string> hash_string;
468 type_base::shared_ptr_hash hash_type_ptr;
469 function_decl::parameter::hash hash_parameter;
470
471 size_t v = hash_string(typeid(t).name());
472 string class_name = t.get_class_type()->get_qualified_name();
473 v = hashing::combine_hashes(v, hash_string(class_name));
474 v = hashing::combine_hashes(v, hash_type_ptr(t.get_return_type()));
475 vector<shared_ptr<function_decl::parameter> >::const_iterator i =
477
478 for (; i != t.get_parameters().end(); ++i)
479 v = hashing::combine_hashes(v, hash_parameter(**i));
480
481 return v;
482 }
483
484 size_t
485 operator()(const method_type* t)
486 {return operator()(*t);}
487
488 size_t
489 operator()(const method_type_sptr t)
490 {return operator()(t.get());}
491}; // end struct method_type::hash
492
493// <struct function_type::hash stuff>
494
495/// Hashing function for @ref function_type.
496///
497/// @param t the function type to hash.
498///
499/// @return the resulting hash value.
500size_t
502{
503 std::hash<string> hash_string;
504 type_base::shared_ptr_hash hash_type_ptr;
505 function_decl::parameter::hash hash_parameter;
506
507 size_t v = hash_string(typeid(t).name());
508 v = hashing::combine_hashes(v, hash_type_ptr(t.get_return_type()));
509 for (vector<shared_ptr<function_decl::parameter> >::const_iterator i =
511 i != t.get_parameters().end();
512 ++i)
513 v = hashing::combine_hashes(v, hash_parameter(**i));
514 return v;
515}
516
517/// Hashing function for a pointer to @ref function_type.
518///
519/// @param t the pointer to @ref function_type to hash.
520///
521/// @return the resulting hash value.
522size_t
524{
525 if (const method_type* m = dynamic_cast<const method_type*>(t))
526 {
528 return h(m);
529 }
530 return operator()(*t);
531}
532
533/// Hashing function for a shared pointer to @ref function_type.
534///
535/// @param t the pointer to @ref function_type to hash.
536///
537/// @return the resulting hash value.
538size_t
540{return operator()(t.get());}
541
542// </struct function_type::hash stuff>
543
544size_t
545member_base::hash::operator()(const member_base& m) const
546{
547 std::hash<int> hash_int;
548 return hash_int(m.get_access_specifier());
549}
550
551size_t
552class_decl::base_spec::hash::operator()(const base_spec& t) const
553{
554 member_base::hash hash_member;
555 type_base::shared_ptr_hash hash_type_ptr;
556 std::hash<size_t> hash_size;
557 std::hash<bool> hash_bool;
558 std::hash<string> hash_string;
559
560 size_t v = hash_string(typeid(t).name());
561 v = hashing::combine_hashes(v, hash_member(t));
562 v = hashing::combine_hashes(v, hash_size(t.get_offset_in_bits()));
563 v = hashing::combine_hashes(v, hash_bool(t.get_is_virtual()));
564 v = hashing::combine_hashes(v, hash_type_ptr(t.get_base_class()));
565 return v;
566}
567
568size_t
569member_function_template::hash::operator()
570 (const member_function_template& t) const
571{
572 std::hash<bool> hash_bool;
573 function_tdecl::hash hash_function_tdecl;
574 member_base::hash hash_member;
575 std::hash<string> hash_string;
576
577 size_t v = hash_member(t);
578 string n = t.get_qualified_name();
579 v = hashing::combine_hashes(v, hash_string(n));
580 v = hashing::combine_hashes(v, hash_function_tdecl(t));
581 v = hashing::combine_hashes(v, hash_bool(t.is_constructor()));
582 v = hashing::combine_hashes(v, hash_bool(t.is_const()));
583 return v;
584}
585
586size_t
587member_class_template::hash::operator()
588 (const member_class_template& t) const
589{
590 member_base::hash hash_member;
591 class_tdecl::hash hash_class_tdecl;
592 std::hash<string> hash_string;
593
594 size_t v = hash_member(t);
595 string n = t.get_qualified_name();
596 v = hashing::combine_hashes(v, hash_string(n));
597 v = hashing::combine_hashes(v, hash_class_tdecl(t));
598 return v;
599}
600
601/// Compute a hash for a @ref class_or_union
602///
603/// @param t the class_or_union for which to compute the hash value.
604///
605/// @return the computed hash value.
606size_t
608{
609 if (t.hashing_started()
611 // All non-resolved decl-only types have a hash of zero. Their hash
612 // will differ from the resolved hash, but then at least, having
613 // it be zero will give a hint that we couldn't actually compute
614 // the hash.
615 return 0;
616
617 // If the type is decl-only and now has a definition, then hash its
618 // definition instead.
619
621 {
623 size_t v = operator()
625 return v;
626 }
627
629
630 std::hash<string> hash_string;
631 scope_type_decl::hash hash_scope_type;
632 var_decl::hash hash_data_member;
633 member_function_template::hash hash_member_fn_tmpl;
634 member_class_template::hash hash_member_class_tmpl;
635
636 size_t v = hash_string(typeid(t).name());
637 v = hashing::combine_hashes(v, hash_scope_type(t));
638
639 t.hashing_started(true);
640
641 // Hash data members.
642 for (class_decl::data_members::const_iterator d =
643 t.get_non_static_data_members().begin();
644 d != t.get_non_static_data_members().end();
645 ++d)
646 v = hashing::combine_hashes(v, hash_data_member(**d));
647
648 // Do not hash member functions. All of them are not necessarily
649 // emitted per class, in a given TU so do not consider them when
650 // hashing a class.
651
652 // Hash member function templates
653 for (member_function_templates::const_iterator f =
655 f != t.get_member_function_templates().end();
656 ++f)
657 v = hashing::combine_hashes(v, hash_member_fn_tmpl(**f));
658
659 // Hash member class templates
660 for (member_class_templates::const_iterator c =
661 t.get_member_class_templates().begin();
662 c != t.get_member_class_templates().end();
663 ++c)
664 v = hashing::combine_hashes(v, hash_member_class_tmpl(**c));
665
666 t.hashing_started(false);
667
668 return v;
669};
670
671/// Compute a hash for a @ref class_or_union
672///
673/// @param t the class_or_union for which to compute the hash value.
674///
675/// @return the computed hash value.
676size_t
678{return t ? operator()(*t) : 0;}
679
680/// Compute a hash for a @ref class_decl
681///
682/// @param t the class_decl for which to compute the hash value.
683///
684/// @return the computed hash value.
685size_t
687{
688 if (t.hashing_started()
690 // All non-resolved decl-only types have a hash of zero. Their hash
691 // will differ from the resolved hash, but then at least, having
692 // it be zero will give a hint that we couldn't actually compute
693 // the hash.
694 return 0;
695
696
697 // If the type is decl-only and now has a definition, then hash its
698 // definition instead.
699
701 {
703 size_t v = operator()(*is_class_type(t.get_definition_of_declaration()));
704 return v;
705 }
706
708
709 std::hash<string> hash_string;
711 class_or_union::hash hash_class_or_union;
712
713 size_t v = hash_string(typeid(t).name());
714
715 t.hashing_started(true);
716
717 // Hash bases.
718 for (class_decl::base_specs::const_iterator b =
719 t.get_base_specifiers().begin();
720 b != t.get_base_specifiers().end();
721 ++b)
722 {
723 class_decl_sptr cl = (*b)->get_base_class();
724 v = hashing::combine_hashes(v, hash_base(**b));
725 }
726
727 v = hashing::combine_hashes(v, hash_class_or_union(t));
728
729 t.hashing_started(false);
730
731 return v;
732}
733
734/// Compute a hash for a @ref class_decl
735///
736/// @param t the class_decl for which to compute the hash value.
737///
738/// @return the computed hash value.
739size_t
741{return t ? operator()(*t) : 0;}
742
743struct template_parameter::hash
744{
745 size_t
746 operator()(const template_parameter& t) const
747 {
748 // Let's avoid infinite recursion triggered from the fact that
749 // hashing a template parameter triggers hashing the enclosed
750 // template decl, which in turn triggers the hashing of its
751 // template parameters; so the initial template parameter that
752 // triggered the hashing could be hashed again ...
753 if (t.get_hashing_has_started())
754 return 0;
755
756 t.set_hashing_has_started(true);
757
758 std::hash<unsigned> hash_unsigned;
759 std::hash<std::string> hash_string;
760 template_decl::hash hash_template_decl;
761
762 size_t v = hash_string(typeid(t).name());
763 v = hashing::combine_hashes(v, hash_unsigned(t.get_index()));
764 v = hashing::combine_hashes(v, hash_template_decl
765 (*t.get_enclosing_template_decl()));
766
767 t.set_hashing_has_started(false);
768
769 return v;
770 }
771};
772
773struct template_parameter::dynamic_hash
774{
775 size_t
776 operator()(const template_parameter* t) const;
777};
778
779struct template_parameter::shared_ptr_hash
780{
781 size_t
782 operator()(const shared_ptr<template_parameter> t) const
783 {return template_parameter::dynamic_hash()(t.get());}
784};
785
786size_t
787template_decl::hash::operator()(const template_decl& t) const
788{
789 std::hash<string> hash_string;
790 template_parameter::shared_ptr_hash hash_template_parameter;
791
792 size_t v = hash_string(typeid(t).name());
793 v = hashing::combine_hashes(v, hash_string(t.get_qualified_name()));
794
795 for (list<template_parameter_sptr>::const_iterator p =
796 t.get_template_parameters().begin();
797 p != t.get_template_parameters().end();
798 ++p)
799 if (!(*p)->get_hashing_has_started())
800 v = hashing::combine_hashes(v, hash_template_parameter(*p));
801
802 return v;
803}
804
806{
807 size_t
808 operator()(const type_tparameter& t) const
809 {
810 std::hash<string> hash_string;
811 template_parameter::hash hash_template_parameter;
813
814 size_t v = hash_string(typeid(t).name());
815 v = hashing::combine_hashes(v, hash_template_parameter(t));
816 v = hashing::combine_hashes(v, hash_type(t));
817
818 return v;
819 }
820};
821
822/// Compute a hash value for a @ref non_type_tparameter
823///
824/// @param t the non_type_tparameter for which to compute the value.
825///
826/// @return the computed hash value.
827size_t
829{
830 template_parameter::hash hash_template_parameter;
831 std::hash<string> hash_string;
833
834 size_t v = hash_string(typeid(t).name());
835 v = hashing::combine_hashes(v, hash_template_parameter(t));
836 v = hashing::combine_hashes(v, hash_string(t.get_name()));
837 v = hashing::combine_hashes(v, hash_type(t.get_type()));
838
839 return v;
840}
841
842/// Compute a hash value for a @ref non_type_tparameter
843///
844/// @param t the non_type_tparameter to compute the hash value for.
845///
846/// @return the computed hash value.
847size_t
849{return t ? operator()(*t) : 0;}
850
852{
853 size_t
854 operator()(const template_tparameter& t) const
855 {
856 std::hash<string> hash_string;
857 type_tparameter::hash hash_template_type_parm;
858 template_decl::hash hash_template_decl;
859
860 size_t v = hash_string(typeid(t).name());
861 v = hashing::combine_hashes(v, hash_template_type_parm(t));
862 v = hashing::combine_hashes(v, hash_template_decl(t));
863
864 return v;
865 }
866};
867
868size_t
869template_parameter::dynamic_hash::
870operator()(const template_parameter* t) const
871{
872 if (const template_tparameter* p =
873 dynamic_cast<const template_tparameter*>(t))
874 return template_tparameter::hash()(*p);
875 else if (const type_tparameter* p =
876 dynamic_cast<const type_tparameter*>(t))
877 return type_tparameter::hash()(*p);
878 if (const non_type_tparameter* p =
879 dynamic_cast<const non_type_tparameter*>(t))
880 return non_type_tparameter::hash()(*p);
881
882 // Poor man's fallback.
883 return template_parameter::hash()(*t);
884}
885
886/// Compute a hash value for a @ref type_composition type.
887///
888/// @param t the type_composition to compute the hash value for.
889///
890/// @return the computed hash value.
891size_t
893{
894 std::hash<string> hash_string;
896
897 size_t v = hash_string(typeid(t).name());
898 v = hashing::combine_hashes(v, hash_type(t.get_composed_type().get()));
899 return v;
900}
901
902/// Compute a hash value for a @ref type_composition type.
903///
904/// @param t the type_composition to compute the hash value for.
905///
906/// @return the computed hash value.
907size_t
909{return t ? operator()(*t): 0;}
910
911size_t
912function_tdecl::hash::
913operator()(const function_tdecl& t) const
914{
915 std::hash<string> hash_string;
916 decl_base::hash hash_decl_base;
917 template_decl::hash hash_template_decl;
918 function_decl::hash hash_function_decl;
919
920 size_t v = hash_string(typeid(t).name());
921
922 v = hashing::combine_hashes(v, hash_decl_base(t));
923 v = hashing::combine_hashes(v, hash_template_decl(t));
924 if (t.get_pattern())
925 v = hashing::combine_hashes(v, hash_function_decl(*t.get_pattern()));
926
927 return v;
928}
929
930size_t
931function_tdecl::shared_ptr_hash::
932operator()(const shared_ptr<function_tdecl> f) const
933{
934 function_tdecl::hash hash_fn_tmpl_decl;
935 if (f)
936 return hash_fn_tmpl_decl(*f);
937 return 0;
938}
939
940size_t
941class_tdecl::hash::
942operator()(const class_tdecl& t) const
943{
944 std::hash<string> hash_string;
945 decl_base::hash hash_decl_base;
946 template_decl::hash hash_template_decl;
947 class_decl::hash hash_class_decl;
948
949 size_t v = hash_string(typeid(t).name());
950 v = hashing::combine_hashes(v, hash_decl_base(t));
951 v = hashing::combine_hashes(v, hash_template_decl(t));
952 if (t.get_pattern())
953 v = hashing::combine_hashes(v, hash_class_decl(*t.get_pattern()));
954
955 return v;
956}
957
958size_t
959class_tdecl::shared_ptr_hash::
960operator()(const shared_ptr<class_tdecl> t) const
961{
962 class_tdecl::hash hash_class_tmpl_decl;
963
964 if (t)
965 return hash_class_tmpl_decl(*t);
966 return 0;
967}
968
969/// A hashing function for type declarations.
970///
971/// This function gets the dynamic type of the actual type
972/// declaration and calls the right hashing function for that type.
973///
974/// Note that each time a new type declaration kind is added to the
975/// system, this function needs to be updated. For a given
976/// inheritance hierarchy, make sure to handle the most derived type
977/// first.
978///
979/// FIXME: This hashing function is not maintained and is surely
980/// broken in subtle ways. In pratice, the various *::hash functors
981/// should be audited before they are used here. They should all
982/// match what is done in the 'equals' functions in abg-ir.cc.
983///
984/// @param t a pointer to the type declaration to be hashed
985///
986/// @return the resulting hash
987size_t
989{
990 if (t == 0)
991 return 0;
992
993 if (const member_function_template* d =
994 dynamic_cast<const member_function_template*>(t))
996 if (const member_class_template* d =
997 dynamic_cast<const member_class_template*>(t))
998 return member_class_template::hash()(*d);
999 if (const template_tparameter* d =
1000 dynamic_cast<const template_tparameter*>(t))
1001 return template_tparameter::hash()(*d);
1002 if (const type_tparameter* d =
1003 dynamic_cast<const type_tparameter*>(t))
1004 return type_tparameter::hash()(*d);
1005 if (const type_decl* d = dynamic_cast<const type_decl*> (t))
1006 return type_decl::hash()(*d);
1007 if (const qualified_type_def* d = dynamic_cast<const qualified_type_def*>(t))
1008 return qualified_type_def::hash()(*d);
1009 if (const pointer_type_def* d = dynamic_cast<const pointer_type_def*>(t))
1010 return pointer_type_def::hash()(*d);
1011 if (const reference_type_def* d = dynamic_cast<const reference_type_def*>(t))
1012 return reference_type_def::hash()(*d);
1013 if (const array_type_def* d = dynamic_cast<const array_type_def*>(t))
1014 return array_type_def::hash()(*d);
1015 if (const enum_type_decl* d = dynamic_cast<const enum_type_decl*>(t))
1016 return enum_type_decl::hash()(*d);
1017 if (const typedef_decl* d = dynamic_cast<const typedef_decl*>(t))
1018 return typedef_decl::hash()(*d);
1019 if (const class_decl* d = dynamic_cast<const class_decl*>(t))
1020 return class_decl::hash()(*d);
1021 if (const union_decl* d = dynamic_cast<const union_decl*>(t))
1022 return union_decl::hash()(*d);
1023 if (const scope_type_decl* d = dynamic_cast<const scope_type_decl*>(t))
1024 return scope_type_decl::hash()(*d);
1025 if (const method_type* d = dynamic_cast<const method_type*>(t))
1026 return method_type::hash()(*d);
1027 if (const function_type* d = dynamic_cast<const function_type*>(t))
1028 return function_type::hash()(*d);
1029
1030 // Poor man's fallback case.
1031 return type_base::hash()(*t);
1032}
1033
1034size_t
1035type_base::shared_ptr_hash::operator()(const shared_ptr<type_base> t) const
1036{return type_base::dynamic_hash()(t.get());}
1037
1038}//end namespace abigail
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
Definition: abg-fwd.h:1714
Types of the main internal representation of libabigail.
bool empty() const
Test if the current instance of interned_string is empty.
Abstraction for an array range type, like in Ada, or just for an array dimension like in C or C++.
Definition: abg-ir.h:2545
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
Definition: abg-ir.cc:18699
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition: abg-ir.cc:18706
The abstraction of an array type.
Definition: abg-ir.h:2519
const type_base_sptr get_element_type() const
Getter of the type of an array element.
Definition: abg-ir.cc:19256
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition: abg-ir.cc:19415
Abstracts a class declaration.
Definition: abg-ir.h:4233
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition: abg-ir.cc:24371
The base type of class_decl and union_decl.
Definition: abg-ir.h:4031
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition: abg-ir.cc:23512
const data_members & get_non_static_data_members() const
Get the non-static data memebers of this class_or_union.
Definition: abg-ir.cc:23391
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition: abg-ir.cc:23519
Abstract a class template.
Definition: abg-ir.h:3834
shared_ptr< class_decl > get_pattern() const
Getter of the pattern of the template.
Definition: abg-ir.cc:27417
The base type of all declarations.
Definition: abg-ir.h:1538
scope_decl * get_scope() const
Return the type containing the current decl, if any.
Definition: abg-ir.cc:4777
friend bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
Definition: abg-ir.cc:5561
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
Definition: abg-ir.cc:4808
const interned_string & get_name() const
Getter for the name of the current decl.
Definition: abg-ir.cc:4796
const decl_base_sptr get_definition_of_declaration() const
If this decl_base is declaration-only, get its definition, if any.
Definition: abg-ir.cc:4916
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
Definition: abg-ir.cc:4939
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition: abg-ir.cc:4745
friend enum access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5501
Abstracts a declaration for an enum type.
Definition: abg-ir.h:2750
const enumerators & get_enumerators() const
Definition: abg-ir.cc:19487
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition: abg-ir.cc:19482
Abstraction of a function parameter.
Definition: abg-ir.h:3286
Abstraction for a function declaration.
Definition: abg-ir.h:3111
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3135
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition: abg-ir.cc:22049
bool is_declared_inline() const
Test if the function was declared inline.
Definition: abg-ir.cc:22109
Abstract a function template declaration.
Definition: abg-ir.h:3785
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition: abg-ir.cc:27247
Abstraction of a function type.
Definition: abg-ir.h:3390
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
Definition: abg-ir.cc:21120
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:21405
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition: abg-ir.cc:21137
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
Definition: abg-ir.h:3880
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Definition: abg-ir.h:3901
Abstracts a member class template template.
Definition: abg-ir.h:4763
Abstract a member function template.
Definition: abg-ir.h:4708
Abstracts the type of a class member function.
Definition: abg-ir.h:3486
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
Definition: abg-ir.cc:21709
Abstracts non type template parameters.
Definition: abg-ir.h:3662
const type_base_sptr get_type() const
Getter for the type of the template parameter.
Definition: abg-ir.cc:26933
The abstraction of a pointer type.
Definition: abg-ir.h:2337
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
Definition: abg-ir.cc:17576
The abstraction of a qualified type.
Definition: abg-ir.h:2226
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
Definition: abg-ir.cc:17217
Abstracts a reference type.
Definition: abg-ir.h:2400
A declaration that introduces a scope.
Definition: abg-ir.h:1809
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
Definition: abg-ir.cc:7817
A type that introduces a scope.
Definition: abg-ir.h:2171
The base class of templates.
Definition: abg-ir.h:3544
const std::list< template_parameter_sptr > & get_template_parameters() const
Get the list of template parameters of the current instance of template_decl.
Definition: abg-ir.cc:26601
Base class for a template parameter. Client code should use the more specialized type_template_parame...
Definition: abg-ir.h:3579
Abstracts a template template parameter.
Definition: abg-ir.h:3709
An abstraction helper for type declarations.
Definition: abg-ir.h:1973
virtual size_t get_size_in_bits() const
Getter for the size of the type.
Definition: abg-ir.cc:15870
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition: abg-ir.cc:15884
This abstracts a composition of types based on template type parameters. The result of the compositio...
Definition: abg-ir.h:3747
const type_base_sptr get_composed_type() const
Getter for the resulting composed type.
Definition: abg-ir.cc:27126
A basic type declaration that introduces no scope.
Definition: abg-ir.h:2108
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
Definition: abg-ir.cc:10701
bool hashing_started() const
Getter for the 'hashing_started' property.
Definition: abg-ir.cc:4153
Abstracts a type template parameter.
Definition: abg-ir.h:3625
The abstraction of a typedef declaration.
Definition: abg-ir.h:2889
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
Definition: abg-ir.cc:20364
Abstracts a union type declaration.
Definition: abg-ir.h:4488
Abstracts a variable declaration.
Definition: abg-ir.h:3008
const type_base_sptr get_type() const
Getter of the type of the variable.
Definition: abg-ir.cc:20507
uint32_t fnv_hash(const std::string &str)
Compute a stable string hash.
Definition: abg-hash.cc:64
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.
Definition: abg-ir.cc:6440
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
Definition: abg-fwd.h:222
size_t hash_type(const type_base *t)
Hash an ABI artifact that is either a type.
Definition: abg-ir.cc:27709
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition: abg-ir.cc:6564
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
Definition: abg-ir.cc:10923
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
Definition: abg-fwd.h:194
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition: abg-fwd.h:211
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6330
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
Definition: abg-ir.cc:6496
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
Definition: abg-ir.cc:6354
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition: abg-ir.cc:6170
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition: abg-ir.cc:5599
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Definition: abg-ir.cc:5403
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Definition: abg-ir.cc:6381
Toplevel namespace for libabigail.
The hashing functor for class_decl::base_spec.
Definition: abg-ir.h:4890
Hasher for the class_decl type.
Definition: abg-ir.h:4391
size_t operator()(const class_decl &t) const
Compute a hash for a class_decl.
Definition: abg-hash.cc:686
Hasher for the class_or_union type.
Definition: abg-ir.h:4223
size_t operator()(const class_or_union &t) const
Compute a hash for a class_or_union.
Definition: abg-hash.cc:607
A hashing functor fo instances and pointers of function_decl.
Definition: abg-ir.h:4856
size_t operator()(const function_decl &t) const
Compute a hash value for an instance of function_decl.
Definition: abg-hash.cc:396
A hashing functor for a function_decl::parameter.
Definition: abg-ir.h:3368
The hashing functor for function_type.
Definition: abg-ir.h:3473
size_t operator()(const function_type &t) const
Hashing function for function_type.
Definition: abg-hash.cc:501
The hashing functor for member_base.
Definition: abg-ir.h:4897
The hashing functor for member_class_template.
Definition: abg-ir.h:4911
The hashing functor for member_function_template.
Definition: abg-ir.h:4904
Hasher for the non_type_tparameter type.
Definition: abg-ir.h:3697
size_t operator()(const non_type_tparameter &t) const
Compute a hash value for a non_type_tparameter.
Definition: abg-hash.cc:828
Hasher for the scope_decl type.
Definition: abg-ir.h:1938
size_t operator()(const type_base *t) const
A hashing function for type declarations.
Definition: abg-hash.cc:988
Hash functor for instances of type_base.
Definition: abg-ir.h:2052
size_t operator()(const type_composition &t) const
Compute a hash value for a type_composition type.
Definition: abg-hash.cc:892
A hashing functor for instances and pointers of var_decl.
Definition: abg-ir.h:4825