GCC Code Coverage Report


Directory: ../
File: src/SourceFile.h
Date: 2024-11-22 23:10:59
Exec Total Coverage
Lines: 3 3 100.0%
Functions: 0 0 -%
Branches: 6 12 50.0%

Line Branch Exec Source
1 // Copyright (c) 2021-2024 ChilliBits. All rights reserved.
2
3 #pragma once
4
5 #include <string>
6
7 #include <ast/ASTNodes.h>
8 #include <exception/AntlrThrowingErrorListener.h>
9 #include <global/RuntimeModuleManager.h>
10 #include <symboltablebuilder/Scope.h>
11 #include <util/CompilerWarning.h>
12
13 #include <llvm/IR/IRBuilder.h>
14 #include <llvm/Target/TargetMachine.h>
15
16 // Ignore some warnings in ANTLR generated code
17 #pragma GCC diagnostic push
18 #pragma GCC diagnostic ignored "-Woverloaded-virtual"
19 #include <SpiceLexer.h>
20 #include <SpiceParser.h>
21 #pragma GCC diagnostic pop
22
23 namespace spice::compiler {
24
25 // Forward declarations
26 class GlobalResourceManager;
27 class EntryNode;
28 class ASTNode;
29 class Timer;
30 struct CliOptions;
31
32 enum CompileStageType : uint8_t {
33 NONE,
34 LEXER,
35 PARSER,
36 CST_VISUALIZER,
37 AST_BUILDER,
38 AST_VISUALIZER,
39 IMPORT_COLLECTOR,
40 SYMBOL_TABLE_BUILDER,
41 TYPE_CHECKER_PRE,
42 TYPE_CHECKER_POST,
43 IR_GENERATOR,
44 IR_OPTIMIZER,
45 OBJECT_EMITTER,
46 FINISHED
47 };
48
49 enum CompileStageIOType : uint8_t {
50 IO_CODE,
51 IO_TOKENS,
52 IO_CST,
53 IO_AST,
54 IO_IR,
55 IO_OBJECT_FILE,
56 };
57
58 struct SourceFileAntlrCtx {
59 // Create error handlers for lexer and parser
60 std::unique_ptr<AntlrThrowingErrorListener> lexerErrorHandler;
61 std::unique_ptr<AntlrThrowingErrorListener> parserErrorHandler;
62 std::unique_ptr<antlr4::ANTLRInputStream> inputStream;
63 std::unique_ptr<SpiceLexer> lexer;
64 std::unique_ptr<antlr4::CommonTokenStream> tokenStream;
65 std::unique_ptr<SpiceParser> parser;
66 };
67
68 struct TimerOutput {
69 uint64_t lexer = 0;
70 uint64_t parser = 0;
71 uint64_t cstVisualizer = 0;
72 uint64_t astBuilder = 0;
73 uint64_t astVisualizer = 0;
74 uint64_t importCollector = 0;
75 uint64_t symbolTableBuilder = 0;
76 uint64_t typeCheckerPre = 0;
77 uint64_t typeCheckerPost = 0;
78 uint64_t irGenerator = 0;
79 uint64_t irOptimizer = 0;
80 uint64_t objectEmitter = 0;
81 };
82
83 struct CompilerOutput {
84 std::string cstString;
85 std::string astString;
86 std::string symbolTableString;
87 std::string irString;
88 std::string irOptString;
89 std::string asmString;
90 std::string typesString;
91 std::vector<CompilerWarning> warnings;
92 TimerOutput times;
93 };
94
95 struct NameRegistryEntry {
96 std::string name;
97 uint64_t typeId; // Set for structs, interfaces, enums and aliases
98 SymbolTableEntry *targetEntry;
99 Scope *targetScope;
100 SymbolTableEntry *importEntry = nullptr;
101 };
102
103 class SourceFile {
104 public:
105 // Constructors
106 SourceFile(GlobalResourceManager &resourceManager, SourceFile *parent, std::string name, const std::filesystem::path &filePath,
107 bool stdFile);
108 SourceFile(const SourceFile &) = delete;
109
110 // Friend classes
111 friend class RuntimeModuleManager;
112
113 // Compiler pipeline triggers
114 void runLexer();
115 void runParser();
116 void runCSTVisualizer();
117 void runASTBuilder();
118 void runASTVisualizer();
119 void runImportCollector();
120 void runSymbolTableBuilder();
121 void runTypeChecker();
122
123 private:
124 void runTypeCheckerPre();
125 void runTypeCheckerPost();
126
127 public:
128 void runIRGenerator();
129 void runDefaultIROptimizer();
130 void runPreLinkIROptimizer();
131 void runBitcodeLinker();
132 void runPostLinkIROptimizer();
133 void runObjectEmitter();
134 void concludeCompilation();
135
136 // Shortcuts
137 void runFrontEnd();
138 void runMiddleEnd();
139 void runBackEnd();
140
141 // Public methods
142 void addDependency(SourceFile *sourceFile, const ASTNode *declNode, const std::string &dependencyName, const std::string &path);
143 [[nodiscard]] bool imports(const SourceFile *sourceFile) const;
144 [[nodiscard]] bool isAlreadyImported(const std::string &filePathSearch, std::stack<const SourceFile *> &circle) const;
145 SourceFile *requestRuntimeModule(RuntimeModule runtimeModule);
146 bool isRuntimeModuleAvailable(RuntimeModule runtimeModule) const;
147 void addNameRegistryEntry(const std::string &symbolName, uint64_t typeId, SymbolTableEntry *entry, Scope *scope,
148 bool keepNewOnCollision = true, SymbolTableEntry *importEntry = nullptr);
149 [[nodiscard]] const NameRegistryEntry *getNameRegistryEntry(const std::string &symbolName) const;
150 [[nodiscard]] llvm::Type *getLLVMType(const Type *type);
151 void checkForSoftErrors() const;
152 void collectAndPrintWarnings();
153 const SourceFile *getRootSourceFile() const;
154 bool isRT(RuntimeModule runtimeModule) const;
155
3/6
✓ Branch 1 taken 938 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 157 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 23 times.
✗ Branch 8 not taken.
1171 ALWAYS_INLINE bool isStringRT() const { return isRT(STRING_RT); }
156
1/2
✓ Branch 1 taken 880 times.
✗ Branch 2 not taken.
880 ALWAYS_INLINE bool isMemoryRT() const { return isRT(MEMORY_RT); }
157
2/4
✓ Branch 1 taken 322 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 136 times.
✗ Branch 5 not taken.
458 ALWAYS_INLINE bool isRttiRT() const { return isRT(RTTI_RT); }
158
159 // Public fields
160 std::string name;
161 std::string fileName;
162 std::filesystem::path filePath;
163 std::string fileDir;
164 bool isStdFile = false;
165 bool isMainFile = true;
166 bool alwaysKeepSymbolsOnNameCollision = false;
167 bool ignoreWarnings = false;
168 bool restoredFromCache = false;
169 bool reVisitRequested = false;
170 CompileStageType previousStage = NONE;
171 SourceFileAntlrCtx antlrCtx;
172 CompilerOutput compilerOutput;
173 SourceFile *parent;
174 std::string cacheKey;
175 EntryNode *ast = nullptr;
176 std::unique_ptr<Scope> globalScope;
177 llvm::LLVMContext context;
178 llvm::IRBuilder<> builder;
179 std::unique_ptr<llvm::TargetMachine> targetMachine;
180 std::unique_ptr<llvm::Module> llvmModule;
181 std::map<std::string, SourceFile *> dependencies; // Has to be an ordered map to keep the compilation order deterministic
182 std::vector<const SourceFile *> dependants;
183 std::unordered_map<std::string, NameRegistryEntry> exportedNameRegistry;
184 std::vector<const Function *> testFunctions;
185
186 private:
187 // Private fields
188 GlobalResourceManager &resourceManager;
189 const CliOptions &cliOptions;
190 std::unordered_map<const Type *, llvm::Type *> typeToLLVMTypeMapping;
191 uint8_t importedRuntimeModules = 0;
192 uint8_t totalTypeCheckerRuns = 0;
193
194 // Private methods
195 bool haveAllDependantsBeenTypeChecked() const;
196 void mergeNameRegistries(const SourceFile &importedSourceFile, const std::string &importName);
197 void dumpOutput(const std::string &content, const std::string &caption, const std::string &fileSuffix) const;
198 void visualizerPreamble(std::stringstream &output) const;
199 void visualizerOutput(std::string outputName, const std::string &output) const;
200 void printStatusMessage(const char *stage, const CompileStageIOType &in, const CompileStageIOType &out, uint64_t stageRuntime,
201 unsigned short stageRuns = 0) const;
202 };
203
204 } // namespace spice::compiler
205