1
2
3
4
5
6 #include <cmajor/symbols/SymbolTable.hpp>
7 #include <cmajor/symbols/SymbolWriter.hpp>
8 #include <cmajor/symbols/SymbolReader.hpp>
9 #include <cmajor/symbols/BasicTypeSymbol.hpp>
10 #include <cmajor/symbols/BasicTypeOperation.hpp>
11 #include <cmajor/symbols/FunctionSymbol.hpp>
12 #include <cmajor/symbols/ClassTypeSymbol.hpp>
13 #include <cmajor/symbols/InterfaceTypeSymbol.hpp>
14 #include <cmajor/symbols/DelegateSymbol.hpp>
15 #include <cmajor/symbols/TypedefSymbol.hpp>
16 #include <cmajor/symbols/VariableSymbol.hpp>
17 #include <cmajor/symbols/ConstantSymbol.hpp>
18 #include <cmajor/symbols/EnumSymbol.hpp>
19 #include <cmajor/symbols/Exception.hpp>
20 #include <cmajor/symbols/TemplateSymbol.hpp>
21 #include <cmajor/symbols/ConceptSymbol.hpp>
22 #include <cmajor/symbols/StringFunctions.hpp>
23 #include <cmajor/symbols/GlobalFlags.hpp>
24 #include <cmajor/symbols/Module.hpp>
25 #include <cmajor/symbols/ModuleCache.hpp>
26 #include <cmajor/symbols/DebugFlags.hpp>
27 #include <sngcm/ast/Identifier.hpp>
28 #include <soulng/util/Unicode.hpp>
29 #include <soulng/util/Log.hpp>
30 #include <soulng/util/Time.hpp>
31 #include <boost/filesystem.hpp>
32 #include <boost/uuid/uuid_generators.hpp>
33
34 namespace cmajor { namespace symbols {
35
36 using namespace soulng::unicode;
37
38 bool operator==(const ClassTemplateSpecializationKey& left, const ClassTemplateSpecializationKey& right)
39 {
40 if (!TypesEqual(left.classTemplate, right.classTemplate)) return false;
41 int n = left.templateArgumentTypes.size();
42 if (n != right.templateArgumentTypes.size()) return false;
43 for (int i = 0; i < n; ++i)
44 {
45 if (!TypesEqual(left.templateArgumentTypes[i], right.templateArgumentTypes[i])) return false;
46 }
47 return true;
48 }
49
50 bool operator!=(const ClassTemplateSpecializationKey& left, const ClassTemplateSpecializationKey& right)
51 {
52 return !(left == right);
53 }
54
55 bool operator==(const ArrayKey& left, const ArrayKey& right)
56 {
57 if (!TypesEqual(left.elementType, right.elementType)) return false;
58 if (left.size != right.size) return false;
59 return true;
60 }
61
62 bool operator!=(const ArrayKey& left, const ArrayKey& right)
63 {
64 return !(left == right);
65 }
66
67 void MapIdentifierToSymbolDefinition(IdentifierNode* identifierNode, Symbol* symbol)
68 {
69 if (identifierNode->IsInternal()) return;
70 if (!identifierNode->GetSpan().Valid()) return;
71 if (identifierNode->ModuleId().is_nil()) return;
72 if (symbol->SourceModuleId().is_nil()) return;
73 if (!symbol->GetSpan().Valid()) return;
74 Module* module = GetModuleById(identifierNode->ModuleId());
75 if (!module) return;
76 if (module->IsImmutable()) return;
77 module->GetSymbolTable().MapIdentifierToSymbolDefinition(identifierNode, module, symbol);
78 }
79
80 SymbolTable::SymbolTable(Module* module_) :
81 module(module_), globalNs(Span(), boost::uuids::nil_uuid(), std::u32string()), currentCompileUnit(nullptr), container(&globalNs), currentClass(nullptr), currentInterface(nullptr),
82 mainFunctionSymbol(nullptr), currentFunctionSymbol(nullptr), parameterIndex(0), declarationBlockIndex(0), conversionTable(ConversionTable::Owner::symbolTable, module),
83 numSpecializationsNew(0), numSpecializationsCopied(0), createdFunctionSymbol(nullptr), cursorContainer(nullptr), axiomNumber(0)
84 {
85 globalNs.SetModule(module);
86 }
87
88 SymbolTable::~SymbolTable()
89 {
90 }
91
92 void SymbolTable::Write(SymbolWriter& writer)
93 {
94 if (module->Name() == U"System.Core")
95 {
96 uint32_t numDerivationIds = derivationIds.size();
97 writer.GetBinaryWriter().WriteULEB128UInt(numDerivationIds);
98 for (uint32_t i = 0; i < numDerivationIds; ++i)
99 {
100 writer.GetBinaryWriter().Write(derivationIds[i]);
101 }
102 uint32_t numPositionIds = positionIds.size();
103 writer.GetBinaryWriter().WriteULEB128UInt(numPositionIds);
104 for (uint32_t i = 0; i < numPositionIds; ++i)
105 {
106 writer.GetBinaryWriter().Write(positionIds[i]);
107 }
108 }
109 globalNs.Write(writer);
110 WriteSymbolDefinitionMap(writer);
111 std::vector<ArrayTypeSymbol*> exportedArrayTypes;
112 for (const std::std::unique_ptr<ArrayTypeSymbol>&arrayType : arrayTypes)
113 {
114 if (arrayType->IsProject())
115 {
116 exportedArrayTypes.push_back(arrayType.get());
117 }
118 }
119 uint32_t na = exportedArrayTypes.size();
120 writer.GetBinaryWriter().WriteULEB128UInt(na);
121 for (ArrayTypeSymbol* exportedArrayType : exportedArrayTypes)
122 {
123 writer.Write(exportedArrayType);
124 }
125 std::vector<TypeSymbol*> exportedDerivedTypes;
126 std::unordered_map<boost::uuids::uuid, TypeSymbol*, boost::boost::hash<boost::uuids::uuid>>derivedTypeMap;
127 for (const auto& derivedType : derivedTypes)
128 {
129 if (derivedType->IsProject())
130 {
131 derivedTypeMap[derivedType->TypeId()] = derivedType.get();
132 }
133 }
134 for (const auto& p : derivedTypeMap)
135 {
136 exportedDerivedTypes.push_back(p.second);
137 }
138 uint32_t ned = exportedDerivedTypes.size();
139 writer.GetBinaryWriter().WriteULEB128UInt(ned);
140 for (TypeSymbol* exportedDerivedType : exportedDerivedTypes)
141 {
142 writer.Write(exportedDerivedType);
143 }
144 std::vector<TypeSymbol*> exportedClassTemplateSpecializations;
145 std::unordered_map<boost::uuids::uuid, TypeSymbol*, boost::boost::hash<boost::uuids::uuid>>specializationMap;
146 for (const auto& classTemplateSpecialization : classTemplateSpecializations)
147 {
148 if (classTemplateSpecialization->IsProject())
149 {
150 specializationMap[classTemplateSpecialization->TypeId()] = classTemplateSpecialization.get();
151 }
152 }
153 for (const auto& p : specializationMap)
154 {
155 exportedClassTemplateSpecializations.push_back(p.second);
156 }
157 uint32_t nec = exportedClassTemplateSpecializations.size();
158 writer.GetBinaryWriter().WriteULEB128UInt(nec);
159 for (TypeSymbol* classTemplateSpecialization : exportedClassTemplateSpecializations)
160 {
161 writer.Write(classTemplateSpecialization);
162 }
163 uint32_t nj = jsonClasses.size();
164 writer.GetBinaryWriter().WriteULEB128UInt(nj);
165 for (const std::u32string& jsonClass : jsonClasses)
166 {
167 writer.GetBinaryWriter().Write(jsonClass);
168 }
169 if (GetGlobalFlag(GlobalFlags::profile))
170 {
171 uint32_t n = profiledFunctionNameMap.size();
172 writer.GetBinaryWriter().WriteULEB128UInt(n);
173 for (const auto& p : profiledFunctionNameMap)
174 {
175 writer.GetBinaryWriter().Write(p.first);
176 writer.GetBinaryWriter().Write(p.second);
177 }
178 }
179 }
180
181 void SymbolTable::Read(SymbolReader& reader)
182 {
183 reader.SetSymbolTable(this);
184 if (module->Name() == U"System.Core")
185 {
186 uint32_t numDerivationIds = reader.GetBinaryReader().ReadULEB128UInt();
187 for (uint32_t i = 0; i < numDerivationIds; ++i)
188 {
189 boost::uuids::uuid derivationId;
190 reader.GetBinaryReader().ReadUuid(derivationId);
191 derivationIds.push_back(derivationId);
192 }
193 uint32_t numPositionIds = reader.GetBinaryReader().ReadULEB128UInt();
194 for (uint32_t i = 0; i < numPositionIds; ++i)
195 {
196 boost::uuids::uuid positionId;
197 reader.GetBinaryReader().ReadUuid(positionId);
198 positionIds.push_back(positionId);
199 }
200 }
201 globalNs.Read(reader);
202 ReadSymbolDefinitionMap(reader);
203 uint32_t na = reader.GetBinaryReader().ReadULEB128UInt();
204 for (uint32_t i = 0; i < na; ++i)
205 {
206 ArrayTypeSymbol* arrayTypeSymbol = reader.ReadArrayTypeSymbol(&globalNs);
207 arrayTypes.push_back(std::unique_ptr<ArrayTypeSymbol>(arrayTypeSymbol));
208 reader.AddArrayType(arrayTypeSymbol);
209 }
210 uint32_t nd = reader.GetBinaryReader().ReadULEB128UInt();
211 for (uint32_t i = 0; i < nd; ++i)
212 {
213 DerivedTypeSymbol* derivedTypeSymbol = reader.ReadDerivedTypeSymbol(&globalNs);
214 derivedTypes.push_back(std::unique_ptr<DerivedTypeSymbol>(derivedTypeSymbol));
215 reader.AddDerivedType(derivedTypeSymbol);
216 }
217 uint32_t nc = reader.GetBinaryReader().ReadULEB128UInt();
218 for (uint32_t i = 0; i < nc; ++i)
219 {
220 ClassTemplateSpecializationSymbol* classTemplateSpecialization = reader.ReadClassTemplateSpecializationSymbol(&globalNs);
221 classTemplateSpecializations.push_back(std::unique_ptr<ClassTemplateSpecializationSymbol>(classTemplateSpecialization));
222 reader.AddClassTemplateSpecialization(classTemplateSpecialization);
223 }
224 uint32_t nj = reader.GetBinaryReader().ReadULEB128UInt();
225 for (uint32_t i = 0; i < nj; ++i)
226 {
227 std::u32string jsonClass = reader.GetBinaryReader().ReadUtf32String();
228 jsonClasses.insert(jsonClass);
229 }
230 if (GetGlobalFlag(GlobalFlags::profile))
231 {
232 uint32_t n = reader.GetBinaryReader().ReadULEB128UInt();
233 for (uint32_t i = 0; i < n; ++i)
234 {
235 boost::uuids::uuid functionId;
236 reader.GetBinaryReader().ReadUuid(functionId);
237 std::u32string profiledFunctionName = reader.GetBinaryReader().ReadUtf32String();
238 MapProfiledFunction(functionId, profiledFunctionName);
239 }
240 }
241 }
242
243 void SymbolTable::Import(const SymbolTable& symbolTable)
244 {
245 globalNs.Import(const_cast<NamespaceSymbol*>(&symbolTable.globalNs), *this);
246 for (const auto& pair : symbolTable.typeIdMap)
247 {
248 Symbol* typeOrConcept = pair.second;
249 if (typeOrConcept->IsTypeSymbol())
250 {
251 TypeSymbol* type = static_cast<TypeSymbol*>(typeOrConcept);
252 typeIdMap[type->TypeId()] = type;
253 typeNameMap[type->FullName()] = type;
254 }
255 else if (typeOrConcept->GetSymbolType() == SymbolType::conceptSymbol)
256 {
257 ConceptSymbol* conceptSymbol = static_cast<ConceptSymbol*>(typeOrConcept);
258 typeIdMap[conceptSymbol->TypeId()] = conceptSymbol;
259 }
260 else
261 {
262 Assert(false, "type or concept symbol expected");
263 }
264 }
265 for (const auto& pair : symbolTable.functionIdMap)
266 {
267 FunctionSymbol* function = pair.second;
268 functionIdMap[function->FunctionId()] = function;
269 }
270 for (const auto& p : symbolTable.derivedTypeMap)
271 {
272 derivedTypeMap[p.first] = p.second;
273 }
274 for (const auto& p : symbolTable.classTemplateSpecializationMap)
275 {
276 classTemplateSpecializationMap[p.first] = p.second;
277 }
278 for (const auto& p : symbolTable.arrayTypeMap)
279 {
280 arrayTypeMap[p.first] = p.second;
281 }
282 conversionTable.Add(symbolTable.conversionTable);
283 for (ClassTypeSymbol* polymorphicClass : symbolTable.PolymorphicClasses())
284 {
285 AddPolymorphicClass(polymorphicClass);
286 }
287 for (ClassTypeSymbol* classHavingStaticConstructor : symbolTable.ClassesHavingStaticConstructor())
288 {
289 AddClassHavingStaticConstructor(classHavingStaticConstructor);
290 }
291 for (const std::u32string& jsonClass : symbolTable.JsonClasses())
292 {
293 AddJsonClass(jsonClass);
294 }
295 if (GetGlobalFlag(GlobalFlags::profile))
296 {
297 for (const auto& p : symbolTable.profiledFunctionNameMap)
298 {
299 const boost::uuids::uuid& functionId = p.first;
300 const std::u32string& profiledFunctionName = p.second;
301 MapProfiledFunction(functionId, profiledFunctionName);
302 }
303 }
304 }
305
306 void SymbolTable::FinishRead(const std::std::vector<ArrayTypeSymbol*>&arrayTypes, conststd::std::vector<DerivedTypeSymbol*>&derivedTypes,
307 const std::std::vector<ClassTemplateSpecializationSymbol*>&classTemplateSpecializations, conststd::std::vector<TypeOrConceptRequest>&typeAndConceptRequests,
308 const std::std::vector<FunctionRequest>&functionRequests, std::std::vector<FunctionSymbol*>&conversions)
309 {
310 ProcessTypeConceptAndFunctionRequests(typeAndConceptRequests, functionRequests);
311 for (FunctionSymbol* conversion : conversions)
312 {
313 AddConversion(conversion, module);
314 }
315 for (ArrayTypeSymbol* arrayTypeSymbol : arrayTypes)
316 {
317 ArrayKey key(arrayTypeSymbol->ElementType(), arrayTypeSymbol->Size());
318 arrayTypeMap[key] = arrayTypeSymbol;
319 }
320 for (DerivedTypeSymbol* derivedTypeSymbol : derivedTypes)
321 {
322 std::std::vector<DerivedTypeSymbol*>&derivedTypeVec=derivedTypeMap[derivedTypeSymbol->BaseType()->TypeId()];
323 int n = derivedTypeVec.size();
324 bool found = false;
325 for (int i = 0; i < n; ++i)
326 {
327 DerivedTypeSymbol* prevDerivedTypeSymbol = derivedTypeVec[i];
328 if (prevDerivedTypeSymbol->DerivationRec() == derivedTypeSymbol->DerivationRec())
329 {
330 found = true;
331 break;
332 }
333 }
334 if (!found)
335 {
336 derivedTypeVec.push_back(derivedTypeSymbol);
337 }
338 }
339 AddClassTemplateSpecializationsToClassTemplateSpecializationMap(classTemplateSpecializations);
340 }
341
342 void SymbolTable::Clear()
343 {
344 globalNs.Clear();
345 typeIdMap.clear();
346 functionIdMap.clear();
347 typeNameMap.clear();
348 profiledFunctionNameMap.clear();
349 }
350
351 void SymbolTable::BeginContainer(ContainerSymbol* container_)
352 {
353 #ifdef IMMUTABLE_MODULE_CHECK
354
355
356
357
358 #endif
359 containerStack.push(container);
360 container = container_;
361 }
362
363 void SymbolTable::EndContainer()
364 {
365 container = containerStack.top();
366 containerStack.pop();
367 }
368
369 void SymbolTable::MapNs(NamespaceSymbol* fromNs, NamespaceSymbol* toNs)
370 {
371 nsMap[fromNs] = toNs;
372 }
373
374 NamespaceSymbol* SymbolTable::GetMappedNs(NamespaceSymbol* fromNs) const
375 {
376 auto it = nsMap.find(fromNs);
377 if (it != nsMap.cend())
378 {
379 return it->second;
380 }
381 return nullptr;
382 }
383
384 NamespaceSymbol* SymbolTable::BeginNamespace(NamespaceNode& namespaceNode)
385 {
386 std::u32string nsName = namespaceNode.Id()->Str();
387 NamespaceSymbol* ns = BeginNamespace(nsName, namespaceNode.GetSpan(), namespaceNode.ModuleId());
388 MapNode(&namespaceNode, container);
389 return ns;
390 }
391
392 NamespaceSymbol* SymbolTable::BeginNamespace(const std::u32string& namespaceName, const Span& span, const boost::uuids::uuid& sourceModuleId)
393 {
394 if (namespaceName.empty())
395 {
396 if (!globalNs.GetSpan().Valid())
397 {
398 globalNs.SetSpan(span);
399 }
400 BeginContainer(&globalNs);
401 return &globalNs;
402 }
403 else
404 {
405 Symbol* symbol = container->GetContainerScope()->Lookup(namespaceName);
406 if (symbol)
407 {
408 if (symbol->GetSymbolType() == SymbolType::namespaceSymbol)
409 {
410 NamespaceSymbol* ns = static_cast<NamespaceSymbol*>(symbol);
411 BeginContainer(ns);
412 return ns;
413 }
414 else
415 {
416 throw Exception("symbol '" + ToUtf8(symbol->Name()) + "' does not denote a namespace", symbol->GetSpan(), symbol->SourceModuleId());
417 }
418 }
419 else
420 {
421 NamespaceSymbol* ns = container->GetContainerScope()->CreateNamespace(namespaceName, span, sourceModuleId);
422 BeginContainer(ns);
423 return ns;
424 }
425 }
426 }
427
428 void SymbolTable::EndNamespace()
429 {
430 EndContainer();
431 }
432
433 void SymbolTable::BeginFunction(FunctionNode& functionNode, int32_t functionIndex)
434 {
435 FunctionSymbol* functionSymbol = new FunctionSymbol(functionNode.GetSpan(), functionNode.ModuleId(), functionNode.GroupId());
436 SetFunctionIdFor(functionSymbol);
437 functionSymbol->SetIndex(functionIndex);
438 if ((functionNode.GetSpecifiers() & Specifiers::constexpr_) != Specifiers::none)
439 {
440 functionSymbol->SetConstExpr();
441 }
442 functionSymbol->SetHasSource();
443 functionSymbol->SetCompileUnit(currentCompileUnit);
444 functionSymbol->SetModule(module);
445 functionSymbol->SetGroupName(functionNode.GroupId());
446 if (functionNode.WhereConstraint())
447 {
448 CloneContext cloneContext;
449 functionSymbol->SetConstraint(static_cast<WhereConstraintNode*>(functionNode.WhereConstraint()->Clone(cloneContext)));
450 }
451 if (functionSymbol->GroupName() == U"main" || functionSymbol->GroupName() == U"wmain" || functionSymbol->GroupName() == U"WinMain" || functionSymbol->GroupName() == U"wWinMain")
452 {
453 if (functionNode.IsProgramMain())
454 {
455 functionSymbol->SetCDecl();
456 functionSymbol->SetProgramMain();
457 }
458 else
459 {
460 if (mainFunctionSymbol)
461 {
462 throw Exception("already has main function", functionNode.GetSpan(), functionNode.ModuleId(), mainFunctionSymbol->GetSpan(), mainFunctionSymbol->SourceModuleId());
463 }
464 else
465 {
466 mainFunctionSymbol = functionSymbol;
467 }
468 }
469 }
470 MapNode(&functionNode, functionSymbol);
471 BeginContainer(functionSymbol);
472 parameterIndex = 0;
473 ResetDeclarationBlockIndex();
474 }
475
476 void SymbolTable::EndFunction(bool addMember)
477 {
478 FunctionSymbol* functionSymbol = static_cast<FunctionSymbol*>(container);
479 EndContainer();
480 if (addMember)
481 {
482 container->AddMember(functionSymbol);
483 }
484 else
485 {
486 createdFunctionSymbol = functionSymbol;
487 }
488 }
489
490 void SymbolTable::AddParameter(ParameterNode& parameterNode)
491 {
492 bool artificialId = false;
493 std::u32string parameterName = ToUtf32("@p" + std::to_string(parameterIndex));
494 if (parameterNode.Id())
495 {
496 parameterName = parameterNode.Id()->Str();
497 }
498 else
499 {
500 parameterNode.SetId(new IdentifierNode(parameterNode.GetSpan(), parameterNode.ModuleId(), parameterName));
501 artificialId = true;
502 }
503 ParameterSymbol* parameterSymbol = new ParameterSymbol(parameterNode.GetSpan(), parameterNode.ModuleId(), parameterName);
504 parameterSymbol->SetCompileUnit(currentCompileUnit);
505 MapNode(¶meterNode, parameterSymbol);
506 container->AddMember(parameterSymbol);
507 ++parameterIndex;
508 if (artificialId)
509 {
510 parameterSymbol->SetArtificialName();
511 }
512 }
513
514 void SymbolTable::BeginClass(ClassNode& classNode)
515 {
516 ClassTypeSymbol* classTypeSymbol = new ClassTypeSymbol(classNode.GetSpan(), classNode.ModuleId(), classNode.Id()->Str());
517 classTypeSymbol->SetGroupName(classNode.Id()->Str());
518 currentClassStack.push(currentClass);
519 currentClass = classTypeSymbol;
520 classTypeSymbol->SetCompileUnit(currentCompileUnit);
521 classTypeSymbol->SetModule(module);
522 MapNode(&classNode, classTypeSymbol);
523 SetTypeIdFor(classTypeSymbol);
524 BeginContainer(classTypeSymbol);
525 }
526
527 void SymbolTable::EndClass()
528 {
529 ClassTypeSymbol* classTypeSymbol = currentClass;
530 currentClass = currentClassStack.top();
531 currentClassStack.pop();
532 EndContainer();
533 classTypeSymbol->ComputeMinArity();
534 container->AddMember(classTypeSymbol);
535 }
536
537 void SymbolTable::BeginClassTemplateSpecialization(ClassNode& classInstanceNode, ClassTemplateSpecializationSymbol* classTemplateSpecialization)
538 {
539 currentClassStack.push(currentClass);
540 currentClass = classTemplateSpecialization;
541 MapNode(&classInstanceNode, classTemplateSpecialization);
542 if (classTemplateSpecialization->TypeIdNotSet())
543 {
544 SetTypeIdFor(classTemplateSpecialization);
545 }
546 BeginContainer(classTemplateSpecialization);
547 }
548
549 void SymbolTable::EndClassTemplateSpecialization()
550 {
551 EndContainer();
552 currentClass = currentClassStack.top();
553 currentClassStack.pop();
554 }
555
556 void SymbolTable::AddTemplateParameter(TemplateParameterNode& templateParameterNode)
557 {
558 TemplateParameterSymbol* templateParameterSymbol = new TemplateParameterSymbol(templateParameterNode.GetSpan(), templateParameterNode.ModuleId(), templateParameterNode.Id()->Str());
559 if (templateParameterNode.DefaultTemplateArgument())
560 {
561 templateParameterSymbol->SetHasDefault();
562 }
563 templateParameterSymbol->SetCompileUnit(currentCompileUnit);
564 templateParameterSymbol->SetModule(module);
565 SetTypeIdFor(templateParameterSymbol);
566 MapNode(&templateParameterNode, templateParameterSymbol);
567 container->AddMember(templateParameterSymbol);
568 }
569
570 void SymbolTable::AddTemplateParameter(IdentifierNode& identifierNode)
571 {
572 TemplateParameterSymbol* templateParameterSymbol = new TemplateParameterSymbol(identifierNode.GetSpan(), identifierNode.ModuleId(), identifierNode.Str());
573 templateParameterSymbol->SetCompileUnit(currentCompileUnit);
574 templateParameterSymbol->SetModule(module);
575 SetTypeIdFor(templateParameterSymbol);
576 MapNode(&identifierNode, templateParameterSymbol);
577 container->AddMember(templateParameterSymbol);
578 }
579
580 void SymbolTable::BeginInterface(InterfaceNode& interfaceNode)
581 {
582 InterfaceTypeSymbol* interfaceTypeSymbol = new InterfaceTypeSymbol(interfaceNode.GetSpan(), interfaceNode.ModuleId(), interfaceNode.Id()->Str());
583 currentInterfaceStack.push(currentInterface);
584 currentInterface = interfaceTypeSymbol;
585 interfaceTypeSymbol->SetCompileUnit(currentCompileUnit);
586 interfaceTypeSymbol->SetModule(module);
587 MapNode(&interfaceNode, interfaceTypeSymbol);
588 SetTypeIdFor(interfaceTypeSymbol);
589 container->AddMember(interfaceTypeSymbol);
590 BeginContainer(interfaceTypeSymbol);
591 }
592
593 void SymbolTable::EndInterface()
594 {
595 currentInterface = currentInterfaceStack.top();
596 currentInterfaceStack.pop();
597 EndContainer();
598 }
599
600 void SymbolTable::BeginStaticConstructor(StaticConstructorNode& staticConstructorNode, int32_t functionIndex)
601 {
602 StaticConstructorSymbol* staticConstructorSymbol = new StaticConstructorSymbol(staticConstructorNode.GetSpan(), staticConstructorNode.ModuleId(), U"@static_constructor");
603 staticConstructorSymbol->SetIndex(functionIndex);
604 SetFunctionIdFor(staticConstructorSymbol);
605 staticConstructorSymbol->SetHasSource();
606 staticConstructorSymbol->SetCompileUnit(currentCompileUnit);
607 staticConstructorSymbol->SetModule(module);
608 if (staticConstructorNode.WhereConstraint())
609 {
610 CloneContext cloneContext;
611 staticConstructorSymbol->SetConstraint(static_cast<WhereConstraintNode*>(staticConstructorNode.WhereConstraint()->Clone(cloneContext)));
612 }
613 MapNode(&staticConstructorNode, staticConstructorSymbol);
614 BeginContainer(staticConstructorSymbol);
615 ResetDeclarationBlockIndex();
616 }
617
618 void SymbolTable::EndStaticConstructor(bool addMember)
619 {
620 StaticConstructorSymbol* staticConstructorSymbol = static_cast<StaticConstructorSymbol*>(container);
621 EndContainer();
622 if (addMember)
623 {
624 container->AddMember(staticConstructorSymbol);
625 }
626 else
627 {
628 createdFunctionSymbol = staticConstructorSymbol;
629 }
630 }
631
632 void SymbolTable::BeginConstructor(ConstructorNode& constructorNode, int32_t functionIndex)
633 {
634 ConstructorSymbol* constructorSymbol = new ConstructorSymbol(constructorNode.GetSpan(), constructorNode.ModuleId(), U"@constructor");
635 constructorSymbol->SetIndex(functionIndex);
636 SetFunctionIdFor(constructorSymbol);
637 if ((constructorNode.GetSpecifiers() & Specifiers::constexpr_) != Specifiers::none)
638 {
639 constructorSymbol->SetConstExpr();
640 }
641 constructorSymbol->SetHasSource();
642 constructorSymbol->SetCompileUnit(currentCompileUnit);
643 constructorSymbol->SetModule(module);
644 if (constructorNode.WhereConstraint())
645 {
646 CloneContext cloneContext;
647 constructorSymbol->SetConstraint(static_cast<WhereConstraintNode*>(constructorNode.WhereConstraint()->Clone(cloneContext)));
648 }
649 MapNode(&constructorNode, constructorSymbol);
650 BeginContainer(constructorSymbol);
651 parameterIndex = 0;
652 ResetDeclarationBlockIndex();
653 ParameterSymbol* thisParam = new ParameterSymbol(constructorNode.GetSpan(), constructorNode.ModuleId(), U"this");
654 TypeSymbol* thisParamType = nullptr;
655 if (currentClass)
656 {
657 thisParamType = currentClass->AddPointer(constructorNode.GetSpan(), constructorNode.ModuleId());
658 thisParam->SetType(thisParamType);
659 thisParam->SetBound();
660 constructorSymbol->AddMember(thisParam);
661 }
662 else if (currentInterface)
663 {
664 throw Exception("interface type cannot have a constructor", constructorNode.GetSpan(), constructorNode.ModuleId());
665 }
666 }
667
668 void SymbolTable::EndConstructor(bool addMember)
669 {
670 ConstructorSymbol* constructorSymbol = static_cast<ConstructorSymbol*>(container);
671 EndContainer();
672 if (addMember)
673 {
674 container->AddMember(constructorSymbol);
675 }
676 else
677 {
678 createdFunctionSymbol = constructorSymbol;
679 }
680 }
681
682 void SymbolTable::BeginDestructor(DestructorNode& destructorNode, int32_t functionIndex)
683 {
684 DestructorSymbol* destructorSymbol = new DestructorSymbol(destructorNode.GetSpan(), destructorNode.ModuleId(), U"@destructor");
685 destructorSymbol->SetIndex(functionIndex);
686 SetFunctionIdFor(destructorSymbol);
687 destructorSymbol->SetHasSource();
688 destructorSymbol->SetCompileUnit(currentCompileUnit);
689 destructorSymbol->SetModule(module);
690 if (destructorNode.WhereConstraint())
691 {
692 CloneContext cloneContext;
693 destructorSymbol->SetConstraint(static_cast<WhereConstraintNode*>(destructorNode.WhereConstraint()->Clone(cloneContext)));
694 }
695 MapNode(&destructorNode, destructorSymbol);
696 BeginContainer(destructorSymbol);
697 ResetDeclarationBlockIndex();
698 ParameterSymbol* thisParam = new ParameterSymbol(destructorNode.GetSpan(), destructorNode.ModuleId(), U"this");
699 TypeSymbol* thisParamType = nullptr;
700 if (currentClass)
701 {
702 thisParamType = currentClass->AddPointer(destructorNode.GetSpan(), destructorNode.ModuleId());
703 thisParam->SetType(thisParamType);
704 thisParam->SetBound();
705 destructorSymbol->AddMember(thisParam);
706 }
707 else if (currentInterface)
708 {
709 throw Exception("interface type cannot have a destructor", destructorNode.GetSpan(), destructorNode.ModuleId());
710 }
711 }
712
713 void SymbolTable::EndDestructor(bool addMember)
714 {
715 DestructorSymbol* destructorSymbol = static_cast<DestructorSymbol*>(container);
716 EndContainer();
717 if (addMember)
718 {
719 container->AddMember(destructorSymbol);
720 }
721 else
722 {
723 createdFunctionSymbol = destructorSymbol;
724 }
725 }
726
727 void SymbolTable::BeginMemberFunction(MemberFunctionNode& memberFunctionNode, int32_t functionIndex)
728 {
729 MemberFunctionSymbol* memberFunctionSymbol = new MemberFunctionSymbol(memberFunctionNode.GetSpan(), memberFunctionNode.ModuleId(), memberFunctionNode.GroupId());
730 memberFunctionSymbol->SetIndex(functionIndex);
731 SetFunctionIdFor(memberFunctionSymbol);
732 if ((memberFunctionNode.GetSpecifiers() & Specifiers::constexpr_) != Specifiers::none)
733 {
734 memberFunctionSymbol->SetConstExpr();
735 }
736 memberFunctionSymbol->SetHasSource();
737 memberFunctionSymbol->SetCompileUnit(currentCompileUnit);
738 memberFunctionSymbol->SetModule(module);
739 memberFunctionSymbol->SetGroupName(memberFunctionNode.GroupId());
740 if (memberFunctionNode.WhereConstraint())
741 {
742 CloneContext cloneContext;
743 memberFunctionSymbol->SetConstraint(static_cast<WhereConstraintNode*>(memberFunctionNode.WhereConstraint()->Clone(cloneContext)));
744 }
745 MapNode(&memberFunctionNode, memberFunctionSymbol);
746 BeginContainer(memberFunctionSymbol);
747 parameterIndex = 0;
748 ResetDeclarationBlockIndex();
749 if ((memberFunctionNode.GetSpecifiers() & Specifiers::static_) == Specifiers::none)
750 {
751 ParameterSymbol* thisParam = new ParameterSymbol(memberFunctionNode.GetSpan(), memberFunctionNode.ModuleId(), U"this");
752 TypeSymbol* thisParamType = nullptr;
753 if (currentClass)
754 {
755 if (memberFunctionNode.IsConst())
756 {
757 thisParamType = currentClass->AddConst(memberFunctionNode.GetSpan(), memberFunctionNode.ModuleId())->AddPointer(memberFunctionNode.GetSpan(), memberFunctionNode.ModuleId());
758 }
759 else
760 {
761 thisParamType = currentClass->AddPointer(memberFunctionNode.GetSpan(), memberFunctionNode.ModuleId());
762 }
763 }
764 else if (currentInterface)
765 {
766 thisParamType = currentInterface->AddPointer(memberFunctionNode.GetSpan(), memberFunctionNode.ModuleId());
767 }
768 else
769 {
770 Assert(false, "class or interface expected");
771 }
772 thisParam->SetType(thisParamType);
773 thisParam->SetBound();
774 memberFunctionSymbol->AddMember(thisParam);
775 }
776 }
777
778 void SymbolTable::EndMemberFunction(bool addMember)
779 {
780 MemberFunctionSymbol* memberFunctionSymbol = static_cast<MemberFunctionSymbol*>(container);
781 EndContainer();
782 if (addMember)
783 {
784 container->AddMember(memberFunctionSymbol);
785 }
786 else
787 {
788 createdFunctionSymbol = memberFunctionSymbol;
789 }
790 }
791
792 void SymbolTable::BeginConversionFunction(ConversionFunctionNode& conversionFunctionNode, int32_t functionIndex)
793 {
794 ConversionFunctionSymbol* conversionFunctionSymbol = new ConversionFunctionSymbol(conversionFunctionNode.GetSpan(), conversionFunctionNode.ModuleId(), U"@conversion");
795 conversionFunctionSymbol->SetIndex(functionIndex);
796 SetFunctionIdFor(conversionFunctionSymbol);
797 if ((conversionFunctionNode.GetSpecifiers() & Specifiers::constexpr_) != Specifiers::none)
798 {
799 conversionFunctionSymbol->SetConstExpr();
800 }
801 conversionFunctionSymbol->SetHasSource();
802 conversionFunctionSymbol->SetCompileUnit(currentCompileUnit);
803 conversionFunctionSymbol->SetModule(module);
804 conversionFunctionSymbol->SetGroupName(U"@operator_conv");
805 if (conversionFunctionNode.WhereConstraint())
806 {
807 CloneContext cloneContext;
808 conversionFunctionSymbol->SetConstraint(static_cast<WhereConstraintNode*>(conversionFunctionNode.WhereConstraint()->Clone(cloneContext)));
809 }
810 MapNode(&conversionFunctionNode, conversionFunctionSymbol);
811 BeginContainer(conversionFunctionSymbol);
812 ResetDeclarationBlockIndex();
813 ParameterSymbol* thisParam = new ParameterSymbol(conversionFunctionNode.GetSpan(), conversionFunctionNode.ModuleId(), U"this");
814 TypeSymbol* thisParamType = nullptr;
815 if (conversionFunctionNode.IsConst())
816 {
817 thisParamType = currentClass->AddConst(conversionFunctionNode.GetSpan(), conversionFunctionNode.ModuleId())->AddPointer(conversionFunctionNode.GetSpan(), conversionFunctionNode.ModuleId());
818 }
819 else
820 {
821 thisParamType = currentClass->AddPointer(conversionFunctionNode.GetSpan(), conversionFunctionNode.ModuleId());
822 }
823 thisParam->SetType(thisParamType);
824 thisParam->SetBound();
825 conversionFunctionSymbol->AddMember(thisParam);
826 }
827
828 void SymbolTable::EndConversionFunction(bool addMember)
829 {
830 ConversionFunctionSymbol* conversionFunctionSymbol = static_cast<ConversionFunctionSymbol*>(container);
831 EndContainer();
832 if (addMember)
833 {
834 container->AddMember(conversionFunctionSymbol);
835 }
836 else
837 {
838 createdFunctionSymbol = conversionFunctionSymbol;
839 }
840 }
841
842 void SymbolTable::AddMemberVariable(MemberVariableNode& memberVariableNode)
843 {
844 MemberVariableSymbol* memberVariableSymbol = new MemberVariableSymbol(memberVariableNode.GetSpan(), memberVariableNode.ModuleId(), memberVariableNode.Id()->Str());
845 if ((memberVariableNode.GetSpecifiers() & Specifiers::static_) != Specifiers::none)
846 {
847 memberVariableSymbol->SetStatic();
848 }
849 memberVariableSymbol->SetCompileUnit(currentCompileUnit);
850 MapNode(&memberVariableNode, memberVariableSymbol);
851 container->AddMember(memberVariableSymbol);
852 }
853
854 void SymbolTable::BeginDelegate(DelegateNode& delegateNode)
855 {
856 DelegateTypeSymbol* delegateTypeSymbol = new DelegateTypeSymbol(delegateNode.GetSpan(), delegateNode.ModuleId(), delegateNode.Id()->Str());
857 delegateTypeSymbol->SetCompileUnit(currentCompileUnit);
858 delegateTypeSymbol->SetModule(module);
859 MapNode(&delegateNode, delegateTypeSymbol);
860 SetTypeIdFor(delegateTypeSymbol);
861 container->AddMember(delegateTypeSymbol);
862 BeginContainer(delegateTypeSymbol);
863 parameterIndex = 0;
864 }
865
866 void SymbolTable::EndDelegate()
867 {
868 EndContainer();
869 }
870
871 void SymbolTable::BeginClassDelegate(ClassDelegateNode& classDelegateNode)
872 {
873 ClassDelegateTypeSymbol* classDelegateTypeSymbol = new ClassDelegateTypeSymbol(classDelegateNode.GetSpan(), classDelegateNode.ModuleId(), classDelegateNode.Id()->Str());
874 classDelegateTypeSymbol->SetCompileUnit(currentCompileUnit);
875 classDelegateTypeSymbol->SetModule(module);
876 MapNode(&classDelegateNode, classDelegateTypeSymbol);
877 SetTypeIdFor(classDelegateTypeSymbol);
878 container->AddMember(classDelegateTypeSymbol);
879 BeginContainer(classDelegateTypeSymbol);
880 parameterIndex = 0;
881 }
882
883 void SymbolTable::EndClassDelegate()
884 {
885 EndContainer();
886 }
887
888 void SymbolTable::BeginConcept(ConceptNode& conceptNode, bool hasSource)
889 {
890 ConceptSymbol* conceptSymbol = new ConceptSymbol(conceptNode.GetSpan(), conceptNode.ModuleId(), conceptNode.Id()->Str());
891 if (hasSource)
892 {
893 conceptSymbol->SetHasSource();
894 }
895 conceptSymbol->SetGroupName(conceptNode.Id()->Str());
896 conceptSymbol->SetCompileUnit(currentCompileUnit);
897 conceptSymbol->SetModule(module);
898 MapNode(&conceptNode, conceptSymbol);
899 SetTypeIdFor(conceptSymbol);
900 BeginContainer(conceptSymbol);
901 }
902
903 void SymbolTable::EndConcept()
904 {
905 ConceptSymbol* conceptSymbol = static_cast<ConceptSymbol*>(container);
906 EndContainer();
907 container->AddMember(conceptSymbol);
908 }
909
910 void SymbolTable::BeginAxiom(AxiomNode& axiomNode)
911 {
912 std::u32string axiomId;
913 if (axiomNode.Id())
914 {
915 axiomId = axiomNode.Id()->Str();
916 }
917 else
918 {
919 axiomId = ToUtf32("@axiom" + std::to_string(NextAxiomNumber()));
920 }
921 AxiomSymbol* axiomSymbol = new AxiomSymbol(axiomNode.GetSpan(), axiomNode.ModuleId(), axiomId);
922 MapNode(&axiomNode, axiomSymbol);
923 BeginContainer(axiomSymbol);
924 }
925
926 void SymbolTable::EndAxiom()
927 {
928 AxiomSymbol* axiomSymbol = static_cast<AxiomSymbol*>(container);
929 EndContainer();
930 container->AddMember(axiomSymbol);
931 }
932
933 void SymbolTable::BeginDeclarationBlock(Node& node)
934 {
935 DeclarationBlock* declarationBlock = new DeclarationBlock(node.GetSpan(), node.ModuleId(), U"@locals" + ToUtf32(std::to_string(GetNextDeclarationBlockIndex())));
936 declarationBlock->SetCompileUnit(currentCompileUnit);
937 declarationBlock->SetModule(module);
938 MapNode(&node, declarationBlock);
939 container->AddMember(declarationBlock);
940 BeginContainer(declarationBlock);
941 }
942
943 void SymbolTable::EndDeclarationBlock()
944 {
945 EndContainer();
946 }
947
948 void SymbolTable::AddLocalVariable(ConstructionStatementNode& constructionStatementNode)
949 {
950 if (!constructionStatementNode.Id()) return;
951 if (GetGlobalFlag(GlobalFlags::profile) && constructionStatementNode.Id()->Str() == U"@functionProfiler")
952 {
953 for (LocalVariableSymbol* localVariableSymbol : currentFunctionSymbol->LocalVariables())
954 {
955 if (localVariableSymbol->Name() == U"@functionProfiler")
956 {
957 MapNode(&constructionStatementNode, localVariableSymbol);
958 return;
959 }
960 }
961 }
962 LocalVariableSymbol* localVariableSymbol = new LocalVariableSymbol(constructionStatementNode.GetSpan(), constructionStatementNode.ModuleId(), constructionStatementNode.Id()->Str());
963 localVariableSymbol->SetCompileUnit(currentCompileUnit);
964 localVariableSymbol->SetModule(module);
965 MapNode(&constructionStatementNode, localVariableSymbol);
966 container->AddMember(localVariableSymbol);
967 }
968
969 void SymbolTable::AddLocalVariable(IdentifierNode& identifierNode)
970 {
971 LocalVariableSymbol* localVariableSymbol = new LocalVariableSymbol(identifierNode.GetSpan(), identifierNode.ModuleId(), identifierNode.Str());
972 localVariableSymbol->SetCompileUnit(currentCompileUnit);
973 localVariableSymbol->SetModule(module);
974 MapNode(&identifierNode, localVariableSymbol);
975 container->AddMember(localVariableSymbol);
976 }
977
978 TypedefSymbol* SymbolTable::AddTypedef(TypedefNode& typedefNode)
979 {
980 TypedefSymbol* typedefSymbol = new TypedefSymbol(typedefNode.GetSpan(), typedefNode.ModuleId(), typedefNode.Id()->Str());
981 typedefSymbol->SetCompileUnit(currentCompileUnit);
982 typedefSymbol->SetModule(module);
983 MapNode(&typedefNode, typedefSymbol);
984 container->AddMember(typedefSymbol);
985 return typedefSymbol;
986 }
987
988 ConstantSymbol* SymbolTable::AddConstant(ConstantNode& constantNode)
989 {
990 ConstantSymbol* constantSymbol = new ConstantSymbol(constantNode.GetSpan(), constantNode.ModuleId(), constantNode.Id()->Str());
991 constantSymbol->SetCompileUnit(currentCompileUnit);
992 constantSymbol->SetModule(module);
993 constantSymbol->SetStrValue(constantNode.StrValue());
994 MapNode(&constantNode, constantSymbol);
995 container->AddMember(constantSymbol);
996 return constantSymbol;
997 }
998
999 GlobalVariableSymbol* SymbolTable::AddGlobalVariable(GlobalVariableNode& globalVariableNode)
1000 {
1001 GlobalVariableSymbol* globalVariableSymbol = new GlobalVariableSymbol(globalVariableNode.GetSpan(), globalVariableNode.ModuleId(), globalVariableNode.Id()->Str(), globalVariableNode.CompileUnit()->Id(),
1002 globalVariableNode.CompileUnit()->FilePath());
1003 globalVariableSymbol->SetSpecifiers(globalVariableNode.GetSpecifiers());
1004 globalVariableSymbol->SetCompileUnit(currentCompileUnit);
1005 globalVariableSymbol->SetModule(module);
1006 MapNode(&globalVariableNode, globalVariableSymbol);
1007 container->AddMember(globalVariableSymbol);
1008 return globalVariableSymbol;
1009 }
1010
1011 void SymbolTable::BeginEnumType(EnumTypeNode& enumTypeNode)
1012 {
1013 EnumTypeSymbol* enumTypeSymbol = new EnumTypeSymbol(enumTypeNode.GetSpan(), enumTypeNode.ModuleId(), enumTypeNode.Id()->Str());
1014 enumTypeSymbol->SetCompileUnit(currentCompileUnit);
1015 enumTypeSymbol->SetModule(module);
1016 MapNode(&enumTypeNode, enumTypeSymbol);
1017 SetTypeIdFor(enumTypeSymbol);
1018 container->AddMember(enumTypeSymbol);
1019 BeginContainer(enumTypeSymbol);
1020 }
1021
1022 void SymbolTable::EndEnumType()
1023 {
1024 EndContainer();
1025 }
1026
1027 void SymbolTable::AddEnumConstant(EnumConstantNode& enumConstantNode)
1028 {
1029 EnumConstantSymbol* enumConstantSymbol = new EnumConstantSymbol(enumConstantNode.GetSpan(), enumConstantNode.ModuleId(), enumConstantNode.Id()->Str());
1030 enumConstantSymbol->SetCompileUnit(currentCompileUnit);
1031 enumConstantSymbol->SetModule(module);
1032 enumConstantSymbol->SetStrValue(enumConstantNode.StrValue());
1033 MapNode(&enumConstantNode, enumConstantSymbol);
1034 container->AddMember(enumConstantSymbol);
1035 }
1036
1037 void SymbolTable::AddTypeSymbolToGlobalScope(TypeSymbol* typeSymbol)
1038 {
1039 typeSymbol->SetModule(module);
1040 globalNs.AddMember(typeSymbol);
1041 SetTypeIdFor(typeSymbol);
1042 typeNameMap[typeSymbol->FullName()] = typeSymbol;
1043 }
1044
1045 void SymbolTable::AddFunctionSymbolToGlobalScope(FunctionSymbol* functionSymbol)
1046 {
1047 SetFunctionIdFor(functionSymbol);
1048 functionSymbol->SetModule(module);
1049 globalNs.AddMember(functionSymbol);
1050 if (functionSymbol->IsConversion())
1051 {
1052 conversionTable.AddConversion(functionSymbol);
1053 }
1054 }
1055
1056 void SymbolTable::MapNode(Node* node, Symbol* symbol)
1057 {
1058 nodeSymbolMap[node] = symbol;
1059 symbolNodeMap[symbol] = node;
1060 }
1061
1062 Symbol* SymbolTable::GetSymbolNoThrow(Node* node) const
1063 {
1064 auto it = nodeSymbolMap.find(node);
1065 if (it != nodeSymbolMap.cend())
1066 {
1067 return it->second;
1068 }
1069 else
1070 {
1071 return nullptr;
1072 }
1073 }
1074
1075 Symbol* SymbolTable::GetSymbol(Node* node) const
1076 {
1077 Symbol* symbol = GetSymbolNoThrow(node);
1078 if (symbol)
1079 {
1080 return symbol;
1081 }
1082 else
1083 {
1084 throw std::runtime_error("symbol for node not found");
1085 }
1086 }
1087
1088 Node* SymbolTable::GetNodeNoThrow(Symbol* symbol) const
1089 {
1090 auto it = symbolNodeMap.find(symbol);
1091 if (it != symbolNodeMap.cend())
1092 {
1093 return it->second;
1094 }
1095 else
1096 {
1097 return nullptr;
1098 }
1099 }
1100
1101 Node* SymbolTable::GetNode(Symbol* symbol) const
1102 {
1103 Node* node = GetNodeNoThrow(symbol);
1104 if (node)
1105 {
1106 return node;
1107 }
1108 else
1109 {
1110 throw std::runtime_error("node for symbol not found");
1111 }
1112 }
1113
1114 void SymbolTable::AddTypeOrConceptSymbolToTypeIdMap(Symbol* typeOrConceptSymbol)
1115 {
1116 if (typeOrConceptSymbol->IsTypeSymbol())
1117 {
1118 TypeSymbol* typeSymbol = static_cast<TypeSymbol*>(typeOrConceptSymbol);
1119 typeIdMap[typeSymbol->TypeId()] = typeSymbol;
1120 }
1121 else if (typeOrConceptSymbol->GetSymbolType() == SymbolType::conceptSymbol)
1122 {
1123 ConceptSymbol* conceptSymbol = static_cast<ConceptSymbol*>(typeOrConceptSymbol);
1124 typeIdMap[conceptSymbol->TypeId()] = conceptSymbol;
1125 }
1126 else
1127 {
1128 Assert(false, "type or concept symbol expected");
1129 }
1130 }
1131
1132 void SymbolTable::AddFunctionSymbolToFunctionIdMap(FunctionSymbol* functionSymbol)
1133 {
1134 functionIdMap[functionSymbol->FunctionId()] = functionSymbol;
1135 }
1136
1137 void SymbolTable::SetTypeIdFor(TypeSymbol* typeSymbol)
1138 {
1139 typeSymbol->SetTypeId(boost::uuids::random_generator()());
1140 }
1141
1142 void SymbolTable::SetTypeIdFor(ConceptSymbol* conceptSymbol)
1143 {
1144 conceptSymbol->SetTypeId(boost::uuids::random_generator()());
1145 }
1146
1147 void SymbolTable::SetFunctionIdFor(FunctionSymbol* functionSymbol)
1148 {
1149 functionSymbol->SetFunctionId(boost::uuids::random_generator()());
1150 }
1151
1152 FunctionSymbol* SymbolTable::GetFunctionById(const boost::uuids::uuid& functionId) const
1153 {
1154 auto it = functionIdMap.find(functionId);
1155 if (it != functionIdMap.cend())
1156 {
1157 return it->second;
1158 }
1159 else
1160 {
1161 return nullptr;
1162 }
1163 }
1164
1165 void SymbolTable::EmplaceTypeRequest(SymbolReader& reader, Symbol* forSymbol, const boost::uuids::uuid& typeId, int index)
1166 {
1167 EmplaceTypeOrConceptRequest(reader, forSymbol, typeId, index);
1168 }
1169
1170 const int conceptRequestIndex = std::numeric_limits<int>::max();
1171
1172 void SymbolTable::EmplaceConceptRequest(SymbolReader& reader, Symbol* forSymbol, const boost::uuids::uuid& typeId)
1173 {
1174 EmplaceTypeOrConceptRequest(reader, forSymbol, typeId, conceptRequestIndex);
1175 }
1176
1177 void SymbolTable::EmplaceTypeOrConceptRequest(SymbolReader& reader, Symbol* forSymbol, const boost::uuids::uuid& typeId, int index)
1178 {
1179 auto it = typeIdMap.find(typeId);
1180 if (it != typeIdMap.cend())
1181 {
1182 Symbol* typeOrConceptSymbol = it->second;
1183 if (typeOrConceptSymbol->IsTypeSymbol())
1184 {
1185 if (index == conceptRequestIndex)
1186 {
1187 throw Exception("internal error: invalid concept request (id denotes a type)", forSymbol->GetSpan(), forSymbol->SourceModuleId());
1188 }
1189 TypeSymbol* typeSymbol = static_cast<TypeSymbol*>(typeOrConceptSymbol);
1190 forSymbol->EmplaceType(typeSymbol, index);
1191 }
1192 else if (typeOrConceptSymbol->GetSymbolType() == SymbolType::conceptSymbol)
1193 {
1194 if (index != conceptRequestIndex)
1195 {
1196 throw Exception("internal error: invalid type request (id denotes a concept)", forSymbol->GetSpan(), forSymbol->SourceModuleId());
1197 }
1198 ConceptSymbol* conceptSymbol = static_cast<ConceptSymbol*>(typeOrConceptSymbol);
1199 forSymbol->EmplaceConcept(conceptSymbol);
1200 }
1201 else
1202 {
1203 Assert(false, "internal error: type or concept symbol expected");
1204 }
1205 }
1206 else
1207 {
1208 reader.AddTypeOrConceptRequest(TypeOrConceptRequest(forSymbol, typeId, index));
1209 }
1210 }
1211
1212 void SymbolTable::EmplaceFunctionRequest(SymbolReader& reader, Symbol* forSymbol, const::boost::uuids::uuid& functionId, int index)
1213 {
1214 auto it = functionIdMap.find(functionId);
1215 if (it != functionIdMap.cend())
1216 {
1217 FunctionSymbol* functionSymbol = it->second;
1218 forSymbol->EmplaceFunction(functionSymbol, index);
1219 }
1220 else
1221 {
1222 reader.AddFunctionRequest(FunctionRequest(forSymbol, functionId, index));
1223 }
1224 }
1225
1226 void SymbolTable::ProcessTypeConceptAndFunctionRequests(const std::std::vector<TypeOrConceptRequest>&typeAndConceptRequests, conststd::std::vector<FunctionRequest>&functionRequests)
1227 {
1228 for (const TypeOrConceptRequest& typeOrConceptRequest : typeAndConceptRequests)
1229 {
1230 Symbol* symbol = typeOrConceptRequest.symbol;
1231 auto it = typeIdMap.find(typeOrConceptRequest.typeId);
1232 if (it != typeIdMap.cend())
1233 {
1234 Symbol* typeOrConceptSymbol = it->second;
1235 int index = typeOrConceptRequest.index;
1236 if (typeOrConceptSymbol->IsTypeSymbol())
1237 {
1238 if (index == conceptRequestIndex)
1239 {
1240 throw Exception("internal error: invalid concept request (id denotes a type)", symbol->GetSpan(), symbol->SourceModuleId());
1241 }
1242 TypeSymbol* typeSymbol = static_cast<TypeSymbol*>(typeOrConceptSymbol);
1243 symbol->EmplaceType(typeSymbol, index);
1244 }
1245 else if (typeOrConceptSymbol->GetSymbolType() == SymbolType::conceptSymbol)
1246 {
1247 if (index != conceptRequestIndex)
1248 {
1249 throw Exception("internal error: invalid type request (id denotes a concept)", symbol->GetSpan(), symbol->SourceModuleId());
1250 }
1251 ConceptSymbol* conceptSymbol = static_cast<ConceptSymbol*>(typeOrConceptSymbol);
1252 symbol->EmplaceConcept(conceptSymbol);
1253 }
1254 else
1255 {
1256 Assert(false, "internal error: type or concept symbol expected");
1257 }
1258 }
1259 else
1260 {
1261 throw std::runtime_error("internal error: cannot satisfy type or concept request for symbol '" + ToUtf8(symbol->Name()) + "': type or concept not found from symbol table");
1262 }
1263 }
1264 for (const FunctionRequest& functionRequest : functionRequests)
1265 {
1266 Symbol* symbol = functionRequest.symbol;
1267 auto it = functionIdMap.find(functionRequest.functionId);
1268 if (it != functionIdMap.cend())
1269 {
1270 FunctionSymbol* functionSymbol = it->second;
1271 int index = functionRequest.index;
1272 symbol->EmplaceFunction(functionSymbol, index);
1273 }
1274 else
1275 {
1276 throw std::runtime_error("internal error: cannot satisfy function request for symbol '" + ToUtf8(symbol->Name()) + "': function not found from symbol table");
1277 }
1278 }
1279 }
1280
1281 TypeSymbol* SymbolTable::GetTypeByNameNoThrow(const std::u32string& typeName) const
1282 {
1283 auto it = typeNameMap.find(typeName);
1284 if (it != typeNameMap.cend())
1285 {
1286 return it->second;
1287 }
1288 else
1289 {
1290 return nullptr;
1291 }
1292 }
1293
1294 TypeSymbol* SymbolTable::GetTypeByName(const std::u32string& typeName) const
1295 {
1296 TypeSymbol* typeSymbol = GetTypeByNameNoThrow(typeName);
1297 if (typeSymbol)
1298 {
1299 return typeSymbol;
1300 }
1301 else
1302 {
1303 throw std::runtime_error("type '" + ToUtf8(typeName) + "' not found");
1304 }
1305 }
1306
1307 TypeSymbol* SymbolTable::MakeDerivedType(TypeSymbol* baseType, const TypeDerivationRec& derivationRec, const Span& span, const boost::uuids::uuid& moduleId)
1308 {
1309 if (!baseType)
1310 {
1311 throw Exception("base type is null!", span, moduleId);
1312 }
1313 #ifdef IMMUTABLE_MODULE_CHECK
1314
1315
1316
1317
1318 #endif
1319 if (derivationRec.IsEmpty())
1320 {
1321 return baseType;
1322 }
1323 if (baseType->IsVoidType() && HasReferenceDerivation(derivationRec.derivations) && !HasPointerDerivation(derivationRec.derivations))
1324 {
1325 throw Exception("cannot have reference to void type", span, moduleId);
1326 }
1327 std::std::vector<DerivedTypeSymbol*>&mappedDerivedTypes=derivedTypeMap[baseType->TypeId()];
1328 int n = mappedDerivedTypes.size();
1329 for (int i = 0; i < n; ++i)
1330 {
1331 DerivedTypeSymbol* derivedType = mappedDerivedTypes[i];
1332 if (derivedType->DerivationRec() == derivationRec)
1333 {
1334 return derivedType;
1335 }
1336 }
1337 DerivedTypeSymbol* derivedType = new DerivedTypeSymbol(Span(), boost::uuids::nil_uuid(), MakeDerivedTypeName(baseType, derivationRec), baseType, derivationRec);
1338 derivedType->SetParent(&globalNs);
1339 derivedType->SetModule(module);
1340 derivedType->ComputeTypeId();
1341 mappedDerivedTypes.push_back(derivedType);
1342 derivedTypes.push_back(std::unique_ptr<DerivedTypeSymbol>(derivedType));
1343 if (derivedType->IsPointerType() && !derivedType->BaseType()->IsVoidType() && !derivedType->IsReferenceType())
1344 {
1345 TypedefSymbol* valueType = new TypedefSymbol(baseType->GetSpan(), baseType->SourceModuleId(), U"ValueType");
1346 valueType->SetModule(module);
1347 valueType->SetAccess(SymbolAccess::public_);
1348 valueType->SetType(derivedType->RemovePointer(span, moduleId));
1349 TypeSymbol* withoutConst = valueType->GetType()->RemoveConst(span, moduleId);
1350 if (withoutConst->IsBasicTypeSymbol())
1351 {
1352 valueType->SetType(withoutConst);
1353 }
1354 valueType->SetBound();
1355 derivedType->AddMember(valueType);
1356 TypedefSymbol* referenceType = new TypedefSymbol(baseType->GetSpan(), baseType->SourceModuleId(), U"ReferenceType");
1357 referenceType->SetModule(module);
1358 referenceType->SetAccess(SymbolAccess::public_);
1359 referenceType->SetType(valueType->GetType()->AddLvalueReference(span, moduleId));
1360 referenceType->SetBound();
1361 derivedType->AddMember(referenceType);
1362 TypedefSymbol* pointerType = new TypedefSymbol(baseType->GetSpan(), baseType->SourceModuleId(), U"PointerType");
1363 pointerType->SetModule(module);
1364 pointerType->SetAccess(SymbolAccess::public_);
1365 pointerType->SetType(derivedType);
1366 pointerType->SetBound();
1367 derivedType->AddMember(pointerType);
1368 }
1369 return derivedType;
1370 }
1371
1372 ClassTemplateSpecializationSymbol* SymbolTable::MakeClassTemplateSpecialization(ClassTypeSymbol* classTemplate, const std::std::vector<TypeSymbol*>&templateArgumentTypes,
1373 const Span& span, const boost::uuids::uuid& sourceModuleId)
1374 {
1375 #ifdef IMMUTABLE_MODULE_CHECK
1376
1377
1378
1379
1380 #endif
1381 ClassTemplateSpecializationKey key(classTemplate, templateArgumentTypes);
1382 auto it = classTemplateSpecializationMap.find(key);
1383 if (it != classTemplateSpecializationMap.cend())
1384 {
1385 ClassTemplateSpecializationSymbol* classTemplateSpecialization = it->second;
1386 return classTemplateSpecialization;
1387 }
1388 std::u32string classTemplateSpecializationName = MakeClassTemplateSpecializationName(classTemplate, templateArgumentTypes);
1389 ClassTemplateSpecializationSymbol* classTemplateSpecialization = new ClassTemplateSpecializationSymbol(Span(), boost::uuids::nil_uuid(), classTemplateSpecializationName, classTemplate,
1390 templateArgumentTypes);
1391 SetTypeIdFor(classTemplateSpecialization);
1392 classTemplateSpecialization->SetGroupName(classTemplate->GroupName());
1393 classTemplateSpecializationMap[key] = classTemplateSpecialization;
1394 classTemplateSpecialization->SetParent(&globalNs);
1395 classTemplateSpecialization->SetModule(module);
1396 classTemplateSpecializations.push_back(std::unique_ptr<ClassTemplateSpecializationSymbol>(classTemplateSpecialization));
1397 ++numSpecializationsNew;
1398 return classTemplateSpecialization;
1399 }
1400
1401 ClassTemplateSpecializationSymbol* SymbolTable::CopyClassTemplateSpecialization(ClassTemplateSpecializationSymbol* source)
1402 {
1403 #ifdef IMMUTABLE_MODULE_CHECK
1404
1405
1406
1407
1408 #endif
1409 ClassTypeSymbol* classTemplate = source->GetClassTemplate();
1410 if (classTemplate == nullptr)
1411 {
1412 throw std::runtime_error("class template is null!");
1413 }
1414 std::std::vector<TypeSymbol*>&templateArgumentTypes=source->TemplateArgumentTypes();
1415 ClassTemplateSpecializationKey key(classTemplate, templateArgumentTypes);
1416 std::u32string classTemplateSpecializationName = MakeClassTemplateSpecializationName(classTemplate, templateArgumentTypes);
1417 ClassTemplateSpecializationSymbol* copy = new ClassTemplateSpecializationSymbol(source->GetSpan(), source->SourceModuleId(), classTemplateSpecializationName, classTemplate, templateArgumentTypes);
1418 copy->SetTypeId(source->TypeId());
1419 copy->SetGroupName(classTemplate->GroupName());
1420 classTemplateSpecializationMap[key] = copy;
1421 copy->SetParent(&globalNs);
1422 copy->SetModule(module);
1423 classTemplateSpecializations.push_back(std::unique_ptr<ClassTemplateSpecializationSymbol>(copy));
1424 derivedTypeMap[copy->TypeId()].clear();
1425 specializationCopyMap[source] = copy;
1426 ++numSpecializationsCopied;
1427 return copy;
1428 }
1429
1430 ClassTemplateSpecializationSymbol* SymbolTable::GetCurrentClassTemplateSpecialization(ClassTemplateSpecializationSymbol* source)
1431 {
1432 auto it = specializationCopyMap.find(source);
1433 if (it != specializationCopyMap.cend())
1434 {
1435 return it->second;
1436 }
1437 return source;
1438 }
1439
1440 ArrayTypeSymbol* SymbolTable::MakeArrayType(TypeSymbol* elementType, int64_t size, const Span& span, const boost::uuids::uuid& moduleId)
1441 {
1442 #ifdef IMMUTABLE_MODULE_CHECK
1443
1444
1445
1446
1447 #endif
1448 ArrayKey key(elementType, size);
1449 auto it = arrayTypeMap.find(key);
1450 if (elementType->GetSymbolType() != SymbolType::classTemplateSpecializationSymbol && it != arrayTypeMap.cend())
1451 {
1452 ArrayTypeSymbol* arrayType = it->second;
1453 return arrayType;
1454 }
1455 ArrayTypeSymbol* arrayType = new ArrayTypeSymbol(span, moduleId, elementType->FullName() + U"[" + ToUtf32(std::to_string(size)) + U"]", elementType, size);
1456 SetTypeIdFor(arrayType);
1457 arrayTypeMap[key] = arrayType;
1458 arrayType->SetParent(&globalNs);
1459 arrayType->SetModule(module);
1460 ArrayLengthFunction* arrayLengthFunction = new ArrayLengthFunction(arrayType);
1461 SetFunctionIdFor(arrayLengthFunction);
1462 arrayType->AddMember(arrayLengthFunction);
1463 ArrayBeginFunction* arrayBeginFunction = new ArrayBeginFunction(arrayType);
1464 SetFunctionIdFor(arrayBeginFunction);
1465 arrayType->AddMember(arrayBeginFunction);
1466 ArrayEndFunction* arrayEndFunction = new ArrayEndFunction(arrayType);
1467 SetFunctionIdFor(arrayEndFunction);
1468 arrayType->AddMember(arrayEndFunction);
1469 ArrayCBeginFunction* arrayCBeginFunction = new ArrayCBeginFunction(arrayType);
1470 SetFunctionIdFor(arrayCBeginFunction);
1471 arrayType->AddMember(arrayCBeginFunction);
1472 ArrayCEndFunction* arrayCEndFunction = new ArrayCEndFunction(arrayType);
1473 SetFunctionIdFor(arrayCEndFunction);
1474 arrayType->AddMember(arrayCEndFunction);
1475 TypedefSymbol* iterator = new TypedefSymbol(span, moduleId, U"Iterator");
1476 iterator->SetModule(module);
1477 iterator->SetAccess(SymbolAccess::public_);
1478 iterator->SetType(arrayType->ElementType()->AddPointer(span, moduleId));
1479 iterator->SetBound();
1480 arrayType->AddMember(iterator);
1481 TypedefSymbol* constIterator = new TypedefSymbol(span, moduleId, U"ConstIterator");
1482 constIterator->SetModule(module);
1483 constIterator->SetAccess(SymbolAccess::public_);
1484 constIterator->SetType(arrayType->ElementType()->AddConst(span, moduleId)->AddPointer(span, moduleId));
1485 constIterator->SetBound();
1486 arrayType->AddMember(constIterator);
1487 arrayTypes.push_back(std::unique_ptr<ArrayTypeSymbol>(arrayType));
1488 derivedTypeMap[arrayType->TypeId()].clear();
1489 return arrayType;
1490 }
1491
1492 void SymbolTable::AddClassTemplateSpecializationsToClassTemplateSpecializationMap(const std::std::vector<ClassTemplateSpecializationSymbol*>&classTemplateSpecializations)
1493 {
1494 #ifdef IMMUTABLE_MODULE_CHECK
1495
1496
1497
1498
1499 #endif
1500 for (ClassTemplateSpecializationSymbol* classTemplateSpecialization : classTemplateSpecializations)
1501 {
1502 ClassTemplateSpecializationKey key(classTemplateSpecialization->GetClassTemplate(), classTemplateSpecialization->TemplateArgumentTypes());
1503 auto it = classTemplateSpecializationMap.find(key);
1504 if (it == classTemplateSpecializationMap.cend())
1505 {
1506 classTemplateSpecializationMap[key] = classTemplateSpecialization;
1507 }
1508 }
1509 }
1510
1511 void SymbolTable::AddConversion(FunctionSymbol* conversion, Module* module)
1512 {
1513 #ifdef IMMUTABLE_MODULE_CHECK
1514
1515
1516
1517
1518 #endif
1519 conversionTable.AddConversion(conversion);
1520 }
1521
1522 void SymbolTable::AddConversion(FunctionSymbol* conversion)
1523 {
1524 AddConversion(conversion, nullptr);
1525 }
1526
1527 FunctionSymbol* SymbolTable::GetConversion(TypeSymbol* sourceType, TypeSymbol* targetType, const Span& span, const boost::uuids::uuid& moduleId) const
1528 {
1529 return conversionTable.GetConversion(sourceType, targetType, span, moduleId);
1530 }
1531
1532 void SymbolTable::AddPolymorphicClass(ClassTypeSymbol* polymorphicClass)
1533 {
1534 #ifdef IMMUTABLE_MODULE_CHECK
1535
1536
1537
1538
1539 #endif
1540 if (!polymorphicClass->IsPolymorphic())
1541 {
1542 throw Exception("not a polymorphic class", polymorphicClass->GetSpan(), polymorphicClass->SourceModuleId());
1543 }
1544 polymorphicClasses.insert(polymorphicClass);
1545 }
1546
1547 void SymbolTable::AddClassHavingStaticConstructor(ClassTypeSymbol* classHavingStaticConstructor)
1548 {
1549 #ifdef IMMUTABLE_MODULE_CHECK
1550
1551
1552
1553
1554 #endif
1555 if (!classHavingStaticConstructor->StaticConstructor())
1556 {
1557 throw Exception("not having static constructor", classHavingStaticConstructor->GetSpan(), classHavingStaticConstructor->SourceModuleId());
1558 }
1559 classesHavingStaticConstructor.insert(classHavingStaticConstructor);
1560 }
1561
1562 void SymbolTable::AddJsonClass(const std::u32string& jsonClass)
1563 {
1564 #ifdef IMMUTABLE_MODULE_CHECK
1565
1566
1567
1568
1569 #endif
1570 jsonClasses.insert(jsonClass);
1571 }
1572
1573 std::std::vector<TypeSymbol*>SymbolTable::Types() const
1574 {
1575 std::vector<TypeSymbol*> types;
1576 for (const auto& p : typeNameMap)
1577 {
1578 TypeSymbol* type = p.second;
1579 types.push_back(type);
1580 }
1581 for (const std::std::unique_ptr<DerivedTypeSymbol>&dt : derivedTypes)
1582 {
1583 types.push_back(dt.get());
1584 }
1585 for (const std::std::unique_ptr<ClassTemplateSpecializationSymbol>&ts : classTemplateSpecializations)
1586 {
1587 types.push_back(ts.get());
1588 }
1589 return types;
1590 }
1591
1592 void SymbolTable::Copy(const SymbolTable& that)
1593 {
1594 for (const auto& p : that.typeIdMap)
1595 {
1596 typeIdMap[p.first] = p.second;
1597 }
1598 for (const auto& p : that.functionIdMap)
1599 {
1600 functionIdMap[p.first] = p.second;
1601 }
1602 }
1603
1604 void SymbolTable::MapProfiledFunction(const boost::uuids::uuid& functionId, const std::u32string& profiledFunctionName)
1605 {
1606 profiledFunctionNameMap[functionId] = profiledFunctionName;
1607 }
1608
1609 std::u32string SymbolTable::GetProfiledFunctionName(const boost::uuids::uuid& functionId) const
1610 {
1611 auto it = profiledFunctionNameMap.find(functionId);
1612 if (it != profiledFunctionNameMap.cend())
1613 {
1614 return it->second;
1615 }
1616 return std::u32string();
1617 }
1618
1619 std::std::unique_ptr<sngxml::dom::Document>SymbolTable::ToDomDocument()
1620 {
1621 TypeMap typeMap;
1622 std::unique_ptr<sngxml::dom::Document> doc(new sngxml::dom::Document());
1623 std::unique_ptr<sngxml::dom::Element> st(new sngxml::dom::Element(U"symbolTable"));
1624 std::unique_ptr<sngxml::dom::Element> globalNsElement = globalNs.ToDomElement(typeMap);
1625 std::unique_ptr<sngxml::dom::Element> symbols(new sngxml::dom::Element(U"symbols"));
1626 symbols->AppendChild(std::unique_ptr<sngxml::dom::Node>(globalNsElement.release()));
1627 st->AppendChild(std::unique_ptr<sngxml::dom::Node>(symbols.release()));
1628 std::unique_ptr<sngxml::dom::Element> types(new sngxml::dom::Element(U"types"));
1629 std::vector<std::std::unique_ptr<sngxml::dom::Element>>typeElements=typeMap.TypeElements();
1630 int n = typeElements.size();
1631 for (int i = 0; i < n; ++i)
1632 {
1633 std::unique_ptr<sngxml::dom::Element> typeElement(std::move(typeElements[i]));
1634 types->AppendChild(std::unique_ptr<sngxml::dom::Node>(typeElement.release()));
1635 }
1636 st->AppendChild(std::unique_ptr<sngxml::dom::Node>(types.release()));
1637 doc->AppendChild(std::unique_ptr<sngxml::dom::Node>(st.release()));
1638 return doc;
1639 }
1640
1641 void SymbolTable::MapInvoke(IdentifierNode* invokeId, FunctionSymbol* functionSymbol)
1642 {
1643 invokeMap[invokeId] = functionSymbol;
1644 }
1645
1646 FunctionSymbol* SymbolTable::GetInvoke(IdentifierNode* invokeId) const
1647 {
1648 auto it = invokeMap.find(invokeId);
1649 if (it != invokeMap.cend())
1650 {
1651 return it->second;
1652 }
1653 else
1654 {
1655 return nullptr;
1656 }
1657 }
1658
1659 void SymbolTable::MapSymbol(Node* node, Symbol* symbol)
1660 {
1661 mappedNodeSymbolMap[node] = symbol;
1662 }
1663
1664 Symbol* SymbolTable::GetMappedSymbol(Node* node) const
1665 {
1666 auto it = mappedNodeSymbolMap.find(node);
1667 if (it != mappedNodeSymbolMap.cend())
1668 {
1669 return it->second;
1670 }
1671 else
1672 {
1673 return nullptr;
1674 }
1675 }
1676
1677 void SymbolTable::MapIdentifierToSymbolDefinition(IdentifierNode* identifierNode, Module* module, Symbol* symbol)
1678 {
1679 if (identifierSymbolDefinitionMap.find(identifierNode) != identifierSymbolDefinitionMap.cend()) return;
1680 identifierSymbolDefinitionMap[identifierNode] = symbol;
1681 SymbolLocation identifierLocation = MakeSymbolLocation(identifierNode->GetSpan(), module);
1682 SymbolLocation definitionLocation;
1683 if (symbol->GetLocation(definitionLocation))
1684 {
1685 symbolDefinitionMap[identifierLocation] = definitionLocation;
1686 }
1687 }
1688
1689 SymbolLocation* SymbolTable::GetDefinitionLocation(const SymbolLocation& identifierLocation)
1690 {
1691 auto it = symbolDefinitionMap.find(identifierLocation);
1692 if (it != symbolDefinitionMap.cend())
1693 {
1694 return &(it->second);
1695 }
1696 else
1697 {
1698 return nullptr;
1699 }
1700 }
1701
1702 void SymbolTable::InitUuids()
1703 {
1704 derivationIds.clear();
1705 for (int i = 0; i < static_cast<int>(Derivation::max); ++i)
1706 {
1707 derivationIds.push_back(boost::uuids::random_generator()());
1708 }
1709 positionIds.clear();
1710 for (int i = 0; i < boost::uuids::uuid::static_size(); ++i)
1711 {
1712 positionIds.push_back(boost::uuids::random_generator()());
1713 }
1714 }
1715
1716 const boost::uuids::uuid& SymbolTable::GetDerivationId(Derivation derivation) const
1717 {
1718 if (!module->IsCore())
1719 {
1720 throw std::runtime_error("internal error: derivation id provided only from System.Core module");
1721 }
1722 int index = static_cast<int>(derivation);
1723 if (index < 0 || index >= derivationIds.size())
1724 {
1725 throw std::runtime_error("internal error: invalid derivation id index");
1726 }
1727 return derivationIds[index];
1728 }
1729
1730 const boost::uuids::uuid& SymbolTable::GetPositionId(int index) const
1731 {
1732 if (module->Name() != U"System.Core")
1733 {
1734 throw std::runtime_error("position id provided only from System.Core module");
1735 }
1736 if (index < 0 || index >= positionIds.size())
1737 {
1738 throw std::runtime_error("invalid position id index");
1739 }
1740 return positionIds[index];
1741 }
1742
1743 void SymbolTable::AddFunctionSymbol(std::std::unique_ptr<FunctionSymbol>&&functionSymbol)
1744 {
1745 functionSymbols.push_back(std::move(functionSymbol));
1746 }
1747
1748 void SymbolTable::SetCursorContainer(const sngcm::ast::Node& node)
1749 {
1750 if (cursorContainer == nullptr && (node.GetLexerFlags() & soulng::lexer::LexerFlags::cursorSeen) != soulng::lexer::LexerFlags::none)
1751 {
1752 cursorContainer = container;
1753 }
1754 }
1755
1756 void SymbolTable::ResetAliasNodesAndNamespaceImports()
1757 {
1758 aliasNodes.clear();
1759 namespaceImports.clear();
1760 }
1761
1762 void SymbolTable::Check()
1763 {
1764 globalNs.Check();
1765 if (!module)
1766 {
1767 throw SymbolCheckException("symbol table has no module", globalNs.GetSpan(), globalNs.SourceModuleId());
1768 }
1769 for (const auto& p : nsMap)
1770 {
1771 if (!p.first || !p.second)
1772 {
1773 throw SymbolCheckException("symbol table namespace map contains null namespace pointer", globalNs.GetSpan(), globalNs.SourceModuleId());
1774 }
1775 }
1776 for (const auto& p : nodeSymbolMap)
1777 {
1778 if (!p.first || !p.second)
1779 {
1780 throw SymbolCheckException("symbol table node symbol map contains null symbol or node pointer", globalNs.GetSpan(), globalNs.SourceModuleId());
1781 }
1782 }
1783 for (const auto& p : symbolNodeMap)
1784 {
1785 if (!p.first || !p.second)
1786 {
1787 throw SymbolCheckException("symbol table symbol node map contains null symbol or node pointer", globalNs.GetSpan(), globalNs.SourceModuleId());
1788 }
1789 }
1790 for (const auto& p : typeIdMap)
1791 {
1792 if (!p.second)
1793 {
1794 throw SymbolCheckException("symbol table type id map contains null symbol pointer", globalNs.GetSpan(), globalNs.SourceModuleId());
1795 }
1796 }
1797 for (const auto& p : functionIdMap)
1798 {
1799 if (!p.second)
1800 {
1801 throw SymbolCheckException("symbol table function id map contains null function pointer", globalNs.GetSpan(), globalNs.SourceModuleId());
1802 }
1803 }
1804 for (const auto& p : typeNameMap)
1805 {
1806 if (!p.second)
1807 {
1808 throw SymbolCheckException("symbol table type name map contains null type pointer", globalNs.GetSpan(), globalNs.SourceModuleId());
1809 }
1810 }
1811 for (const auto& p : derivedTypeMap)
1812 {
1813 for (DerivedTypeSymbol* type : p.second)
1814 {
1815 if (!type)
1816 {
1817 throw SymbolCheckException("symbol table derived type name map contains null derived type pointer", globalNs.GetSpan(), globalNs.SourceModuleId());
1818 }
1819 }
1820 }
1821 for (const auto& p : classTemplateSpecializationMap)
1822 {
1823 if (!p.second)
1824 {
1825 throw SymbolCheckException("symbol table class template specialization map contains null specialization pointer", globalNs.GetSpan(), globalNs.SourceModuleId());
1826 }
1827 }
1828 for (const auto& p : specializationCopyMap)
1829 {
1830 if (!p.first || !p.second)
1831 {
1832 throw SymbolCheckException("symbol table specialization copy map contains null specialization pointer", globalNs.GetSpan(), globalNs.SourceModuleId());
1833 }
1834 }
1835 for (const auto& p : arrayTypeMap)
1836 {
1837 if (!p.second)
1838 {
1839 throw SymbolCheckException("symbol table specialization array type map contains null array pointer", globalNs.GetSpan(), globalNs.SourceModuleId());
1840 }
1841 }
1842 conversionTable.Check();
1843 for (ClassTypeSymbol* p : polymorphicClasses)
1844 {
1845 if (!p)
1846 {
1847 throw SymbolCheckException("symbol table contains null polymorphic class pointer", globalNs.GetSpan(), globalNs.SourceModuleId());
1848 }
1849 }
1850 for (ClassTypeSymbol* p : classesHavingStaticConstructor)
1851 {
1852 if (!p)
1853 {
1854 throw SymbolCheckException("symbol table contains null static class pointer", globalNs.GetSpan(), globalNs.SourceModuleId());
1855 }
1856 }
1857 }
1858
1859 void SymbolTable::WriteSymbolDefinitionMap(SymbolWriter& writer)
1860 {
1861 int64_t n = symbolDefinitionMap.size();
1862 writer.GetBinaryWriter().Write(n);
1863 for (const std::std::pair<SymbolLocation, SymbolLocation>&p : symbolDefinitionMap)
1864 {
1865 const SymbolLocation& left = p.first;
1866 writer.GetBinaryWriter().Write(left.moduleId);
1867 writer.GetBinaryWriter().Write(left.fileIndex);
1868 writer.GetBinaryWriter().Write(left.line);
1869 writer.GetBinaryWriter().Write(left.scol);
1870 writer.GetBinaryWriter().Write(left.ecol);
1871 const SymbolLocation& right = p.second;
1872 writer.GetBinaryWriter().Write(right.moduleId);
1873 writer.GetBinaryWriter().Write(right.fileIndex);
1874 writer.GetBinaryWriter().Write(right.line);
1875 writer.GetBinaryWriter().Write(right.scol);
1876 writer.GetBinaryWriter().Write(right.ecol);
1877 }
1878 }
1879
1880 void SymbolTable::ReadSymbolDefinitionMap(SymbolReader& reader)
1881 {
1882 int64_t n = reader.GetBinaryReader().ReadLong();
1883 for (int64_t i = 0; i < n; ++i)
1884 {
1885 SymbolLocation left;
1886 reader.GetBinaryReader().ReadUuid(left.moduleId);
1887 left.fileIndex = reader.GetBinaryReader().ReadInt();
1888 left.line = reader.GetBinaryReader().ReadInt();
1889 left.scol = reader.GetBinaryReader().ReadInt();
1890 left.ecol = reader.GetBinaryReader().ReadInt();
1891 SymbolLocation right;
1892 reader.GetBinaryReader().ReadUuid(right.moduleId);
1893 right.fileIndex = reader.GetBinaryReader().ReadInt();
1894 right.line = reader.GetBinaryReader().ReadInt();
1895 right.scol = reader.GetBinaryReader().ReadInt();
1896 right.ecol = reader.GetBinaryReader().ReadInt();
1897 symbolDefinitionMap[left] = right;
1898 }
1899 }
1900
1901 class IntrinsicConcepts
1902 {
1903 public:
1904 static void Init();
1905 static void Done();
1906 static IntrinsicConcepts& Instance() { return *instance; }
1907 void AddIntrinsicConcept(ConceptNode* intrinsicConcept);
1908 const std::std::vector<std::std::unique_ptr<ConceptNode>>&GetIntrinsicConcepts() const{returnintrinsicConcepts;}
1909 bool Initialized() const { return initialized; }
1910 void SetInitialized() { initialized = true; }
1911 private:
1912 static std::unique_ptr<IntrinsicConcepts> instance;
1913 std::vector<std::std::unique_ptr<ConceptNode>>intrinsicConcepts;
1914 IntrinsicConcepts();
1915 bool initialized;
1916 };
1917
1918 std::unique_ptr<IntrinsicConcepts> IntrinsicConcepts::instance;
1919
1920 void IntrinsicConcepts::Init()
1921 {
1922 instance.reset(new IntrinsicConcepts());
1923 }
1924
1925 void IntrinsicConcepts::Done()
1926 {
1927 instance.reset();
1928 }
1929
1930 IntrinsicConcepts::IntrinsicConcepts() : initialized(false)
1931 {
1932 }
1933
1934 void IntrinsicConcepts::AddIntrinsicConcept(ConceptNode* intrinsicConcept)
1935 {
1936 intrinsicConcepts.push_back(std::unique_ptr<ConceptNode>(intrinsicConcept));
1937 }
1938
1939 void InitCoreSymbolTable(SymbolTable& symbolTable)
1940 {
1941 symbolTable.InitUuids();
1942 BoolTypeSymbol* boolType = new BoolTypeSymbol(Span(), boost::uuids::nil_uuid(), U"bool");
1943 SByteTypeSymbol* sbyteType = new SByteTypeSymbol(Span(), boost::uuids::nil_uuid(), U"sbyte");
1944 ByteTypeSymbol* byteType = new ByteTypeSymbol(Span(), boost::uuids::nil_uuid(), U"byte");
1945 ShortTypeSymbol* shortType = new ShortTypeSymbol(Span(), boost::uuids::nil_uuid(), U"short");
1946 UShortTypeSymbol* ushortType = new UShortTypeSymbol(Span(), boost::uuids::nil_uuid(), U"ushort");
1947 IntTypeSymbol* intType = new IntTypeSymbol(Span(), boost::uuids::nil_uuid(), U"int");
1948 UIntTypeSymbol* uintType = new UIntTypeSymbol(Span(), boost::uuids::nil_uuid(), U"uint");
1949 LongTypeSymbol* longType = new LongTypeSymbol(Span(), boost::uuids::nil_uuid(), U"long");
1950 ULongTypeSymbol* ulongType = new ULongTypeSymbol(Span(), boost::uuids::nil_uuid(), U"ulong");
1951 FloatTypeSymbol* floatType = new FloatTypeSymbol(Span(), boost::uuids::nil_uuid(), U"float");
1952 DoubleTypeSymbol* doubleType = new DoubleTypeSymbol(Span(), boost::uuids::nil_uuid(), U"double");
1953 CharTypeSymbol* charType = new CharTypeSymbol(Span(), boost::uuids::nil_uuid(), U"char");
1954 WCharTypeSymbol* wcharType = new WCharTypeSymbol(Span(), boost::uuids::nil_uuid(), U"wchar");
1955 UCharTypeSymbol* ucharType = new UCharTypeSymbol(Span(), boost::uuids::nil_uuid(), U"uchar");
1956 VoidTypeSymbol* voidType = new VoidTypeSymbol(Span(), boost::uuids::nil_uuid(), U"void");
1957 symbolTable.AddTypeSymbolToGlobalScope(boolType);
1958 symbolTable.AddTypeSymbolToGlobalScope(sbyteType);
1959 symbolTable.AddTypeSymbolToGlobalScope(byteType);
1960 symbolTable.AddTypeSymbolToGlobalScope(shortType);
1961 symbolTable.AddTypeSymbolToGlobalScope(ushortType);
1962 symbolTable.AddTypeSymbolToGlobalScope(intType);
1963 symbolTable.AddTypeSymbolToGlobalScope(uintType);
1964 symbolTable.AddTypeSymbolToGlobalScope(longType);
1965 symbolTable.AddTypeSymbolToGlobalScope(ulongType);
1966 symbolTable.AddTypeSymbolToGlobalScope(floatType);
1967 symbolTable.AddTypeSymbolToGlobalScope(doubleType);
1968 symbolTable.AddTypeSymbolToGlobalScope(charType);
1969 symbolTable.AddTypeSymbolToGlobalScope(wcharType);
1970 symbolTable.AddTypeSymbolToGlobalScope(ucharType);
1971 symbolTable.AddTypeSymbolToGlobalScope(voidType);
1972 symbolTable.AddTypeSymbolToGlobalScope(new NullPtrType(Span(), boost::uuids::nil_uuid(), U"@nullptr_type"));
1973 MakeBasicTypeOperations(symbolTable, boolType, sbyteType, byteType, shortType, ushortType, intType, uintType, longType, ulongType, floatType, doubleType, charType, wcharType, ucharType, voidType);
1974 if (!IntrinsicConcepts::Instance().Initialized())
1975 {
1976 IntrinsicConcepts::Instance().SetInitialized();
1977 IntrinsicConcepts::Instance().AddIntrinsicConcept(new SameConceptNode());
1978 IntrinsicConcepts::Instance().AddIntrinsicConcept(new DerivedConceptNode());
1979 IntrinsicConcepts::Instance().AddIntrinsicConcept(new ConvertibleConceptNode());
1980 IntrinsicConcepts::Instance().AddIntrinsicConcept(new ExplicitlyConvertibleConceptNode());
1981 IntrinsicConcepts::Instance().AddIntrinsicConcept(new CommonConceptNode());
1982 IntrinsicConcepts::Instance().AddIntrinsicConcept(new NonreferenceTypeConceptNode());
1983 }
1984 for (const std::std::unique_ptr<ConceptNode>&conceptNode : IntrinsicConcepts::Instance().GetIntrinsicConcepts())
1985 {
1986 symbolTable.BeginConcept(*conceptNode, false);
1987 ConceptSymbol* conceptSymbol = static_cast<ConceptSymbol*>(symbolTable.Container());
1988 conceptSymbol->SetAccess(SymbolAccess::public_);
1989 int n = conceptNode->TypeParameters().Count();
1990 for (int i = 0; i < n; ++i)
1991 {
1992 IdentifierNode* typeParamId = conceptNode->TypeParameters()[i];
1993 symbolTable.AddTemplateParameter(*typeParamId);
1994 }
1995 symbolTable.EndConcept();
1996 conceptSymbol->ComputeName();
1997 }
1998 symbolTable.AddTypeSymbolToGlobalScope(new StringFunctionContainerSymbol());
1999 }
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049 void InitSymbolTable()
2050 {
2051 IntrinsicConcepts::Init();
2052 }
2053
2054 void DoneSymbolTable()
2055 {
2056 IntrinsicConcepts::Done();
2057 }
2058
2059 } }