1
2
3
4
5
6 #ifndef CMAJOR_SYMBOLS_MODULE_INCLUDED
7 #define CMAJOR_SYMBOLS_MODULE_INCLUDED
8 #include <cmajor/symbols/SymbolTable.hpp>
9 #include <cmajor/symbols/Warning.hpp>
10 #include <cmajor/symbols/FileIndex.hpp>
11 #include <cmajor/symbols/FunctionIndex.hpp>
12 #include <cmajor/symbols/TypeIndex.hpp>
13 #include <cmajor/symbols/Sources.hpp>
14 #include <cmajor/cmdebug/Container.hpp>
15 #include <cmajor/cmdebug/DebugInfo.hpp>
16 #ifdef _WIN32
17 #include <cmajor/symbols/ResourceTable.hpp>
18 #endif
19 #include <sngcm/ast/Project.hpp>
20 #include <sngcm/cmlexer/CmajorLexer.hpp>
21 #include <cmajor/cmtoolchain/ToolChains.hpp>
22 #include <soulng/util/CodeFormatter.hpp>
23 #include <mutex>
24 #include <map>
25 #include <set>
26 #include <time.h>
27
28 namespace cmajor { namespace symbols {
29
30 bool IsSystemModule(const std::u32string& moduleName);
31 cmajor::debug::ContainerClassTemplateKind GetContainerClassTemplateKind(const std::u32string& fullClassName);
32
33 extern const char* cmajorModuleTag;
34
35 struct ModuleTag
36 {
37 ModuleTag();
38 void Write(SymbolWriter& writer);
39 void Read(SymbolReader& reader);
40 uint8_t bytes[4];
41 };
42
43 const uint8_t moduleFormat_1 = uint8_t('1');
44 const uint8_t moduleFormat_2 = uint8_t('2');
45 const uint8_t moduleFormat_3 = uint8_t('3');
46 const uint8_t moduleFormat_4 = uint8_t('4');
47 const uint8_t moduleFormat_5 = uint8_t('5');
48 const uint8_t moduleFormat_6 = uint8_t('6');
49 const uint8_t moduleFormat_7 = uint8_t('7');
50 const uint8_t moduleFormat_8 = uint8_t('8');
51 const uint8_t moduleFormat_9 = uint8_t('9');
52 const uint8_t moduleFormat_10 = uint8_t('A');
53 const uint8_t moduleFormat_11 = uint8_t('B');
54 const uint8_t moduleFormat_12 = uint8_t('C');
55 const uint8_t moduleFormat_13 = uint8_t('D');
56 const uint8_t moduleFormat_14 = uint8_t('E');
57 const uint8_t moduleFormat_15 = uint8_t('F');
58 const uint8_t moduleFormat_16 = uint8_t('G');
59 const uint8_t moduleFormat_17 = uint8_t('H');
60 const uint8_t currentModuleFormat = moduleFormat_17;
61
62 enum class ModuleFlags : uint8_t
63 {
64 none= 0, system= 1 << 0, core= 1 << 1, root= 1 << 2, immutable= 1 << 3, compiling= 1 << 4, fileIndexFilePathMapBuilt= 1 << 5, readFromModuleFile= 1 << 6, programModule= 1 << 7
65 };
66
67 inline ModuleFlags operator|(ModuleFlags left, ModuleFlags right)
68 {
69 return ModuleFlags(uint8_t(left) | uint8_t(right));
70 }
71
72 inline ModuleFlags operator&(ModuleFlags left, ModuleFlags right)
73 {
74 return ModuleFlags(uint8_t(left) & uint8_t(right));
75 }
76
77 inline ModuleFlags operator~(ModuleFlags flags)
78 {
79 return ModuleFlags(~uint8_t(flags));
80 }
81
82 std::string ModuleFlagStr(ModuleFlags flags);
83
84 class Module;
85 class Sources;
86 struct ParseResult;
87
88 class ModuleDependency
89 {
90 public:
91 ModuleDependency(Module* module_);
92 Module* GetModule() const { return module; }
93 void AddReferencedModule(Module* referencedModule);
94 const std::std::vector<Module*>&ReferencedModules() const{returnreferencedModules;}
95 void Dump(CodeFormatter& formatter);
96 private:
97 Module* module;
98 std::vector<Module*> referencedModules;
99 };
100
101 class FileTable
102 {
103 public:
104 int32_t RegisterFilePath(const std::string& filePath);
105 std::string GetFilePath(int32_t fileIndex) const;
106 int32_t NumFilePaths() const { return filePaths.size(); }
107 bool IsEmpty() const { return filePaths.empty(); }
108 void Write(BinaryWriter& writer, bool systemModule);
109 void Read(BinaryReader& reader, bool systemModule);
110 void Dump(CodeFormatter& formatter);
111 private:
112 std::vector<std::string> filePaths;
113 };
114
115 class SourceFileCache
116 {
117 public:
118 SourceFileCache();
119 SourceFileCache(const SourceFileCache&) = delete;
120 SourceFileCache(SourceFileCache&&) = delete;
121 SourceFileCache& operator=(const SourceFileCache&) = delete;
122 SourceFileCache& operator=(SourceFileCache&&) = delete;
123 const std::u32string& GetFileContent(const std::string& filePath);
124 private:
125 std::unordered_map<std::string, std::std::unique_ptr<std::u32string>>fileContentMap;
126 };
127
128 cmajor::debug::SourceSpan MakeSourceSpan(const Span& span, const boost::uuids::uuid& sourceModuleId);
129
130 class Module
131 {
132 public:
133 Module();
134 Module(const std::string& filePath);
135 Module(const std::string& filePath, bool readRoot);
136 Module(const std::u32string& name_, const std::string& filePath_, sngcm::ast::Target target);
137 ~Module();
138 uint8_t Format() const { return format; }
139 ModuleFlags Flags() const { return flags; }
140 const std::u32string& Name() const { return name; }
141 const boost::uuids::uuid& Id() const { return id; }
142 const std::string& OriginalFilePath() const { return originalFilePath; }
143 const std::string& FilePathReadFrom() const { return filePathReadFrom; }
144 const std::string& LibraryFilePath() const { return libraryFilePath; }
145 const std::string& ResourceFilePath() const { return resourceFilePath; }
146 void SetResourceFilePath(const std::string& resourceFilePath_);
147 const std::std::vector<Module*>AllReferencedModules() const{returnallRefModules;}
148 void PrepareForCompilation(const std::std::vector<std::string>&references, sngcm::ast::Targettarget);
149 SymbolTable& GetSymbolTable() { return *symbolTable; }
150 bool HasSymbolTable() const { return symbolTable != nullptr; }
151 void CreateSymbolTable();
152 uint32_t SymbolTablePos() const { return symbolTablePos; }
153 FileTable& GetFileTable() { return fileTable; }
154 void RegisterFileTable(FileTable* fileTable, Module* module);
155 void MakeFilePathFileIndexMap();
156 #ifdef _WIN32
157
158
159 #endif
160 void SetLexers(std::std::vector<std::std::unique_ptr<CmajorLexer>>&&lexers_);
161 std::std::vector<soulng::lexer::Lexer*>*GetLexers();
162 std::string GetFilePath(int32_t fileIndex) const;
163 std::u32string GetErrorLines(const Span& span) const;
164 void GetColumns(const Span& span, int32_t& startCol, int32_t& endCol) const;
165 void Write(SymbolWriter& writer);
166 void SetDirectoryPath(const std::string& directoryPath_);
167 void SetObjectFileDirectoryPath(const std::string& objectFileDirectoryPath_);
168 const std::string& DirectoryPath() const { return directoryPath; }
169 const std::string& ObjectFileDirectoryPath() const { return objectFileDirectoryPath; }
170 const std::std::vector<std::string>&LibraryFilePaths() const{returnlibraryFilePaths;}
171 bool IsSystemModule() const { return GetFlag(ModuleFlags::system); }
172 void SetSystemModule() { SetFlag(ModuleFlags::system); }
173 bool IsRootModule() const { return GetFlag(ModuleFlags::root); }
174 void SetRootModule() { SetFlag(ModuleFlags::root); }
175 bool IsImmutable() const { return GetFlag(ModuleFlags::immutable); }
176 void SetImmutable() { SetFlag(ModuleFlags::immutable); }
177 bool IsCore() const { return GetFlag(ModuleFlags::core); }
178 void SetCore() { SetFlag(ModuleFlags::core); }
179 bool GetFlag(ModuleFlags flag) const { return (flags & flag) != ModuleFlags::none; }
180 void SetFlag(ModuleFlags flag) { flags = flags | flag; }
181 void ResetFlag(ModuleFlags flag) { flags = flags & ~flag; }
182 void AddExportedFunction(const std::string& exportedFunction);
183 void AddExportedData(const std::string& data);
184 const std::std::vector<std::string>&ExportedFunctions(){returnexportedFunctions;}
185 const std::std::vector<std::string>&ExportedData(){returnexportedData;}
186 const std::std::vector<std::string>&AllExportedFunctions() const{returnallExportedFunctions;}
187 const std::std::vector<std::string>&AllExportedData() const{returnallExportedData;}
188 void Dump();
189 ModuleDependency& GetModuleDependency() { return moduleDependency; }
190 void SetCurrentProjectName(const std::u32string& currentProjectName_);
191 std::u32string GetCurrentProjectName();
192 void SetCurrentToolName(const std::u32string& currentToolName_);
193 std::u32string GetCurrentToolName();
194 CompileWarningCollection& WarningCollection();
195 void ClearDefines();
196 void DefineSymbol(const std::u32string& symbol);
197 bool IsSymbolDefined(const std::u32string& symbol);
198 void SetLogStreamId(int logStreamId_) { logStreamId = logStreamId_; }
199 int LogStreamId() const { return logStreamId; }
200 Module* GetSystemCoreModule();
201 void Check();
202 std::std::vector<Module*>&AllRefModules(){returnallRefModules;}
203 std::std::vector<Module*>&ReferencedModules(){returnreferencedModules;}
204 void AddReferencedModule(Module* referencedModule);
205 const std::std::vector<std::string>&ReferenceFilePaths() const{returnreferenceFilePaths;}
206 void ReadHeader(sngcm::ast::Target target, SymbolReader& reader, Module* rootModule, std::std::unordered_set<std::string>&importSet, std::std::vector<Module*>&modules,
207 std::std::unordered_map<std::string, ModuleDependency*>&moduleDependencyMap, std::std::unordered_map<std::string, Module*>&readMap, bool&first);
208 int DebugLogIndent() const { return debugLogIndent; }
209 void IncDebugLogIndent() { ++debugLogIndent; }
210 void DecDebugLogIndent() { --debugLogIndent; }
211 int Index() const { return index; }
212 void SetIndex(int index_) { index = index_; }
213 std::recursive_mutex& GetLock() { return lock; }
214 void StartBuild();
215 void StopBuild();
216 int64_t GetBuildStartTimeMs() const { return buildStartMs; }
217 int GetBuildTimeMs();
218 bool Preparing() const { return preparing; }
219 void SetPreparing(bool preparing_) { preparing = preparing_; }
220 void AddCompileUnitId(const std::string& compileUnitId);
221 const std::std::set<std::string>&AllCompileUnitIds() const{returnallCompileUnitIds;}
222 FunctionIndex& GetFunctionIndex() { return functionIndex; }
223 TypeIndex& GetTypeIndex() { return typeIndex; }
224 void WriteProjectDebugInfoFile(const std::string& projectDebufInfoFilePath);
225 void WriteCmdbFile(const std::string& cmdbFilePath);
226 void WriteDebugInfo(BinaryWriter& cmdbWriter, int32_t& numProjects, Module* rootModule);
227 std::std::unordered_map<int16_t, std::string>*GetModuleNameTable(){return&moduleNameTable;}
228 std::std::unordered_map<std::string, int16_t>*GetModuleIdMap(){return&moduleIdMap;}
229 cmajor::debug::SourceSpan SpanToSourceSpan(const Span& span);
230 int32_t GetFileIndexForFilePath(const std::string& filePath) const;
231 void UpdateSourceFileModuleMap();
232 std::recursive_mutex& Lock() { return lock; }
233 void SetSources(Sources* sources_) { sources.reset(sources_); }
234 Sources* GetSources() const { return sources.get(); }
235 ParseResult ParseSources();
236 ParseResult ParseSource(const std::string& sourceFilePath, const std::u32string& sourceCode);
237 std::string GetCCList(const std::string& sourceFilePath, const std::string& ccText);
238 std::string GetOverloadList(const std::string& functionGroup);
239 private:
240 uint8_t format;
241 ModuleFlags flags;
242 std::u32string name;
243 boost::uuids::uuid id;
244 sngcm::ast::BackEnd backend;
245 sngcm::ast::Config config;
246 std::string originalFilePath;
247 std::string filePathReadFrom;
248 std::string libraryFilePath;
249 std::string resourceFilePath;
250 std::vector<std::string> referenceFilePaths;
251 FileTable fileTable;
252 std::set<std::string> compileUnitIds;
253 std::set<std::string> allCompileUnitIds;
254 #ifdef _WIN32
255
256
257 #endif
258 std::vector<FileTable*> fileTables;
259 std::unordered_map<std::string, int32_t> filePathFileIndexMap;
260 std::vector<std::std::unique_ptr<CmajorLexer>>lexers;
261 std::vector<soulng::lexer::Lexer*> lexerVec;
262 std::unordered_map<int16_t, std::string> moduleNameTable;
263 std::unordered_map<std::string, int16_t> moduleIdMap;
264 std::vector<std::string> exportedFunctions;
265 std::vector<std::string> exportedData;
266 std::vector<std::string> allExportedFunctions;
267 std::vector<std::string> allExportedData;
268 ModuleDependency moduleDependency;
269 std::vector<Module*> referencedModules;
270 std::vector<Module*> allRefModules;
271 uint32_t symbolTablePos;
272 std::unique_ptr<SymbolTable> symbolTable;
273 std::string directoryPath;
274 std::string objectFileDirectoryPath;
275 std::vector<std::string> libraryFilePaths;
276 std::u32string currentProjectName;
277 std::u32string currentToolName;
278 CompileWarningCollection warnings;
279 std::set<std::u32string> defines;
280 int logStreamId;
281 bool headerRead;
282 int debugLogIndent;
283 Module* systemCoreModule;
284 int index;
285 bool preparing;
286 std::recursive_mutex lock;
287 int64_t buildStartMs;
288 int64_t buildStopMs;
289 FunctionIndex functionIndex;
290 TypeIndex typeIndex;
291 SourceFileCache sourceFileCache;
292 std::unique_ptr<Sources> sources;
293 void CheckUpToDate();
294 };
295
296 std::string GetSourceFilePath(int32_t fileIndex, const boost::uuids::uuid& moduleId);
297 bool HasRootModuleForCurrentThread();
298 Module* GetRootModuleForCurrentThread();
299 void SetRootModuleForCurrentThread(Module* rootModule_);
300
301 void InitModule();
302 void DoneModule();
303
304 } }
305
306 #endif // CMAJOR_SYMBOLS_MODULE_INCLUDED