1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef CMAJOR_SYMBOLS_SYMBOL_TABLE_INCLUDED
  7 #define CMAJOR_SYMBOLS_SYMBOL_TABLE_INCLUDED
  8 #include <cmajor/symbols/NamespaceSymbol.hpp>
  9 #include <cmajor/symbols/DerivedTypeSymbol.hpp>
 10 #include <cmajor/symbols/ClassTemplateSpecializationSymbol.hpp>
 11 #include <cmajor/symbols/ArrayTypeSymbol.hpp>
 12 #include <cmajor/symbols/ConversionTable.hpp>
 13 #include <sngxml/dom/Document.hpp>
 14 #include <sngcm/ast/Namespace.hpp>
 15 #include <sngcm/ast/Function.hpp>
 16 #include <sngcm/ast/Class.hpp>
 17 #include <sngcm/ast/Interface.hpp>
 18 #include <sngcm/ast/Delegate.hpp>
 19 #include <sngcm/ast/Typedef.hpp>
 20 #include <sngcm/ast/Constant.hpp>
 21 #include <sngcm/ast/GlobalVariable.hpp>
 22 #include <sngcm/ast/Enumeration.hpp>
 23 #include <boost/functional/hash.hpp>
 24 #include <stack>
 25 
 26 namespace cmajor { namespace symbols {
 27 
 28 using namespace sngcm::ast;
 29 
 30 class Module;
 31 class FunctionSymbol;
 32 class TypeSymbol;
 33 class ConceptSymbol;
 34 class TypedefSymbol;
 35 class ConstantSymbol;
 36 
 37 struct TypeOrConceptRequest 
 38 {
 39     TypeOrConceptRequest(Symbol* symbol_const boost::uuids::uuid& typeId_int index_) : symbol(symbol_)typeId(typeId_)index(index_) {}
 40     Symbol* symbol;
 41     boost::uuids::uuid typeId;
 42     int index;
 43 };
 44 
 45 struct FunctionRequest 
 46 {
 47     FunctionRequest(Symbol* symbol_const boost::uuids::uuid& functionId_int index_) : symbol(symbol_)functionId(functionId_)index(index_) {}
 48     Symbol* symbol;
 49     boost::uuids::uuid functionId;
 50     int index;
 51 };
 52 
 53 struct ClassTemplateSpecializationKey 
 54 {
 55     ClassTemplateSpecializationKey(ClassTypeSymbol* classTemplate_const std::std::vector<TypeSymbol*>&templateArgumentTypes_):
 56         classTemplate(classTemplate_)templateArgumentTypes(templateArgumentTypes_)
 57     {
 58     }
 59     ClassTypeSymbol* classTemplate;
 60     std::vector<TypeSymbol*> templateArgumentTypes;
 61 };
 62 
 63 struct ClassTemplateSpecializationKeyHash 
 64 {
 65     size_t operator()(const ClassTemplateSpecializationKey& key) const
 66     {
 67         size_t x = boost::hash<boost::uuids::uuid>()(key.classTemplate->TypeId());
 68         int n = key.templateArgumentTypes.size();
 69         for (int i = 0; i < n; ++i)
 70         {
 71             x = x ^ boost::hash<boost::uuids::uuid>()(key.templateArgumentTypes[i]->TypeId());
 72         }
 73         return x;
 74     }
 75 };
 76 
 77 bool operator==(const ClassTemplateSpecializationKey& leftconst ClassTemplateSpecializationKey& right);
 78 bool operator!=(const ClassTemplateSpecializationKey& leftconst ClassTemplateSpecializationKey& right);
 79 
 80 struct ArrayKey 
 81 {
 82     ArrayKey(TypeSymbol* elementType_int64_t size_) : elementType(elementType_)size(size_) {}
 83     TypeSymbol* elementType;
 84     int64_t size;
 85 };
 86 
 87 bool operator==(const ArrayKey& leftconst ArrayKey& right);
 88 bool operator!=(const ArrayKey& leftconst ArrayKey& right);
 89 
 90 struct ArrayKeyHash 
 91 {
 92     size_t operator()(const ArrayKey& key) const
 93     {
 94         size_t x = boost::hash<boost::uuids::uuid>()(key.elementType->TypeId());
 95         x = x ^ std::hash<int64_t>()(key.size);
 96         return x;
 97     }
 98 };
 99 
100 void MapIdentifierToSymbolDefinition(IdentifierNode* identifierNodeSymbol* symbol);
101 
102 class SymbolTable 
103 {
104 public:
105     SymbolTable(Module* module_);
106     ~SymbolTable();
107     void Write(SymbolWriter& writer);
108     void Read(SymbolReader& reader);
109     void Import(const SymbolTable& symbolTable);
110     void FinishRead(const std::std::vector<ArrayTypeSymbol*>&arrayTypesconststd::std::vector<DerivedTypeSymbol*>&derivedTypes
111         const std::std::vector<ClassTemplateSpecializationSymbol*>&classTemplateSpecializations
112         const std::std::vector<TypeOrConceptRequest>&typeAndConceptRequestsconststd::std::vector<FunctionRequest>&functionRequestsstd::std::vector<FunctionSymbol*>&conversions);
113     void Clear();
114     const NamespaceSymbol& GlobalNs() const { return globalNs; }
115     NamespaceSymbol& GlobalNs() { return globalNs; }
116     const ContainerSymbol* Container() const { return container; }
117     ContainerSymbol* Container() { return container; }
118     void SetCurrentCompileUnit(CompileUnitNode* currentCompileUnit_) { currentCompileUnit = currentCompileUnit_; }
119     void BeginContainer(ContainerSymbol* container_);
120     void EndContainer();
121     void MapNs(NamespaceSymbol* fromNsNamespaceSymbol* toNs);
122     NamespaceSymbol* GetMappedNs(NamespaceSymbol* fromNs) const;
123     NamespaceSymbol* BeginNamespace(NamespaceNode& namespaceNode);
124     NamespaceSymbol* BeginNamespace(const std::u32string& namespaceNameconst Span& spanconst boost::uuids::uuid& sourceModuleId);
125     void EndNamespace();
126     void BeginFunction(FunctionNode& functionNodeint32_t functionIndex);
127     void EndFunction(bool addMember);
128     void AddParameter(ParameterNode& parameterNode);
129     void BeginClass(ClassNode& classNode);
130     void EndClass();
131     void BeginClassTemplateSpecialization(ClassNode& classInstanceNodeClassTemplateSpecializationSymbol* classTemplateSpecialization);
132     void EndClassTemplateSpecialization();
133     void AddTemplateParameter(TemplateParameterNode& templateParameterNode);
134     void AddTemplateParameter(IdentifierNode& identifierNode);
135     void BeginInterface(InterfaceNode& interfaceNode);
136     void EndInterface();
137     void BeginStaticConstructor(StaticConstructorNode& staticConstructorNodeint32_t functionIndex);
138     void EndStaticConstructor(bool addMember);
139     void BeginConstructor(ConstructorNode& constructorNodeint32_t functionIndex);
140     void EndConstructor(bool addMember);
141     void BeginDestructor(DestructorNode& destructorNodeint32_t functionIndex);
142     void EndDestructor(bool addMember);
143     void BeginMemberFunction(MemberFunctionNode& memberFunctionNodeint32_t functionIndex);
144     void EndMemberFunction(bool addMember);
145     void BeginConversionFunction(ConversionFunctionNode& conversionFunctionNodeint32_t functionIndex);
146     void EndConversionFunction(bool addMember);
147     void AddMemberVariable(MemberVariableNode& memberVariableNode);
148     void BeginDelegate(DelegateNode& delegateNode);
149     void EndDelegate();
150     void BeginClassDelegate(ClassDelegateNode& classDelegateNode);
151     void EndClassDelegate();
152     void BeginConcept(ConceptNode& conceptNodebool hasSource);
153     void EndConcept();
154     void BeginAxiom(AxiomNode& axiomNode);
155     void EndAxiom();
156     void BeginDeclarationBlock(Node& node);
157     void EndDeclarationBlock();
158     void AddLocalVariable(ConstructionStatementNode& constructionStatementNode);
159     void AddLocalVariable(IdentifierNode& identifierNode);
160     TypedefSymbol* AddTypedef(TypedefNode& typedefNode);
161     ConstantSymbol* AddConstant(ConstantNode& constantNode);
162     GlobalVariableSymbol* AddGlobalVariable(GlobalVariableNode& globalVariableNode);
163     void BeginEnumType(EnumTypeNode& enumTypeNode);
164     void EndEnumType();
165     void AddEnumConstant(EnumConstantNode& enumConstantNode);
166     void AddTypeSymbolToGlobalScope(TypeSymbol* typeSymbol);
167     void AddFunctionSymbolToGlobalScope(FunctionSymbol* functionSymbol);
168     void MapNode(Node* nodeSymbol* symbol);
169     Symbol* GetSymbolNoThrow(Node* node) const;
170     Symbol* GetSymbol(Node* node) const;
171     Node* GetNodeNoThrow(Symbol* symbol) const;
172     Node* GetNode(Symbol* symbol) const;
173     void SetTypeIdFor(TypeSymbol* typeSymbol);
174     void SetTypeIdFor(ConceptSymbol* conceptSymbol);
175     void SetFunctionIdFor(FunctionSymbol* functionSymbol);
176     FunctionSymbol* GetFunctionById(const boost::uuids::uuid& functionId) const;
177     void AddTypeOrConceptSymbolToTypeIdMap(Symbol* typeOrConceptSymbol);
178     void AddFunctionSymbolToFunctionIdMap(FunctionSymbol* functionSymbol);
179     void EmplaceTypeRequest(SymbolReader& readerSymbol* forSymbolconst boost::uuids::uuid& typeIdint index);
180     void EmplaceConceptRequest(SymbolReader& readerSymbol* forSymbolconst boost::uuids::uuid& typeId);
181     void EmplaceFunctionRequest(SymbolReader& readerSymbol* forSymbolconst boost::uuids::uuid& functionIdint index);
182     void ProcessTypeConceptAndFunctionRequests(const std::std::vector<TypeOrConceptRequest>&typeAndConceptRequestsconststd::std::vector<FunctionRequest>&functionRequests);
183     TypeSymbol* GetTypeByNameNoThrow(const std::u32string& typeName) const;
184     TypeSymbol* GetTypeByName(const std::u32string& typeName) const;
185     TypeSymbol* MakeDerivedType(TypeSymbol* baseTypeconst TypeDerivationRec& derivationRecconst Span& spanconst boost::uuids::uuid& moduleId);
186     ClassTemplateSpecializationSymbol* MakeClassTemplateSpecialization(ClassTypeSymbol* classTemplateconst std::std::vector<TypeSymbol*>&templateArgumentTypes
187         const Span& spanconst boost::uuids::uuid& moduleId);
188     ClassTemplateSpecializationSymbol* CopyClassTemplateSpecialization(ClassTemplateSpecializationSymbol* source);
189     ClassTemplateSpecializationSymbol* GetCurrentClassTemplateSpecialization(ClassTemplateSpecializationSymbol* source);
190     void AddClassTemplateSpecializationsToClassTemplateSpecializationMap(const std::std::vector<ClassTemplateSpecializationSymbol*>&classTemplateSpecializations);
191     ArrayTypeSymbol* MakeArrayType(TypeSymbol* elementTypeint64_t sizeconst Span& spanconst boost::uuids::uuid& moduleId);
192     const FunctionSymbol* MainFunctionSymbol() const { return mainFunctionSymbol; }
193     FunctionSymbol* MainFunctionSymbol() { return mainFunctionSymbol; }
194     void AddConversion(FunctionSymbol* conversion);
195     void AddConversion(FunctionSymbol* conversionModule* module);
196     FunctionSymbol* GetConversion(TypeSymbol* sourceTypeTypeSymbol* targetTypeconst Span& spanconst boost::uuids::uuid& moduleId) const;
197     ConversionTable& GetConversionTable() { return conversionTable; }
198     const ConversionTable& GetConversionTable() const { return conversionTable; }
199     void AddPolymorphicClass(ClassTypeSymbol* polymorphicClass);
200     const std::std::unordered_set<ClassTypeSymbol*>&PolymorphicClasses() const{returnpolymorphicClasses;}
201     void AddClassHavingStaticConstructor(ClassTypeSymbol* classHavingStaticConstructor);
202     const std::std::unordered_set<ClassTypeSymbol*>&ClassesHavingStaticConstructor() const{returnclassesHavingStaticConstructor;}
203     void AddJsonClass(const std::u32string& jsonClass);
204     const std::std::unordered_set<std::u32string>&JsonClasses() const{returnjsonClasses;}
205     std::vector<TypeSymbol*> Types() const;
206     void Copy(const SymbolTable& that);
207     ClassTypeSymbol* CurrentClass() { return currentClass; }
208     InterfaceTypeSymbol* CurrentInterface() { return currentInterface; }
209     void SetCurrentClass(ClassTypeSymbol* currentClass_) { currentClass = currentClass_; }
210     void SetCurrentFunctionSymbol(FunctionSymbol* currentFunctionSymbol_) { currentFunctionSymbol = currentFunctionSymbol_; }
211     void MapProfiledFunction(const boost::uuids::uuid& functionIdconst std::u32string& profiledFunctionName);
212     std::u32string GetProfiledFunctionName(const boost::uuids::uuid& functionId) const;
213     Module* GetModule() { return module; }
214     std::unique_ptr<sngxml::dom::Document> ToDomDocument();
215     void MapInvoke(IdentifierNode* invokeIdFunctionSymbol* functionSymbol);
216     FunctionSymbol* GetInvoke(IdentifierNode* invokeId) const;
217     void MapSymbol(Node* nodeSymbol* symbol);
218     Symbol* GetMappedSymbol(Node* node) const;
219     void MapIdentifierToSymbolDefinition(IdentifierNode* identifierNodeModule* moduleSymbol* symbol);
220     SymbolLocation* GetDefinitionLocation(const SymbolLocation& identifierLocation);
221     void InitUuids();
222     const boost::uuids::uuid& GetDerivationId(Derivation derivation) const;
223     const boost::uuids::uuid& GetPositionId(int index) const;
224     int NumSpecializations() const { return classTemplateSpecializationMap.size(); }
225     int NumSpecializationsNew() const { return numSpecializationsNew; }
226     int NumSpecializationsCopied() const { return numSpecializationsCopied; }
227     void Check();
228     FunctionSymbol* GetCreatedFunctionSymbol() { return createdFunctionSymbol; }
229     void AddFunctionSymbol(std::std::unique_ptr<FunctionSymbol>&&functionSymbol);
230     void ResetCursorContainer() { cursorContainer = nullptr; }
231     ContainerSymbol* CursorContainer() const { return cursorContainer; }
232     void SetCursorContainer(const sngcm::ast::Node& node);
233     int NextAxiomNumber() { return axiomNumber++; }
234     void ResetAxiomNumber() { axiomNumber = 0; }
235     void ResetAliasNodesAndNamespaceImports();
236     void ResetMainFunctionSymbol() { mainFunctionSymbol = nullptr; }
237     const std::std::vector<AliasNode*>&AliasNodes() const{returnaliasNodes;}
238     void AddAliasNode(AliasNode* aliasNode) { aliasNodes.push_back(aliasNode); }
239     const std::std::vector<NamespaceImportNode*>&NamespaceImports() const{returnnamespaceImports;}
240     void AddNamespaceImport(NamespaceImportNode* namespaceImport) { namespaceImports.push_back(namespaceImport); }
241 private:
242     Module* module;
243     std::vector<boost::uuids::uuid> derivationIds;
244     std::vector<boost::uuids::uuid> positionIds;
245     NamespaceSymbol globalNs;
246     std::vector<AliasNode*> aliasNodes;
247     std::vector<NamespaceImportNode*> namespaceImports;
248     std::unordered_map<IdentifierNode*Symbol*> identifierSymbolDefinitionMap;
249     std::map<SymbolLocationSymbolLocation> symbolDefinitionMap;
250     CompileUnitNode* currentCompileUnit;
251     ContainerSymbol* container;
252     ContainerSymbol* cursorContainer;
253     ClassTypeSymbol* currentClass;
254     std::stack<ClassTypeSymbol*> currentClassStack;
255     InterfaceTypeSymbol* currentInterface;
256     std::stack<InterfaceTypeSymbol*> currentInterfaceStack;
257     std::stack<ContainerSymbol*> containerStack;
258     FunctionSymbol* mainFunctionSymbol;
259     FunctionSymbol* currentFunctionSymbol;
260     FunctionSymbol* createdFunctionSymbol;
261     int parameterIndex;
262     int declarationBlockIndex;
263     int axiomNumber;
264     std::unordered_map<NamespaceSymbol*NamespaceSymbol*> nsMap;
265     std::unordered_map<Node*Symbol*> nodeSymbolMap;
266     std::unordered_map<Symbol*Node*> symbolNodeMap;
267     std::unordered_map<boost::uuids::uuidSymbol*boost::boost::hash<boost::uuids::uuid>>typeIdMap;
268     std::unordered_map<boost::uuids::uuidFunctionSymbol*boost::boost::hash<boost::uuids::uuid>>functionIdMap;
269     std::unordered_map<std::u32stringTypeSymbol*> typeNameMap;
270     std::unordered_map<boost::uuids::uuidstd::u32stringboost::boost::hash<boost::uuids::uuid>>profiledFunctionNameMap;
271     std::unordered_map<boost::uuids::uuidstd::std::vector<DerivedTypeSymbol*>boost::boost::hash<boost::uuids::uuid>>derivedTypeMap;
272     std::vector<std::std::unique_ptr<DerivedTypeSymbol>>derivedTypes;
273     std::unordered_map<ClassTemplateSpecializationKeyClassTemplateSpecializationSymbol*ClassTemplateSpecializationKeyHash> classTemplateSpecializationMap;
274     std::vector<std::std::unique_ptr<ClassTemplateSpecializationSymbol>>classTemplateSpecializations;
275     std::unordered_map<ClassTemplateSpecializationSymbol*ClassTemplateSpecializationSymbol*> specializationCopyMap;
276     std::unordered_map<ArrayKeyArrayTypeSymbol*ArrayKeyHash> arrayTypeMap;
277     std::vector<std::std::unique_ptr<ArrayTypeSymbol>>arrayTypes;
278     std::unordered_map<IdentifierNode*FunctionSymbol*> invokeMap;
279     std::unordered_map<Node*Symbol*> mappedNodeSymbolMap;
280     std::vector<std::std::unique_ptr<FunctionSymbol>>functionSymbols;
281     ConversionTable conversionTable;
282     std::unordered_set<ClassTypeSymbol*> polymorphicClasses;
283     std::unordered_set<ClassTypeSymbol*> classesHavingStaticConstructor;
284     std::unordered_set<std::u32string> jsonClasses;
285     int numSpecializationsCopied;
286     int numSpecializationsNew;
287     int GetNextDeclarationBlockIndex() { return declarationBlockIndex++; }
288     void ResetDeclarationBlockIndex() { declarationBlockIndex = 0; }
289     void EmplaceTypeOrConceptRequest(SymbolReader& readerSymbol* forSymbolconst boost::uuids::uuid& typeIdint index);
290     void WriteSymbolDefinitionMap(SymbolWriter& writer);
291     void ReadSymbolDefinitionMap(SymbolReader& reader);
292 };
293 
294 void InitCoreSymbolTable(SymbolTable& symbolTable);
295 
296 void InitSymbolTable();
297 void DoneSymbolTable();
298 
299 } } // namespace cmajor::symbols
300 
301 #endif // CMAJOR_SYMBOLS_SYMBOL_TABLE_INCLUDED