1
2
3
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& left, const ClassTemplateSpecializationKey& right);
78 bool operator!=(const ClassTemplateSpecializationKey& left, const 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& left, const ArrayKey& right);
88 bool operator!=(const ArrayKey& left, const 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* identifierNode, Symbol* 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*>&arrayTypes, conststd::std::vector<DerivedTypeSymbol*>&derivedTypes,
111 const std::std::vector<ClassTemplateSpecializationSymbol*>&classTemplateSpecializations,
112 const std::std::vector<TypeOrConceptRequest>&typeAndConceptRequests, conststd::std::vector<FunctionRequest>&functionRequests, std::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* fromNs, NamespaceSymbol* toNs);
122 NamespaceSymbol* GetMappedNs(NamespaceSymbol* fromNs) const;
123 NamespaceSymbol* BeginNamespace(NamespaceNode& namespaceNode);
124 NamespaceSymbol* BeginNamespace(const std::u32string& namespaceName, const Span& span, const boost::uuids::uuid& sourceModuleId);
125 void EndNamespace();
126 void BeginFunction(FunctionNode& functionNode, int32_t functionIndex);
127 void EndFunction(bool addMember);
128 void AddParameter(ParameterNode& parameterNode);
129 void BeginClass(ClassNode& classNode);
130 void EndClass();
131 void BeginClassTemplateSpecialization(ClassNode& classInstanceNode, ClassTemplateSpecializationSymbol* 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& staticConstructorNode, int32_t functionIndex);
138 void EndStaticConstructor(bool addMember);
139 void BeginConstructor(ConstructorNode& constructorNode, int32_t functionIndex);
140 void EndConstructor(bool addMember);
141 void BeginDestructor(DestructorNode& destructorNode, int32_t functionIndex);
142 void EndDestructor(bool addMember);
143 void BeginMemberFunction(MemberFunctionNode& memberFunctionNode, int32_t functionIndex);
144 void EndMemberFunction(bool addMember);
145 void BeginConversionFunction(ConversionFunctionNode& conversionFunctionNode, int32_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& conceptNode, bool 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* node, Symbol* 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& reader, Symbol* forSymbol, const boost::uuids::uuid& typeId, int index);
180 void EmplaceConceptRequest(SymbolReader& reader, Symbol* forSymbol, const boost::uuids::uuid& typeId);
181 void EmplaceFunctionRequest(SymbolReader& reader, Symbol* forSymbol, const boost::uuids::uuid& functionId, int index);
182 void ProcessTypeConceptAndFunctionRequests(const std::std::vector<TypeOrConceptRequest>&typeAndConceptRequests, conststd::std::vector<FunctionRequest>&functionRequests);
183 TypeSymbol* GetTypeByNameNoThrow(const std::u32string& typeName) const;
184 TypeSymbol* GetTypeByName(const std::u32string& typeName) const;
185 TypeSymbol* MakeDerivedType(TypeSymbol* baseType, const TypeDerivationRec& derivationRec, const Span& span, const boost::uuids::uuid& moduleId);
186 ClassTemplateSpecializationSymbol* MakeClassTemplateSpecialization(ClassTypeSymbol* classTemplate, const std::std::vector<TypeSymbol*>&templateArgumentTypes,
187 const Span& span, const 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* elementType, int64_t size, const Span& span, const 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* conversion, Module* module);
196 FunctionSymbol* GetConversion(TypeSymbol* sourceType, TypeSymbol* targetType, const Span& span, const 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& functionId, const 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* invokeId, FunctionSymbol* functionSymbol);
216 FunctionSymbol* GetInvoke(IdentifierNode* invokeId) const;
217 void MapSymbol(Node* node, Symbol* symbol);
218 Symbol* GetMappedSymbol(Node* node) const;
219 void MapIdentifierToSymbolDefinition(IdentifierNode* identifierNode, Module* module, Symbol* 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<SymbolLocation, SymbolLocation> 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::uuid, Symbol*, boost::boost::hash<boost::uuids::uuid>>typeIdMap;
268 std::unordered_map<boost::uuids::uuid, FunctionSymbol*, boost::boost::hash<boost::uuids::uuid>>functionIdMap;
269 std::unordered_map<std::u32string, TypeSymbol*> typeNameMap;
270 std::unordered_map<boost::uuids::uuid, std::u32string, boost::boost::hash<boost::uuids::uuid>>profiledFunctionNameMap;
271 std::unordered_map<boost::uuids::uuid, std::std::vector<DerivedTypeSymbol*>, boost::boost::hash<boost::uuids::uuid>>derivedTypeMap;
272 std::vector<std::std::unique_ptr<DerivedTypeSymbol>>derivedTypes;
273 std::unordered_map<ClassTemplateSpecializationKey, ClassTemplateSpecializationSymbol*, ClassTemplateSpecializationKeyHash> classTemplateSpecializationMap;
274 std::vector<std::std::unique_ptr<ClassTemplateSpecializationSymbol>>classTemplateSpecializations;
275 std::unordered_map<ClassTemplateSpecializationSymbol*, ClassTemplateSpecializationSymbol*> specializationCopyMap;
276 std::unordered_map<ArrayKey, ArrayTypeSymbol*, 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& reader, Symbol* forSymbol, const boost::uuids::uuid& typeId, int 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 } }
300
301 #endif // CMAJOR_SYMBOLS_SYMBOL_TABLE_INCLUDED