GCC Code Coverage Report


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

src/typechecker/Builtins.h
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #pragma once
4
5 #include <array>
6
7 #include <irgenerator/IRGenerator.h>
8 #include <typechecker/TypeChecker.h>
9
10 namespace spice::compiler {
11
12 using TypeCheckerVisitMethod = std::any (TypeChecker::*)(FctCallNode *node) const;
13 using IRGeneratorVisitMethod = std::any (IRGenerator::*)(const FctCallNode *node);
14
15 // Represents a compiler builtin function
16 struct BuiltinFunctionInfo {
17 TypeCheckerVisitMethod typeCheckerVisitMethod = nullptr;
18 IRGeneratorVisitMethod irGeneratorVisitMethod = nullptr;
19 unsigned int minTemplateTypes = 0;
20 unsigned int maxTemplateTypes = 0;
21 unsigned int minArgTypes = 0;
22 unsigned int maxArgTypes = 0;
23 bool allTemplateTypesOrAllArgTypes = false;
24 bool isFunctionTerminator = false;
25 };
26
27 struct BuiltinFunctionEntry {
28 std::string_view name;
29 BuiltinFunctionInfo info;
30 };
31
32 // Constants
33 // Documented builtins
34 static constexpr std::string_view BUILTIN_FCT_NAME_PRINTF = "printf";
35 static constexpr std::string_view BUILTIN_FCT_NAME_SIZEOF = "sizeof";
36 static constexpr std::string_view BUILTIN_FCT_NAME_ALIGNOF = "alignof";
37 static constexpr std::string_view BUILTIN_FCT_NAME_TYPEID = "typeid";
38 static constexpr std::string_view BUILTIN_FCT_NAME_LEN = "len";
39 static constexpr std::string_view BUILTIN_FCT_NAME_PANIC = "panic";
40 static constexpr std::string_view BUILTIN_FCT_NAME_SYSCALL = "syscall";
41 // Undocumented builtins (intended to be primarily used via std wrapper functions)
42 static constexpr std::string_view BUILTIN_FCT_NAME_IS_SAME = "__is_same";
43 static constexpr std::string_view BUILTIN_FCT_NAME_IMPLEMENTS_INTERFACE = "__implements_interface";
44 static constexpr std::string_view BUILTIN_FCT_NAME_GET_BUILD_VAR = "__get_build_var";
45
46 static constexpr std::array BUILTIN_FUNCTIONS = {
47 BuiltinFunctionEntry{
48 BUILTIN_FCT_NAME_PRINTF,
49 BuiltinFunctionInfo{
50 .typeCheckerVisitMethod = &TypeChecker::visitBuiltinPrintfCall,
51 .irGeneratorVisitMethod = &IRGenerator::visitBuiltinPrintfCall,
52 .minArgTypes = 1,
53 .maxArgTypes = std::numeric_limits<unsigned int>::max(),
54 },
55 },
56 BuiltinFunctionEntry{
57 BUILTIN_FCT_NAME_SIZEOF,
58 BuiltinFunctionInfo{
59 .typeCheckerVisitMethod = &TypeChecker::visitBuiltinSizeOfCall,
60 .maxTemplateTypes = 1,
61 .maxArgTypes = 1,
62 .allTemplateTypesOrAllArgTypes = true,
63 },
64 },
65 BuiltinFunctionEntry{
66 BUILTIN_FCT_NAME_ALIGNOF,
67 BuiltinFunctionInfo{
68 .typeCheckerVisitMethod = &TypeChecker::visitBuiltinAlignOfCall,
69 .maxTemplateTypes = 1,
70 .maxArgTypes = 1,
71 .allTemplateTypesOrAllArgTypes = true,
72 },
73 },
74 BuiltinFunctionEntry{
75 BUILTIN_FCT_NAME_TYPEID,
76 BuiltinFunctionInfo{
77 .typeCheckerVisitMethod = &TypeChecker::visitBuiltinTypeIdCall,
78 .maxTemplateTypes = 1,
79 .maxArgTypes = 1,
80 .allTemplateTypesOrAllArgTypes = true,
81 },
82 },
83 BuiltinFunctionEntry{
84 BUILTIN_FCT_NAME_LEN,
85 BuiltinFunctionInfo{
86 .typeCheckerVisitMethod = &TypeChecker::visitBuiltinLenCall,
87 .irGeneratorVisitMethod = &IRGenerator::visitBuiltinLenCall,
88 .minArgTypes = 1,
89 .maxArgTypes = 1,
90 },
91 },
92 BuiltinFunctionEntry{
93 BUILTIN_FCT_NAME_PANIC,
94 BuiltinFunctionInfo{
95 .typeCheckerVisitMethod = &TypeChecker::visitBuiltinPanicCall,
96 .irGeneratorVisitMethod = &IRGenerator::visitBuiltinPanicCall,
97 .minArgTypes = 1,
98 .maxArgTypes = 1,
99 .isFunctionTerminator = true,
100 },
101 },
102 BuiltinFunctionEntry{
103 BUILTIN_FCT_NAME_SYSCALL,
104 BuiltinFunctionInfo{
105 .typeCheckerVisitMethod = &TypeChecker::visitBuiltinSyscallCall,
106 .irGeneratorVisitMethod = &IRGenerator::visitBuiltinSyscallCall,
107 .minArgTypes = 1,
108 // According to https://www.chromium.org/chromium-os/developer-library/reference/linux-constants/syscalls/
109 .maxArgTypes = 6,
110 },
111 },
112 BuiltinFunctionEntry{
113 BUILTIN_FCT_NAME_IS_SAME,
114 BuiltinFunctionInfo{
115 .typeCheckerVisitMethod = &TypeChecker::visitBuiltinIsSameCall,
116 .minTemplateTypes = 2,
117 .maxTemplateTypes = std::numeric_limits<unsigned int>::max(),
118 },
119 },
120 BuiltinFunctionEntry{
121 BUILTIN_FCT_NAME_IMPLEMENTS_INTERFACE,
122 BuiltinFunctionInfo{
123 .typeCheckerVisitMethod = &TypeChecker::visitBuiltinImplementsInterfaceCall,
124 .minTemplateTypes = 2,
125 .maxTemplateTypes = 2,
126 },
127 },
128 BuiltinFunctionEntry{
129 BUILTIN_FCT_NAME_GET_BUILD_VAR,
130 BuiltinFunctionInfo{
131 .typeCheckerVisitMethod = &TypeChecker::visitBuiltinGetBuildVarCall,
132 .minTemplateTypes = 1,
133 .maxTemplateTypes = 1,
134 .minArgTypes = 1,
135 .maxArgTypes = 2,
136 },
137 }};
138
139 5 static const std::unordered_map<std::string_view, BuiltinFunctionInfo> BUILTIN_FUNCTIONS_MAP = [] {
140 5 std::unordered_map<std::string_view, BuiltinFunctionInfo> map;
141
2/2
✓ Branch 6 → 4 taken 50 times.
✓ Branch 6 → 7 taken 5 times.
55 for (const auto &[name, info] : BUILTIN_FUNCTIONS)
142
1/2
✓ Branch 4 → 5 taken 50 times.
✗ Branch 4 → 9 not taken.
50 map.emplace(name, info);
143 5 return map;
144 }(); // LCOV_EXCL_LINE - Coverage tool false positive
145
146 // Validate builtins at compile time
147 static consteval bool validateBuiltins() {
148 return std::ranges::all_of(BUILTIN_FUNCTIONS, [](const BuiltinFunctionEntry &entry) {
149 const auto &[name, info] = entry;
150 return !name.empty() && info.minTemplateTypes <= info.maxTemplateTypes && info.minArgTypes <= info.maxArgTypes;
151 });
152 }
153 static_assert(validateBuiltins(), "Invalid builtin function definitions");
154
155 } // namespace spice::compiler
156