GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 45 / 0 / 45
Functions: 100.0% 6 / 0 / 6
Branches: 100.0% 6 / 0 / 6

src/util/CustomHashFunctions.cpp
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #include "CustomHashFunctions.h"
4
5 #include <numeric>
6 #include <string>
7
8 #include <symboltablebuilder/Type.h>
9 #include <symboltablebuilder/TypeChain.h>
10
11 namespace spice::compiler {
12
13 277802593 uint64_t hashMix(uint64_t hash) noexcept {
14 277802593 hash += 0x9e3779b97f4a7c15ull;
15 277802593 hash = (hash ^ (hash >> 30)) * 0xbf58476d1ce4e5b9ull;
16 277802593 hash = (hash ^ (hash >> 27)) * 0x94d049bb133111ebull;
17 277802593 hash ^= (hash >> 31);
18 277802593 return hash;
19 }
20
21 213254410 void hashCombine64(uint64_t &hash, uint64_t value) noexcept {
22 213254410 hash ^= hashMix(value + 0x9e3779b97f4a7c15ull + (hash << 6) + (hash >> 2));
23 213254410 }
24
25 } // namespace spice::compiler
26
27 namespace std {
28
29 26279889 size_t hash<spice::compiler::TypeChainElement>::operator()(const spice::compiler::TypeChainElement &tce) const noexcept {
30 using namespace spice::compiler;
31 26279889 uint64_t hash = 0;
32
33 26279889 hashCombine64(hash, tce.superType);
34 26279889 hashCombine64(hash, std::hash<std::string>{}(tce.subType));
35 26279889 hashCombine64(hash, tce.typeId);
36
37
4/4
✓ Branch 6 → 7 taken 13444 times.
✓ Branch 6 → 9 taken 706643 times.
✓ Branch 6 → 14 taken 6331806 times.
✓ Branch 6 → 17 taken 19227996 times.
26279889 switch (tce.superType) {
38 13444 case TY_ARRAY:
39 13444 hashCombine64(hash, tce.data.arraySize);
40 13444 break;
41 706643 case TY_FUNCTION:
42 case TY_PROCEDURE:
43
2/2
✓ Branch 9 → 10 taken 1894 times.
✓ Branch 9 → 11 taken 704749 times.
706643 hashCombine64(hash, tce.data.hasCaptures ? 0xF00D1234ULL : 0xBAD0C0DEULL);
44 706643 break;
45 6331806 case TY_STRUCT:
46 case TY_INTERFACE:
47 case TY_UNION:
48 case TY_ENUM:
49 // Stable hash based on pointer identity, but randomized for safety
50 6331806 hashCombine64(hash, hashPointer(tce.data.bodyScope));
51 6331806 break;
52 19227996 default:
53 19227996 break;
54 }
55
56 26279889 hashCombine64(hash, hashVector(tce.templateTypes));
57 26279889 hashCombine64(hash, hashVector(tce.paramTypes));
58
59 26279889 return hashMix(hash);
60 }
61
62 24856956 size_t hash<spice::compiler::Type>::operator()(const spice::compiler::Type &t) const noexcept {
63 using namespace spice::compiler;
64 24856956 uint64_t hash = 0;
65 24856956 hashCombine64(hash, hashVector(t.typeChain));
66 24856956 return hashMix(hash);
67 }
68
69 6705669 size_t hash<spice::compiler::TypeQualifiers>::operator()(const spice::compiler::TypeQualifiers &qualifiers) const noexcept {
70 using namespace spice::compiler;
71 6705669 const uint8_t bits = (qualifiers.isConst << 0) | (qualifiers.isSigned << 1) | (qualifiers.isUnsigned << 2) |
72 6705669 (qualifiers.isHeap << 3) | (qualifiers.isPublic << 4) | (qualifiers.isInline << 5) |
73 6705669 (qualifiers.isComposition << 6);
74 6705669 return hashMix(bits);
75 }
76
77 6705669 size_t hash<spice::compiler::QualType>::operator()(const spice::compiler::QualType &qualType) const noexcept {
78 using namespace spice::compiler;
79 6705669 uint64_t seed = 0;
80
81 // Hash type pointer content if possible
82 6705669 hashCombine64(seed, std::hash<Type>{}(*qualType.getType()));
83
84 6705669 TypeQualifiers qualifiers = qualType.getQualifiers();
85 6705669 qualifiers.isPublic = false; // Ignore the public qualifier for hashing
86 6705669 hashCombine64(seed, std::hash<TypeQualifiers>{}(qualifiers));
87 6705669 return hashMix(seed);
88 }
89
90 } // namespace std
91