GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 96.6% 28 / 0 / 29
Functions: 88.9% 8 / 0 / 9
Branches: 55.6% 30 / 0 / 54

src/global/TypeRegistry.cpp
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #include "TypeRegistry.h"
4
5 #include <algorithm>
6 #include <cassert>
7 #include <ranges>
8 #include <sstream>
9
10 #include <symboltablebuilder/Type.h>
11 #include <util/CustomHashFunctions.h>
12
13 namespace spice::compiler {
14
15 // Static member initialization
16 std::unordered_map<uint64_t, std::unique_ptr<Type>> TypeRegistry::types = {};
17
18 /**
19 * Compute the hash for a type (aka type id)
20 *
21 * @param type Input type
22 * @return type hash / type id
23 */
24 6937249 uint64_t TypeRegistry::getTypeHash(const Type &type) { return std::hash<Type>{}(type); }
25
26 /**
27 * Get or insert a type into the type registry
28 *
29 * @param type The type to insert
30 * @return The inserted type
31 */
32 6937238 const Type *TypeRegistry::getOrInsert(const Type &&type) {
33 6937238 const uint64_t hash = getTypeHash(type);
34
35 // Check if type already exists
36
1/2
✓ Branch 3 → 4 taken 6937238 times.
✗ Branch 3 → 25 not taken.
6937238 const auto it = types.find(hash);
37
2/2
✓ Branch 6 → 7 taken 6917629 times.
✓ Branch 6 → 13 taken 19609 times.
6937238 if (it != types.end()) {
38 6917629 const Type *cachedType = it->second.get();
39 // This check should identify hash collisions
40
2/4
✓ Branch 9 → 10 taken 6917629 times.
✗ Branch 9 → 25 not taken.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 6917629 times.
6917629 assert(cachedType->typeChain == type.typeChain);
41 6917629 return cachedType;
42 }
43
44 // Create new type
45
2/4
✓ Branch 13 → 14 taken 19609 times.
✗ Branch 13 → 24 not taken.
✓ Branch 14 → 15 taken 19609 times.
✗ Branch 14 → 22 not taken.
19609 const auto [iter, inserted] = types.emplace(hash, std::make_unique<Type>(type));
46 19609 return iter->second.get();
47 }
48
49 /**
50 * Get or insert a type into the type registry
51 *
52 * @param superType The super type of the type
53 * @return The inserted type
54 */
55
2/4
✓ Branch 2 → 3 taken 5403776 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 5403776 times.
✗ Branch 3 → 8 not taken.
5403776 const Type *TypeRegistry::getOrInsert(SuperType superType) { return getOrInsert(Type(superType)); }
56
57 /**
58 * Get or insert a type into the type registry
59 *
60 * @param superType The super type of the type
61 * @param subType The sub type of the type
62 * @return The inserted type
63 */
64 1869 const Type *TypeRegistry::getOrInsert(SuperType superType, const std::string &subType) {
65
2/4
✓ Branch 2 → 3 taken 1869 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 1869 times.
✗ Branch 3 → 8 not taken.
1869 return getOrInsert(Type(superType, subType));
66 }
67
68 /**
69 * Get or insert a type into the type registry
70 *
71 * @param superType The super type of the type
72 * @param subType The sub type of the type
73 * @param typeId The type ID of the type
74 * @param data The data of the type
75 * @param templateTypes The template types of the type
76 * @return The inserted type
77 */
78 1204 const Type *TypeRegistry::getOrInsert(SuperType superType, const std::string &subType, uint64_t typeId,
79 const TypeChainElementData &data, const QualTypeList &templateTypes) {
80
2/4
✓ Branch 2 → 3 taken 1204 times.
✗ Branch 2 → 10 not taken.
✓ Branch 3 → 4 taken 1204 times.
✗ Branch 3 → 8 not taken.
1204 return getOrInsert(Type(superType, subType, typeId, data, templateTypes));
81 }
82
83 /**
84 * Get or insert a type into the type registry
85 *
86 * @param typeChain The type chain of the type
87 * @return The inserted type
88 */
89
3/6
✓ Branch 2 → 3 taken 1530389 times.
✗ Branch 2 → 14 not taken.
✓ Branch 3 → 4 taken 1530389 times.
✗ Branch 3 → 12 not taken.
✓ Branch 4 → 5 taken 1530389 times.
✗ Branch 4 → 10 not taken.
1530389 const Type *TypeRegistry::getOrInsert(const TypeChain &typeChain) { return getOrInsert(Type(typeChain)); }
90
91 /**
92 * Get the number of types in the type registry
93 *
94 * @return The number of types in the type registry
95 */
96 size_t TypeRegistry::getTypeCount() { return types.size(); }
97
98 /**
99 * Dump all types in the type registry
100 */
101 213 std::string TypeRegistry::dump() {
102 213 std::vector<std::string> typeStrings;
103
1/2
✓ Branch 3 → 4 taken 213 times.
✗ Branch 3 → 38 not taken.
213 typeStrings.reserve(types.size());
104
4/6
✓ Branch 4 → 5 taken 213 times.
✗ Branch 4 → 34 not taken.
✓ Branch 5 → 6 taken 213 times.
✗ Branch 5 → 34 not taken.
✓ Branch 14 → 7 taken 15797 times.
✓ Branch 14 → 15 taken 213 times.
16010 for (const std::unique_ptr<Type> &type : types | std::views::values)
105
2/4
✓ Branch 9 → 10 taken 15797 times.
✗ Branch 9 → 33 not taken.
✓ Branch 10 → 11 taken 15797 times.
✗ Branch 10 → 31 not taken.
15797 typeStrings.push_back(type->getName(false, true, true));
106 // Sort to ensure deterministic output
107
1/2
✓ Branch 15 → 16 taken 213 times.
✗ Branch 15 → 38 not taken.
213 std::ranges::sort(typeStrings);
108 // Serialize type registry
109
1/2
✓ Branch 16 → 17 taken 213 times.
✗ Branch 16 → 38 not taken.
213 std::stringstream typeRegistryString;
110
2/2
✓ Branch 24 → 19 taken 15797 times.
✓ Branch 24 → 25 taken 213 times.
16010 for (const std::string &typeString : typeStrings)
111
2/4
✓ Branch 20 → 21 taken 15797 times.
✗ Branch 20 → 35 not taken.
✓ Branch 21 → 22 taken 15797 times.
✗ Branch 21 → 35 not taken.
15797 typeRegistryString << typeString << "\n";
112
1/2
✓ Branch 25 → 26 taken 213 times.
✗ Branch 25 → 36 not taken.
426 return typeRegistryString.str();
113 213 }
114
115 /**
116 * Clear the type registry
117 */
118 451 void TypeRegistry::clear() { types.clear(); }
119
120 } // namespace spice::compiler
121