GCC Code Coverage Report


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

src/typechecker/TypeChecker.h
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #pragma once
4
5 #include <CompilerPass.h>
6 #include <ast/ASTVisitor.h>
7 #include <typechecker/OpRuleManager.h>
8
9 namespace spice::compiler {
10
11 // Forward declarations
12 class LambdaBaseNode;
13 class CompilerWarning;
14 struct Param;
15 struct NamedParam;
16 using ParamList = std::vector<Param>;
17 using NamedParamList = std::vector<NamedParam>;
18 using Arg = std::pair</*type=*/QualType, /*isTemporary=*/bool>;
19 using ArgList = std::vector<Arg>;
20
21 enum TypeCheckerMode : bool {
22 TC_MODE_PRE,
23 TC_MODE_POST,
24 };
25
26 /**
27 * Global switch that tells StructManager whether a freshly substantiated struct manifestation may still be given its
28 * compiler-generated default members (ctor, copy ctor, move ctor, dtor).
29 *
30 * Creating those mutates the symbol table and registers new functions, which is only valid while the middle end runs.
31 * The back end reaches StructManager::match as well - through QualType::getStruct, on multiple threads - but by then
32 * every manifestation exists already, so those calls never take the creation path anyway. The switch makes that an
33 * invariant instead of an assumption.
34 */
35 inline bool structDefaultMembersDecidable = false;
36
37 /**
38 * RAII marker for the section of the compiler in which struct manifestations are still allowed to receive their
39 * compiler-generated default members, i.e. the middle end.
40 */
41 class DefaultMemberCreationSection final {
42 public:
43 // Constructors
44 573 DefaultMemberCreationSection() { structDefaultMembersDecidable = true; }
45
46 // Prevent copy
47 DefaultMemberCreationSection(const DefaultMemberCreationSection &) = delete;
48 DefaultMemberCreationSection &operator=(const DefaultMemberCreationSection &) = delete;
49
50 // Destructor
51 573 ~DefaultMemberCreationSection() { structDefaultMembersDecidable = false; }
52 };
53
54 /**
55 * Jobs:
56 * - Ensure that all actual types match the expected types
57 * - Perform type inference
58 */
59 class TypeChecker final : CompilerPass, public ASTVisitor {
60 public:
61 // Constructors
62 TypeChecker(GlobalResourceManager &resourceManager, SourceFile *sourceFile, TypeCheckerMode typeCheckerMode);
63
64 // Friend classes
65 friend class OpRuleManager;
66 friend class FunctionManager;
67 friend class StructManager;
68
69 // Visitor methods
70 // Top level definitions
71 std::any visitEntry(EntryNode *node) override;
72 std::any visitMainFctDef(MainFctDefNode *node) override;
73 std::any visitMainFctDefPrepare(MainFctDefNode *node);
74 std::any visitMainFctDefCheck(MainFctDefNode *node);
75 std::any visitFctDef(FctDefNode *node) override;
76 std::any visitFctDefPrepare(FctDefNode *node);
77 std::any visitFctDefCheck(FctDefNode *node);
78 std::any visitProcDef(ProcDefNode *node) override;
79 std::any visitProcDefPrepare(ProcDefNode *node);
80 std::any visitProcDefCheck(ProcDefNode *node);
81 std::any visitStructDef(StructDefNode *node) override;
82 std::any visitStructDefPrepare(StructDefNode *node);
83 std::any visitStructDefCheck(StructDefNode *node);
84 std::any visitInterfaceDef(InterfaceDefNode *node) override;
85 std::any visitInterfaceDefPrepare(InterfaceDefNode *node);
86 void assignDeferredOpaqueType(SymbolTableEntry *entry);
87 std::any visitEnumDef(EnumDefNode *node) override;
88 std::any visitEnumDefPrepare(EnumDefNode *node);
89 std::any visitGenericTypeDef(GenericTypeDefNode *node) override;
90 std::any visitGenericTypeDefPrepare(GenericTypeDefNode *node);
91 std::any visitAliasDef(AliasDefNode *node) override;
92 std::any visitAliasDefPrepare(AliasDefNode *node);
93 std::any visitGlobalVarDef(GlobalVarDefNode *node) override;
94 std::any visitGlobalVarDefPrepare(GlobalVarDefNode *node);
95 std::any visitExtDecl(ExtDeclNode *node) override;
96 std::any visitExtDeclPrepare(ExtDeclNode *node);
97 std::any visitImportDef(ImportDefNode *node) override;
98 std::any visitImportDefPrepare(ImportDefNode *node);
99 // Control structures
100 std::any visitUnsafeBlock(UnsafeBlockNode *node) override;
101 std::any visitForLoop(ForLoopNode *node) override;
102 std::any visitForeachLoop(ForeachLoopNode *node) override;
103 std::any visitWhileLoop(WhileLoopNode *node) override;
104 std::any visitDoWhileLoop(DoWhileLoopNode *node) override;
105 std::any visitIfStmt(IfStmtNode *node) override;
106 std::any visitElseStmt(ElseStmtNode *node) override;
107 std::any visitSwitchStmt(SwitchStmtNode *node) override;
108 std::any visitCaseBranch(CaseBranchNode *node) override;
109 std::any visitDefaultBranch(DefaultBranchNode *node) override;
110 std::any visitAssertStmt(AssertStmtNode *node) override;
111 std::any visitAnonymousBlockStmt(AnonymousBlockStmtNode *node) override;
112 // Statements
113 std::any visitStmtLst(StmtLstNode *node) override;
114 std::any visitParamLst(ParamLstNode *node) override;
115 std::any visitField(FieldNode *node) override;
116 std::any visitSignature(SignatureNode *node) override;
117 std::any visitDeclStmt(DeclStmtNode *node) override;
118 std::any visitCaseConstant(CaseConstantNode *node) override;
119 std::any visitReturnStmt(ReturnStmtNode *node) override;
120 std::any visitBreakStmt(BreakStmtNode *node) override;
121 std::any visitContinueStmt(ContinueStmtNode *node) override;
122 std::any visitFallthroughStmt(FallthroughStmtNode *node) override;
123 // Expressions
124 std::any visitAssignExpr(AssignExprNode *node) override;
125 std::any visitTernaryExpr(TernaryExprNode *node) override;
126 std::any visitLogicalOrExpr(LogicalOrExprNode *node) override;
127 std::any visitLogicalAndExpr(LogicalAndExprNode *node) override;
128 std::any visitBitwiseOrExpr(BitwiseOrExprNode *node) override;
129 std::any visitBitwiseXorExpr(BitwiseXorExprNode *node) override;
130 std::any visitBitwiseAndExpr(BitwiseAndExprNode *node) override;
131 std::any visitEqualityExpr(EqualityExprNode *node) override;
132 std::any visitRelationalExpr(RelationalExprNode *node) override;
133 std::any visitShiftExpr(ShiftExprNode *node) override;
134 std::any visitAdditiveExpr(AdditiveExprNode *node) override;
135 std::any visitMultiplicativeExpr(MultiplicativeExprNode *node) override;
136 std::any visitCastExpr(CastExprNode *node) override;
137 std::any visitPrefixUnaryExpr(PrefixUnaryExprNode *node) override;
138 std::any visitPostfixUnaryExpr(PostfixUnaryExprNode *node) override;
139 std::any visitAtomicExpr(AtomicExprNode *node) override;
140 // Values and types
141 std::any visitValue(ValueNode *node) override;
142 std::any visitConstant(ConstantNode *node) override;
143 std::any visitFctCall(FctCallNode *node) override;
144 std::any visitArrayInitialization(ArrayInitializationNode *node) override;
145 std::any visitStructInstantiation(StructInstantiationNode *node) override;
146 std::any visitLambdaFunc(LambdaFuncNode *node) override;
147 std::any visitLambdaProc(LambdaProcNode *node) override;
148 std::any visitLambdaExpr(LambdaExprNode *node) override;
149 std::any visitDataType(DataTypeNode *node) override;
150 std::any visitBaseDataType(BaseDataTypeNode *node) override;
151 std::any visitCustomDataType(CustomDataTypeNode *node) override;
152 std::any visitFunctionDataType(FunctionDataTypeNode *node) override;
153
154 // Builtin function handlers
155 std::any visitBuiltinCall(FctCallNode *node) const;
156 std::any visitBuiltinPrintfCall(FctCallNode *node) const;
157 std::any visitBuiltinSizeOfCall(FctCallNode *node) const;
158 std::any visitBuiltinAlignOfCall(FctCallNode *node) const;
159 std::any visitBuiltinOffsetOfCall(FctCallNode *node) const;
160 std::any visitBuiltinTypeIdCall(FctCallNode *node) const;
161 std::any visitBuiltinTypeNameCall(FctCallNode *node) const;
162 std::any visitBuiltinLenCall(FctCallNode *node) const;
163 std::any visitBuiltinPanicCall(FctCallNode *node) const;
164 std::any visitBuiltinSyscallCall(FctCallNode *node) const;
165 std::any visitBuiltinIsSameCall(FctCallNode *node) const;
166 std::any visitBuiltinImplementsInterfaceCall(FctCallNode *node) const;
167 std::any visitBuiltinGetBuildVarCall(FctCallNode *node) const;
168 std::any visitBuiltinIsTriviallyConstructible(FctCallNode *node) const;
169 std::any visitBuiltinIsTriviallyCopyable(FctCallNode *node) const;
170 std::any visitBuiltinIsTriviallyDestructible(FctCallNode *node) const;
171 std::any visitBuiltinIsHeap(FctCallNode *node) const;
172 std::any visitBuiltinNewCall(FctCallNode *node) const;
173 std::any visitBuiltinPlacementNewCall(FctCallNode *node) const;
174
175 private:
176 // Private members
177 OpRuleManager opRuleManager = OpRuleManager(this);
178 const TypeCheckerMode typeCheckerMode;
179 std::vector<CompilerWarning> &warnings;
180 TypeMapping typeMapping;
181 bool typeCheckedMainFct = false;
182
183 // Private methods
184 bool visitOrdinaryFctCall(FctCallNode *node, std::string fqFunctionName) const;
185 bool visitFctPtrCall(const FctCallNode *node, const QualType &functionType) const;
186 bool visitMethodCall(FctCallNode *node, Scope *structScope) const;
187 bool checkAsyncLambdaCaptureRules(const LambdaBaseNode *node, const LambdaAttrNode *attrs) const;
188 [[nodiscard]] Function *matchCopyCtor(const QualType &thisType, const ASTNode *node) const;
189 [[nodiscard]] Function *matchMoveCtor(const QualType &thisType, const ASTNode *node) const;
190 [[nodiscard]] QualType mapLocalTypeToImportedScopeType(const Scope *targetScope, const QualType &symbolType) const;
191 [[nodiscard]] QualType mapImportedScopeTypeToLocalType(const Scope *sourceScope, const QualType &symbolType) const;
192 std::vector<const Function *> &getOpFctPointers(ASTNode *node) const;
193 static void requestRevisitIfRequired(const Function *fct);
194 void ensureLoadedRuntimeForTypeName(const std::string &typeName) const;
195 void ensureLoadedRuntimeForFunctionName(const std::string &functionName) const;
196 void softError(const ASTNode *node, SemanticErrorType errorType, const std::string &message) const;
197
198 // Implicit code generation
199 static void createImplicitDefaultMembers(Struct &spiceStruct, const ASTNode *node, bool withMoveCtor = true);
200 static void createDefaultStructMethod(const Struct &spiceStruct, const std::string &entryName, const std::string &name,
201 const ParamList &params);
202 static void createDefaultCtorIfRequired(const Struct &spiceStruct, Scope *structScope);
203 static void createDefaultCopyCtorIfRequired(const Struct &spiceStruct, Scope *structScope);
204 static void createDefaultMoveCtorIfRequired(const Struct &spiceStruct, Scope *structScope);
205 static void createDefaultDtorIfRequired(const Struct &spiceStruct, Scope *structScope);
206 void createCtorBodyPreamble(const Scope *bodyScope) const;
207 void createCopyCtorBodyPreamble(const Scope *bodyScope) const;
208 void createMoveCtorBodyPreamble(const Scope *bodyScope) const;
209 void createDtorBodyPreamble(const Scope *bodyScope, const ASTNode *node) const;
210 Function *implicitlyCallStructMethod(const SymbolTableEntry *entry, const std::string &methodName, const ArgList &args,
211 const ASTNode *node) const;
212 Function *implicitlyCallStructMethod(QualType thisType, const std::string &methodName, const ArgList &args,
213 const ASTNode *node) const;
214 Function *implicitlyCallStructCopyCtor(const SymbolTableEntry *entry, const ASTNode *node) const;
215 Function *implicitlyCallStructCopyCtor(const QualType &thisType, const ASTNode *node) const;
216 Function *implicitlyCallStructMoveCtor(const SymbolTableEntry *entry, const ASTNode *node) const;
217 Function *implicitlyCallStructMoveCtor(const QualType &thisType, const ASTNode *node) const;
218 void implicitlyCallStructDtor(SymbolTableEntry *entry, StmtLstNode *node) const;
219 void implicitlyCallDeallocate(const ASTNode *node) const;
220 void doScopeCleanup(StmtLstNode *node) const;
221 bool isCopyCtorCall(const FctCallNode *node, const QualType &thisType) const;
222 };
223
224 } // namespace spice::compiler
225