1 // =================================
   2 // Copyright (c) 2021 Seppo Laakko
   3 // Distributed under the MIT license
   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& leftconst ClassTemplateSpecializationKey& right)
  39 {
  40     if (!TypesEqual(left.classTemplateright.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& leftconst ClassTemplateSpecializationKey& right)
  51 {
  52     return !(left == right);
  53 }
  54 
  55 bool operator==(const ArrayKey& leftconst ArrayKey& right)
  56 {
  57     if (!TypesEqual(left.elementTyperight.elementType)) return false;
  58     if (left.size != right.size) return false;
  59     return true;
  60 }
  61 
  62 bool operator!=(const ArrayKey& leftconst ArrayKey& right)
  63 {
  64     return !(left == right);
  65 }
  66 
  67 void MapIdentifierToSymbolDefinition(IdentifierNode* identifierNodeSymbol* 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(identifierNodemodulesymbol);
  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::symbolTablemodule)
  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::uuidTypeSymbol*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::uuidTypeSymbol*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(functionIdprofiledFunctionName);
 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(functionIdprofiledFunctionName);
 302         }
 303     }
 304 }
 305 
 306 void SymbolTable::FinishRead(const std::std::vector<ArrayTypeSymbol*>&arrayTypesconststd::std::vector<DerivedTypeSymbol*>&derivedTypes
 307     const std::std::vector<ClassTemplateSpecializationSymbol*>&classTemplateSpecializationsconststd::std::vector<TypeOrConceptRequest>&typeAndConceptRequests
 308     const std::std::vector<FunctionRequest>&functionRequestsstd::std::vector<FunctionSymbol*>&conversions)
 309 {
 310     ProcessTypeConceptAndFunctionRequests(typeAndConceptRequestsfunctionRequests);
 311     for (FunctionSymbol* conversion : conversions)
 312     {
 313         AddConversion(conversionmodule);
 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* fromNsNamespaceSymbol* 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(nsNamenamespaceNode.GetSpan()namespaceNode.ModuleId());
 388     MapNode(&namespaceNodecontainer);
 389     return ns;
 390 }
 391 
 392 NamespaceSymbol* SymbolTable::BeginNamespace(const std::u32string& namespaceNameconst Span& spanconst 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(namespaceNamespansourceModuleId);
 422             BeginContainer(ns);
 423             return ns;
 424         }
 425     }
 426 }
 427 
 428 void SymbolTable::EndNamespace()
 429 {
 430     EndContainer();
 431 }
 432 
 433 void SymbolTable::BeginFunction(FunctionNode& functionNodeint32_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(&functionNodefunctionSymbol);
 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(&parameterNodeparameterSymbol);
 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(&classNodeclassTypeSymbol);
 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& classInstanceNodeClassTemplateSpecializationSymbol* classTemplateSpecialization)
 538 {
 539     currentClassStack.push(currentClass);
 540     currentClass = classTemplateSpecialization;
 541     MapNode(&classInstanceNodeclassTemplateSpecialization);
 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(&templateParameterNodetemplateParameterSymbol);
 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(&identifierNodetemplateParameterSymbol);
 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(&interfaceNodeinterfaceTypeSymbol);
 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& staticConstructorNodeint32_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(&staticConstructorNodestaticConstructorSymbol);
 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& constructorNodeint32_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(&constructorNodeconstructorSymbol);
 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& destructorNodeint32_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(&destructorNodedestructorSymbol);
 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& memberFunctionNodeint32_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(&memberFunctionNodememberFunctionSymbol);
 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& conversionFunctionNodeint32_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(&conversionFunctionNodeconversionFunctionSymbol);
 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(&memberVariableNodememberVariableSymbol);
 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(&delegateNodedelegateTypeSymbol);
 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(&classDelegateNodeclassDelegateTypeSymbol);
 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& conceptNodebool 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(&conceptNodeconceptSymbol);
 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(&axiomNodeaxiomSymbol);
 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(&nodedeclarationBlock);
 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(&constructionStatementNodelocalVariableSymbol);
 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(&constructionStatementNodelocalVariableSymbol);
 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(&identifierNodelocalVariableSymbol);
 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(&typedefNodetypedefSymbol);
 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(&constantNodeconstantSymbol);
 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(&globalVariableNodeglobalVariableSymbol);
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(&enumTypeNodeenumTypeSymbol);
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(&enumConstantNodeenumConstantSymbol);
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* nodeSymbol* 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& readerSymbol* forSymbolconst boost::uuids::uuid& typeIdint index)
1166 {
1167     EmplaceTypeOrConceptRequest(readerforSymboltypeIdindex);
1168 }
1169 
1170 const int conceptRequestIndex = std::numeric_limits<int>::max();
1171 
1172 void SymbolTable::EmplaceConceptRequest(SymbolReader& readerSymbol* forSymbolconst boost::uuids::uuid& typeId)
1173 {
1174     EmplaceTypeOrConceptRequest(readerforSymboltypeIdconceptRequestIndex);
1175 }
1176 
1177 void SymbolTable::EmplaceTypeOrConceptRequest(SymbolReader& readerSymbol* forSymbolconst boost::uuids::uuid& typeIdint 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(typeSymbolindex);
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(forSymboltypeIdindex));
1209     }
1210 }
1211 
1212 void SymbolTable::EmplaceFunctionRequest(SymbolReader& readerSymbol* forSymbolconst::boost::uuids::uuid& functionIdint index)
1213 {
1214     auto it = functionIdMap.find(functionId);
1215     if (it != functionIdMap.cend())
1216     {
1217         FunctionSymbol* functionSymbol = it->second;
1218         forSymbol->EmplaceFunction(functionSymbolindex);
1219     }
1220     else
1221     {
1222         reader.AddFunctionRequest(FunctionRequest(forSymbolfunctionIdindex));
1223     }
1224 }
1225 
1226 void SymbolTable::ProcessTypeConceptAndFunctionRequests(const std::std::vector<TypeOrConceptRequest>&typeAndConceptRequestsconststd::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(typeSymbolindex);
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(functionSymbolindex);
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* baseTypeconst TypeDerivationRec& derivationRecconst Span& spanconst boost::uuids::uuid& moduleId)
1308 {
1309     if (!baseType)
1310     {
1311         throw Exception("base type is null!"spanmoduleId);
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"spanmoduleId);
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(baseTypederivationRec)baseTypederivationRec);
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(spanmoduleId));
1349         TypeSymbol* withoutConst = valueType->GetType()->RemoveConst(spanmoduleId);
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(spanmoduleId));
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* classTemplateconst std::std::vector<TypeSymbol*>&templateArgumentTypes
1373     const Span& spanconst boost::uuids::uuid& sourceModuleId)
1374 {
1375 #ifdef IMMUTABLE_MODULE_CHECK
1376 
1377 
1378 
1379 
1380 #endif
1381     ClassTemplateSpecializationKey key(classTemplatetemplateArgumentTypes);
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(classTemplatetemplateArgumentTypes);
1389     ClassTemplateSpecializationSymbol* classTemplateSpecialization = new ClassTemplateSpecializationSymbol(Span()boost::uuids::nil_uuid()classTemplateSpecializationNameclassTemplate
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(classTemplatetemplateArgumentTypes);
1416     std::u32string classTemplateSpecializationName = MakeClassTemplateSpecializationName(classTemplatetemplateArgumentTypes);
1417     ClassTemplateSpecializationSymbol* copy = new ClassTemplateSpecializationSymbol(source->GetSpan()source->SourceModuleId()classTemplateSpecializationNameclassTemplatetemplateArgumentTypes);
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* elementTypeint64_t sizeconst Span& spanconst boost::uuids::uuid& moduleId)
1441 {
1442 #ifdef IMMUTABLE_MODULE_CHECK
1443 
1444 
1445 
1446 
1447 #endif
1448     ArrayKey key(elementTypesize);
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(spanmoduleIdelementType->FullName() + U"[" + ToUtf32(std::to_string(size)) + U"]"elementTypesize);
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(spanmoduleIdU"Iterator");
1476     iterator->SetModule(module);
1477     iterator->SetAccess(SymbolAccess::public_);
1478     iterator->SetType(arrayType->ElementType()->AddPointer(spanmoduleId));
1479     iterator->SetBound();
1480     arrayType->AddMember(iterator);
1481     TypedefSymbol* constIterator = new TypedefSymbol(spanmoduleIdU"ConstIterator");
1482     constIterator->SetModule(module);
1483     constIterator->SetAccess(SymbolAccess::public_);
1484     constIterator->SetType(arrayType->ElementType()->AddConst(spanmoduleId)->AddPointer(spanmoduleId));
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* conversionModule* 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(conversionnullptr);
1525 }
1526 
1527 FunctionSymbol* SymbolTable::GetConversion(TypeSymbol* sourceTypeTypeSymbol* targetTypeconst Span& spanconst boost::uuids::uuid& moduleId) const
1528 {
1529     return conversionTable.GetConversion(sourceTypetargetTypespanmoduleId);
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& functionIdconst 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* invokeIdFunctionSymbol* 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* nodeSymbol* 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* identifierNodeModule* moduleSymbol* 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<SymbolLocationSymbolLocation>&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(symbolTableboolTypesbyteTypebyteTypeshortTypeushortTypeintTypeuintTypelongTypeulongTypefloatTypedoubleTypecharTypewcharTypeucharTypevoidType);
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(*conceptNodefalse);
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 void CreateClassFile(const std::string& executableFilePath, SymbolTable& symbolTable)
2003 {
2004     if (GetGlobalFlag(GlobalFlags::verbose) && !GetGlobalFlag(GlobalFlags::unitTest))
2005     {
2006         LogMessage(symbolTable.GetModule()->LogStreamId(), "Generating class file...");
2007     }
2008     boost::filesystem::path cfp = boost::filesystem::path(executableFilePath).replace_extension(".cls");
2009     std::string classFilePath = cfp.generic_string();
2010     const std::unordered_set<ClassTypeSymbol*>& polymorphicClasses = symbolTable.PolymorphicClasses();
2011     std::unordered_map<boost::uuids::uuid, ClassTypeSymbol*, boost::hash<boost::uuids::uuid>> classIdClassMap;
2012     for (ClassTypeSymbol* polymorphicClass : polymorphicClasses)
2013     {
2014         classIdClassMap[polymorphicClass->TypeId()] = polymorphicClass;
2015     }
2016     uint32_t n = classIdClassMap.size();
2017     BinaryWriter writer(classFilePath);
2018     writer.WriteULEB128UInt(n);
2019     for (const auto& p : classIdClassMap)
2020     {
2021         const boost::uuids::uuid& typeId = p.first;
2022         ClassTypeSymbol* cls = p.second;
2023         std::string vmtObjectName = cls->VmtObjectNameStr();
2024         boost::uuids::uuid baseClassTypeId = boost::uuids::nil_uuid();
2025         if (cls->BaseClass())
2026         {
2027             baseClassTypeId = cls->BaseClass()->TypeId();
2028         }
2029         writer.Write(typeId);
2030         writer.Write(vmtObjectName);
2031         writer.Write(baseClassTypeId);
2032     }
2033     const std::unordered_set<ClassTypeSymbol*>& classesHavingStaticConstructor = symbolTable.ClassesHavingStaticConstructor();
2034     uint32_t ns = classesHavingStaticConstructor.size();
2035     writer.WriteULEB128UInt(ns);
2036     for (ClassTypeSymbol* classHavingStaticConstructor : classesHavingStaticConstructor)
2037     {
2038         const boost::uuids::uuid& typeId = classHavingStaticConstructor->TypeId();
2039         writer.Write(typeId);
2040     }
2041     if (GetGlobalFlag(GlobalFlags::verbose) && !GetGlobalFlag(GlobalFlags::unitTest))
2042     {
2043         LogMessage(symbolTable.GetModule()->LogStreamId(), "==> " + classFilePath);
2044     }
2045 }
2046 */
2047 
2048 
2049 void InitSymbolTable()
2050 {
2051     IntrinsicConcepts::Init();
2052 }
2053 
2054 void DoneSymbolTable()
2055 {
2056     IntrinsicConcepts::Done();
2057 }
2058 
2059 } } // namespace cmajor::symbols