GCC Code Coverage Report


Directory: ../
File: src/global/TypeRegistry.cpp
Date: 2025-11-16 23:33:18
Coverage Exec Excl Total
Lines: 96.7% 29 0 30
Functions: 88.9% 8 0 9
Branches: 55.6% 30 0 54

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