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-2023 Red Hat, Inc.
5 
6 /// @file
7 
8 #include <functional>
9 #include "abg-internal.h"
10 // <headers defining libabigail's API go under here>
11 ABG_BEGIN_EXPORT_DECLARATIONS
12 
13 #include "abg-hash.h"
14 #include "abg-ir.h"
15 
16 ABG_END_EXPORT_DECLARATIONS
17 // </headers defining libabigail's API>
18 
19 namespace abigail
20 {
21 
22 namespace 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 
39 size_t
40 combine_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.
63 uint32_t
64 fnv_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 
80 using std::list;
81 using std::vector;
82 
83 using 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.
94 size_t
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.
112 size_t
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.
121 size_t
122 type_base::hash::operator()(const type_base_sptr t) const
123 {return operator()(*t);}
124 
125 struct 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 
146 struct 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.
168 size_t
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.
187 size_t
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 
208 struct qualified_type_def::hash
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 
225 struct pointer_type_def::hash
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 
243 struct reference_type_def::hash
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 
264 struct array_type_def::subrange_type::hash
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 
276 struct array_type_def::hash
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;
285  array_type_def::subrange_type::hash hash_subrange;
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 
303 struct enum_type_decl::hash
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 
328 struct typedef_decl::hash
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.
356 size_t
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
382 size_t
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.
395 size_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
434 size_t
436 {return operator()(*t);}
437 
438 size_t
439 function_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 
451 size_t
452 function_decl::parameter::hash::operator()
453  (const function_decl::parameter* p) const
454 {return operator()(*p);}
455 
456 size_t
457 function_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.
462 struct method_type::hash
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.
500 size_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.
522 size_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.
538 size_t
540 {return operator()(t.get());}
541 
542 // </struct function_type::hash stuff>
543 
544 size_t
545 member_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 
551 size_t
552 class_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 
568 size_t
569 member_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 
586 size_t
587 member_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.
606 size_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 
620  if (t.get_is_declaration_only())
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 =
654  t.get_member_function_templates().begin();
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.
676 size_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.
685 size_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 
700  if (t.get_is_declaration_only())
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;
710  class_decl::base_spec::hash hash_base;
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.
739 size_t
741 {return t ? operator()(*t) : 0;}
742 
743 struct 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 
773 struct template_parameter::dynamic_hash
774 {
775  size_t
776  operator()(const template_parameter* t) const;
777 };
778 
779 struct 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 
786 size_t
787 template_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 
805 struct type_tparameter::hash
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;
812  type_decl::hash hash_type;
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.
827 size_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.
847 size_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 
868 size_t
869 template_parameter::dynamic_hash::
870 operator()(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.
891 size_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.
907 size_t
909 {return t ? operator()(*t): 0;}
910 
911 size_t
912 function_tdecl::hash::
913 operator()(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 
930 size_t
931 function_tdecl::shared_ptr_hash::
932 operator()(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 
940 size_t
941 class_tdecl::hash::
942 operator()(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 
958 size_t
959 class_tdecl::shared_ptr_hash::
960 operator()(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
987 size_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))
995  return member_function_template::hash()(*d);
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 
1034 size_t
1035 type_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:18951
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
Definition: abg-ir.cc:18958
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:19508
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
Definition: abg-ir.cc:19667
Abstracts a class declaration.
Definition: abg-ir.h:4231
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
Definition: abg-ir.cc:24586
The base type of class_decl and union_decl.
Definition: abg-ir.h:4029
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
Definition: abg-ir.cc:23727
const data_members & get_non_static_data_members() const
Get the non-static data memebers of this class_or_union.
Definition: abg-ir.cc:23606
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
Definition: abg-ir.cc:23734
Abstract a class template.
Definition: abg-ir.h:3832
shared_ptr< class_decl > get_pattern() const
Getter of the pattern of the template.
Definition: abg-ir.cc:27632
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:5032
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
Definition: abg-ir.cc:5063
const interned_string & get_name() const
Getter for the name of the current decl.
Definition: abg-ir.cc:5051
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:5171
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
Definition: abg-ir.cc:5194
const interned_string & get_linkage_name() const
Getter for the mangled name.
Definition: abg-ir.cc:5000
Abstracts a declaration for an enum type.
Definition: abg-ir.h:2750
const enumerators & get_enumerators() const
Definition: abg-ir.cc:19739
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
Definition: abg-ir.cc:19734
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:3131
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
Definition: abg-ir.cc:22264
bool is_declared_inline() const
Test if the function was declared inline.
Definition: abg-ir.cc:22324
Abstract a function template declaration.
Definition: abg-ir.h:3783
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
Definition: abg-ir.cc:27462
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:21372
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
Definition: abg-ir.cc:21657
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
Definition: abg-ir.cc:21389
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
Definition: abg-ir.h:3878
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
Definition: abg-ir.h:3899
Abstracts a member class template template.
Definition: abg-ir.h:4761
Abstract a member function template.
Definition: abg-ir.h:4706
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:21961
Abstracts non type template parameters.
Definition: abg-ir.h:3660
const type_base_sptr get_type() const
Getter for the type of the template parameter.
Definition: abg-ir.cc:27148
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:17829
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:17470
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:8072
A type that introduces a scope.
Definition: abg-ir.h:2171
The base class of templates.
Definition: abg-ir.h:3542
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:26816
Base class for a template parameter. Client code should use the more specialized type_template_parame...
Definition: abg-ir.h:3577
Abstracts a template template parameter.
Definition: abg-ir.h:3707
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:16123
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
Definition: abg-ir.cc:16137
This abstracts a composition of types based on template type parameters. The result of the compositio...
Definition: abg-ir.h:3745
const type_base_sptr get_composed_type() const
Getter for the resulting composed type.
Definition: abg-ir.cc:27341
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:10956
bool hashing_started() const
Getter for the 'hashing_started' property.
Definition: abg-ir.cc:4408
Abstracts a type template parameter.
Definition: abg-ir.h:3623
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:20616
Abstracts a union type declaration.
Definition: abg-ir.h:4486
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:20759
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:6695
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
Definition: abg-fwd.h:219
size_t hash_type(const type_base *t)
Hash an ABI artifact that is either a type.
Definition: abg-ir.cc:27924
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:5816
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
Definition: abg-ir.cc:6819
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:11178
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
Definition: abg-fwd.h:191
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition: abg-fwd.h:209
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
Definition: abg-ir.cc:6585
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
Definition: abg-ir.cc:6751
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
Definition: abg-ir.cc:6609
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
Definition: abg-ir.cc:5756
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Definition: abg-ir.cc:6425
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
Definition: abg-ir.cc:5854
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
Definition: abg-ir.cc:5658
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
Definition: abg-ir.cc:6636
Toplevel namespace for libabigail.
The hashing functor for class_decl::base_spec.
Definition: abg-ir.h:4888
Hasher for the class_decl type.
Definition: abg-ir.h:4389
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:4221
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:4854
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:4895
The hashing functor for member_class_template.
Definition: abg-ir.h:4909
The hashing functor for member_function_template.
Definition: abg-ir.h:4902
Hasher for the non_type_tparameter type.
Definition: abg-ir.h:3695
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 scope_decl &d) const
Hashing operator for the scope_decl type.
Definition: abg-hash.cc:169
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_base &t) const
Hash function for an instance of type_base.
Definition: abg-hash.cc:95
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:4823
size_t operator()(const var_decl &t) const
Compute a hash for an instance var_decl.
Definition: abg-hash.cc:357