Line |
Branch |
Exec |
Source |
1 |
|
|
// Copyright (c) 2021-2025 ChilliBits. All rights reserved. |
2 |
|
|
|
3 |
|
|
#pragma once |
4 |
|
|
|
5 |
|
|
#include <CompilerPass.h> |
6 |
|
|
#include <ast/ASTVisitor.h> |
7 |
|
|
#include <model/Function.h> |
8 |
|
|
#include <symboltablebuilder/Scope.h> |
9 |
|
|
#include <typechecker/FunctionManager.h> |
10 |
|
|
#include <typechecker/OpRuleManager.h> |
11 |
|
|
#include <util/CompilerWarning.h> |
12 |
|
|
|
13 |
|
|
namespace spice::compiler { |
14 |
|
|
|
15 |
|
|
// Forward declarations |
16 |
|
|
class LambdaBaseNode; |
17 |
|
|
|
18 |
|
|
enum TypeCheckerMode : bool { |
19 |
|
|
TC_MODE_PRE, |
20 |
|
|
TC_MODE_POST, |
21 |
|
|
}; |
22 |
|
|
|
23 |
|
|
/** |
24 |
|
|
* Jobs: |
25 |
|
|
* - Ensure that all actual types match the expected types |
26 |
|
|
* - Perform type inference |
27 |
|
|
*/ |
28 |
|
|
class TypeChecker final : CompilerPass, public ASTVisitor { |
29 |
|
|
public: |
30 |
|
|
// Constructors |
31 |
|
|
TypeChecker(GlobalResourceManager &resourceManager, SourceFile *sourceFile, TypeCheckerMode typeCheckerMode); |
32 |
|
|
|
33 |
|
|
// Friend classes |
34 |
|
|
friend class OpRuleManager; |
35 |
|
|
friend class FunctionManager; |
36 |
|
|
friend class StructManager; |
37 |
|
|
|
38 |
|
|
// Visitor methods |
39 |
|
|
// Top level definitions |
40 |
|
|
std::any visitEntry(EntryNode *node) override; |
41 |
|
|
std::any visitMainFctDef(MainFctDefNode *node) override; |
42 |
|
|
std::any visitMainFctDefPrepare(MainFctDefNode *node); |
43 |
|
|
std::any visitMainFctDefCheck(MainFctDefNode *node); |
44 |
|
|
std::any visitFctDef(FctDefNode *node) override; |
45 |
|
|
std::any visitFctDefPrepare(FctDefNode *node); |
46 |
|
|
std::any visitFctDefCheck(FctDefNode *node); |
47 |
|
|
std::any visitProcDef(ProcDefNode *node) override; |
48 |
|
|
std::any visitProcDefPrepare(ProcDefNode *node); |
49 |
|
|
std::any visitProcDefCheck(ProcDefNode *node); |
50 |
|
|
std::any visitStructDef(StructDefNode *node) override; |
51 |
|
|
std::any visitStructDefPrepare(StructDefNode *node); |
52 |
|
|
std::any visitStructDefCheck(StructDefNode *node); |
53 |
|
|
std::any visitInterfaceDef(InterfaceDefNode *node) override; |
54 |
|
|
std::any visitInterfaceDefPrepare(InterfaceDefNode *node); |
55 |
|
|
std::any visitEnumDef(EnumDefNode *node) override; |
56 |
|
|
std::any visitEnumDefPrepare(EnumDefNode *node); |
57 |
|
|
std::any visitGenericTypeDef(GenericTypeDefNode *node) override; |
58 |
|
|
std::any visitGenericTypeDefPrepare(GenericTypeDefNode *node); |
59 |
|
|
std::any visitAliasDef(AliasDefNode *node) override; |
60 |
|
|
std::any visitAliasDefPrepare(AliasDefNode *node); |
61 |
|
|
std::any visitGlobalVarDef(GlobalVarDefNode *node) override; |
62 |
|
|
std::any visitGlobalVarDefPrepare(GlobalVarDefNode *node); |
63 |
|
|
std::any visitExtDecl(ExtDeclNode *node) override; |
64 |
|
|
std::any visitExtDeclPrepare(ExtDeclNode *node); |
65 |
|
|
std::any visitImportDef(ImportDefNode *node) override; |
66 |
|
|
std::any visitImportDefPrepare(ImportDefNode *node); |
67 |
|
|
// Control structures |
68 |
|
|
std::any visitUnsafeBlock(UnsafeBlockNode *node) override; |
69 |
|
|
std::any visitForLoop(ForLoopNode *node) override; |
70 |
|
|
std::any visitForeachLoop(ForeachLoopNode *node) override; |
71 |
|
|
std::any visitWhileLoop(WhileLoopNode *node) override; |
72 |
|
|
std::any visitDoWhileLoop(DoWhileLoopNode *node) override; |
73 |
|
|
std::any visitIfStmt(IfStmtNode *node) override; |
74 |
|
|
std::any visitElseStmt(ElseStmtNode *node) override; |
75 |
|
|
std::any visitSwitchStmt(SwitchStmtNode *node) override; |
76 |
|
|
std::any visitCaseBranch(CaseBranchNode *node) override; |
77 |
|
|
std::any visitDefaultBranch(DefaultBranchNode *node) override; |
78 |
|
|
std::any visitAssertStmt(AssertStmtNode *node) override; |
79 |
|
|
std::any visitAnonymousBlockStmt(AnonymousBlockStmtNode *node) override; |
80 |
|
|
// Statements |
81 |
|
|
std::any visitStmtLst(StmtLstNode *node) override; |
82 |
|
|
std::any visitParamLst(ParamLstNode *node) override; |
83 |
|
|
std::any visitField(FieldNode *node) override; |
84 |
|
|
std::any visitSignature(SignatureNode *node) override; |
85 |
|
|
std::any visitDeclStmt(DeclStmtNode *node) override; |
86 |
|
|
std::any visitCaseConstant(CaseConstantNode *node) override; |
87 |
|
|
std::any visitReturnStmt(ReturnStmtNode *node) override; |
88 |
|
|
std::any visitBreakStmt(BreakStmtNode *node) override; |
89 |
|
|
std::any visitContinueStmt(ContinueStmtNode *node) override; |
90 |
|
|
std::any visitFallthroughStmt(FallthroughStmtNode *node) override; |
91 |
|
|
// Builtin functions |
92 |
|
|
std::any visitBuiltinCall(BuiltinCallNode *node) override; |
93 |
|
|
std::any visitPrintfCall(PrintfCallNode *node) override; |
94 |
|
|
std::any visitSizeofCall(SizeofCallNode *node) override; |
95 |
|
|
std::any visitAlignofCall(AlignofCallNode *node) override; |
96 |
|
|
std::any visitLenCall(LenCallNode *node) override; |
97 |
|
|
std::any visitPanicCall(PanicCallNode *node) override; |
98 |
|
|
std::any visitSysCall(SysCallNode *node) override; |
99 |
|
|
// Expressions |
100 |
|
|
std::any visitAssignExpr(AssignExprNode *node) override; |
101 |
|
|
std::any visitTernaryExpr(TernaryExprNode *node) override; |
102 |
|
|
std::any visitLogicalOrExpr(LogicalOrExprNode *node) override; |
103 |
|
|
std::any visitLogicalAndExpr(LogicalAndExprNode *node) override; |
104 |
|
|
std::any visitBitwiseOrExpr(BitwiseOrExprNode *node) override; |
105 |
|
|
std::any visitBitwiseXorExpr(BitwiseXorExprNode *node) override; |
106 |
|
|
std::any visitBitwiseAndExpr(BitwiseAndExprNode *node) override; |
107 |
|
|
std::any visitEqualityExpr(EqualityExprNode *node) override; |
108 |
|
|
std::any visitRelationalExpr(RelationalExprNode *node) override; |
109 |
|
|
std::any visitShiftExpr(ShiftExprNode *node) override; |
110 |
|
|
std::any visitAdditiveExpr(AdditiveExprNode *node) override; |
111 |
|
|
std::any visitMultiplicativeExpr(MultiplicativeExprNode *node) override; |
112 |
|
|
std::any visitCastExpr(CastExprNode *node) override; |
113 |
|
|
std::any visitPrefixUnaryExpr(PrefixUnaryExprNode *node) override; |
114 |
|
|
std::any visitPostfixUnaryExpr(PostfixUnaryExprNode *node) override; |
115 |
|
|
std::any visitAtomicExpr(AtomicExprNode *node) override; |
116 |
|
|
// Values and types |
117 |
|
|
std::any visitValue(ValueNode *node) override; |
118 |
|
|
std::any visitConstant(ConstantNode *node) override; |
119 |
|
|
std::any visitFctCall(FctCallNode *node) override; |
120 |
|
|
std::any visitArrayInitialization(ArrayInitializationNode *node) override; |
121 |
|
|
std::any visitStructInstantiation(StructInstantiationNode *node) override; |
122 |
|
|
std::any visitLambdaFunc(LambdaFuncNode *node) override; |
123 |
|
|
std::any visitLambdaProc(LambdaProcNode *node) override; |
124 |
|
|
std::any visitLambdaExpr(LambdaExprNode *node) override; |
125 |
|
|
std::any visitDataType(DataTypeNode *node) override; |
126 |
|
|
std::any visitBaseDataType(BaseDataTypeNode *node) override; |
127 |
|
|
std::any visitCustomDataType(CustomDataTypeNode *node) override; |
128 |
|
|
std::any visitFunctionDataType(FunctionDataTypeNode *node) override; |
129 |
|
|
|
130 |
|
|
private: |
131 |
|
|
// Private members |
132 |
|
|
OpRuleManager opRuleManager = OpRuleManager(this); |
133 |
|
|
Scope *accessScope = nullptr; |
134 |
|
|
const TypeCheckerMode typeCheckerMode; |
135 |
|
|
std::vector<CompilerWarning> &warnings; |
136 |
|
|
TypeMapping typeMapping; |
137 |
|
|
bool typeCheckedMainFct = false; |
138 |
|
|
|
139 |
|
|
// Private methods |
140 |
|
|
bool visitOrdinaryFctCall(FctCallNode *node, QualTypeList &templateTypes, std::string fqFunctionName); |
141 |
|
|
bool visitFctPtrCall(const FctCallNode *node, const QualType &functionType) const; |
142 |
|
|
bool visitMethodCall(FctCallNode *node, Scope *structScope, QualTypeList &templateTypes); |
143 |
|
|
bool checkAsyncLambdaCaptureRules(const LambdaBaseNode *node, const LambdaAttrNode *attrs) const; |
144 |
|
|
[[nodiscard]] Function *matchCopyCtor(const QualType &thisType, const ASTNode *node); |
145 |
|
|
[[nodiscard]] QualType mapLocalTypeToImportedScopeType(const Scope *targetScope, const QualType &symbolType) const; |
146 |
|
|
[[nodiscard]] QualType mapImportedScopeTypeToLocalType(const Scope *sourceScope, const QualType &symbolType) const; |
147 |
|
|
static void autoDeReference(QualType &symbolType); |
148 |
|
|
std::vector<const Function *> &getOpFctPointers(ASTNode *node) const; |
149 |
|
|
static void requestRevisitIfRequired(const Function *fct); |
150 |
|
|
void softError(const ASTNode *node, SemanticErrorType errorType, const std::string &message) const; |
151 |
|
|
|
152 |
|
|
// Implicit code generation |
153 |
|
|
void createDefaultStructMethod(const Struct &spiceStruct, const std::string &entryName, const std::string &name, |
154 |
|
|
const ParamList ¶ms) const; |
155 |
|
|
void createDefaultCtorIfRequired(const Struct &spiceStruct, Scope *structScope); |
156 |
|
|
void createDefaultCopyCtorIfRequired(const Struct &spiceStruct, Scope *structScope); |
157 |
|
|
void createDefaultDtorIfRequired(const Struct &spiceStruct, Scope *structScope); |
158 |
|
|
void createCtorBodyPreamble(const Scope *bodyScope); |
159 |
|
|
void createCopyCtorBodyPreamble(const Scope *bodyScope); |
160 |
|
|
void createDtorBodyPreamble(const Scope *bodyScope); |
161 |
|
|
Function *implicitlyCallStructMethod(const SymbolTableEntry *entry, const std::string &methodName, const ArgList &args, |
162 |
|
|
const ASTNode *node); |
163 |
|
|
Function *implicitlyCallStructMethod(QualType thisType, const std::string &methodName, const ArgList &args, |
164 |
|
|
const ASTNode *node); |
165 |
|
|
Function *implicitlyCallStructCopyCtor(const SymbolTableEntry *entry, const ASTNode *node); |
166 |
|
|
Function *implicitlyCallStructCopyCtor(const QualType &thisType, const ASTNode *node); |
167 |
|
|
void implicitlyCallStructDtor(SymbolTableEntry *entry, StmtLstNode *node); |
168 |
|
|
void implicitlyCallDeallocate(const ASTNode *node); |
169 |
|
|
void doScopeCleanup(StmtLstNode *node); |
170 |
|
|
}; |
171 |
|
|
|
172 |
|
|
} // namespace spice::compiler |
173 |
|
|
|