1 // =================================
   2 // Copyright (c) 2021 Seppo Laakko
   3 // Distributed under the MIT license
   4 // =================================
   5 
   6 #include <cmajor/codegenllvm/LlvmCodeGenerator.hpp>
   7 #include <cmajor/binder/BoundCompileUnit.hpp>
   8 #include <cmajor/binder/BoundNamespace.hpp>
   9 #include <cmajor/binder/BoundEnum.hpp>
  10 #include <cmajor/binder/BoundFunction.hpp>
  11 #include <cmajor/symbols/GlobalFlags.hpp>
  12 #include <cmajor/symbols/InterfaceTypeSymbol.hpp>
  13 #include <soulng/util/Log.hpp>
  14 #include <soulng/util/Util.hpp>
  15 #include <soulng/util/Unicode.hpp>
  16 #include <soulng/util/Path.hpp>
  17 #include <iostream>
  18 
  19 namespace cmajor { namespace codegenllvm {
  20 
  21 using namespace cmajor::symbols;
  22 using namespace soulng::util;
  23 using namespace soulng::unicode;
  24 
  25 struct NativeModule 
  26 {
  27     NativeModule(cmajor::ir::Emitter* emitter_const std::string& moduleFilePath_) : emitter(emitter_)
  28     {
  29         module = emitter->CreateModule(moduleFilePath_);
  30         emitter->SetModule(module);
  31     }
  32     ~NativeModule()
  33     {
  34         emitter->DestroyModule(module);
  35     }
  36     cmajor::ir::Emitter* emitter;
  37     void* module;
  38 };
  39 
  40 LlvmCodeGenerator::LlvmCodeGenerator(cmajor::ir::EmittingContext& emittingContext_) :
  41     cmajor::codegenbase::CodeGenerator(emittingContext_)symbolTable(nullptr)symbolsModule(nullptr)emitter(GetEmitter())emittingContext(&emittingContext_)debugInfo(false)
  42     compileUnit(nullptr)currentClass(nullptr)currentFunction(nullptr)trueBlock(nullptr)falseBlock(nullptr)breakTarget(nullptr)continueTarget(nullptr)handlerBlock(nullptr)
  43     cleanupBlock(nullptr)entryBasicBlock(nullptr)newCleanupNeeded(false)currentPad(nullptr)prevLineNumber(0)destructorCallGenerated(false)lastInstructionWasRet(false)
  44     basicBlockOpen(false)lastAlloca(nullptr)compoundLevel(0)function(nullptr)sequenceSecond(nullptr)currentBlock(nullptr)genJumpingBoolCode(false)breakTargetBlock(nullptr)
  45     continueTargetBlock(nullptr)defaultDest(nullptr)currentCaseMap(nullptr)
  46 {
  47     emitter->SetEmittingDelegate(this);
  48 }
  49 
  50 void LlvmCodeGenerator::GenerateCode(void* boundCompileUnit)
  51 {
  52     BoundCompileUnit* compileUnit = static_cast<BoundCompileUnit*>(boundCompileUnit);
  53     compileUnit->Accept(*this);
  54 }
  55 
  56 void LlvmCodeGenerator::Visit(BoundCompileUnit& boundCompileUnit)
  57 {
  58     symbolTable = &boundCompileUnit.GetSymbolTable();
  59     symbolsModule = &boundCompileUnit.GetModule();
  60     compileUnitId = boundCompileUnit.Id();
  61     if (!symbolsModule->IsCore())
  62     {
  63         symbolsModule->AddCompileUnitId(compileUnitId);
  64     }
  65     emitter->SetCompileUnitId(compileUnitId);
  66     NativeModule nativeModule(emitterboundCompileUnit.GetCompileUnitNode()->FilePath());
  67     module = nativeModule.module;
  68     emitter->SetTargetTriple(emittingContext->TargetTriple());
  69     emitter->SetDataLayout(emittingContext->DataLayout());
  70     emitter->SetSourceFileName(boundCompileUnit.GetCompileUnitNode()->FilePath());
  71     emitter->ResetCurrentDebugLocation();
  72     debugInfo = false;
  73     if (GetGlobalFlag(GlobalFlags::generateDebugInfo) && boundCompileUnit.GetCompileUnitNode() && !boundCompileUnit.GetCompileUnitNode()->IsSynthesizedUnit())
  74     {
  75         emitter->StartDebugInfo(boundCompileUnit.GetCompileUnitNode()->FilePath()GetCompilerVersion()GetGlobalFlag(GlobalFlags::release)boundCompileUnit.GetCompileUnitNode());
  76         debugInfo = true;
  77     }
  78     compileUnit = &boundCompileUnit;
  79     ConstantArrayRepository& constantArrayRepository = boundCompileUnit.GetConstantArrayRepository();
  80     for (ConstantSymbol* constantSymbol : constantArrayRepository.ConstantArrays())
  81     {
  82         constantSymbol->ArrayIrObject(*emittertrue);
  83     }
  84     ConstantStructureRepository& constantStructureRepository = boundCompileUnit.GetConstantStructureRepository();
  85     for (ConstantSymbol* constantSymbol : constantStructureRepository.ConstantStructures())
  86     {
  87         constantSymbol->StructureIrObject(*emittertrue);
  88     }
  89     int n = boundCompileUnit.BoundNodes().size();
  90     for (int i = 0; i < n; ++i)
  91     {
  92         BoundNode* boundNode = boundCompileUnit.BoundNodes()[i].get();
  93         boundNode->Accept(*this);
  94     }
  95     GenerateInitUnwindInfoFunction(boundCompileUnit);
  96     GenerateInitCompileUnitFunction(boundCompileUnit);
  97     if (boundCompileUnit.GetGlobalInitializationFunctionSymbol() != nullptr)
  98     {
  99         GenerateGlobalInitFuncion(boundCompileUnit);
 100     }
 101     if (debugInfo)
 102     {
 103         emitter->FinalizeDebugInfo();
 104     }
 105     if (GetGlobalFlag(GlobalFlags::emitLlvm))
 106     {
 107         emitter->EmitIrText(boundCompileUnit.LLFilePath());
 108     }
 109     emitter->VerifyModule();
 110     if (GetGlobalFlag(GlobalFlags::release))
 111     {
 112         emitter->EmitIrFile(boundCompileUnit.BCFilePath());
 113         Optimize(GetOptimizationLevel()boundCompileUnit.BCFilePath()boundCompileUnit.OptBCFilePath());
 114         if (GetGlobalFlag(GlobalFlags::emitOptLlvm))
 115         {
 116             emitter->Disassemble(boundCompileUnit.OptBCFilePath()boundCompileUnit.OptLLFilePath());
 117         }
 118         emitter->Compile(boundCompileUnit.OptBCFilePath()boundCompileUnit.ObjectFilePath()GetOptimizationLevel());
 119     }
 120     else
 121     {
 122         emitter->EmitObjectCodeFile(boundCompileUnit.ObjectFilePath());
 123     }
 124     if (debugInfo)
 125     {
 126         emitter->EndDebugInfo();
 127     }
 128 }
 129 
 130 void LlvmCodeGenerator::Visit(BoundNamespace& boundNamespace)
 131 {
 132     int numComponents = 0;
 133     if (debugInfo)
 134     {
 135         if (!boundNamespace.GetNamespaceNode().Id()->Str().empty())
 136         {
 137             std::vector<std::u32string> components = Split(boundNamespace.GetNamespaceNode().Id()->Str()'.');
 138             numComponents = components.size();
 139             for (int i = 0; i < numComponents; ++i)
 140             {
 141                 void* ns = emitter->CreateDebugInfoForNamespace(emitter->CurrentScope()ToUtf8(components[i]));
 142                 emitter->PushScope(ns);
 143             }
 144         }
 145         else
 146         {
 147             emitter->PushScope(emitter->GetDebugInfoForFile(boundNamespace.GetSpan()boundNamespace.ModuleId()));
 148         }
 149     }
 150     int n = boundNamespace.Members().size();
 151     for (int i = 0; i < n; ++i)
 152     {
 153         BoundNode* member = boundNamespace.Members()[i].get();
 154         member->Accept(*this);
 155     }
 156     if (debugInfo)
 157     {
 158         if (!boundNamespace.GetNamespaceNode().Id()->Str().empty())
 159         {
 160             for (int i = 0; i < numComponents; ++i)
 161             {
 162                 emitter->PopScope();
 163             }
 164         }
 165         else
 166         {
 167             emitter->PopScope();
 168         }
 169     }
 170 }
 171 
 172 void LlvmCodeGenerator::Visit(BoundClass& boundClass)
 173 {
 174     classStack.push(currentClass);
 175     currentClass = &boundClass;
 176     bool prevDebugInfo = debugInfo;
 177     void* prevDIBuilder = emitter->DIBuilder();
 178     if (!boundClass.ContainsSourceFunctions())
 179     {
 180         emitter->ResetCurrentDebugLocation();
 181         debugInfo = false;
 182         emitter->SetCurrentDIBuilder(nullptr);
 183     }
 184     if (debugInfo)
 185     {
 186         emitter->MapClassPtr(currentClass->GetClassTypeSymbol()->TypeId()currentClass->GetClassTypeSymbol()ToUtf8(currentClass->GetClassTypeSymbol()->FullName()));
 187         void* diType = emitter->GetDITypeByTypeId(currentClass->GetClassTypeSymbol()->TypeId());
 188         if (diType)
 189         {
 190             emitter->PushScope(diType);
 191         }
 192         else
 193         {
 194             void* baseClassDIType = nullptr;
 195             if (currentClass->GetClassTypeSymbol()->BaseClass())
 196             {
 197                 baseClassDIType = currentClass->GetClassTypeSymbol()->BaseClass()->GetDIType(*emitter);
 198             }
 199             void* vtableHolderClassDIType = nullptr;
 200             if (currentClass->GetClassTypeSymbol()->IsPolymorphic() && currentClass->GetClassTypeSymbol()->VmtPtrHolderClass())
 201             {
 202                 vtableHolderClassDIType = currentClass->GetClassTypeSymbol()->VmtPtrHolderClass()->CreateDIForwardDeclaration(*emitter);
 203                 emitter->MapFwdDeclaration(vtableHolderClassDITypecurrentClass->GetClassTypeSymbol()->VmtPtrHolderClass()->TypeId());
 204             }
 205             void* classIrType = currentClass->GetClassTypeSymbol()->IrType(*emitter);
 206             Span classSpan = currentClass->GetClassTypeSymbol()->GetSpan();
 207             boost::uuids::uuid moduleId = currentClass->GetClassTypeSymbol()->SourceModuleId();
 208             if (currentClass->GetClassTypeSymbol()->GetSymbolType() == SymbolType::classTemplateSpecializationSymbol)
 209             {
 210                 ClassTemplateSpecializationSymbol* specialization = static_cast<ClassTemplateSpecializationSymbol*>(currentClass->GetClassTypeSymbol());
 211                 classSpan = specialization->GetClassTemplate()->GetSpan();
 212                 moduleId = specialization->GetClassTemplate()->SourceModuleId();
 213             }
 214             void* forwardDeclaration = emitter->CreateIrDIForwardDeclaration(classIrTypeToUtf8(currentClass->GetClassTypeSymbol()->Name())ToUtf8(currentClass->GetClassTypeSymbol()->MangledName())
 215                 classSpanmoduleId);
 216             emitter->SetDITypeByTypeId(currentClass->GetClassTypeSymbol()->TypeId()forwardDeclarationToUtf8(currentClass->GetClassTypeSymbol()->FullName()));
 217             std::vector<void*> memberVariableElements;
 218             for (MemberVariableSymbol* memberVariable : currentClass->GetClassTypeSymbol()->MemberVariables())
 219             {
 220                 int memberVariableLayoutIndex = memberVariable->LayoutIndex();
 221                 uint64_t offsetInBits = emitter->GetOffsetInBits(classIrTypememberVariableLayoutIndex);
 222                 memberVariableElements.push_back(memberVariable->GetDIMemberType(*emitteroffsetInBits));
 223             }
 224             void* clsDIType = emitter->CreateDITypeForClassType(classIrTypememberVariableElementsclassSpancurrentClass->GetClassTypeSymbol()->SourceModuleId()ToUtf8(currentClass->GetClassTypeSymbol()->Name())vtableHolderClassDIType
 225                 ToUtf8(currentClass->GetClassTypeSymbol()->MangledName())baseClassDIType);
 226             emitter->MapFwdDeclaration(forwardDeclarationcurrentClass->GetClassTypeSymbol()->TypeId());
 227             emitter->SetDITypeByTypeId(currentClass->GetClassTypeSymbol()->TypeId()clsDITypeToUtf8(currentClass->GetClassTypeSymbol()->FullName()));
 228             emitter->PushScope(clsDIType);
 229         }
 230     }
 231     int n = boundClass.Members().size();
 232     for (int i = 0; i < n; ++i)
 233     {
 234         BoundNode* boundNode = boundClass.Members()[i].get();
 235         boundNode->Accept(*this);
 236     }
 237     if (debugInfo)
 238     {
 239         emitter->PopScope();
 240     }
 241     currentClass = classStack.top();
 242     classStack.pop();
 243     debugInfo = prevDebugInfo;
 244     emitter->SetCurrentDIBuilder(prevDIBuilder);
 245 }
 246 
 247 void LlvmCodeGenerator::Visit(BoundEnumTypeDefinition& boundEnumTypeDefinition)
 248 {
 249     if (debugInfo)
 250     {
 251         EnumTypeSymbol* enumTypeSymbol = boundEnumTypeDefinition.GetEnumTypeSymbol();
 252         uint64_t sizeInBits = enumTypeSymbol->SizeInBits(*emitter);
 253         uint32_t alignInBits = enumTypeSymbol->AlignmentInBits(*emitter);
 254         std::vector<void*> elements;
 255         std::vector<EnumConstantSymbol*> enumConstants = enumTypeSymbol->GetEnumConstants();
 256         for (EnumConstantSymbol* enumConstant : enumConstants)
 257         {
 258             int64_t value = 0;
 259             if (enumTypeSymbol->UnderlyingType()->IsUnsignedType())
 260             {
 261                 Value* val = enumConstant->GetValue()->As(symbolTable->GetTypeByName(U"ulong")falseenumTypeSymbol->GetSpan()enumTypeSymbol->SourceModuleId()true);
 262                 if (val)
 263                 {
 264                     ULongValue* ulongValue = static_cast<ULongValue*>(val);
 265                     value = static_cast<int64_t>(ulongValue->GetValue());
 266                 }
 267             }
 268             else
 269             {
 270                 Value* val = enumConstant->GetValue()->As(symbolTable->GetTypeByName(U"long")falseenumTypeSymbol->GetSpan()enumTypeSymbol->SourceModuleId()true);
 271                 if (val)
 272                 {
 273                     LongValue* longValue = static_cast<LongValue*>(val);
 274                     value = longValue->GetValue();
 275                 }
 276             }
 277             elements.push_back(emitter->CreateDITypeForEnumConstant(ToUtf8(enumConstant->Name())value));
 278         }
 279         void* enumTypeDI = emitter->CreateDITypeForEnumType(ToUtf8(enumTypeSymbol->Name())ToUtf8(enumTypeSymbol->MangledName())enumTypeSymbol->GetSpan()enumTypeSymbol->SourceModuleId()elements
 280             sizeInBitsalignInBitsenumTypeSymbol->UnderlyingType()->GetDIType(*emitter));
 281         emitter->SetDITypeByTypeId(enumTypeSymbol->TypeId()enumTypeDIToUtf8(enumTypeSymbol->FullName()));
 282     }
 283 }
 284 
 285 void LlvmCodeGenerator::Visit(BoundFunction& boundFunction)
 286 {
 287     if (!boundFunction.Body()) return;
 288     currentFunction = &boundFunction;
 289     handlerBlock = nullptr;
 290     cleanupBlock = nullptr;
 291     newCleanupNeeded = false;
 292     currentPad = nullptr;
 293     prevLineNumber = 0;
 294     destructorCallGenerated = false;
 295     lastInstructionWasRet = false;
 296     basicBlockOpen = false;
 297     lastAlloca = nullptr;
 298     compoundLevel = 0;
 299     cleanups.clear();
 300     pads.clear();
 301     labeledStatementMap.clear();
 302     FunctionSymbol* functionSymbol = boundFunction.GetFunctionSymbol();
 303     if (compileUnit->CodeGenerated(functionSymbol)) return;
 304     compileUnit->SetCodeGenerated(functionSymbol);
 305     void* functionType = functionSymbol->IrType(*emitter);
 306     function = emitter->GetOrInsertFunction(ToUtf8(functionSymbol->MangledName())functionTypefunctionSymbol->DontThrow());
 307     bool setInline = false;
 308     if (GetGlobalFlag(GlobalFlags::release) && functionSymbol->IsInline())
 309     {
 310         emitter->AddInlineFunctionAttribute(function);
 311         functionSymbol->SetLinkOnceOdrLinkage();
 312     }
 313     else if (functionSymbol->IsGeneratedFunction())
 314     {
 315         emitter->AddInlineFunctionAttribute(function);
 316         functionSymbol->SetLinkOnceOdrLinkage();
 317     }
 318     if (functionSymbol->HasLinkOnceOdrLinkage())
 319     {
 320         setInline = true;
 321         void* comdat = emitter->GetOrInsertAnyFunctionComdat(ToUtf8(functionSymbol->MangledName())function);
 322     }
 323     if (functionSymbol->GetFlag(FunctionSymbolFlags::winapi))
 324     {
 325         emitter->SetFunctionCallConventionToStdCall(function);
 326     }
 327     emitter->SetFunctionLinkage(functionsetInline);
 328     int32_t fileIndex = -1;
 329     boost::uuids::uuid functionId;
 330     if (functionSymbol->HasSource())
 331     {
 332         fileIndex = functionSymbol->GetSpan().fileIndex;
 333         functionId = functionSymbol->FunctionId();
 334     }
 335     emitter->SetFunction(functionfileIndexfunctionSymbol->SourceModuleId()functionId);
 336     bool hasSource = functionSymbol->HasSource();
 337     bool prevDebugInfo = debugInfo;
 338     void* prevDIBuilder = emitter->DIBuilder();
 339     if (!hasSource)
 340     {
 341         emitter->ResetCurrentDebugLocation();
 342         debugInfo = false;
 343         emitter->SetCurrentDIBuilder(nullptr);
 344     }
 345     if (debugInfo)
 346     {
 347         emitter->SetInPrologue(true);
 348         emitter->SetCurrentDebugLocation(Span());
 349         std::vector<void*> elementTypes;
 350         if (functionSymbol->ReturnType())
 351         {
 352             elementTypes.push_back(functionSymbol->ReturnType()->GetDIType(*emitter));
 353         }
 354         else
 355         {
 356             elementTypes.push_back(symbolTable->GetTypeByName(U"void")->GetDIType(*emitter));
 357         }
 358         for (ParameterSymbol* parameter : functionSymbol->Parameters())
 359         {
 360             TypeSymbol* parameterType = parameter->GetType();
 361             elementTypes.push_back(parameterType->GetDIType(*emitter));
 362         }
 363         void* subroutineType = emitter->CreateSubroutineType(elementTypes);
 364         void* subprogram = nullptr;
 365         if (functionSymbol->IsConstructorDestructorOrNonstaticMemberFunction())
 366         {
 367             unsigned virtuality = 0;
 368             if (functionSymbol->IsVirtualAbstractOrOverride())
 369             {
 370                 if (functionSymbol->IsAbstract())
 371                 {
 372                     virtuality = emitter->GetPureVirtualVirtuality();
 373                 }
 374                 else
 375                 {
 376                     virtuality = emitter->GetVirtualVirtuality();
 377                 }
 378             }
 379             void* vtableHolder = nullptr;
 380             Symbol* parent = functionSymbol->Parent();
 381             if (parent && parent->IsClassTypeSymbol())
 382             {
 383                 ClassTypeSymbol* cls = static_cast<ClassTypeSymbol*>(parent);
 384                 if (cls->IsPolymorphic() && cls->VmtPtrHolderClass())
 385                 {
 386                     vtableHolder = cls->VmtPtrHolderClass()->GetDIType(*emitter);
 387                 }
 388             }
 389             unsigned flags = emitter->GetFunctionFlags(functionSymbol->IsStatic()AccessFlag(*emitterfunctionSymbol->Access())functionSymbol->IsExplicit());
 390             unsigned vtableIndex = 0;
 391             if (functionSymbol->VmtIndex() != -1)
 392             {
 393                 vtableIndex = functionSymbol->VmtIndex();
 394             }
 395             subprogram = emitter->CreateDIMethod(ToUtf8(functionSymbol->Name())ToUtf8(functionSymbol->MangledName())functionSymbol->GetSpan()functionSymbol->SourceModuleId()subroutineTypevirtualityvtableIndex
 396                 vtableHolderflags);
 397         }
 398         else
 399         {
 400             unsigned flags = AccessFlag(*emitterfunctionSymbol->Access());
 401             subprogram = emitter->CreateDIFunction(ToUtf8(functionSymbol->Name())ToUtf8(functionSymbol->MangledName())functionSymbol->GetSpan()functionSymbol->SourceModuleId()subroutineTypeflags);
 402         }
 403         emitter->SetDISubprogram(functionsubprogram);
 404         emitter->PushScope(subprogram);
 405     }
 406     void* entryBlock = emitter->CreateBasicBlock("entry");
 407     entryBasicBlock = entryBlock;
 408     emitter->SetCurrentBasicBlock(entryBlock);
 409     if (currentClass && !currentClass->IsInlineFunctionContainer())
 410     {
 411         ClassTypeSymbol* classTypeSymbol = currentClass->GetClassTypeSymbol();
 412         if (!emitter->IsVmtObjectCreated(classTypeSymbol))
 413         {
 414             classTypeSymbol->VmtObject(*emittertrue);
 415         }
 416         if (!emitter->IsStaticObjectCreated(classTypeSymbol))
 417         {
 418             classTypeSymbol->StaticObject(*emittertrue);
 419         }
 420     }
 421     int np = functionSymbol->Parameters().size();
 422     for (int i = 0; i < np; ++i)
 423     {
 424         ParameterSymbol* parameter = functionSymbol->Parameters()[i];
 425         void* allocaInst = emitter->CreateAlloca(parameter->GetType()->IrType(*emitter));
 426         emitter->SetIrObject(parameterallocaInst);
 427         lastAlloca = allocaInst;
 428         if (debugInfo)
 429         {
 430             void* paramVar = emitter->CreateDIParameterVariable(ToUtf8(parameter->Name())i + 1parameter->GetSpan()parameter->SourceModuleId()parameter->GetType()->GetDIType(*emitter)allocaInst);
 431         }
 432     }
 433     if (functionSymbol->ReturnParam())
 434     {
 435         ParameterSymbol* parameter = functionSymbol->ReturnParam();
 436         void* allocaInst = emitter->CreateAlloca(parameter->GetType()->IrType(*emitter));
 437         emitter->SetIrObject(parameterallocaInst);
 438         lastAlloca = allocaInst;
 439     }
 440     int nlv = functionSymbol->LocalVariables().size();
 441     for (int i = 0; i < nlv; ++i)
 442     {
 443         LocalVariableSymbol* localVariable = functionSymbol->LocalVariables()[i];
 444         void* allocaInst = emitter->CreateAlloca(localVariable->GetType()->IrType(*emitter));
 445         emitter->SetIrObject(localVariableallocaInst);
 446         lastAlloca = allocaInst;
 447         if (debugInfo && localVariable->GetSpan().Valid())
 448         {
 449             void* localVar = emitter->CreateDIAutoVariable(ToUtf8(localVariable->Name())localVariable->GetSpan()localVariable->SourceModuleId()
 450                 localVariable->GetType()->GetDIType(*emitter)allocaInst);
 451         }
 452     }
 453     if (!functionSymbol->DontThrow())
 454     {
 455         GenerateEnterFunctionCode(boundFunction);
 456     }
 457     for (int i = 0; i < np; ++i)
 458     {
 459         void* arg = emitter->GetFunctionArgument(functioni);
 460         ParameterSymbol* parameter = functionSymbol->Parameters()[i];
 461         if (parameter->GetType()->IsClassTypeSymbol())
 462         {
 463             ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(parameter->GetType());
 464             FunctionSymbol* copyConstructor = classType->CopyConstructor();
 465             if (!copyConstructor)
 466             {
 467                 copyConstructor = compileUnit->GetCopyConstructorFor(classType->TypeId());
 468             }
 469             void* copyCtorType = copyConstructor->IrType(*emitter);
 470             void* callee = emitter->GetOrInsertFunction(ToUtf8(copyConstructor->MangledName())copyCtorTypecopyConstructor->DontThrow());
 471             std::vector<void*> args;
 472             args.push_back(parameter->IrObject(*emitter));
 473             args.push_back(arg);
 474             if (debugInfo)
 475             {
 476                 emitter->SetInPrologue(false);
 477                 emitter->SetCurrentDebugLocation(boundFunction.Body()->GetSpan());
 478                 emitter->CreateCall(calleeargs);
 479                 emitter->SetInPrologue(true);
 480                 emitter->SetCurrentDebugLocation(Span());
 481             }
 482             else
 483             {
 484                 emitter->CreateCall(calleeargs);
 485             }
 486         }
 487         else if (parameter->GetType()->GetSymbolType() == SymbolType::classDelegateTypeSymbol)
 488         {
 489             ClassDelegateTypeSymbol* classDelegateType = static_cast<ClassDelegateTypeSymbol*>(parameter->GetType());
 490             FunctionSymbol* copyConstructor = classDelegateType->CopyConstructor();
 491             if (!copyConstructor)
 492             {
 493                 throw std::runtime_error("internal error: class delegate type has no copy constructor");
 494             }
 495             std::vector<GenObject*> copyCtorArgs;
 496             NativeValue paramValue(parameter->IrObject(*emitter));
 497             copyCtorArgs.push_back(&paramValue);
 498             NativeValue argumentValue(arg);
 499             copyCtorArgs.push_back(&argumentValue);
 500             if (debugInfo)
 501             {
 502                 emitter->SetInPrologue(false);
 503                 emitter->SetCurrentDebugLocation(boundFunction.Body()->GetSpan());
 504                 copyConstructor->GenerateCall(*emittercopyCtorArgsOperationFlags::noneboundFunction.Body()->GetSpan()boundFunction.Body()->ModuleId());
 505                 emitter->SetInPrologue(true);
 506                 emitter->SetCurrentDebugLocation(Span());
 507             }
 508             else
 509             {
 510                 copyConstructor->GenerateCall(*emittercopyCtorArgsOperationFlags::noneboundFunction.Body()->GetSpan()boundFunction.Body()->ModuleId());
 511             }
 512         }
 513         else if (parameter->GetType()->GetSymbolType() == SymbolType::interfaceTypeSymbol)
 514         {
 515             InterfaceTypeSymbol* interfaceType = static_cast<InterfaceTypeSymbol*>(parameter->GetType());
 516             FunctionSymbol* copyConstructor = interfaceType->CopyConstructor();
 517             if (!copyConstructor)
 518             {
 519                 copyConstructor = compileUnit->GetCopyConstructorFor(interfaceType->TypeId());
 520             }
 521             std::vector<GenObject*> copyCtorArgs;
 522             NativeValue paramValue(parameter->IrObject(*emitter));
 523             paramValue.SetType(interfaceType->AddPointer(Span()boost::uuids::nil_uuid()));
 524             copyCtorArgs.push_back(&paramValue);
 525             NativeValue argumentValue(arg);
 526             argumentValue.SetType(interfaceType->AddPointer(Span()boost::uuids::nil_uuid()));
 527             copyCtorArgs.push_back(&argumentValue);
 528             if (debugInfo)
 529             {
 530                 emitter->SetInPrologue(false);
 531                 emitter->SetCurrentDebugLocation(boundFunction.Body()->GetSpan());
 532                 copyConstructor->GenerateCall(*emittercopyCtorArgsOperationFlags::noneboundFunction.Body()->GetSpan()boundFunction.Body()->ModuleId());
 533                 emitter->SetInPrologue(true);
 534                 emitter->SetCurrentDebugLocation(Span());
 535             }
 536             else
 537             {
 538                 copyConstructor->GenerateCall(*emittercopyCtorArgsOperationFlags::noneboundFunction.Body()->GetSpan()boundFunction.Body()->ModuleId());
 539             }
 540         }
 541         else
 542         {
 543             emitter->CreateStore(argparameter->IrObject(*emitter));
 544         }
 545     }
 546     if (functionSymbol->ReturnParam())
 547     {
 548         void* arg = emitter->GetFunctionArgument(functionnp);
 549         emitter->CreateStore(argfunctionSymbol->ReturnParam()->IrObject(*emitter));
 550     }
 551     for (BoundStatement* labeledStatement : boundFunction.LabeledStatements())
 552     {
 553         void* target = emitter->CreateBasicBlock(ToUtf8(labeledStatement->Label()));
 554         labeledStatementMap[labeledStatement] = target;
 555     }
 556     BoundCompoundStatement* body = boundFunction.Body();
 557     if (debugInfo)
 558     {
 559         emitter->SetInPrologue(false);
 560     }
 561     body->Accept(*this);
 562     BoundStatement* lastStatement = nullptr;
 563     if (!body->Statements().empty())
 564     {
 565         lastStatement = body->Statements().back().get();
 566     }
 567     if (!lastStatement || lastStatement->GetBoundNodeType() != BoundNodeType::boundReturnStatement || lastStatement->GetBoundNodeType() == BoundNodeType::boundReturnStatement && destructorCallGenerated)
 568     {
 569         GenerateExitFunctionCode(boundFunction);
 570         if (functionSymbol->ReturnType() && functionSymbol->ReturnType()->GetSymbolType() != SymbolType::voidTypeSymbol && !functionSymbol->ReturnsClassInterfaceOrClassDelegateByValue())
 571         {
 572             void* defaultValue = functionSymbol->ReturnType()->CreateDefaultIrValue(*emitter);
 573             emitter->CreateRet(defaultValue);
 574             lastInstructionWasRet = true;
 575         }
 576         else
 577         {
 578             emitter->CreateRetVoid();
 579             lastInstructionWasRet = true;
 580         }
 581     }
 582     if (functionSymbol->HasTry() || !cleanups.empty())
 583     {
 584         void* personalityFunction = GetPersonalityFunction();
 585         emitter->SetPersonalityFunction(functionpersonalityFunction);
 586     }
 587     if (functionSymbol->DontThrow() && !functionSymbol->HasTry() && cleanups.empty())
 588     {
 589         emitter->AddNoUnwindAttribute(function);
 590     }
 591     else
 592     {
 593         emitter->AddUWTableAttribute(function);
 594     }
 595     GenerateCodeForCleanups();
 596     if (debugInfo)
 597     {
 598         emitter->PopScope();
 599     }
 600     debugInfo = prevDebugInfo;
 601     emitter->SetCurrentDIBuilder(prevDIBuilder);
 602 }
 603 
 604 void LlvmCodeGenerator::Visit(BoundSequenceStatement& boundSequenceStatement)
 605 {
 606     destructorCallGenerated = false;
 607     lastInstructionWasRet = false;
 608     basicBlockOpen = false;
 609     SetTarget(&boundSequenceStatement);
 610     BoundStatement* prevSequence = sequenceSecond;
 611     sequenceSecond = boundSequenceStatement.Second();
 612     boundSequenceStatement.First()->Accept(*this);
 613     sequenceSecond = prevSequence;
 614     if (!boundSequenceStatement.Second()->Generated())
 615     {
 616         boundSequenceStatement.Second()->Accept(*this);
 617     }
 618 }
 619 
 620 void LlvmCodeGenerator::Visit(BoundCompoundStatement& boundCompoundStatement)
 621 {
 622     if (debugInfo)
 623     {
 624         emitter->SetCurrentDebugLocation(boundCompoundStatement.GetSpan());
 625     }
 626     if (debugInfo && compoundLevel > 0)
 627     {
 628         void* block = emitter->CreateLexicalBlock(boundCompoundStatement.GetSpan()boundCompoundStatement.ModuleId());
 629     }
 630     ++compoundLevel;
 631     destructorCallGenerated = false;
 632     lastInstructionWasRet = false;
 633     basicBlockOpen = false;
 634     SetTarget(&boundCompoundStatement);
 635     BoundCompoundStatement* prevBlock = currentBlock;
 636     currentBlock = &boundCompoundStatement;
 637     blockDestructionMap[currentBlock] = std::vector<std::std::unique_ptr<BoundFunctionCall>>();
 638     blocks.push_back(currentBlock);
 639     SetLineNumber(boundCompoundStatement.GetSpan().line);
 640     int n = boundCompoundStatement.Statements().size();
 641     for (int i = 0; i < n; ++i)
 642     {
 643         BoundStatement* boundStatement = boundCompoundStatement.Statements()[i].get();
 644         boundStatement->Accept(*this);
 645     }
 646     ExitBlocks(prevBlock);
 647     blocks.pop_back();
 648     currentBlock = prevBlock;
 649     --compoundLevel;
 650     if (debugInfo && compoundLevel > 0)
 651     {
 652         emitter->PopScope();
 653     }
 654 }
 655 
 656 void LlvmCodeGenerator::Visit(BoundIfStatement& boundIfStatement)
 657 {
 658     destructorCallGenerated = false;
 659     lastInstructionWasRet = false;
 660     basicBlockOpen = false;
 661     SetTarget(&boundIfStatement);
 662     void* prevTrueBlock = trueBlock;
 663     void* prevFalseBlock = falseBlock;
 664     trueBlock = emitter->CreateBasicBlock("true");
 665     void* nextBlock = emitter->CreateBasicBlock("next");
 666     if (boundIfStatement.ElseS())
 667     {
 668         falseBlock = emitter->CreateBasicBlock("false");
 669     }
 670     else
 671     {
 672         falseBlock = nextBlock;
 673     }
 674     bool prevGenJumpingBoolCode = genJumpingBoolCode;
 675     genJumpingBoolCode = true;
 676     boundIfStatement.Condition()->Accept(*this);
 677     genJumpingBoolCode = prevGenJumpingBoolCode;
 678     emitter->SetCurrentBasicBlock(trueBlock);
 679     boundIfStatement.ThenS()->Accept(*this);
 680     emitter->CreateBr(nextBlock);
 681     if (boundIfStatement.ElseS())
 682     {
 683         emitter->SetCurrentBasicBlock(falseBlock);
 684         boundIfStatement.ElseS()->Accept(*this);
 685         emitter->CreateBr(nextBlock);
 686     }
 687     trueBlock = prevTrueBlock;
 688     falseBlock = prevFalseBlock;
 689     emitter->SetCurrentBasicBlock(nextBlock);
 690     basicBlockOpen = true;
 691 }
 692 
 693 void LlvmCodeGenerator::Visit(BoundWhileStatement& boundWhileStatement)
 694 {
 695     destructorCallGenerated = false;
 696     lastInstructionWasRet = false;
 697     basicBlockOpen = false;
 698     SetTarget(&boundWhileStatement);
 699     void* prevTrueBlock = trueBlock;
 700     void* prevFalseBlock = falseBlock;
 701     void* prevBreakTarget = breakTarget;
 702     void* prevContinueTarget = continueTarget;
 703     BoundCompoundStatement* prevBreakTargetBlock = breakTargetBlock;
 704     BoundCompoundStatement* prevContinueTargetBlock = continueTargetBlock;
 705     breakTargetBlock = currentBlock;
 706     continueTargetBlock = currentBlock;
 707     trueBlock = emitter->CreateBasicBlock("true");
 708     falseBlock = emitter->CreateBasicBlock("next");
 709     breakTarget = falseBlock;
 710     void* condBlock = emitter->CreateBasicBlock("cond");
 711     emitter->CreateBr(condBlock);
 712     emitter->SetCurrentBasicBlock(condBlock);
 713     continueTarget = condBlock;
 714     bool prevGenJumpingBoolCode = genJumpingBoolCode;
 715     genJumpingBoolCode = true;
 716     boundWhileStatement.Condition()->Accept(*this);
 717     genJumpingBoolCode = prevGenJumpingBoolCode;
 718     emitter->SetCurrentBasicBlock(trueBlock);
 719     boundWhileStatement.Statement()->Accept(*this);
 720     emitter->CreateBr(condBlock);
 721     emitter->SetCurrentBasicBlock(falseBlock);
 722     breakTargetBlock = prevBreakTargetBlock;
 723     continueTargetBlock = prevContinueTargetBlock;
 724     breakTarget = prevBreakTarget;
 725     continueTarget = prevContinueTarget;
 726     trueBlock = prevTrueBlock;
 727     falseBlock = prevFalseBlock;
 728 }
 729 
 730 void LlvmCodeGenerator::Visit(BoundDoStatement& boundDoStatement)
 731 {
 732     destructorCallGenerated = false;
 733     lastInstructionWasRet = false;
 734     basicBlockOpen = false;
 735     SetTarget(&boundDoStatement);
 736     void* prevTrueBlock = trueBlock;
 737     void* prevFalseBlock = falseBlock;
 738     void* prevBreakTarget = breakTarget;
 739     void* prevContinueTarget = continueTarget;
 740     void* doBlock = emitter->CreateBasicBlock("do");
 741     void* condBlock = emitter->CreateBasicBlock("cond");
 742     BoundCompoundStatement* prevBreakTargetBlock = breakTargetBlock;
 743     BoundCompoundStatement* prevContinueTargetBlock = continueTargetBlock;
 744     breakTargetBlock = currentBlock;
 745     continueTargetBlock = currentBlock;
 746     trueBlock = doBlock;
 747     falseBlock = emitter->CreateBasicBlock("next");
 748     breakTarget = falseBlock;
 749     continueTarget = condBlock;
 750     emitter->CreateBr(doBlock);
 751     emitter->SetCurrentBasicBlock(doBlock);
 752     boundDoStatement.Statement()->Accept(*this);
 753     emitter->CreateBr(condBlock);
 754     emitter->SetCurrentBasicBlock(condBlock);
 755     bool prevGenJumpingBoolCode = genJumpingBoolCode;
 756     genJumpingBoolCode = true;
 757     boundDoStatement.Condition()->Accept(*this);
 758     genJumpingBoolCode = prevGenJumpingBoolCode;
 759     emitter->SetCurrentBasicBlock(falseBlock);
 760     basicBlockOpen = true;
 761     breakTargetBlock = prevBreakTargetBlock;
 762     continueTargetBlock = prevContinueTargetBlock;
 763     breakTarget = prevBreakTarget;
 764     continueTarget = prevContinueTarget;
 765     trueBlock = prevTrueBlock;
 766     falseBlock = prevFalseBlock;
 767 }
 768 
 769 void LlvmCodeGenerator::Visit(BoundForStatement& boundForStatement)
 770 {
 771     destructorCallGenerated = false;
 772     lastInstructionWasRet = false;
 773     basicBlockOpen = false;
 774     SetTarget(&boundForStatement);
 775     void* prevTrueBlock = trueBlock;
 776     void* prevFalseBlock = falseBlock;
 777     void* prevBreakTarget = breakTarget;
 778     void* prevContinueTarget = continueTarget;
 779     boundForStatement.InitS()->Accept(*this);
 780     void* condBlock = emitter->CreateBasicBlock("cond");
 781     void* actionBlock = emitter->CreateBasicBlock("action");
 782     void* loopBlock = emitter->CreateBasicBlock("loop");
 783     trueBlock = actionBlock;
 784     falseBlock = emitter->CreateBasicBlock("next");
 785     breakTarget = falseBlock;
 786     continueTarget = loopBlock;
 787     BoundCompoundStatement* prevBreakTargetBlock = breakTargetBlock;
 788     BoundCompoundStatement* prevContinueTargetBlock = continueTargetBlock;
 789     breakTargetBlock = currentBlock;
 790     continueTargetBlock = currentBlock;
 791     emitter->CreateBr(condBlock);
 792     emitter->SetCurrentBasicBlock(condBlock);
 793     bool prevGenJumpingBoolCode = genJumpingBoolCode;
 794     genJumpingBoolCode = true;
 795     boundForStatement.Condition()->Accept(*this);
 796     genJumpingBoolCode = prevGenJumpingBoolCode;
 797     emitter->SetCurrentBasicBlock(actionBlock);
 798     boundForStatement.ActionS()->Accept(*this);
 799     emitter->CreateBr(loopBlock);
 800     emitter->SetCurrentBasicBlock(loopBlock);
 801     boundForStatement.LoopS()->Accept(*this);
 802     emitter->CreateBr(condBlock);
 803     emitter->SetCurrentBasicBlock(falseBlock);
 804     basicBlockOpen = true;
 805     breakTargetBlock = prevBreakTargetBlock;
 806     continueTargetBlock = prevContinueTargetBlock;
 807     breakTarget = prevBreakTarget;
 808     continueTarget = prevContinueTarget;
 809     trueBlock = prevTrueBlock;
 810     falseBlock = prevFalseBlock;
 811 }
 812 
 813 void LlvmCodeGenerator::Visit(BoundSwitchStatement& boundSwitchStatement)
 814 {
 815     destructorCallGenerated = false;
 816     lastInstructionWasRet = false;
 817     basicBlockOpen = false;
 818     SetTarget(&boundSwitchStatement);
 819     void* prevBreakTarget = breakTarget;
 820     BoundCompoundStatement* prevBreakTargetBlock = breakTargetBlock;
 821     breakTargetBlock = currentBlock;
 822     boundSwitchStatement.Condition()->Accept(*this);
 823     void* condition = emitter->Stack().Pop();
 824     void* prevDefaultDest = defaultDest;
 825     void* next = nullptr;
 826     if (boundSwitchStatement.DefaultStatement())
 827     {
 828         defaultDest = emitter->CreateBasicBlock("default");
 829         next = emitter->CreateBasicBlock("next");
 830     }
 831     else
 832     {
 833         defaultDest = emitter->CreateBasicBlock("next");
 834         next = defaultDest;
 835     }
 836     breakTarget = next;
 837     unsigned n = boundSwitchStatement.CaseStatements().size();
 838     void* switchInst = emitter->CreateSwitch(conditiondefaultDestn);
 839     std::std::unordered_map<IntegralValuevoid*IntegralValueHash>*prevCaseMap=currentCaseMap;
 840     std::unordered_map<IntegralValuevoid*IntegralValueHash> caseMap;
 841     currentCaseMap = &caseMap;
 842     for (unsigned i = 0; i < n; ++i)
 843     {
 844         const std::std::unique_ptr<BoundCaseStatement>&caseS=boundSwitchStatement.CaseStatements()[i];
 845         void* caseDest = emitter->CreateBasicBlock("case" + std::to_string(i));
 846         for (const std::std::unique_ptr<Value>&caseValue : caseS->CaseValues())
 847         {
 848             IntegralValue integralCaseValue(caseValue.get());
 849             caseMap[integralCaseValue] = caseDest;
 850             emitter->AddCase(switchInstcaseValue->IrValue(*emitter)caseDest);
 851         }
 852     }
 853     for (unsigned i = 0; i < n; ++i)
 854     {
 855         const std::std::unique_ptr<BoundCaseStatement>&caseS=boundSwitchStatement.CaseStatements()[i];
 856         caseS->Accept(*this);
 857         if (basicBlockOpen)
 858         {
 859             emitter->CreateBr(next);
 860             basicBlockOpen = false;
 861         }
 862     }
 863     if (boundSwitchStatement.DefaultStatement())
 864     {
 865         boundSwitchStatement.DefaultStatement()->Accept(*this);
 866         if (basicBlockOpen)
 867         {
 868             emitter->CreateBr(next);
 869             basicBlockOpen = false;
 870         }
 871     }
 872     emitter->SetCurrentBasicBlock(next);
 873     basicBlockOpen = true;
 874     currentCaseMap = prevCaseMap;
 875     defaultDest = prevDefaultDest;
 876     breakTargetBlock = prevBreakTargetBlock;
 877     breakTarget = prevBreakTarget;
 878 }
 879 
 880 void LlvmCodeGenerator::Visit(BoundCaseStatement& boundCaseStatement)
 881 {
 882     destructorCallGenerated = false;
 883     lastInstructionWasRet = false;
 884     basicBlockOpen = false;
 885     SetTarget(&boundCaseStatement);
 886     if (!boundCaseStatement.CaseValues().empty())
 887     {
 888         IntegralValue integralCaseValue(boundCaseStatement.CaseValues().front().get());
 889         auto it = currentCaseMap->find(integralCaseValue);
 890         if (it != currentCaseMap->cend())
 891         {
 892             void* caseDest = it->second;
 893             emitter->SetCurrentBasicBlock(caseDest);
 894             if (boundCaseStatement.CompoundStatement())
 895             {
 896                 boundCaseStatement.CompoundStatement()->Accept(*this);
 897             }
 898         }
 899         else
 900         {
 901             throw Exception("case not found"boundCaseStatement.GetSpan()boundCaseStatement.ModuleId());
 902         }
 903     }
 904     else
 905     {
 906         throw Exception("no cases"boundCaseStatement.GetSpan()boundCaseStatement.ModuleId());
 907     }
 908 }
 909 
 910 void LlvmCodeGenerator::Visit(BoundDefaultStatement& boundDefaultStatement)
 911 {
 912     destructorCallGenerated = false;
 913     lastInstructionWasRet = false;
 914     basicBlockOpen = false;
 915     SetTarget(&boundDefaultStatement);
 916     if (defaultDest)
 917     {
 918         emitter->SetCurrentBasicBlock(defaultDest);
 919         if (boundDefaultStatement.CompoundStatement())
 920         {
 921             boundDefaultStatement.CompoundStatement()->Accept(*this);
 922         }
 923     }
 924     else
 925     {
 926         throw Exception("no default destination"boundDefaultStatement.GetSpan()boundDefaultStatement.ModuleId());
 927     }
 928 }
 929 
 930 void LlvmCodeGenerator::Visit(BoundConstructionStatement& boundConstructionStatement)
 931 {
 932     destructorCallGenerated = false;
 933     lastInstructionWasRet = false;
 934     basicBlockOpen = false;
 935     SetTarget(&boundConstructionStatement);
 936     boundConstructionStatement.ConstructorCall()->Accept(*this);
 937     if (!boundConstructionStatement.ConstructorCall()->GetFunctionSymbol()->IsBasicTypeOperation())
 938     {
 939         int n = boundConstructionStatement.ConstructorCall()->Arguments().size();
 940         if (n > 0)
 941         {
 942             const std::std::unique_ptr<BoundExpression>&firstArgument=boundConstructionStatement.ConstructorCall()->Arguments()[0];
 943             TypeSymbol* firstArgumentBaseType = firstArgument->GetType()->BaseType();
 944             if (firstArgumentBaseType->IsClassTypeSymbol())
 945             {
 946                 if (firstArgument->GetType()->IsPointerType() && firstArgument->GetType()->RemovePointer(
 947                     boundConstructionStatement.GetSpan()boundConstructionStatement.ModuleId())->IsClassTypeSymbol())
 948                 {
 949                     ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(firstArgumentBaseType);
 950                     if (classType->Destructor())
 951                     {
 952                         newCleanupNeeded = true;
 953                         std::unique_ptr<BoundExpression> classPtrArgument(firstArgument->Clone());
 954                         std::unique_ptr<BoundFunctionCall> destructorCall(new BoundFunctionCall(currentBlock->EndSpan()currentBlock->ModuleId()classType->Destructor()));
 955                         destructorCall->AddArgument(std::move(classPtrArgument));
 956                         Assert(currentBlock"current block not set");
 957                         auto it = blockDestructionMap.find(currentBlock);
 958                         if (it != blockDestructionMap.cend())
 959                         {
 960                             std::std::vector<std::std::unique_ptr<BoundFunctionCall>>&destructorCallVec=it->second;
 961                             destructorCallVec.push_back(std::move(destructorCall));
 962                         }
 963                         else
 964                         {
 965                             Assert(false"block destruction not found");
 966                         }
 967                     }
 968                 }
 969             }
 970         }
 971     }
 972 }
 973 
 974 void LlvmCodeGenerator::Visit(BoundAssignmentStatement& boundAssignmentStatement)
 975 {
 976     destructorCallGenerated = false;
 977     lastInstructionWasRet = false;
 978     basicBlockOpen = false;
 979     SetTarget(&boundAssignmentStatement);
 980     boundAssignmentStatement.AssignmentCall()->Accept(*this);
 981 }
 982 
 983 void LlvmCodeGenerator::Visit(BoundExpressionStatement& boundExpressionStatement)
 984 {
 985     destructorCallGenerated = false;
 986     lastInstructionWasRet = false;
 987     basicBlockOpen = false;
 988     SetTarget(&boundExpressionStatement);
 989     boundExpressionStatement.Expression()->Accept(*this);
 990     if (boundExpressionStatement.Expression()->HasValue())
 991     {
 992         emitter->Stack().Pop();
 993     }
 994 }
 995 
 996 void LlvmCodeGenerator::Visit(BoundInitializationStatement& boundInitializationStatement)
 997 {
 998     destructorCallGenerated = false;
 999     lastInstructionWasRet = false;
1000     basicBlockOpen = false;
1001     SetTarget(&boundInitializationStatement);
1002     boundInitializationStatement.InitializationExpression()->Accept(*this);
1003     if (boundInitializationStatement.InitializationExpression()->HasValue())
1004     {
1005         emitter->Stack().Pop();
1006     }
1007 }
1008 
1009 void LlvmCodeGenerator::Visit(BoundEmptyStatement& boundEmptyStatement)
1010 {
1011     destructorCallGenerated = false;
1012     lastInstructionWasRet = false;
1013     basicBlockOpen = false;
1014     SetTarget(&boundEmptyStatement);
1015     void* retType = emitter->GetIrTypeForVoid();
1016     std::vector<void*> paramTypes;
1017     void* doNothingFunType = emitter->GetIrTypeForFunction(retTypeparamTypes);
1018     void* doNothingFun = emitter->GetOrInsertFunction("llvm.donothing"doNothingFunTypetrue);
1019     std::vector<void*> args;
1020     std::vector<void*> bundles;
1021     if (currentPad != nullptr)
1022     {
1023         bundles.push_back(currentPad->value);
1024     }
1025     if (currentPad == nullptr)
1026     {
1027         emitter->CreateCall(doNothingFunargs);
1028     }
1029     else
1030     {
1031         void* callInst = emitter->CreateCallInst(doNothingFunargsbundlesboundEmptyStatement.GetSpan());
1032     }
1033 }
1034 
1035 void LlvmCodeGenerator::Visit(BoundSetVmtPtrStatement& boundSetVmtPtrStatement)
1036 {
1037     destructorCallGenerated = false;
1038     lastInstructionWasRet = false;
1039     basicBlockOpen = false;
1040     SetTarget(&boundSetVmtPtrStatement);
1041     BoundExpression* classPtr = boundSetVmtPtrStatement.ClassPtr();
1042     TypeSymbol* type = classPtr->GetType()->BaseType();
1043     Assert(type->IsClassTypeSymbol()"class type expected");
1044     ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type);
1045     int32_t vmtPtrIndex = classType->VmtPtrIndex();
1046     Assert(vmtPtrIndex != -1"invalid vmt ptr index");
1047     classPtr->Accept(*this);
1048     void* classPtrValue = emitter->Stack().Pop();
1049     void* ptr = emitter->GetMemberVariablePtr(classPtrValuevmtPtrIndex);
1050     void* vmtPtr = emitter->CreateBitCast(boundSetVmtPtrStatement.ClassType()->VmtObject(*emitterfalse)emitter->GetIrTypeForVoidPtrType());
1051     emitter->CreateStore(vmtPtrptr);
1052 }
1053 
1054 void LlvmCodeGenerator::Visit(BoundThrowStatement& boundThrowStatement)
1055 {
1056     destructorCallGenerated = false;
1057     lastInstructionWasRet = false;
1058     basicBlockOpen = false;
1059     SetTarget(&boundThrowStatement);
1060     boundThrowStatement.ThrowCallExpr()->Accept(*this);
1061 }
1062 
1063 void LlvmCodeGenerator::Visit(BoundParameter& boundParameter)
1064 {
1065     boundParameter.Load(*emitterOperationFlags::none);
1066     GenJumpingBoolCode();
1067 }
1068 
1069 void LlvmCodeGenerator::Visit(BoundLocalVariable& boundLocalVariable)
1070 {
1071     boundLocalVariable.Load(*emitterOperationFlags::none);
1072     GenJumpingBoolCode();
1073 }
1074 
1075 void LlvmCodeGenerator::Visit(BoundMemberVariable& boundMemberVariable)
1076 {
1077     boundMemberVariable.Load(*emitterOperationFlags::none);
1078     GenJumpingBoolCode();
1079 }
1080 
1081 void LlvmCodeGenerator::Visit(BoundConstant& boundConstant)
1082 {
1083     boundConstant.Load(*emitterOperationFlags::none);
1084     GenJumpingBoolCode();
1085 }
1086 
1087 void LlvmCodeGenerator::Visit(BoundEnumConstant& boundEnumConstant)
1088 {
1089     boundEnumConstant.Load(*emitterOperationFlags::none);
1090     GenJumpingBoolCode();
1091 }
1092 
1093 void LlvmCodeGenerator::Visit(BoundLiteral& boundLiteral)
1094 {
1095     boundLiteral.Load(*emitterOperationFlags::none);
1096     GenJumpingBoolCode();
1097 }
1098 
1099 void LlvmCodeGenerator::Visit(BoundTemporary& boundTemporary)
1100 {
1101     boundTemporary.Load(*emitterOperationFlags::none);
1102     GenJumpingBoolCode();
1103 }
1104 
1105 void LlvmCodeGenerator::Visit(BoundSizeOfExpression& boundSizeOfExpression)
1106 {
1107     boundSizeOfExpression.Load(*emitterOperationFlags::none);
1108 }
1109 
1110 void LlvmCodeGenerator::Visit(BoundAddressOfExpression& boundAddressOfExpression)
1111 {
1112     boundAddressOfExpression.Load(*emitterOperationFlags::none);
1113 }
1114 
1115 void LlvmCodeGenerator::Visit(BoundDereferenceExpression& boundDereferenceExpression)
1116 {
1117     boundDereferenceExpression.Load(*emitterOperationFlags::none);
1118     GenJumpingBoolCode();
1119 }
1120 
1121 void LlvmCodeGenerator::Visit(BoundReferenceToPointerExpression& boundReferenceToPointerExpression)
1122 {
1123     boundReferenceToPointerExpression.Load(*emitterOperationFlags::none);
1124 }
1125 
1126 void LlvmCodeGenerator::Visit(BoundFunctionCall& boundFunctionCall)
1127 {
1128     boundFunctionCall.Load(*emitterOperationFlags::none);
1129     GenJumpingBoolCode();
1130 }
1131 
1132 void LlvmCodeGenerator::Visit(BoundDelegateCall& boundDelegateCall)
1133 {
1134     boundDelegateCall.Load(*emitterOperationFlags::none);
1135     GenJumpingBoolCode();
1136 }
1137 
1138 void LlvmCodeGenerator::Visit(BoundClassDelegateCall& boundClassDelegateCall)
1139 {
1140     boundClassDelegateCall.Load(*emitterOperationFlags::none);
1141     GenJumpingBoolCode();
1142 }
1143 
1144 void LlvmCodeGenerator::Visit(BoundConversion& boundConversion)
1145 {
1146     boundConversion.Load(*emitterOperationFlags::none);
1147     GenJumpingBoolCode();
1148 }
1149 
1150 void LlvmCodeGenerator::Visit(BoundConstructExpression& boundConstructExpression)
1151 {
1152     boundConstructExpression.Load(*emitterOperationFlags::none);
1153     GenJumpingBoolCode();
1154 }
1155 
1156 void LlvmCodeGenerator::Visit(BoundConstructAndReturnTemporaryExpression& boundConstructAndReturnTemporaryExpression)
1157 {
1158     boundConstructAndReturnTemporaryExpression.Load(*emitterOperationFlags::none);
1159     GenJumpingBoolCode();
1160 }
1161 
1162 void LlvmCodeGenerator::Visit(BoundClassOrClassDelegateConversionResult& boundClassOrClassDelegateConversionResult)
1163 {
1164     boundClassOrClassDelegateConversionResult.Load(*emitterOperationFlags::none);
1165     GenJumpingBoolCode();
1166 }
1167 
1168 void LlvmCodeGenerator::Visit(BoundIsExpression& boundIsExpression)
1169 {
1170     boundIsExpression.Load(*emitterOperationFlags::none);
1171     GenJumpingBoolCode();
1172 }
1173 
1174 void LlvmCodeGenerator::Visit(BoundAsExpression& boundAsExpression)
1175 {
1176     boundAsExpression.Load(*emitterOperationFlags::none);
1177 }
1178 
1179 void LlvmCodeGenerator::Visit(BoundTypeNameExpression& boundTypeNameExpression)
1180 {
1181     boundTypeNameExpression.Load(*emitterOperationFlags::none);
1182 }
1183 
1184 void LlvmCodeGenerator::Visit(BoundBitCast& boundBitCast)
1185 {
1186     boundBitCast.Load(*emitterOperationFlags::none);
1187 }
1188 
1189 void LlvmCodeGenerator::Visit(BoundFunctionPtr& boundFunctionPtr)
1190 {
1191     boundFunctionPtr.Load(*emitterOperationFlags::none);
1192 }
1193 
1194 void LlvmCodeGenerator::Visit(BoundDisjunction& boundDisjunction)
1195 {
1196     if (genJumpingBoolCode)
1197     {
1198         Assert(trueBlock"true block not set");
1199         Assert(falseBlock"false block not set");
1200         void* rightBlock = emitter->CreateBasicBlock("right");
1201         void* prevFalseBlock = falseBlock;
1202         falseBlock = rightBlock;
1203         boundDisjunction.Left()->Accept(*this);
1204         emitter->SetCurrentBasicBlock(rightBlock);
1205         falseBlock = prevFalseBlock;
1206         boundDisjunction.Right()->Accept(*this);
1207         boundDisjunction.DestroyTemporaries(*emitter);
1208     }
1209 }
1210 
1211 void LlvmCodeGenerator::Visit(BoundConjunction& boundConjunction)
1212 {
1213     if (genJumpingBoolCode)
1214     {
1215         Assert(trueBlock"true block not set");
1216         Assert(falseBlock"false block not set");
1217         void* rightBlock = emitter->CreateBasicBlock("right");
1218         void* prevTrueBlock = trueBlock;
1219         trueBlock = rightBlock;
1220         boundConjunction.Left()->Accept(*this);
1221         trueBlock = prevTrueBlock;
1222         emitter->SetCurrentBasicBlock(rightBlock);
1223         boundConjunction.Right()->Accept(*this);
1224         boundConjunction.DestroyTemporaries(*emitter);
1225     }
1226 }
1227 
1228 void LlvmCodeGenerator::Visit(BoundGlobalVariable& boundGlobalVariable)
1229 {
1230     GlobalVariableSymbol* globalVariableSymbol = boundGlobalVariable.GetGlobalVariableSymbol();
1231     globalVariableSymbol->CreateIrObject(*emitter);
1232 }
1233 
1234 void* LlvmCodeGenerator::GetGlobalStringPtr(int stringId)
1235 {
1236     auto it = utf8stringMap.find(stringId);
1237     if (it != utf8stringMap.cend())
1238     {
1239         return it->second;
1240     }
1241     else
1242     {
1243         void* stringValue = emitter->CreateGlobalStringPtr(compileUnit->GetUtf8String(stringId));
1244         utf8stringMap[stringId] = stringValue;
1245         return stringValue;
1246     }
1247 }
1248 
1249 void* LlvmCodeGenerator::GetGlobalWStringConstant(int stringId)
1250 {
1251     auto it = utf16stringMap.find(stringId);
1252     if (it != utf16stringMap.cend())
1253     {
1254         return it->second;
1255     }
1256     else
1257     {
1258         const std::u16string& str = compileUnit->GetUtf16String(stringId);
1259         uint64_t length = str.length();
1260         std::vector<void*> wcharConstants;
1261         for (char16_t c : str)
1262         {
1263             wcharConstants.push_back(emitter->CreateIrValueForUShort(static_cast<uint16_t>(c)));
1264         }
1265         wcharConstants.push_back(emitter->CreateIrValueForUShort(static_cast<uint16_t>(0)));
1266         void* arrayType = emitter->GetIrTypeForArrayType(emitter->GetIrTypeForUShort()length + 1);
1267         void* stringObject = emitter->GetOrInsertGlobal("wstring" + std::to_string(stringId)arrayType);
1268         void* stringGlobal = stringObject;
1269         emitter->SetPrivateLinkage(stringGlobal);
1270         void* constant = emitter->CreateIrValueForConstantArray(arrayTypewcharConstantsstd::string());
1271         emitter->SetInitializer(stringGlobalconstant);
1272         void* stringValue = stringGlobal;
1273         utf16stringMap[stringId] = stringValue;
1274         return stringValue;
1275     }
1276 }
1277 
1278 void* LlvmCodeGenerator::GetGlobalUStringConstant(int stringId)
1279 {
1280     auto it = utf32stringMap.find(stringId);
1281     if (it != utf32stringMap.cend())
1282     {
1283         return it->second;
1284     }
1285     else
1286     {
1287         const std::u32string& str = compileUnit->GetUtf32String(stringId);
1288         uint64_t length = str.length();
1289         std::vector<void*> ucharConstants;
1290         for (char32_t c : str)
1291         {
1292             ucharConstants.push_back(emitter->CreateIrValueForUInt(static_cast<uint32_t>(c)));
1293         }
1294         ucharConstants.push_back(emitter->CreateIrValueForUInt(static_cast<uint32_t>(0)));
1295         void* arrayType = emitter->GetIrTypeForArrayType(emitter->GetIrTypeForUInt()length + 1);
1296         void* stringObject = emitter->GetOrInsertGlobal("ustring" + std::to_string(stringId)arrayType);
1297         void* stringGlobal = stringObject;
1298         emitter->SetPrivateLinkage(stringGlobal);
1299         void* constant = emitter->CreateIrValueForConstantArray(arrayTypeucharConstantsstd::string());
1300         emitter->SetInitializer(stringGlobalconstant);
1301         void* stringValue = stringGlobal;
1302         utf32stringMap[stringId] = stringValue;
1303         return stringValue;
1304     }
1305 }
1306 
1307 void* LlvmCodeGenerator::GetGlobalUuidConstant(int uuidId)
1308 {
1309     auto it = uuidMap.find(uuidId);
1310     if (it != uuidMap.cend())
1311     {
1312         return it->second;
1313     }
1314     else
1315     {
1316         const boost::uuids::uuid& uuid = compileUnit->GetUuid(uuidId);
1317         uint64_t length = uuid.static_size();
1318         std::vector<void*> byteConstants;
1319         for (boost::uuids::uuid::value_type x : uuid)
1320         {
1321             byteConstants.push_back(emitter->CreateIrValueForByte(static_cast<int8_t>(x)));
1322         }
1323         void* arrayType = emitter->GetIrTypeForArrayType(emitter->GetIrTypeForByte()length);
1324         void* uuidObject = emitter->GetOrInsertGlobal("uuid" + std::to_string(uuidId)arrayType);
1325         void* uuidGlobal = uuidObject;
1326         emitter->SetPrivateLinkage(uuidGlobal);
1327         void* constant = emitter->CreateIrValueForConstantArray(arrayTypebyteConstantsstd::string());
1328         emitter->SetInitializer(uuidGlobalconstant);
1329         void* uuidValue = uuidGlobal;
1330         uuidMap[uuidId] = uuidValue;
1331         return uuidValue;
1332     }
1333 }
1334 
1335 void LlvmCodeGenerator::SetLineNumber(int32_t lineNumber)
1336 {
1337     if (currentFunction->GetFunctionSymbol()->DontThrow()) return;
1338     if (prevLineNumber == lineNumber) return;
1339     prevLineNumber = lineNumber;
1340     BoundStatement* setLineNumberStatement = currentFunction->GetLineCode();
1341     if (setLineNumberStatement)
1342     {
1343         bool prevGenJumpingBoolCode = genJumpingBoolCode;
1344         genJumpingBoolCode = false;
1345         emitter->BeginSubstituteLineNumber(lineNumber);
1346         setLineNumberStatement->Accept(*this);
1347         emitter->EndSubstituteLineNumber();
1348         genJumpingBoolCode = prevGenJumpingBoolCode;
1349     }
1350 }
1351 
1352 void LlvmCodeGenerator::GenerateEnterFunctionCode(BoundFunction& boundFunction)
1353 {
1354     const std::std::vector<std::std::unique_ptr<BoundStatement>>&enterCode=boundFunction.EnterCode();
1355     if (enterCode.empty()) return;
1356     compileUnitFunctions.insert(boundFunction.GetFunctionSymbol());
1357     LocalVariableSymbol* prevUnwindInfoVar = boundFunction.GetFunctionSymbol()->PrevUnwindInfoVar();
1358     void* prevUnwindInfoAlloca = emitter->CreateAlloca(prevUnwindInfoVar->GetType()->IrType(*emitter));
1359     emitter->SetIrObject(prevUnwindInfoVarprevUnwindInfoAlloca);
1360     LocalVariableSymbol* unwindInfoVar = boundFunction.GetFunctionSymbol()->UnwindInfoVar();
1361     void* unwindInfoAlloca = emitter->CreateAlloca(unwindInfoVar->GetType()->IrType(*emitter));
1362     emitter->SetIrObject(unwindInfoVarunwindInfoAlloca);
1363     lastAlloca = unwindInfoAlloca;
1364     for (const auto& statement : enterCode)
1365     {
1366         statement->Accept(*this);
1367     }
1368 }
1369 
1370 void LlvmCodeGenerator::GenerateExitFunctionCode(BoundFunction& boundFunction)
1371 {
1372     const std::std::vector<std::std::unique_ptr<BoundStatement>>&exitCode=boundFunction.ExitCode();
1373     if (exitCode.empty()) return;
1374     for (const auto& statement : exitCode)
1375     {
1376         statement->Accept(*this);
1377     }
1378 }
1379 
1380 void LlvmCodeGenerator::GenerateInitUnwindInfoFunction(BoundCompileUnit& boundCompileUnit)
1381 {
1382     void* prevDIBuilder = emitter->DIBuilder();
1383     emitter->SetCurrentDIBuilder(nullptr);
1384     bool prevDebugInfo = debugInfo;
1385     debugInfo = false;
1386     emitter->SetCurrentSourceSpan(000);
1387     handlerBlock = nullptr;
1388     cleanupBlock = nullptr;
1389     newCleanupNeeded = false;
1390     currentPad = nullptr;
1391     prevLineNumber = 0;
1392     destructorCallGenerated = false;
1393     lastInstructionWasRet = false;
1394     basicBlockOpen = false;
1395     lastAlloca = nullptr;
1396     compoundLevel = 0;
1397     cleanups.clear();
1398     pads.clear();
1399     labeledStatementMap.clear();
1400     FunctionSymbol* initUnwindInfoFunctionSymbol = boundCompileUnit.GetInitUnwindInfoFunctionSymbol();
1401     if (!initUnwindInfoFunctionSymbol)
1402     {
1403         emitter->SetCurrentDIBuilder(prevDIBuilder);
1404         debugInfo = prevDebugInfo;
1405         return;
1406     }
1407     if (compileUnitFunctions.empty())
1408     {
1409         emitter->SetCurrentDIBuilder(prevDIBuilder);
1410         debugInfo = prevDebugInfo;
1411         return;
1412     }
1413     FunctionSymbol* addCompileUnitFunctionSymbol = boundCompileUnit.GetSystemRuntimeAddCompileUnitFunctionSymbol();
1414     if (!addCompileUnitFunctionSymbol)
1415     {
1416         emitter->SetCurrentDIBuilder(prevDIBuilder);
1417         debugInfo = prevDebugInfo;
1418         return;
1419     }
1420     void* functionType = initUnwindInfoFunctionSymbol->IrType(*emitter);
1421     void* function = emitter->GetOrInsertFunction(ToUtf8(initUnwindInfoFunctionSymbol->MangledName())functionTypetrue);
1422     emitter->SetFunction(function-1boost::uuids::nil_uuid()boost::uuids::nil_uuid());
1423     emitter->SetFunctionName(ToUtf8(initUnwindInfoFunctionSymbol->FullName()));
1424     void* entryBlock = emitter->CreateBasicBlock("entry");
1425     emitter->SetCurrentBasicBlock(entryBlock);
1426     for (FunctionSymbol* compileUnitFunction : compileUnitFunctions)
1427     {
1428         std::unique_ptr<BoundFunctionCall> boundFunctionCall(new BoundFunctionCall(compileUnitFunction->GetSpan()compileUnitFunction->SourceModuleId()addCompileUnitFunctionSymbol));
1429         BoundBitCast* functionPtrAsVoidPtr = new BoundBitCast(std::unique_ptr<BoundExpression>(
1430             new BoundFunctionPtr(compileUnitFunction->GetSpan()compileUnitFunction->SourceModuleId()
1431                 compileUnitFunctionsymbolTable->GetTypeByName(U"void")->AddPointer(compileUnitFunction->GetSpan()compileUnitFunction->SourceModuleId())))
1432             symbolTable->GetTypeByName(U"void")->AddPointer(compileUnitFunction->GetSpan()compileUnitFunction->SourceModuleId()));
1433         boundFunctionCall->AddArgument(std::unique_ptr<BoundExpression>(functionPtrAsVoidPtr));
1434         std::string functionName = ToUtf8(compileUnitFunction->FullName());
1435         int functionNameStringId = Install(functionName);
1436         BoundLiteral* boundFunctionNameLiteral = new BoundLiteral(std::unique_ptr<Value>(new StringValue(compileUnitFunction->GetSpan()compileUnitFunction->SourceModuleId()
1437             functionNameStringIdfunctionName))
1438             symbolTable->GetTypeByName(U"char")->AddConst(compileUnitFunction->GetSpan()compileUnitFunction->SourceModuleId())->AddPointer(
1439                 compileUnitFunction->GetSpan()compileUnitFunction->SourceModuleId()));
1440         boundFunctionCall->AddArgument(std::unique_ptr<BoundExpression>(boundFunctionNameLiteral));
1441         std::string sourceFilePath = GetSourceFilePath(compileUnitFunction->GetSpan()compileUnitFunction->SourceModuleId());
1442         int sourceFilePathStringId = Install(sourceFilePath);
1443         BoundLiteral* boundSourceFilePathLiteral = new BoundLiteral(std::unique_ptr<Value>(new StringValue(
1444             compileUnitFunction->GetSpan()compileUnitFunction->SourceModuleId()sourceFilePathStringIdsourceFilePath))
1445             symbolTable->GetTypeByName(U"char")->AddConst(compileUnitFunction->GetSpan()compileUnitFunction->SourceModuleId())->AddPointer(
1446                 compileUnitFunction->GetSpan()compileUnitFunction->SourceModuleId()));
1447         boundFunctionCall->AddArgument(std::unique_ptr<BoundExpression>(boundSourceFilePathLiteral));
1448         boundFunctionCall->Accept(*this);
1449     }
1450     emitter->CreateRetVoid();
1451     debugInfo = prevDebugInfo;
1452     emitter->SetCurrentDIBuilder(prevDIBuilder);
1453 }
1454 
1455 void LlvmCodeGenerator::GenerateInitCompileUnitFunction(BoundCompileUnit& boundCompileUnit)
1456 {
1457     void* prevDIBuilder = emitter->DIBuilder();
1458     emitter->SetCurrentDIBuilder(nullptr);
1459     bool prevDebugInfo = debugInfo;
1460     debugInfo = false;
1461     emitter->ResetCurrentDebugLocation();
1462     emitter->SetCurrentSourceSpan(000);
1463     handlerBlock = nullptr;
1464     cleanupBlock = nullptr;
1465     newCleanupNeeded = false;
1466     currentPad = nullptr;
1467     prevLineNumber = 0;
1468     destructorCallGenerated = false;
1469     lastInstructionWasRet = false;
1470     basicBlockOpen = false;
1471     lastAlloca = nullptr;
1472     compoundLevel = 0;
1473     cleanups.clear();
1474     pads.clear();
1475     labeledStatementMap.clear();
1476     FunctionSymbol* initCompileUnitFunctionSymbol = boundCompileUnit.GetInitCompileUnitFunctionSymbol();
1477     if (!initCompileUnitFunctionSymbol)
1478     {
1479         emitter->SetCurrentDIBuilder(prevDIBuilder);
1480         debugInfo = prevDebugInfo;
1481         return;
1482     }
1483     Span span = initCompileUnitFunctionSymbol->GetSpan();
1484     boost::uuids::uuid moduleId = initCompileUnitFunctionSymbol->SourceModuleId();
1485     void* functionType = initCompileUnitFunctionSymbol->IrType(*emitter);
1486     void* function = emitter->GetOrInsertFunction(ToUtf8(initCompileUnitFunctionSymbol->MangledName())functionTypetrue);
1487     emitter->SetFunction(function-1boost::uuids::nil_uuid()boost::uuids::nil_uuid());
1488     emitter->SetFunctionName(ToUtf8(initCompileUnitFunctionSymbol->FullName()));
1489     void* entryBlock = emitter->CreateBasicBlock("entry");
1490     emitter->SetCurrentBasicBlock(entryBlock);
1491     FunctionSymbol* initUnwindInfoFunctionSymbol = boundCompileUnit.GetInitUnwindInfoFunctionSymbol();
1492     if (!initUnwindInfoFunctionSymbol)
1493     {
1494         emitter->SetCurrentDIBuilder(prevDIBuilder);
1495         debugInfo = prevDebugInfo;
1496         emitter->CreateRetVoid();
1497         return;
1498     }
1499     FunctionSymbol* pushCompileUnitUnwindInfoInitFunctionSymbol = boundCompileUnit.GetPushCompileUnitUnwindInfoInitFunctionSymbol();
1500     TypeSymbol* initUnwindInfoDelegateType = boundCompileUnit.GetInitUnwindInfoDelegateType();
1501     GlobalVariableSymbol* compileUnitUnwindInfoVarSymbol = boundCompileUnit.GetCompileUnitUnwindInfoVarSymbol();
1502     BoundGlobalVariable* boundCompileUnitUnwindInfoVar = new BoundGlobalVariable(spanmoduleIdcompileUnitUnwindInfoVarSymbol);
1503     BoundAddressOfExpression* unwindInfoVarAddress = new BoundAddressOfExpression(std::unique_ptr<BoundExpression>(boundCompileUnitUnwindInfoVar)
1504         boundCompileUnitUnwindInfoVar->GetType()->AddPointer(spanmoduleId));
1505     BoundFunctionPtr* boundInitUnwindInfoFunction = new BoundFunctionPtr(spanmoduleIdinitUnwindInfoFunctionSymbolinitUnwindInfoDelegateType);
1506     std::unique_ptr<BoundFunctionCall> boundFunctionCall(new BoundFunctionCall(spanmoduleIdpushCompileUnitUnwindInfoInitFunctionSymbol));
1507     boundFunctionCall->AddArgument(std::unique_ptr<BoundExpression>(boundInitUnwindInfoFunction));
1508     boundFunctionCall->AddArgument(std::unique_ptr<BoundExpression>(unwindInfoVarAddress));
1509     boundFunctionCall->Accept(*this);
1510     emitter->CreateRetVoid();
1511     emitter->SetCurrentDIBuilder(prevDIBuilder);
1512     debugInfo = prevDebugInfo;
1513 }
1514 
1515 void LlvmCodeGenerator::GenerateGlobalInitFuncion(BoundCompileUnit& boundCompileUnit)
1516 {
1517     void* prevDIBuilder = emitter->DIBuilder();
1518     emitter->SetCurrentDIBuilder(nullptr);
1519     bool prevDebugInfo = debugInfo;
1520     debugInfo = false;
1521     emitter->ResetCurrentDebugLocation();
1522     emitter->SetCurrentSourceSpan(000);
1523     emitter->ResetCurrentDebugLocation();
1524     FunctionSymbol* globalInitFunctionSymbol = boundCompileUnit.GetGlobalInitializationFunctionSymbol();
1525     if (!globalInitFunctionSymbol)
1526     {
1527         emitter->SetCurrentDIBuilder(prevDIBuilder);
1528         debugInfo = prevDebugInfo;
1529         return;
1530     }
1531     handlerBlock = nullptr;
1532     cleanupBlock = nullptr;
1533     newCleanupNeeded = false;
1534     currentPad = nullptr;
1535     prevLineNumber = 0;
1536     destructorCallGenerated = false;
1537     lastInstructionWasRet = false;
1538     basicBlockOpen = false;
1539     lastAlloca = nullptr;
1540     compoundLevel = 0;
1541     cleanups.clear();
1542     pads.clear();
1543     labeledStatementMap.clear();
1544     Span span = globalInitFunctionSymbol->GetSpan();
1545     boost::uuids::uuid moduleId = globalInitFunctionSymbol->SourceModuleId();
1546     void* functionType = globalInitFunctionSymbol->IrType(*emitter);
1547     void* function = emitter->GetOrInsertFunction(ToUtf8(globalInitFunctionSymbol->MangledName())functionTypetrue);
1548     emitter->SetFunction(function-1boost::uuids::nil_uuid()boost::uuids::nil_uuid());
1549     emitter->SetFunctionName(ToUtf8(globalInitFunctionSymbol->FullName()));
1550     void* entryBlock = emitter->CreateBasicBlock("entry");
1551     emitter->SetCurrentBasicBlock(entryBlock);
1552     const std::std::vector<std::std::unique_ptr<FunctionSymbol>>&allCompileUnitInitFunctionSymbols=boundCompileUnit.AllCompileUnitInitFunctionSymbols();
1553     for (const std::std::unique_ptr<FunctionSymbol>&initCompileUnitFunctionSymbol : allCompileUnitInitFunctionSymbols)
1554     {
1555         std::unique_ptr<BoundFunctionCall> boundFunctionCall(new BoundFunctionCall(spanmoduleIdinitCompileUnitFunctionSymbol.get()));
1556         boundFunctionCall->Accept(*this);
1557     }
1558     emitter->CreateRetVoid();
1559     emitter->SetCurrentDIBuilder(prevDIBuilder);
1560     debugInfo = prevDebugInfo;
1561 }
1562 
1563 void* LlvmCodeGenerator::HandlerBlock()
1564 {
1565     return handlerBlock;
1566 }
1567 
1568 void* LlvmCodeGenerator::CleanupBlock()
1569 {
1570     return cleanupBlock;
1571 }
1572 
1573 bool LlvmCodeGenerator::NewCleanupNeeded()
1574 {
1575     return newCleanupNeeded;
1576 }
1577 
1578 std::string LlvmCodeGenerator::GetSourceFilePath(const Span& spanconst boost::uuids::uuid& moduleId)
1579 {
1580     return cmajor::symbols::GetSourceFilePath(span.fileIndexmoduleId);
1581 }
1582 
1583 cmajor::ir::Pad* LlvmCodeGenerator::CurrentPad()
1584 {
1585     return currentPad;
1586 }
1587 
1588 void* LlvmCodeGenerator::CreateClassDIType(void* classPtr)
1589 {
1590     ClassTypeSymbol* cls = static_cast<ClassTypeSymbol*>(classPtr);
1591     return cls->CreateDIType(*emitter);
1592 }
1593 
1594 void LlvmCodeGenerator::CreateExitFunctionCall()
1595 {
1596     if (currentFunction->GetFunctionSymbol()->DontThrow()) return;
1597     std::vector<void*> exitFunctionParamTypes;
1598     void* exitFunctionType = emitter->GetIrTypeForFunction(emitter->GetIrTypeForVoid()exitFunctionParamTypes);
1599     void* exitFunction = emitter->GetOrInsertFunction("RtExitFunction"exitFunctionTypetrue);
1600     std::vector<void*> exitFunctionArgs;
1601     if (currentPad == nullptr)
1602     {
1603         emitter->CreateCall(exitFunctionexitFunctionArgs);
1604     }
1605     else
1606     {
1607         std::vector<void*> bundles;
1608         bundles.push_back(currentPad->value);
1609         void* callInst = emitter->CreateCallInst(exitFunctionexitFunctionArgsbundlesSpan());
1610         if (debugInfo)
1611         {
1612             emitter->SetDebugLoc(callInst);
1613         }
1614     }
1615 }
1616 
1617 void LlvmCodeGenerator::SetTarget(BoundStatement* labeledStatement)
1618 {
1619     if (labeledStatement->Label().empty()) return;
1620     auto it = labeledStatementMap.find(labeledStatement);
1621     if (it != labeledStatementMap.cend())
1622     {
1623         void* target = it->second;
1624         emitter->CreateBr(target);
1625         emitter->SetCurrentBasicBlock(target);
1626     }
1627     else
1628     {
1629         throw Exception("target for labeled statement not found"labeledStatement->GetSpan()labeledStatement->ModuleId());
1630     }
1631 }
1632 
1633 void LlvmCodeGenerator::ExitBlocks(BoundCompoundStatement* targetBlock)
1634 {
1635     if (debugInfo)
1636     {
1637         if (currentBlock->EndSpan().Valid())
1638         {
1639             emitter->SetCurrentDebugLocation(currentBlock->EndSpan());
1640         }
1641     }
1642     bool createBasicBlock = false;
1643     BoundStatement* lastStatement = nullptr;
1644     if (!currentFunction->Body()->Statements().empty())
1645     {
1646         lastStatement = currentFunction->Body()->Statements().back().get();
1647     }
1648     BoundStatement* currentBlockLastStatement = nullptr;
1649     if (currentBlock && !currentBlock->Statements().empty())
1650     {
1651         currentBlockLastStatement = currentBlock->Statements().back().get();
1652     }
1653     if (lastStatement && currentBlockLastStatement && lastStatement == currentBlockLastStatement && currentBlockLastStatement->GetBoundNodeType() == BoundNodeType::boundReturnStatement)
1654     {
1655         createBasicBlock = true;
1656     }
1657     int n = blocks.size();
1658     for (int i = n - 1; i >= 0; --i)
1659     {
1660         BoundCompoundStatement* block = blocks[i];
1661         if (block == targetBlock)
1662         {
1663             break;
1664         }
1665         auto it = blockDestructionMap.find(block);
1666         if (it != blockDestructionMap.cend())
1667         {
1668             std::std::vector<std::std::unique_ptr<BoundFunctionCall>>&destructorCallVec=it->second;
1669             int nd = destructorCallVec.size();
1670             for (int i = nd - 1; i >= 0; --i)
1671             {
1672                 std::std::unique_ptr<BoundFunctionCall>&destructorCall=destructorCallVec[i];
1673                 if (destructorCall)
1674                 {
1675                     if (createBasicBlock)
1676                     {
1677                         void* nextBlock = emitter->CreateBasicBlock("next");
1678                         if (!lastInstructionWasRet)
1679                         {
1680                             emitter->CreateBr(nextBlock);
1681                         }
1682                         emitter->SetCurrentBasicBlock(nextBlock);
1683                         createBasicBlock = false;
1684                     }
1685                     destructorCall->Accept(*this);
1686                     destructorCallGenerated = true;
1687                     newCleanupNeeded = true;
1688                 }
1689             }
1690         }
1691     }
1692 }
1693 
1694 void LlvmCodeGenerator::GenJumpingBoolCode()
1695 {
1696     if (!genJumpingBoolCode) return;
1697     Assert(trueBlock"true block not set");
1698     Assert(falseBlock"false block not set");
1699     void* cond = emitter->Stack().Pop();
1700     if (sequenceSecond)
1701     {
1702         genJumpingBoolCode = false;
1703         sequenceSecond->SetGenerated();
1704         sequenceSecond->Accept(*this);
1705         genJumpingBoolCode = true;
1706     }
1707     emitter->CreateCondBr(condtrueBlockfalseBlock);
1708 }
1709 
1710 void LlvmCodeGenerator::ClearFlags()
1711 {
1712     destructorCallGenerated = false;
1713     lastInstructionWasRet = false;
1714     basicBlockOpen = false;
1715 }
1716 
1717 int LlvmCodeGenerator::Install(const std::string& str)
1718 {
1719     return compileUnit->Install(str);
1720 }
1721 
1722 int LlvmCodeGenerator::Install(const std::u16string& str)
1723 {
1724     return compileUnit->Install(str);
1725 }
1726 
1727 int LlvmCodeGenerator::Install(const std::u32string& str)
1728 {
1729     return compileUnit->Install(str);
1730 }
1731 
1732 void LlvmCodeGenerator::MoveAllocaIntoEntryBlock(void* allocaInst)
1733 {
1734     emitter->MoveAllocaIntoBasicBlock(allocaInstlastAllocaentryBasicBlock);
1735     lastAlloca = allocaInst;
1736 }
1737 
1738 void LlvmCodeGenerator::Optimize(int optimizationLevelconst std::string& bcFilePathconst std::string& optBCFilePath)
1739 {
1740     emitter->Optimize(bcFilePathoptBCFilePath"-O" + std::to_string(optimizationLevel));
1741 }
1742 
1743 } } // namespace cmajor::codegen