1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  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=  0system=  1 << 0core=  1 << 1root=  1 << 2immutable=  1 << 3compiling=  1 << 4fileIndexFilePathMapBuilt=  1 << 5readFromModuleFile=  1 << 6programModule=  1 << 7
 65 };
 66 
 67 inline ModuleFlags operator|(ModuleFlags leftModuleFlags right)
 68 {
 69     return ModuleFlags(uint8_t(left) | uint8_t(right));
 70 }
 71 
 72 inline ModuleFlags operator&(ModuleFlags leftModuleFlags 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& writerbool systemModule);
109     void Read(BinaryReader& readerbool 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::stringstd::std::unique_ptr<std::u32string>>fileContentMap;
126 };
127 
128 cmajor::debug::SourceSpan MakeSourceSpan(const Span& spanconst boost::uuids::uuid& sourceModuleId);
129 
130 class Module 
131 {
132 public:
133     Module();
134     Module(const std::string& filePath);
135     Module(const std::string& filePathbool 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>&referencessngcm::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* fileTableModule* 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& spanint32_t& startColint32_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 targetSymbolReader& readerModule* rootModulestd::std::unordered_set<std::string>&importSetstd::std::vector<Module*>&modules
207         std::std::unordered_map<std::stringModuleDependency*>&moduleDependencyMapstd::std::unordered_map<std::stringModule*>&readMapbool&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& cmdbWriterint32_t& numProjectsModule* rootModule);
227     std::std::unordered_map<int16_tstd::string>*GetModuleNameTable(){return&moduleNameTable;}
228     std::std::unordered_map<std::stringint16_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& sourceFilePathconst std::u32string& sourceCode);
237     std::string GetCCList(const std::string& sourceFilePathconst 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::stringint32_t> filePathFileIndexMap;
260     std::vector<std::std::unique_ptr<CmajorLexer>>lexers;
261     std::vector<soulng::lexer::Lexer*> lexerVec;
262     std::unordered_map<int16_tstd::string> moduleNameTable;
263     std::unordered_map<std::stringint16_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 fileIndexconst boost::uuids::uuid& moduleId);
297 bool HasRootModuleForCurrentThread();
298 Module* GetRootModuleForCurrentThread();
299 void SetRootModuleForCurrentThread(Module* rootModule_);
300 
301 void InitModule();
302 void DoneModule();
303 
304 } } // namespace cmajor::symbols
305 
306 #endif // CMAJOR_SYMBOLS_MODULE_INCLUDED