1 // =================================
   2 // Copyright (c) 2021 Seppo Laakko
   3 // Distributed under the MIT license
   4 // =================================
   5 
   6 #include <cmajor/binder/BoundExpression.hpp>
   7 #include <cmajor/binder/TypeResolver.hpp>
   8 #include <cmajor/binder/BoundNodeVisitor.hpp>
   9 #include <cmajor/binder/BoundFunction.hpp>
  10 #include <cmajor/binder/BoundCompileUnit.hpp>
  11 #include <cmajor/symbols/FunctionSymbol.hpp>
  12 #include <cmajor/symbols/Exception.hpp>
  13 #include <cmajor/symbols/EnumSymbol.hpp>
  14 #include <cmajor/symbols/ClassTypeSymbol.hpp>
  15 #include <cmajor/symbols/InterfaceTypeSymbol.hpp>
  16 #include <cmajor/symbols/GlobalFlags.hpp>
  17 #include <cmajor/symbols/ModuleCache.hpp>
  18 #include <cmajor/ir/Emitter.hpp>
  19 #include <soulng/util/Unicode.hpp>
  20 
  21 namespace cmajor { namespace binder {
  22 
  23 using namespace soulng::unicode;
  24  
  25 BoundExpression::BoundExpression(const Span& span_const boost::uuids::uuid& moduleId_BoundNodeType boundNodeType_TypeSymbol* type_) :
  26     BoundNode(span_moduleId_boundNodeType_)type(type_)flags(BoundExpressionFlags::none)
  27 {
  28 }
  29 
  30 void BoundExpression::AddTemporaryDestructorCall(std::std::unique_ptr<BoundFunctionCall>&&destructorCall)
  31 {
  32     temporaryDestructorCalls.push_back(std::move(destructorCall));
  33 }
  34 
  35 void BoundExpression::MoveTemporaryDestructorCallsTo(BoundExpression& expression)
  36 {
  37     for (std::std::unique_ptr<BoundFunctionCall>&destructorCall : temporaryDestructorCalls)
  38     {
  39         expression.AddTemporaryDestructorCall(std::move(destructorCall));
  40     }
  41     temporaryDestructorCalls.clear();
  42 }
  43 
  44 void BoundExpression::DestroyTemporaries(Emitter& emitter)
  45 {
  46     for (const std::std::unique_ptr<BoundFunctionCall>&destructorCall : temporaryDestructorCalls)
  47     {
  48         destructorCall->Load(emitterOperationFlags::none);
  49     }
  50 }
  51 
  52 BoundParameter::BoundParameter(const Span& span_const boost::uuids::uuid& moduleId_ParameterSymbol* parameterSymbol_) :
  53     BoundExpression(span_moduleId_BoundNodeType::boundParameterparameterSymbol_->GetType())parameterSymbol(parameterSymbol_)
  54 {
  55 }
  56 
  57 BoundExpression* BoundParameter::Clone()
  58 {
  59     return new BoundParameter(GetSpan()ModuleId()parameterSymbol);
  60 }
  61 
  62 void BoundParameter::Load(Emitter& emitterOperationFlags flags)
  63 {
  64     emitter.SetCurrentDebugLocation(GetSpan());
  65     if ((flags & OperationFlags::addr) != OperationFlags::none)
  66     {
  67         emitter.Stack().Push(parameterSymbol->IrObject(emitter));
  68     }
  69     else if ((flags & OperationFlags::deref) != OperationFlags::none)
  70     {
  71         void* value = emitter.CreateLoad(parameterSymbol->IrObject(emitter));
  72         uint8_t n = GetDerefCount(flags);
  73         for (uint8_t i = 0; i < n; ++i)
  74         {
  75             value = emitter.CreateLoad(value);
  76         }
  77         emitter.Stack().Push(value);
  78     }
  79     else
  80     {
  81         emitter.Stack().Push(emitter.CreateLoad(parameterSymbol->IrObject(emitter)));
  82     }
  83     DestroyTemporaries(emitter);
  84 }
  85 
  86 void BoundParameter::Store(Emitter& emitterOperationFlags flags)
  87 {
  88     emitter.SetCurrentDebugLocation(GetSpan());
  89     void* value = emitter.Stack().Pop();
  90     if ((flags & OperationFlags::addr) != OperationFlags::none)
  91     {
  92         throw Exception("cannot take address of a parameter"GetSpan()ModuleId());
  93     }
  94     else if ((flags & OperationFlags::deref) != OperationFlags::none)
  95     {
  96         void* ptr = emitter.CreateLoad(parameterSymbol->IrObject(emitter));
  97         uint8_t n = GetDerefCount(flags);
  98         for (uint8_t i = 1; i < n; ++i)
  99         {
 100             ptr = emitter.CreateLoad(ptr);
 101         }
 102         emitter.CreateStore(valueptr);
 103     }
 104     else
 105     {
 106         emitter.CreateStore(valueparameterSymbol->IrObject(emitter));
 107     }
 108     DestroyTemporaries(emitter);
 109 }
 110 
 111 void BoundParameter::Accept(BoundNodeVisitor& visitor)
 112 {
 113     visitor.Visit(*this);
 114 }
 115 
 116 BoundLocalVariable::BoundLocalVariable(const Span& span_const boost::uuids::uuid& moduleId_LocalVariableSymbol* localVariableSymbol_) :
 117     BoundExpression(span_moduleId_BoundNodeType::boundLocalVariablelocalVariableSymbol_->GetType())localVariableSymbol(localVariableSymbol_)
 118 {
 119 }
 120 
 121 BoundExpression* BoundLocalVariable::Clone()
 122 {
 123     return new BoundLocalVariable(GetSpan()ModuleId()localVariableSymbol);
 124 }
 125 
 126 void BoundLocalVariable::Load(Emitter& emitterOperationFlags flags)
 127 {
 128     emitter.SetCurrentDebugLocation(GetSpan());
 129     if ((flags & OperationFlags::addr) != OperationFlags::none)
 130     {
 131         emitter.Stack().Push(localVariableSymbol->IrObject(emitter));
 132     }
 133     else if ((flags & OperationFlags::deref) != OperationFlags::none)
 134     {
 135         void* value = emitter.CreateLoad(localVariableSymbol->IrObject(emitter));
 136         uint8_t n = GetDerefCount(flags);
 137         for (uint8_t i = 0; i < n; ++i)
 138         {
 139             value = emitter.CreateLoad(value);
 140         }
 141         emitter.Stack().Push(value);
 142     }
 143     else
 144     {
 145         emitter.Stack().Push(emitter.CreateLoad(localVariableSymbol->IrObject(emitter)));
 146     }
 147     DestroyTemporaries(emitter);
 148 }
 149 
 150 void BoundLocalVariable::Store(Emitter& emitterOperationFlags flags)
 151 {
 152     emitter.SetCurrentDebugLocation(GetSpan());
 153     void* value = emitter.Stack().Pop();
 154     if ((flags & OperationFlags::addr) != OperationFlags::none)
 155     {
 156         throw Exception("cannot store to address of a local variable"GetSpan()ModuleId());
 157     }
 158     else if ((flags & OperationFlags::deref) != OperationFlags::none)
 159     {
 160         void* ptr = emitter.CreateLoad(localVariableSymbol->IrObject(emitter));
 161         uint8_t n = GetDerefCount(flags);
 162         for (uint8_t i = 1; i < n; ++i)
 163         {
 164             ptr = emitter.CreateLoad(ptr);
 165         }
 166         emitter.CreateStore(valueptr);
 167     }
 168     else
 169     {
 170         emitter.CreateStore(valuelocalVariableSymbol->IrObject(emitter));
 171     }
 172     DestroyTemporaries(emitter);
 173 }
 174 
 175 void BoundLocalVariable::Accept(BoundNodeVisitor& visitor)
 176 {
 177     visitor.Visit(*this);
 178 }
 179 
 180 BoundMemberVariable::BoundMemberVariable(const Span& span_const boost::uuids::uuid& moduleId_MemberVariableSymbol* memberVariableSymbol_) :
 181     BoundExpression(span_moduleId_BoundNodeType::boundMemberVariablememberVariableSymbol_->GetType())
 182     memberVariableSymbol(memberVariableSymbol_)staticInitNeeded(false)
 183 {
 184 }
 185 
 186 BoundExpression* BoundMemberVariable::Clone()
 187 {
 188     BoundMemberVariable* clone = new BoundMemberVariable(GetSpan()ModuleId()memberVariableSymbol);
 189     if (classPtr)
 190     {
 191         clone->classPtr.reset(classPtr->Clone());
 192     }
 193     if (staticInitNeeded)
 194     {
 195         clone->staticInitNeeded = true;
 196     }
 197     return clone;
 198 }
 199 
 200 void BoundMemberVariable::Load(Emitter& emitterOperationFlags flags)
 201 {
 202     emitter.SetCurrentDebugLocation(GetSpan());
 203     Assert(memberVariableSymbol->LayoutIndex() != -1"layout index of the member variable not set");
 204     if (memberVariableSymbol->IsStatic())
 205     {
 206         ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(memberVariableSymbol->Parent());
 207         if (staticInitNeeded)
 208         {
 209             if (classType->StaticConstructor())
 210             {
 211                 BoundFunctionCall staticConstructorCall(classType->StaticConstructor()->GetSpan()classType->StaticConstructor()->SourceModuleId()classType->StaticConstructor());
 212                 staticConstructorCall.Load(emitterOperationFlags::none);
 213             }
 214         }
 215         emitter.Stack().Push(classType->StaticObject(emitterfalse));
 216     }
 217     else
 218     {
 219         if (!classPtr)
 220         {
 221             throw Exception("class pointer of the member variable not set"GetSpan()ModuleId());
 222         }
 223         classPtr->Load(emitterOperationFlags::none);
 224     }
 225     void* ptr = emitter.Stack().Pop();
 226     void* memberVariablePtr = emitter.GetMemberVariablePtr(ptrmemberVariableSymbol->LayoutIndex());
 227     if ((flags & OperationFlags::addr) != OperationFlags::none)
 228     {
 229         emitter.Stack().Push(memberVariablePtr);
 230     }
 231     else if ((flags & OperationFlags::deref) != OperationFlags::none)
 232     {
 233         void* value = emitter.CreateLoad(memberVariablePtr);
 234         uint8_t n = GetDerefCount(flags);
 235         for (uint8_t i = 0; i < n; ++i)
 236         {
 237             value = emitter.CreateLoad(value);
 238         }
 239         emitter.Stack().Push(value);
 240     }
 241     else
 242     {
 243         emitter.Stack().Push(emitter.CreateLoad(memberVariablePtr));
 244     }
 245     DestroyTemporaries(emitter);
 246 }
 247 
 248 void BoundMemberVariable::Store(Emitter& emitterOperationFlags flags)
 249 {
 250     emitter.SetCurrentDebugLocation(GetSpan());
 251     Assert(memberVariableSymbol->LayoutIndex() != -1"layout index of the member variable not set");
 252     void* value = emitter.Stack().Pop();
 253     if ((flags & OperationFlags::addr) != OperationFlags::none)
 254     {
 255         throw Exception("cannot store to the address of a member variable"GetSpan()ModuleId());
 256     }
 257     else
 258     {
 259         if (memberVariableSymbol->IsStatic())
 260         {
 261             ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(memberVariableSymbol->Parent());
 262             if (staticInitNeeded)
 263             {
 264                 if (classType->StaticConstructor())
 265                 {
 266                     BoundFunctionCall staticConstructorCall(classType->StaticConstructor()->GetSpan()classType->StaticConstructor()->SourceModuleId()classType->StaticConstructor());
 267                     staticConstructorCall.Load(emitterOperationFlags::none);
 268                 }
 269             }
 270             emitter.Stack().Push(classType->StaticObject(emitterfalse));
 271         }
 272         else
 273         {
 274             classPtr->Load(emitterOperationFlags::none);
 275         }
 276         void* ptr = emitter.Stack().Pop();
 277         void* memberVariablePtr = emitter.GetMemberVariablePtr(ptrmemberVariableSymbol->LayoutIndex());
 278         if ((flags & OperationFlags::deref) != OperationFlags::none)
 279         {
 280             void* ptr = emitter.CreateLoad(memberVariablePtr);
 281             uint8_t n = GetDerefCount(flags);
 282             for (uint8_t i = 1; i < n; ++i)
 283             {
 284                 ptr = emitter.CreateLoad(ptr);
 285             }
 286             emitter.CreateStore(valueptr);
 287         }
 288         else
 289         {
 290             emitter.CreateStore(valuememberVariablePtr);
 291         }
 292     }
 293     DestroyTemporaries(emitter);
 294 }
 295 
 296 void BoundMemberVariable::Accept(BoundNodeVisitor& visitor)
 297 {
 298     visitor.Visit(*this);
 299 }
 300 
 301 void BoundMemberVariable::SetClassPtr(std::std::unique_ptr<BoundExpression>&&classPtr_)
 302 {
 303     classPtr = std::move(classPtr_);
 304 }
 305 
 306 BoundConstant::BoundConstant(const Span& span_const boost::uuids::uuid& moduleId_ConstantSymbol* constantSymbol_) :
 307     BoundExpression(span_moduleId_BoundNodeType::boundConstantconstantSymbol_->GetType())constantSymbol(constantSymbol_)
 308 {
 309 }
 310 
 311 BoundExpression* BoundConstant::Clone()
 312 {
 313     return new BoundConstant(GetSpan()ModuleId()constantSymbol);
 314 }
 315 
 316 void BoundConstant::Load(Emitter& emitterOperationFlags flags)
 317 {
 318     emitter.SetCurrentDebugLocation(GetSpan());
 319     if (constantSymbol->GetValue()->GetValueType() == ValueType::arrayValue&&(  flags & OperationFlags::addr) != OperationFlags::none)
 320     {
 321         emitter.Stack().Push(constantSymbol->ArrayIrObject(emitterfalse));
 322     }
 323     else
 324     {
 325         if ((flags & OperationFlags::addr) != OperationFlags::none)
 326         {
 327             throw Exception("cannot take address of a constant"GetSpan()ModuleId());
 328         }
 329         else if ((flags & OperationFlags::deref) != OperationFlags::none)
 330         {
 331             throw Exception("cannot dereference a constant"GetSpan()ModuleId());
 332         }
 333         else
 334         {
 335             emitter.Stack().Push(constantSymbol->GetValue()->IrValue(emitter));
 336         }
 337     }
 338     DestroyTemporaries(emitter);
 339 }
 340 
 341 void BoundConstant::Store(Emitter& emitterOperationFlags flags)
 342 {
 343     throw Exception("cannot store to a constant"GetSpan()ModuleId());
 344 }
 345 
 346 void BoundConstant::Accept(BoundNodeVisitor& visitor)
 347 {
 348     visitor.Visit(*this);
 349 }
 350 
 351 BoundEnumConstant::BoundEnumConstant(const Span& span_const boost::uuids::uuid& moduleId_EnumConstantSymbol* enumConstantSymbol_) :
 352     BoundExpression(span_moduleId_BoundNodeType::boundEnumConstantenumConstantSymbol_->GetType())enumConstantSymbol(enumConstantSymbol_)
 353 {
 354 }
 355 
 356 BoundExpression* BoundEnumConstant::Clone()
 357 {
 358     return new BoundEnumConstant(GetSpan()ModuleId()enumConstantSymbol);
 359 }
 360 
 361 void BoundEnumConstant::Load(Emitter& emitterOperationFlags flags)
 362 {
 363     emitter.SetCurrentDebugLocation(GetSpan());
 364     if ((flags & OperationFlags::addr) != OperationFlags::none)
 365     {
 366         throw Exception("cannot take address of an enumeration constant"GetSpan()ModuleId());
 367     }
 368     else if ((flags & OperationFlags::deref) != OperationFlags::none)
 369     {
 370         throw Exception("cannot dereference an enumeration constant"GetSpan()ModuleId());
 371     }
 372     else
 373     {
 374         emitter.Stack().Push(enumConstantSymbol->GetValue()->IrValue(emitter));
 375     }
 376     DestroyTemporaries(emitter);
 377 }
 378 
 379 void BoundEnumConstant::Store(Emitter& emitterOperationFlags flags)
 380 {
 381     throw Exception("cannot store to an enumeration constant"GetSpan()ModuleId());
 382 }
 383 
 384 void BoundEnumConstant::Accept(BoundNodeVisitor& visitor)
 385 {
 386     visitor.Visit(*this);
 387 }
 388 
 389 BoundLiteral::BoundLiteral(std::std::unique_ptr<Value>&&value_TypeSymbol*type_):
 390     BoundExpression(value_->GetSpan()value_->ModuleId()BoundNodeType::boundLiteraltype_)value(std::move(value_))
 391 {
 392 }
 393 
 394 BoundExpression* BoundLiteral::Clone()
 395 {
 396     std::unique_ptr<Value> clonedValue;
 397     clonedValue.reset(value->Clone());
 398     return new BoundLiteral(std::move(clonedValue)GetType());
 399 }
 400 
 401 void BoundLiteral::Load(Emitter& emitterOperationFlags flags)
 402 {
 403     emitter.SetCurrentDebugLocation(GetSpan());
 404     if ((flags & OperationFlags::addr) != OperationFlags::none)
 405     {
 406         throw Exception("cannot take address of a literal"GetSpan()ModuleId());
 407     }
 408     else if ((flags & OperationFlags::deref) != OperationFlags::none)
 409     {
 410         throw Exception("cannot dereference a literal"GetSpan()ModuleId());
 411     }
 412     else
 413     {
 414         emitter.Stack().Push(value->IrValue(emitter));
 415     }
 416     DestroyTemporaries(emitter);
 417 }
 418 
 419 void BoundLiteral::Store(Emitter& emitterOperationFlags flags)
 420 {
 421     throw Exception("cannot store to a literal"GetSpan()ModuleId());
 422 }
 423 
 424 void BoundLiteral::Accept(BoundNodeVisitor& visitor)
 425 {
 426     visitor.Visit(*this);
 427 }
 428 
 429 std::std::unique_ptr<Value>BoundLiteral::ToValue(BoundCompileUnit&boundCompileUnit) const
 430 {
 431     return std::unique_ptr<Value>(value->Clone());
 432 }
 433 
 434 BoundGlobalVariable::BoundGlobalVariable(const Span& span_const boost::uuids::uuid& moduleId_GlobalVariableSymbol* globalVariableSymbol_) :
 435     BoundExpression(span_moduleId_BoundNodeType::boundGlobalVariableglobalVariableSymbol_->GetType())globalVariableSymbol(globalVariableSymbol_)
 436 {
 437 }
 438 
 439 BoundExpression* BoundGlobalVariable::Clone()
 440 {
 441     return new BoundGlobalVariable(GetSpan()ModuleId()globalVariableSymbol);
 442 }
 443 
 444 void BoundGlobalVariable::Load(Emitter& emitterOperationFlags flags)
 445 {
 446     emitter.SetCurrentDebugLocation(GetSpan());
 447     void* globalVariablePtr = globalVariableSymbol->IrObject(emitter);
 448     if ((flags & OperationFlags::addr) != OperationFlags::none)
 449     {
 450         emitter.Stack().Push(globalVariablePtr);
 451     }
 452     else if ((flags & OperationFlags::deref) != OperationFlags::none)
 453     {
 454         void* value = emitter.CreateLoad(globalVariablePtr);
 455         uint8_t n = GetDerefCount(flags);
 456         for (uint8_t i = 0; i < n; ++i)
 457         {
 458             value = emitter.CreateLoad(value);
 459         }
 460         emitter.Stack().Push(value);
 461     }
 462     else
 463     {
 464         emitter.Stack().Push(emitter.CreateLoad(globalVariablePtr));
 465     }
 466     DestroyTemporaries(emitter);
 467 }
 468 
 469 void BoundGlobalVariable::Store(Emitter& emitterOperationFlags flags)
 470 {
 471     emitter.SetCurrentDebugLocation(GetSpan());
 472     if ((flags & OperationFlags::addr) != OperationFlags::none)
 473     {
 474         throw Exception("cannot store to the address of a global variable"GetSpan()ModuleId());
 475     }
 476     else
 477     {
 478         void* value = emitter.Stack().Pop();
 479         void* ptr = globalVariableSymbol->IrObject(emitter);
 480         if ((flags & OperationFlags::deref) != OperationFlags::none)
 481         {
 482             void* loadedPtr = emitter.CreateLoad(ptr);
 483             uint8_t n = GetDerefCount(flags);
 484             for (uint8_t i = 1; i < n; ++i)
 485             {
 486                 loadedPtr = emitter.CreateLoad(loadedPtr);
 487             }
 488             emitter.CreateStore(valueloadedPtr);
 489         }
 490         else
 491         {
 492             emitter.CreateStore(valueptr);
 493         }
 494     }
 495     DestroyTemporaries(emitter);
 496 }
 497 
 498 void BoundGlobalVariable::Accept(BoundNodeVisitor& visitor)
 499 {
 500     visitor.Visit(*this);
 501 }
 502 
 503 BoundTemporary::BoundTemporary(std::std::unique_ptr<BoundExpression>&&rvalueExpr_std::std::unique_ptr<BoundLocalVariable>&&backingStore_):
 504     BoundExpression(rvalueExpr_->GetSpan()rvalueExpr_->ModuleId()BoundNodeType::boundTemporaryrvalueExpr_->GetType())rvalueExpr(std::move(rvalueExpr_))backingStore(std::move(backingStore_))
 505 {
 506     rvalueExpr->MoveTemporaryDestructorCallsTo(*this);
 507     if (backingStore)
 508     {
 509         backingStore->MoveTemporaryDestructorCallsTo(*this);
 510     }
 511 }
 512 
 513 BoundExpression* BoundTemporary::Clone()
 514 {
 515     std::unique_ptr<BoundExpression> clonedRvalueExpr;
 516     clonedRvalueExpr.reset(rvalueExpr->Clone());
 517     std::unique_ptr<BoundLocalVariable> clonedBackingStore;
 518     if (backingStore)
 519     {
 520         clonedBackingStore.reset(static_cast<BoundLocalVariable*>(backingStore->Clone()));
 521     }
 522     return new BoundTemporary(std::move(clonedRvalueExpr)std::move(clonedBackingStore));
 523 }
 524 
 525 void BoundTemporary::Load(Emitter& emitterOperationFlags flags)
 526 {
 527     rvalueExpr->Load(emitterOperationFlags::none);
 528     if (!backingStore)
 529     {
 530         throw Exception("backing store of temporary not set"GetSpan()ModuleId());
 531     }
 532     backingStore->Store(emitterOperationFlags::none);
 533     if ((flags & OperationFlags::addr) != OperationFlags::none)
 534     {
 535         backingStore->Load(emitterOperationFlags::addr);
 536     }
 537     else if ((flags & OperationFlags::deref) != OperationFlags::none)
 538     {
 539         backingStore->Load(emitterSetDerefCount(OperationFlags::derefGetDerefCount(flags) + 1));
 540     }
 541     else
 542     {
 543         backingStore->Load(emitterOperationFlags::none);
 544     }
 545     DestroyTemporaries(emitter);
 546 }
 547 
 548 void BoundTemporary::Store(Emitter& emitterOperationFlags flags)
 549 {
 550     throw Exception("cannot store to a temporary"GetSpan()ModuleId());
 551 }
 552 
 553 void BoundTemporary::Accept(BoundNodeVisitor& visitor)
 554 {
 555     visitor.Visit(*this);
 556 }
 557 
 558 std::std::unique_ptr<Value>BoundTemporary::ToValue(BoundCompileUnit&boundCompileUnit) const
 559 {
 560     return rvalueExpr->ToValue(boundCompileUnit);
 561 }
 562 
 563 bool BoundTemporary::ContainsExceptionCapture() const
 564 {
 565     if (BoundExpression::ContainsExceptionCapture())
 566     {
 567         return true;
 568     }
 569     if (rvalueExpr->ContainsExceptionCapture())
 570     {
 571         return true;
 572     }
 573     return false;
 574 }
 575 
 576 BoundSizeOfExpression::BoundSizeOfExpression(const Span& span_const boost::uuids::uuid& moduleId_TypeSymbol* type_TypeSymbol* pointerType_) :
 577     BoundExpression(span_moduleId_BoundNodeType::boundSizeOfExpressiontype_)pointerType(pointerType_)
 578 {
 579 }
 580 
 581 BoundExpression* BoundSizeOfExpression::Clone()
 582 {
 583     return new BoundSizeOfExpression(GetSpan()ModuleId()GetType()pointerType);
 584 }
 585 
 586 void BoundSizeOfExpression::Load(Emitter& emitterOperationFlags flags)
 587 {
 588     if ((flags & OperationFlags::addr) != OperationFlags::none)
 589     {
 590         throw Exception("cannot take address of a sizeof expression"GetSpan()ModuleId());
 591     }
 592     else if ((flags & OperationFlags::deref) != OperationFlags::none)
 593     {
 594         throw Exception("cannot dereference a sizeof expression"GetSpan()ModuleId());
 595     }
 596     else
 597     {
 598         emitter.Stack().Push(emitter.SizeOf(pointerType->IrType(emitter)));
 599     }
 600     DestroyTemporaries(emitter);
 601 }
 602 
 603 void BoundSizeOfExpression::Store(Emitter& emitterOperationFlags flags)
 604 {
 605     throw Exception("cannot store to a sizeof expression"GetSpan()ModuleId());
 606 }
 607 
 608 void BoundSizeOfExpression::Accept(BoundNodeVisitor& visitor)
 609 {
 610     visitor.Visit(*this);
 611 }
 612 
 613 BoundAddressOfExpression::BoundAddressOfExpression(std::std::unique_ptr<BoundExpression>&&subject_TypeSymbol*type_):
 614     BoundExpression(subject_->GetSpan()subject_->ModuleId()BoundNodeType::boundAddressOfExpressiontype_)subject(std::move(subject_))
 615 {
 616     subject->MoveTemporaryDestructorCallsTo(*this);
 617 }
 618 
 619 BoundExpression* BoundAddressOfExpression::Clone()
 620 {
 621     std::unique_ptr<BoundExpression> clonedSubject;
 622     clonedSubject.reset(subject->Clone());
 623     return new BoundAddressOfExpression(std::move(clonedSubject)GetType());
 624 }
 625 
 626 void BoundAddressOfExpression::Load(Emitter& emitterOperationFlags flags)
 627 {
 628     if (subject->GetBoundNodeType() != BoundNodeType::boundDereferenceExpression)
 629     {
 630         subject->Load(emitterOperationFlags::addr);
 631     }
 632     else
 633     {
 634         BoundDereferenceExpression* derefExpr = static_cast<BoundDereferenceExpression*>(subject.get());
 635         derefExpr->Subject()->Load(emitterflags);
 636     }
 637     DestroyTemporaries(emitter);
 638 }
 639 
 640 void BoundAddressOfExpression::Store(Emitter& emitterOperationFlags flags)
 641 {
 642     if (subject->GetBoundNodeType() != BoundNodeType::boundDereferenceExpression)
 643     {
 644         subject->Store(emitterflags);
 645     }
 646     else
 647     {
 648         BoundDereferenceExpression* derefExpr = static_cast<BoundDereferenceExpression*>(subject.get());
 649         derefExpr->Subject()->Store(emitterflags);
 650     }
 651     DestroyTemporaries(emitter);
 652 }
 653 
 654 void BoundAddressOfExpression::Accept(BoundNodeVisitor& visitor)
 655 {
 656     visitor.Visit(*this);
 657 }
 658 
 659 std::std::unique_ptr<Value>BoundAddressOfExpression::ToValue(BoundCompileUnit&boundCompileUnit) const
 660 {
 661     return subject->ToValue(boundCompileUnit);
 662 }
 663 
 664 bool BoundAddressOfExpression::ContainsExceptionCapture() const
 665 {
 666     if (BoundExpression::ContainsExceptionCapture())
 667     {
 668         return true;
 669     }
 670     if (subject->ContainsExceptionCapture())
 671     {
 672         return true;
 673     }
 674     return false;
 675 }
 676 
 677 BoundDereferenceExpression::BoundDereferenceExpression(std::std::unique_ptr<BoundExpression>&&subject_TypeSymbol*type_):
 678     BoundExpression(subject_->GetSpan()subject_->ModuleId()BoundNodeType::boundDereferenceExpressiontype_)subject(std::move(subject_))
 679 {
 680     subject->MoveTemporaryDestructorCallsTo(*this);
 681 }
 682 
 683 BoundExpression* BoundDereferenceExpression::Clone()
 684 {
 685     std::unique_ptr<BoundExpression> clonedSubject;
 686     clonedSubject.reset(subject->Clone());
 687     return new BoundDereferenceExpression(std::move(clonedSubject)GetType());
 688 }
 689 
 690 void BoundDereferenceExpression::Load(Emitter& emitterOperationFlags flags)
 691 {
 692     if (subject->GetBoundNodeType() != BoundNodeType::boundAddressOfExpression)
 693     {
 694         if (GetDerefCount(flags) == 0 && (flags & OperationFlags::addr) != OperationFlags::none)
 695         {
 696             subject->Load(emitterOperationFlags::none);
 697         }
 698         else
 699         {
 700             subject->Load(emitterSetDerefCount(OperationFlags::derefGetDerefCount(flags) + 1));
 701         }
 702     }
 703     else
 704     {
 705         BoundAddressOfExpression* addressOfExpr = static_cast<BoundAddressOfExpression*>(subject.get());
 706         addressOfExpr->Subject()->Load(emitterflags);
 707     }
 708     DestroyTemporaries(emitter);
 709 }
 710 
 711 void BoundDereferenceExpression::Store(Emitter& emitterOperationFlags flags)
 712 {
 713     if (subject->GetBoundNodeType() != BoundNodeType::boundAddressOfExpression)
 714     {
 715         subject->Store(emitterSetDerefCount(OperationFlags::deref | (flags & OperationFlags::functionCallFlags)GetDerefCount(flags) + 1));
 716     }
 717     else
 718     {
 719         BoundAddressOfExpression* addressOfExpr = static_cast<BoundAddressOfExpression*>(subject.get());
 720         addressOfExpr->Subject()->Store(emitterflags | (flags & OperationFlags::functionCallFlags));
 721     }
 722     DestroyTemporaries(emitter);
 723 }
 724 
 725 void BoundDereferenceExpression::Accept(BoundNodeVisitor& visitor)
 726 {
 727     visitor.Visit(*this);
 728 }
 729 
 730 bool BoundDereferenceExpression::ContainsExceptionCapture() const
 731 {
 732     if (BoundExpression::ContainsExceptionCapture())
 733     {
 734         return true;
 735     }
 736     if (subject->ContainsExceptionCapture())
 737     {
 738         return true;
 739     }
 740     return false;
 741 }
 742 
 743 BoundReferenceToPointerExpression::BoundReferenceToPointerExpression(std::std::unique_ptr<BoundExpression>&&subject_TypeSymbol*type_):
 744     BoundExpression(subject_->GetSpan()subject_->ModuleId()BoundNodeType::boundReferenceToPointerExpressiontype_)subject(std::move(subject_))
 745 {
 746     subject->MoveTemporaryDestructorCallsTo(*this);
 747 }
 748 
 749 BoundExpression* BoundReferenceToPointerExpression::Clone()
 750 {
 751     std::unique_ptr<BoundExpression> clonedSubject;
 752     clonedSubject.reset(subject->Clone());
 753     return new BoundReferenceToPointerExpression(std::move(clonedSubject)GetType());
 754 }
 755 
 756 void BoundReferenceToPointerExpression::Load(Emitter& emitterOperationFlags flags)
 757 {
 758     subject->Load(emitterflags);
 759     DestroyTemporaries(emitter);
 760 }
 761 
 762 void BoundReferenceToPointerExpression::Store(Emitter& emitterOperationFlags flags)
 763 {
 764     subject->Store(emitterflags);
 765     DestroyTemporaries(emitter);
 766 }
 767 
 768 void BoundReferenceToPointerExpression::Accept(BoundNodeVisitor& visitor)
 769 {
 770     visitor.Visit(*this);
 771 }
 772 
 773 bool BoundReferenceToPointerExpression::ContainsExceptionCapture() const
 774 {
 775     if (BoundExpression::ContainsExceptionCapture())
 776     {
 777         return true;
 778     }
 779     if (subject->ContainsExceptionCapture())
 780     {
 781         return true;
 782     }
 783     return false;
 784 }
 785 
 786 BoundFunctionCall::BoundFunctionCall(const Span& span_const boost::uuids::uuid& moduleId_FunctionSymbol* functionSymbol_) :
 787     BoundExpression(span_moduleId_BoundNodeType::boundFunctionCallfunctionSymbol_->ReturnType())functionSymbol(functionSymbol_)
 788 {
 789 }
 790 
 791 BoundExpression* BoundFunctionCall::Clone()
 792 {
 793     BoundFunctionCall* clone = new BoundFunctionCall(GetSpan()ModuleId()functionSymbol);
 794     for (std::std::unique_ptr<BoundExpression>&argument : arguments)
 795     {
 796         clone->AddArgument(std::unique_ptr<BoundExpression>(argument->Clone()));
 797     }
 798     for (const auto& p : temporaries)
 799     {
 800         clone->AddTemporary(std::unique_ptr<BoundLocalVariable>(static_cast<BoundLocalVariable*>(p->Clone())));
 801     }
 802     return clone;
 803 }
 804 
 805 void BoundFunctionCall::AddArgument(std::std::unique_ptr<BoundExpression>&&argument)
 806 {
 807     argument->MoveTemporaryDestructorCallsTo(*this);
 808     arguments.push_back(std::move(argument));
 809 }
 810 
 811 void BoundFunctionCall::SetArguments(std::std::vector<std::std::unique_ptr<BoundExpression>>&&arguments_)
 812 {
 813     arguments = std::move(arguments_);
 814 }
 815 
 816 void BoundFunctionCall::AddTemporary(std::std::unique_ptr<BoundLocalVariable>&&temporary)
 817 {
 818     temporaries.push_back(std::move(temporary));
 819 }
 820 
 821 bool BoundFunctionCall::ContainsExceptionCapture() const
 822 {
 823     if (BoundExpression::ContainsExceptionCapture())
 824     {
 825         return true;
 826     }
 827     for (const std::std::unique_ptr<BoundExpression>&arg : arguments)
 828     {
 829         if (arg->ContainsExceptionCapture())
 830         {
 831             return true;
 832         }
 833     }
 834     return false;
 835 }
 836 
 837 std::std::vector<std::std::unique_ptr<GenObject>>BoundFunctionCall::ReleaseTemporaries()
 838 {
 839     std::vector<std::std::unique_ptr<GenObject>>temps;
 840     for (std::std::unique_ptr<BoundLocalVariable>&temp : temporaries)
 841     {
 842         temps.push_back(std::move(temp));
 843     }
 844     return temps;
 845 }
 846 
 847 void BoundFunctionCall::Load(Emitter& emitterOperationFlags flags)
 848 {
 849     if ((flags & OperationFlags::addr) != OperationFlags::none)
 850     {
 851         if (functionSymbol->IsArrayElementAccess())
 852         {
 853             std::vector<GenObject*> genObjects;
 854             for (const std::std::unique_ptr<BoundExpression>&argument : arguments)
 855             {
 856                 genObjects.push_back(argument.get());
 857                 genObjects.back()->SetType(argument->GetType());
 858             }
 859             functionSymbol->GenerateCall(emittergenObjectsflagsGetSpan()ModuleId());
 860         }
 861         else
 862         {
 863             throw Exception("cannot take address of a function call"GetSpan()ModuleId());
 864         }
 865     }
 866     else
 867     {
 868         std::vector<GenObject*> genObjects;
 869         for (const std::std::unique_ptr<BoundExpression>&argument : arguments)
 870         {
 871             genObjects.push_back(argument.get());
 872             genObjects.back()->SetType(argument->GetType());
 873         }
 874         for (const std::std::unique_ptr<BoundLocalVariable>&temporary : temporaries)
 875         {
 876             genObjects.push_back(temporary.get());
 877             genObjects.back()->SetType(temporary->GetType());
 878         }
 879         OperationFlags callFlags = flags & OperationFlags::functionCallFlags;
 880         if (GetFlag(BoundExpressionFlags::virtualCall))
 881         {
 882             Assert(!arguments.empty()"nonempty argument list expected");
 883             genObjects[0]->SetType(arguments[0]->GetType());
 884             callFlags = callFlags | OperationFlags::virtualCall;
 885         }
 886         if (!functionSymbol->DontThrow())
 887         {
 888             emitter.SetLineNumber(GetSpan().line);
 889         }
 890         if (functionSymbol->Parent()->GetSymbolType() == SymbolType::interfaceTypeSymbol)
 891         {
 892             InterfaceTypeSymbol* interfaceType = static_cast<InterfaceTypeSymbol*>(functionSymbol->Parent());
 893             MemberFunctionSymbol* interfaceMemberFunction = static_cast<MemberFunctionSymbol*>(functionSymbol);
 894             interfaceType->GenerateCall(emittergenObjectscallFlagsinterfaceMemberFunctionGetSpan()ModuleId());
 895         }
 896         else
 897         {
 898             functionSymbol->GenerateCall(emittergenObjectscallFlagsGetSpan()ModuleId());
 899         }
 900         if ((flags & OperationFlags::deref) != OperationFlags::none)
 901         {
 902             void* value = emitter.Stack().Pop();
 903             uint8_t n = GetDerefCount(flags);
 904             for (uint8_t i = 0; i < n; ++i)
 905             {
 906                 value = emitter.CreateLoad(value);
 907             }
 908             emitter.Stack().Push(value);
 909         }
 910     }
 911     DestroyTemporaries(emitter);
 912 }
 913 
 914 void BoundFunctionCall::Store(Emitter& emitterOperationFlags flags)
 915 {
 916     if ((flags & OperationFlags::addr) != OperationFlags::none)
 917     {
 918         throw Exception("cannot take address of a function call"GetSpan()ModuleId());
 919     }
 920     else
 921     {
 922         void* value = emitter.Stack().Pop();
 923         std::vector<GenObject*> genObjects;
 924         for (const std::std::unique_ptr<BoundExpression>&argument : arguments)
 925         {
 926             genObjects.push_back(argument.get());
 927             genObjects.back()->SetType(argument->GetType());
 928         }
 929         OperationFlags callFlags = OperationFlags::none;
 930         if (GetFlag(BoundExpressionFlags::virtualCall))
 931         {
 932             callFlags = callFlags | OperationFlags::virtualCall;
 933         }
 934         if (!functionSymbol->DontThrow())
 935         {
 936             emitter.SetLineNumber(GetSpan().line);
 937         }
 938         if (functionSymbol->IsArrayElementAccess())
 939         {
 940             functionSymbol->GenerateCall(emittergenObjectscallFlags | OperationFlags::addrGetSpan()ModuleId());
 941             void* ptr = emitter.Stack().Pop();
 942             emitter.CreateStore(valueptr);
 943         }
 944         else
 945         {
 946             functionSymbol->GenerateCall(emittergenObjectscallFlagsGetSpan()ModuleId());
 947             void* ptr = emitter.Stack().Pop();
 948             if ((flags & OperationFlags::leaveFirstArg) != OperationFlags::none)
 949             {
 950                 emitter.SaveObjectPointer(ptr);
 951             }
 952             if ((flags & OperationFlags::deref) != OperationFlags::none || GetFlag(BoundExpressionFlags::deref))
 953             {
 954                 uint8_t n = GetDerefCount(flags);
 955                 for (uint8_t i = 1; i < n; ++i)
 956                 {
 957                     ptr = emitter.CreateLoad(ptr);
 958                 }
 959                 emitter.CreateStore(valueptr);
 960             }
 961             else
 962             {
 963                 emitter.CreateStore(emitter.CreateLoad(value)ptr);
 964             }
 965         }
 966     }
 967     DestroyTemporaries(emitter);
 968 }
 969 
 970 void BoundFunctionCall::Accept(BoundNodeVisitor& visitor)
 971 {
 972     visitor.Visit(*this);
 973 }
 974 
 975 bool BoundFunctionCall::HasValue() const
 976 {
 977     return functionSymbol->ReturnType() && functionSymbol->ReturnType()->GetSymbolType() != SymbolType::voidTypeSymbol;
 978 }
 979 
 980 bool BoundFunctionCall::IsLvalueExpression() const
 981 {
 982     if (functionSymbol->IsArrayElementAccess()) return true;
 983     TypeSymbol* returnType = functionSymbol->ReturnType();
 984     if (returnType && returnType->GetSymbolType() != SymbolType::voidTypeSymbol)
 985     {
 986         return !returnType->IsConstType() && returnType->IsLvalueReferenceType();
 987     }
 988     return false;
 989 }
 990 
 991 BoundDelegateCall::BoundDelegateCall(const Span& span_const boost::uuids::uuid& moduleId_DelegateTypeSymbol* delegateType_) :
 992     BoundExpression(span_moduleId_BoundNodeType::boundDelegateCalldelegateType_->ReturnType())delegateTypeSymbol(delegateType_)arguments()
 993 {
 994 }
 995 
 996 BoundExpression* BoundDelegateCall::Clone()
 997 {
 998     return new BoundDelegateCall(GetSpan()ModuleId()delegateTypeSymbol);
 999 }
1000 
1001 void BoundDelegateCall::Load(Emitter& emitterOperationFlags flags)
1002 {
1003     if ((flags & OperationFlags::addr) != OperationFlags::none)
1004     {
1005         throw Exception("cannot take address of a delegate call"GetSpan()ModuleId());
1006     }
1007     else
1008     {
1009         std::vector<GenObject*> genObjects;
1010         for (const std::std::unique_ptr<BoundExpression>&argument : arguments)
1011         {
1012             genObjects.push_back(argument.get());
1013             genObjects.back()->SetType(argument->GetType());
1014         }
1015         OperationFlags callFlags = flags & OperationFlags::functionCallFlags;
1016         if (!delegateTypeSymbol->IsNothrow())
1017         {
1018             emitter.SetLineNumber(GetSpan().line);
1019         }
1020         delegateTypeSymbol->GenerateCall(emittergenObjectscallFlagsGetSpan()ModuleId());
1021         if ((flags & OperationFlags::deref) != OperationFlags::none)
1022         {
1023             void* value = emitter.Stack().Pop();
1024             uint8_t n = GetDerefCount(flags);
1025             for (uint8_t i = 0; i < n; ++i)
1026             {
1027                 value = emitter.CreateLoad(value);
1028             }
1029             emitter.Stack().Push(value);
1030         }
1031     }
1032     DestroyTemporaries(emitter);
1033 }
1034 
1035 void BoundDelegateCall::Store(Emitter& emitterOperationFlags flags)
1036 {
1037     if ((flags & OperationFlags::addr) != OperationFlags::none)
1038     {
1039         throw Exception("cannot take address of a delegate call"GetSpan()ModuleId());
1040     }
1041     else
1042     {
1043         void* value = emitter.Stack().Pop();
1044         std::vector<GenObject*> genObjects;
1045         for (const std::std::unique_ptr<BoundExpression>&argument : arguments)
1046         {
1047             genObjects.push_back(argument.get());
1048             genObjects.back()->SetType(argument->GetType());
1049         }
1050         OperationFlags callFlags = OperationFlags::none;
1051         if (GetFlag(BoundExpressionFlags::virtualCall))
1052         {
1053             callFlags = callFlags | OperationFlags::virtualCall;
1054         }
1055         if (!delegateTypeSymbol->IsNothrow())
1056         {
1057             emitter.SetLineNumber(GetSpan().line);
1058         }
1059         delegateTypeSymbol->GenerateCall(emittergenObjectscallFlagsGetSpan()ModuleId());
1060         void* ptr = emitter.Stack().Pop();
1061         if ((flags & OperationFlags::leaveFirstArg) != OperationFlags::none)
1062         {
1063             emitter.SaveObjectPointer(ptr);
1064         }
1065         if ((flags & OperationFlags::deref) != OperationFlags::none || GetFlag(BoundExpressionFlags::deref))
1066         {
1067             uint8_t n = GetDerefCount(flags);
1068             for (uint8_t i = 1; i < n; ++i)
1069             {
1070                 ptr = emitter.CreateLoad(ptr);
1071             }
1072             emitter.CreateStore(valueptr);
1073         }
1074         else
1075         {
1076             emitter.CreateStore(emitter.CreateLoad(value)ptr);
1077         }
1078     }
1079     DestroyTemporaries(emitter);
1080 }
1081 
1082 void BoundDelegateCall::Accept(BoundNodeVisitor& visitor)
1083 {
1084     visitor.Visit(*this);
1085 }
1086 
1087 bool BoundDelegateCall::HasValue() const
1088 {
1089     return delegateTypeSymbol->ReturnType()->GetSymbolType() != SymbolType::voidTypeSymbol;
1090 }
1091 
1092 bool BoundDelegateCall::IsLvalueExpression() const
1093 {
1094     TypeSymbol* returnType = delegateTypeSymbol->ReturnType();
1095     if (returnType->GetSymbolType() != SymbolType::voidTypeSymbol)
1096     {
1097         return !returnType->IsConstType() && returnType->IsLvalueReferenceType();
1098     }
1099     return false;
1100 }
1101 
1102 void BoundDelegateCall::AddArgument(std::std::unique_ptr<BoundExpression>&&argument)
1103 {
1104     arguments.push_back(std::move(argument));
1105 }
1106 
1107 bool BoundDelegateCall::ContainsExceptionCapture() const
1108 {
1109     if (BoundExpression::ContainsExceptionCapture())
1110     {
1111         return true;
1112     }
1113     for (const std::std::unique_ptr<BoundExpression>&arg : arguments)
1114     {
1115         if (arg->ContainsExceptionCapture())
1116         {
1117             return true;
1118         }
1119     }
1120     return false;
1121 }
1122 
1123 BoundClassDelegateCall::BoundClassDelegateCall(const Span& span_const boost::uuids::uuid& moduleId_ClassDelegateTypeSymbol* classDelegateType_) :
1124     BoundExpression(span_moduleId_BoundNodeType::boundClassDelegateCallclassDelegateType_->ReturnType())classDelegateTypeSymbol(classDelegateType_)arguments()
1125 {
1126 }
1127 
1128 BoundExpression* BoundClassDelegateCall::Clone()
1129 {
1130     return new BoundClassDelegateCall(GetSpan()ModuleId()classDelegateTypeSymbol);
1131 }
1132 
1133 void BoundClassDelegateCall::Load(Emitter& emitterOperationFlags flags)
1134 {
1135     if ((flags & OperationFlags::addr) != OperationFlags::none)
1136     {
1137         throw Exception("cannot take address of a class delegate call"GetSpan()ModuleId());
1138     }
1139     else
1140     {
1141         std::vector<GenObject*> genObjects;
1142         for (const std::std::unique_ptr<BoundExpression>&argument : arguments)
1143         {
1144             genObjects.push_back(argument.get());
1145             genObjects.back()->SetType(argument->GetType());
1146         }
1147         OperationFlags callFlags = flags & OperationFlags::functionCallFlags;
1148         if (!classDelegateTypeSymbol->IsNothrow())
1149         {
1150             emitter.SetLineNumber(GetSpan().line);
1151         }
1152         classDelegateTypeSymbol->GenerateCall(emittergenObjectscallFlagsGetSpan()ModuleId());
1153         if ((flags & OperationFlags::deref) != OperationFlags::none)
1154         {
1155             void* value = emitter.Stack().Pop();
1156             uint8_t n = GetDerefCount(flags);
1157             for (uint8_t i = 0; i < n; ++i)
1158             {
1159                 value = emitter.CreateLoad(value);
1160             }
1161             emitter.Stack().Push(value);
1162         }
1163     }
1164     DestroyTemporaries(emitter);
1165 }
1166 
1167 void BoundClassDelegateCall::Store(Emitter& emitterOperationFlags flags)
1168 {
1169     if ((flags & OperationFlags::addr) != OperationFlags::none)
1170     {
1171         throw Exception("cannot take address of a clas delegate call"GetSpan()ModuleId());
1172     }
1173     else
1174     {
1175         void* value = emitter.Stack().Pop();
1176         std::vector<GenObject*> genObjects;
1177         for (const std::std::unique_ptr<BoundExpression>&argument : arguments)
1178         {
1179             genObjects.push_back(argument.get());
1180             genObjects.back()->SetType(argument->GetType());
1181         }
1182         OperationFlags callFlags = OperationFlags::none;
1183         if (GetFlag(BoundExpressionFlags::virtualCall))
1184         {
1185             callFlags = callFlags | OperationFlags::virtualCall;
1186         }
1187         if (!classDelegateTypeSymbol->IsNothrow())
1188         {
1189             emitter.SetLineNumber(GetSpan().line);
1190         }
1191         classDelegateTypeSymbol->GenerateCall(emittergenObjectscallFlagsGetSpan()ModuleId());
1192         void* ptr = emitter.Stack().Pop();
1193         if ((flags & OperationFlags::leaveFirstArg) != OperationFlags::none)
1194         {
1195             emitter.SaveObjectPointer(ptr);
1196         }
1197         if ((flags & OperationFlags::deref) != OperationFlags::none || GetFlag(BoundExpressionFlags::deref))
1198         {
1199             uint8_t n = GetDerefCount(flags);
1200             for (uint8_t i = 1; i < n; ++i)
1201             {
1202                 ptr = emitter.CreateLoad(ptr);
1203             }
1204             emitter.CreateStore(valueptr);
1205         }
1206         else
1207         {
1208             emitter.CreateStore(emitter.CreateLoad(value)ptr);
1209         }
1210     }
1211     DestroyTemporaries(emitter);
1212 }
1213 
1214 void BoundClassDelegateCall::Accept(BoundNodeVisitor& visitor)
1215 {
1216     visitor.Visit(*this);
1217 }
1218 
1219 bool BoundClassDelegateCall::HasValue() const
1220 {
1221     return classDelegateTypeSymbol->ReturnType()->GetSymbolType() != SymbolType::voidTypeSymbol;
1222 }
1223 
1224 bool BoundClassDelegateCall::IsLvalueExpression() const
1225 {
1226     TypeSymbol* returnType = classDelegateTypeSymbol->ReturnType();
1227     if (returnType->GetSymbolType() != SymbolType::voidTypeSymbol)
1228     {
1229         return !returnType->IsConstType() && returnType->IsLvalueReferenceType();
1230     }
1231     return false;
1232 }
1233 
1234 void BoundClassDelegateCall::AddArgument(std::std::unique_ptr<BoundExpression>&&argument)
1235 {
1236     arguments.push_back(std::move(argument));
1237 }
1238 
1239 bool BoundClassDelegateCall::ContainsExceptionCapture() const
1240 {
1241     if (BoundExpression::ContainsExceptionCapture())
1242     {
1243         return true;
1244     }
1245     for (const std::std::unique_ptr<BoundExpression>&arg : arguments)
1246     {
1247         if (arg->ContainsExceptionCapture())
1248         {
1249             return true;
1250         }
1251     }
1252     return false;
1253 }
1254 
1255 BoundConstructExpression::BoundConstructExpression(std::std::unique_ptr<BoundExpression>&&constructorCall_TypeSymbol*resultType_):
1256     BoundExpression(constructorCall_->GetSpan()constructorCall_->ModuleId()BoundNodeType::boundConstructExpressionresultType_)constructorCall(std::move(constructorCall_))
1257 {
1258     constructorCall->MoveTemporaryDestructorCallsTo(*this);
1259 }
1260 
1261 BoundExpression* BoundConstructExpression::Clone()
1262 {
1263     std::unique_ptr<BoundExpression> clonedConstructorCall;
1264     clonedConstructorCall.reset(constructorCall->Clone());
1265     return new BoundConstructExpression(std::move(clonedConstructorCall)GetType());
1266 }
1267 
1268 void BoundConstructExpression::Load(Emitter& emitterOperationFlags flags)
1269 {
1270     void* prevObjectPointer = emitter.GetObjectPointer();
1271     emitter.SetObjectPointer(nullptr);
1272     if ((flags & OperationFlags::addr) != OperationFlags::none)
1273     {
1274         throw Exception("cannot take address of a construct expression"GetSpan()ModuleId());
1275     }
1276     else
1277     {
1278         constructorCall->Load(emitterOperationFlags::leaveFirstArg);
1279         void* objectPointer = emitter.GetObjectPointer();
1280         if (!objectPointer)
1281         {
1282             throw Exception("do not have object pointer"GetSpan()ModuleId());
1283         }
1284         else
1285         {
1286             emitter.Stack().Push(objectPointer);
1287         }
1288     }
1289     DestroyTemporaries(emitter);
1290     emitter.SetObjectPointer(prevObjectPointer);
1291 }
1292 
1293 void BoundConstructExpression::Store(Emitter& emitterOperationFlags flags)
1294 {
1295     throw Exception("cannot store to construct expression"GetSpan()ModuleId());
1296 }
1297 
1298 void BoundConstructExpression::Accept(BoundNodeVisitor& visitor)
1299 {
1300     visitor.Visit(*this);
1301 }
1302 
1303 bool BoundConstructExpression::ContainsExceptionCapture() const
1304 {
1305     if (BoundExpression::ContainsExceptionCapture())
1306     {
1307         return true;
1308     }
1309     return constructorCall->ContainsExceptionCapture();
1310 }
1311 
1312 BoundConstructAndReturnTemporaryExpression::BoundConstructAndReturnTemporaryExpression(std::std::unique_ptr<BoundExpression>&&constructorCall_std::std::unique_ptr<BoundExpression>&&boundTemporary_):
1313     BoundExpression(constructorCall_->GetSpan()constructorCall_->ModuleId()BoundNodeType::boundConstructAndReturnTemporaryboundTemporary_->GetType())constructorCall(std::move(constructorCall_))
1314     boundTemporary(std::move(boundTemporary_))
1315 {
1316     constructorCall->MoveTemporaryDestructorCallsTo(*this);
1317     boundTemporary->MoveTemporaryDestructorCallsTo(*this);
1318 }
1319 
1320 BoundExpression* BoundConstructAndReturnTemporaryExpression::Clone()
1321 {
1322     return new BoundConstructAndReturnTemporaryExpression(std::unique_ptr<BoundExpression>(constructorCall->Clone())std::unique_ptr<BoundExpression>(boundTemporary->Clone()));
1323 }
1324 
1325 void BoundConstructAndReturnTemporaryExpression::Load(Emitter& emitterOperationFlags flags)
1326 {
1327     constructorCall->Load(emitterOperationFlags::none);
1328     if (boundTemporary->GetType()->IsClassTypeSymbol() || boundTemporary->GetType()->GetSymbolType() == SymbolType::classDelegateTypeSymbol)
1329     {
1330         flags = flags | OperationFlags::addr;
1331     }
1332     boundTemporary->Load(emitterflags);
1333     DestroyTemporaries(emitter);
1334 }
1335 
1336 void BoundConstructAndReturnTemporaryExpression::Store(Emitter& emitterOperationFlags flags)
1337 {
1338     throw Exception("cannot store to construct and return temporary expression"GetSpan()ModuleId());
1339 }
1340 
1341 void BoundConstructAndReturnTemporaryExpression::Accept(BoundNodeVisitor& visitor)
1342 {
1343     visitor.Visit(*this);
1344 }
1345 
1346 bool BoundConstructAndReturnTemporaryExpression::ContainsExceptionCapture() const
1347 {
1348     if (BoundExpression::ContainsExceptionCapture())
1349     {
1350         return true;
1351     }
1352     if (constructorCall->ContainsExceptionCapture())
1353     {
1354         return true;
1355     }
1356     if (boundTemporary->ContainsExceptionCapture())
1357     {
1358         return true;
1359     }
1360     return false;
1361 }
1362 
1363 BoundClassOrClassDelegateConversionResult::BoundClassOrClassDelegateConversionResult(std::std::unique_ptr<BoundExpression>&&conversionResult_std::std::unique_ptr<BoundFunctionCall>&&conversionFunctionCall_):
1364     BoundExpression(conversionResult_->GetSpan()conversionResult_->ModuleId()BoundNodeType::boundClassOrClassDelegateConversionResultconversionResult_->GetType())
1365     conversionResult(std::move(conversionResult_))conversionFunctionCall(std::move(conversionFunctionCall_))
1366 {
1367 }
1368 
1369 BoundExpression* BoundClassOrClassDelegateConversionResult::Clone()
1370 {
1371     return new BoundClassOrClassDelegateConversionResult(std::unique_ptr<BoundExpression>(conversionResult->Clone())
1372         std::unique_ptr<BoundFunctionCall>(static_cast<BoundFunctionCall*>(conversionFunctionCall->Clone())));
1373 }
1374 
1375 void BoundClassOrClassDelegateConversionResult::Load(Emitter& emitterOperationFlags flags)
1376 {
1377     conversionFunctionCall->Load(emitterOperationFlags::none);
1378     conversionResult->Load(emitterflags);
1379 }
1380 
1381 void BoundClassOrClassDelegateConversionResult::Store(Emitter& emitterOperationFlags flags)
1382 {
1383     throw Exception("cannot store to class conversion result"GetSpan()ModuleId());
1384 }
1385 
1386 void BoundClassOrClassDelegateConversionResult::Accept(BoundNodeVisitor& visitor)
1387 {
1388     visitor.Visit(*this);
1389 }
1390 
1391 bool BoundClassOrClassDelegateConversionResult::ContainsExceptionCapture() const
1392 {
1393     if (BoundExpression::ContainsExceptionCapture())
1394     {
1395         return true;
1396     }
1397     if (conversionResult->ContainsExceptionCapture())
1398     {
1399         return true;
1400     }
1401     if (conversionFunctionCall->ContainsExceptionCapture())
1402     {
1403         return true;
1404     }
1405     return false;
1406 }
1407 
1408 BoundConversion::BoundConversion(std::std::unique_ptr<BoundExpression>&&sourceExpr_FunctionSymbol*conversionFun_):
1409     BoundExpression(sourceExpr_->GetSpan()sourceExpr_->ModuleId()BoundNodeType::boundConversionconversionFun_->ConversionTargetType())sourceExpr(std::move(sourceExpr_))conversionFun(conversionFun_)
1410 {
1411     sourceExpr->MoveTemporaryDestructorCallsTo(*this);
1412 }
1413 
1414 void BoundConversion::AddTemporary(std::std::unique_ptr<BoundLocalVariable>&&temporary)
1415 {
1416     temporaries.push_back(std::move(temporary));
1417 }
1418 
1419 BoundExpression* BoundConversion::Clone()
1420 {
1421     std::unique_ptr<BoundExpression> clonedSourceExpr;
1422     clonedSourceExpr.reset(sourceExpr->Clone());
1423     BoundConversion* clone = new BoundConversion(std::move(clonedSourceExpr)conversionFun);
1424     for (const auto& p : temporaries)
1425     {
1426         clone->AddTemporary(std::unique_ptr<BoundLocalVariable>(static_cast<BoundLocalVariable*>(p->Clone())));
1427     }
1428     return clone;
1429 }
1430 
1431 void BoundConversion::Load(Emitter& emitterOperationFlags flags)
1432 {
1433     sourceExpr->Load(emitterflags);
1434     std::vector<GenObject*> genObjects;
1435     for (const std::std::unique_ptr<BoundLocalVariable>&temporary : temporaries)
1436     {
1437         genObjects.push_back(temporary.get());
1438         genObjects.back()->SetType(temporary->GetType());
1439     }
1440     conversionFun->GenerateCall(emittergenObjectsOperationFlags::noneGetSpan()ModuleId());
1441     DestroyTemporaries(emitter);
1442 }
1443 
1444 void BoundConversion::Store(Emitter& emitterOperationFlags flags)
1445 {
1446     throw Exception("cannot store to a conversion"GetSpan()ModuleId());
1447 }
1448 
1449 bool BoundConversion::IsLvalueExpression() const
1450 {
1451     if (conversionFun->GetSymbolType() == SymbolType::conversionFunctionSymbol) return true;
1452     if (conversionFun->IsClassToInterfaceTypeConversion()) return true;
1453     if (conversionFun->IsMemberFunctionToClassDelegateConversion()) return true;
1454     return false;
1455 }
1456 
1457 void BoundConversion::Accept(BoundNodeVisitor& visitor)
1458 {
1459     visitor.Visit(*this);
1460 }
1461 
1462 std::std::unique_ptr<Value>BoundConversion::ToValue(BoundCompileUnit&boundCompileUnit) const
1463 {
1464     std::unique_ptr<Value> sourceValue = sourceExpr->ToValue(boundCompileUnit);
1465     if (sourceValue)
1466     {
1467         return conversionFun->ConvertValue(sourceValue);
1468     }
1469     return std::unique_ptr<Value>();
1470 }
1471 
1472 bool BoundConversion::ContainsExceptionCapture() const
1473 {
1474     if (BoundExpression::ContainsExceptionCapture())
1475     {
1476         return true;
1477     }
1478     return sourceExpr->ContainsExceptionCapture();
1479 }
1480 
1481 BoundIsExpression::BoundIsExpression(std::std::unique_ptr<BoundExpression>&&expr_ClassTypeSymbol*rightClassType_TypeSymbol*boolType_
1482     std::std::unique_ptr<BoundLocalVariable>&&leftClassIdVar_std::std::unique_ptr<BoundLocalVariable>&&rightClassIdVar_):
1483     BoundExpression(expr_->GetSpan()expr_->ModuleId()BoundNodeType::boundIsExpressionboolType_)expr(std::move(expr_))rightClassType(rightClassType_)
1484     leftClassIdVar(std::move(leftClassIdVar_))rightClassIdVar(std::move(rightClassIdVar_))
1485 {
1486 }
1487 
1488 BoundExpression* BoundIsExpression::Clone()
1489 {
1490     std::unique_ptr<BoundExpression> clonedExpr;
1491     clonedExpr.reset(expr->Clone());
1492     return new BoundIsExpression(std::move(clonedExpr)rightClassTypeGetType()
1493         std::unique_ptr<BoundLocalVariable>(static_cast<BoundLocalVariable*>(leftClassIdVar->Clone()))
1494         std::unique_ptr<BoundLocalVariable>(static_cast<BoundLocalVariable*>(rightClassIdVar->Clone())));
1495 }
1496 
1497 void BoundIsExpression::Load(Emitter& emitterOperationFlags flags)
1498 {
1499     if (GetBackEnd() == BackEnd::llvm || GetBackEnd() == BackEnd::cmcpp)
1500     {
1501         expr->Load(emitterOperationFlags::none);
1502         void* thisPtr = emitter.Stack().Pop();
1503         TypeSymbol* exprType = static_cast<TypeSymbol*>(expr->GetType());
1504         Assert(exprType->IsPointerType()"pointer type expected");
1505         TypeSymbol* leftType = exprType->RemovePointer(GetSpan()ModuleId());
1506         Assert(leftType->IsClassTypeSymbol()"class type expected");
1507         ClassTypeSymbol* leftClassType = static_cast<ClassTypeSymbol*>(leftType);
1508         ClassTypeSymbol* leftVmtPtrHolderClass = leftClassType->VmtPtrHolderClass();
1509         if (leftClassType != leftVmtPtrHolderClass)
1510         {
1511             thisPtr = emitter.CreateBitCast(thisPtrleftVmtPtrHolderClass->AddPointer(GetSpan()ModuleId())->IrType(emitter));
1512         }
1513         void* vmtPtr = emitter.GetVmtPtr(thisPtrleftVmtPtrHolderClass->VmtPtrIndex()leftClassType->VmtPtrType(emitter));
1514         void* leftClassIdPtr = emitter.GetClassIdPtr(vmtPtrGetClassIdVmtIndexOffset());
1515         void* rightClassTypeVmtObject = rightClassType->VmtObject(emitterfalse);
1516         void* rightClassIdPtr = emitter.GetClassIdPtr(rightClassTypeVmtObjectGetClassIdVmtIndexOffset());
1517         void* retType = emitter.GetIrTypeForBool();
1518         std::vector<void*> paramTypes;
1519         paramTypes.push_back(emitter.GetIrTypeForVoidPtrType());
1520         paramTypes.push_back(emitter.GetIrTypeForVoidPtrType());
1521         void* dynamicInitAndCompareFnType = emitter.GetIrTypeForFunction(retTypeparamTypes);
1522         void* dynamicInitAndCompareFn = emitter.GetOrInsertFunction("DynamicInitVmtsAndCompare"dynamicInitAndCompareFnTypetrue);
1523         std::vector<void*> args;
1524         args.push_back(emitter.CreateBitCast(leftClassIdPtremitter.GetIrTypeForVoidPtrType()));
1525         args.push_back(emitter.CreateBitCast(rightClassIdPtremitter.GetIrTypeForVoidPtrType()));
1526         emitter.Stack().Push(emitter.CreateCall(dynamicInitAndCompareFnargs));
1527         DestroyTemporaries(emitter);
1528     }
1529     else if (GetBackEnd() == BackEnd::cmsx)
1530     {
1531         expr->Load(emitterOperationFlags::none);
1532         void* thisPtr = emitter.Stack().Pop();
1533         TypeSymbol* exprType = static_cast<TypeSymbol*>(expr->GetType());
1534         Assert(exprType->IsPointerType()"pointer type expected");
1535         TypeSymbol* leftType = exprType->RemovePointer(GetSpan()ModuleId());
1536         Assert(leftType->IsClassTypeSymbol()"class type expected");
1537         ClassTypeSymbol* leftClassType = static_cast<ClassTypeSymbol*>(leftType);
1538         ClassTypeSymbol* leftVmtPtrHolderClass = leftClassType->VmtPtrHolderClass();
1539         if (leftClassType != leftVmtPtrHolderClass)
1540         {
1541             thisPtr = emitter.CreateBitCast(thisPtrleftVmtPtrHolderClass->AddPointer(GetSpan()ModuleId())->IrType(emitter));
1542         }
1543         void* vmtPtr = emitter.GetVmtPtr(thisPtrleftVmtPtrHolderClass->VmtPtrIndex()leftClassType->VmtPtrType(emitter));
1544         void* leftClassIdPtr = emitter.GetClassIdPtr(vmtPtrGetClassIdVmtIndexOffset());
1545         void* leftClassId = emitter.CreatePtrToInt(emitter.CreateLoad(leftClassIdPtr)emitter.GetIrTypeForULong());
1546         void* rightClassTypeVmtObject = rightClassType->VmtObject(emitterfalse);
1547         void* rightClassIdPtr = emitter.GetClassIdPtr(rightClassTypeVmtObjectGetClassIdVmtIndexOffset());
1548         void* rightClassId = emitter.CreatePtrToInt(emitter.CreateLoad(rightClassIdPtr)emitter.GetIrTypeForULong());
1549         void* remainder = emitter.CreateURem(leftClassIdrightClassId);
1550         void* remainderIsZero = emitter.CreateICmpEQ(remainderemitter.CreateDefaultIrValueForULong());
1551         emitter.Stack().Push(remainderIsZero);
1552         DestroyTemporaries(emitter);
1553     }
1554 }
1555 
1556 void BoundIsExpression::Store(Emitter& emitterOperationFlags flags)
1557 {
1558     throw Exception("cannot store to a 'is' expression"GetSpan()ModuleId());
1559 }
1560 
1561 void BoundIsExpression::Accept(BoundNodeVisitor& visitor)
1562 {
1563     visitor.Visit(*this);
1564 }
1565 
1566 bool BoundIsExpression::ContainsExceptionCapture() const
1567 {
1568     if (BoundExpression::ContainsExceptionCapture())
1569     {
1570         return true;
1571     }
1572     return expr->ContainsExceptionCapture();
1573 }
1574 
1575 BoundAsExpression::BoundAsExpression(std::std::unique_ptr<BoundExpression>&&expr_ClassTypeSymbol*rightClassType_std::std::unique_ptr<BoundLocalVariable>&&variable_
1576     std::std::unique_ptr<BoundLocalVariable>&&leftClassIdVar_std::std::unique_ptr<BoundLocalVariable>&&rightClassIdVar_):
1577     BoundExpression(expr_->GetSpan()expr_->ModuleId()BoundNodeType::boundAsExpressionrightClassType_->AddPointer(expr_->GetSpan()expr_->ModuleId()))
1578     expr(std::move(expr_))rightClassType(rightClassType_)variable(std::move(variable_))
1579     leftClassIdVar(std::move(leftClassIdVar_))rightClassIdVar(std::move(rightClassIdVar_))
1580 {
1581 }
1582 
1583 BoundExpression* BoundAsExpression::Clone()
1584 {
1585     std::unique_ptr<BoundExpression> clonedExpr;
1586     clonedExpr.reset(expr->Clone());
1587     std::unique_ptr<BoundLocalVariable> clonedVariable;
1588     clonedVariable.reset(static_cast<BoundLocalVariable*>(variable->Clone()));
1589     return new BoundAsExpression(std::move(clonedExpr)rightClassTypestd::move(clonedVariable)
1590         std::unique_ptr<BoundLocalVariable>(static_cast<BoundLocalVariable*>(leftClassIdVar->Clone()))
1591         std::unique_ptr<BoundLocalVariable>(static_cast<BoundLocalVariable*>(rightClassIdVar->Clone())));
1592 }
1593 
1594 void BoundAsExpression::Load(Emitter& emitterOperationFlags flags)
1595 {
1596     if (GetBackEnd() == BackEnd::llvm || GetBackEnd() == BackEnd::cmcpp)
1597     {
1598         expr->Load(emitterOperationFlags::none);
1599         void* thisPtr = emitter.Stack().Pop();
1600         TypeSymbol* exprType = static_cast<TypeSymbol*>(expr->GetType());
1601         Assert(exprType->IsPointerType()"pointer type expected");
1602         TypeSymbol* leftType = exprType->RemovePointer(GetSpan()ModuleId());
1603         Assert(leftType->IsClassTypeSymbol()"class type expected");
1604         ClassTypeSymbol* leftClassType = static_cast<ClassTypeSymbol*>(leftType);
1605         ClassTypeSymbol* leftVmtPtrHolderClass = leftClassType->VmtPtrHolderClass();
1606         if (leftClassType != leftVmtPtrHolderClass)
1607         {
1608             thisPtr = emitter.CreateBitCast(thisPtrleftVmtPtrHolderClass->AddPointer(GetSpan()ModuleId())->IrType(emitter));
1609         }
1610         void* vmtPtr = emitter.GetVmtPtr(thisPtrleftVmtPtrHolderClass->VmtPtrIndex()leftClassType->VmtPtrType(emitter));
1611         void* leftClassIdPtr = emitter.GetClassIdPtr(vmtPtrGetClassIdVmtIndexOffset());
1612         void* rightClassTypeVmtObject = rightClassType->VmtObject(emitterfalse);
1613         void* rightClassIdPtr = emitter.GetClassIdPtr(rightClassTypeVmtObjectGetClassIdVmtIndexOffset());
1614 
1615         void* retType = emitter.GetIrTypeForBool();
1616         std::vector<void*> paramTypes;
1617         paramTypes.push_back(emitter.GetIrTypeForVoidPtrType());
1618         paramTypes.push_back(emitter.GetIrTypeForVoidPtrType());
1619         void* dynamicInitAndCompareFnType = emitter.GetIrTypeForFunction(retTypeparamTypes);
1620         void* dynamicInitAndCompareFn = emitter.GetOrInsertFunction("DynamicInitVmtsAndCompare"dynamicInitAndCompareFnTypetrue);
1621         std::vector<void*> args;
1622         args.push_back(emitter.CreateBitCast(leftClassIdPtremitter.GetIrTypeForVoidPtrType()));
1623         args.push_back(emitter.CreateBitCast(rightClassIdPtremitter.GetIrTypeForVoidPtrType()));
1624         emitter.Stack().Push(emitter.CreateCall(dynamicInitAndCompareFnargs));
1625         void* remainderIsZero = emitter.Stack().Pop();
1626         void* trueBlock = emitter.CreateBasicBlock("true");
1627         void* falseBlock = emitter.CreateBasicBlock("false");
1628         void* continueBlock = emitter.CreateBasicBlock("continue");
1629         emitter.CreateCondBr(remainderIsZerotrueBlockfalseBlock);
1630         emitter.SetCurrentBasicBlock(trueBlock);
1631         emitter.Stack().Push(emitter.CreateBitCast(thisPtrrightClassType->AddPointer(GetSpan()ModuleId())->IrType(emitter)));
1632         variable->Store(emitterOperationFlags::none);
1633         emitter.CreateBr(continueBlock);
1634         emitter.SetCurrentBasicBlock(falseBlock);
1635         emitter.Stack().Push(emitter.CreateDefaultIrValueForPtrType(rightClassType->AddPointer(GetSpan()ModuleId())->IrType(emitter)));
1636         variable->Store(emitterOperationFlags::none);
1637         emitter.CreateBr(continueBlock);
1638         emitter.SetCurrentBasicBlock(continueBlock);
1639         variable->Load(emitterOperationFlags::none);
1640         DestroyTemporaries(emitter);
1641     }
1642     else if (GetBackEnd() == BackEnd::cmsx)
1643     {
1644         expr->Load(emitterOperationFlags::none);
1645         void* thisPtr = emitter.Stack().Pop();
1646         TypeSymbol* exprType = static_cast<TypeSymbol*>(expr->GetType());
1647         Assert(exprType->IsPointerType()"pointer type expected");
1648         TypeSymbol* leftType = exprType->RemovePointer(GetSpan()ModuleId());
1649         Assert(leftType->IsClassTypeSymbol()"class type expected");
1650         ClassTypeSymbol* leftClassType = static_cast<ClassTypeSymbol*>(leftType);
1651         ClassTypeSymbol* leftVmtPtrHolderClass = leftClassType->VmtPtrHolderClass();
1652         if (leftClassType != leftVmtPtrHolderClass)
1653         {
1654             thisPtr = emitter.CreateBitCast(thisPtrleftVmtPtrHolderClass->AddPointer(GetSpan()ModuleId())->IrType(emitter));
1655         }
1656         void* vmtPtr = emitter.GetVmtPtr(thisPtrleftVmtPtrHolderClass->VmtPtrIndex()leftClassType->VmtPtrType(emitter));
1657         void* leftClassIdPtr = emitter.GetClassIdPtr(vmtPtrGetClassIdVmtIndexOffset());
1658         void* leftClassId = emitter.CreatePtrToInt(emitter.CreateLoad(leftClassIdPtr)emitter.GetIrTypeForULong());
1659         void* rightClassTypeVmtObject = rightClassType->VmtObject(emitterfalse);
1660         void* rightClassIdPtr = emitter.GetClassIdPtr(rightClassTypeVmtObjectGetClassIdVmtIndexOffset());
1661         void* rightClassId = emitter.CreatePtrToInt(emitter.CreateLoad(rightClassIdPtr)emitter.GetIrTypeForULong());
1662         void* remainder = emitter.CreateURem(leftClassIdrightClassId);
1663         void* remainderIsZero = emitter.CreateICmpEQ(remainderemitter.CreateDefaultIrValueForULong());
1664         void* trueBlock = emitter.CreateBasicBlock("true");
1665         void* falseBlock = emitter.CreateBasicBlock("false");
1666         void* continueBlock = emitter.CreateBasicBlock("continue");
1667         emitter.CreateCondBr(remainderIsZerotrueBlockfalseBlock);
1668         emitter.SetCurrentBasicBlock(trueBlock);
1669         emitter.Stack().Push(emitter.CreateBitCast(thisPtrrightClassType->AddPointer(GetSpan()ModuleId())->IrType(emitter)));
1670         variable->Store(emitterOperationFlags::none);
1671         emitter.CreateBr(continueBlock);
1672         emitter.SetCurrentBasicBlock(falseBlock);
1673         emitter.Stack().Push(emitter.CreateDefaultIrValueForPtrType(rightClassType->AddPointer(GetSpan()ModuleId())->IrType(emitter)));
1674         variable->Store(emitterOperationFlags::none);
1675         emitter.CreateBr(continueBlock);
1676         emitter.SetCurrentBasicBlock(continueBlock);
1677         variable->Load(emitterOperationFlags::none);
1678         DestroyTemporaries(emitter);
1679     }
1680 }
1681 
1682 void BoundAsExpression::Store(Emitter& emitterOperationFlags flags)
1683 {
1684     throw Exception("cannot store to an 'as' expression"GetSpan()ModuleId());
1685 }
1686 
1687 void BoundAsExpression::Accept(BoundNodeVisitor& visitor)
1688 {
1689     visitor.Visit(*this);
1690 }
1691 
1692 bool BoundAsExpression::ContainsExceptionCapture() const
1693 {
1694     if (BoundExpression::ContainsExceptionCapture())
1695     {
1696         return true;
1697     }
1698     return expr->ContainsExceptionCapture();
1699 }
1700 
1701 BoundTypeNameExpression::BoundTypeNameExpression(std::std::unique_ptr<BoundExpression>&&classPtr_TypeSymbol*constCharPtrType_):
1702     BoundExpression(classPtr_->GetSpan()classPtr_->ModuleId()BoundNodeType::boundTypeNameExpressionconstCharPtrType_)classPtr(std::move(classPtr_))
1703 {
1704     classPtr->MoveTemporaryDestructorCallsTo(*this);
1705 }
1706 
1707 BoundExpression* BoundTypeNameExpression::Clone()
1708 {
1709     std::unique_ptr<BoundExpression> clonedClassPtr;
1710     clonedClassPtr.reset(classPtr->Clone());
1711     return new BoundTypeNameExpression(std::move(clonedClassPtr)GetType());
1712 }
1713 
1714 void BoundTypeNameExpression::Load(Emitter& emitterOperationFlags flags)
1715 {
1716     classPtr->Load(emitterOperationFlags::none);
1717     void* thisPtr = emitter.Stack().Pop();
1718     TypeSymbol* classPtrType = static_cast<TypeSymbol*>(classPtr->GetType());
1719     Assert(classPtrType->IsPointerType()"pointer type expected");
1720     TypeSymbol* type = classPtrType->BaseType();
1721     Assert(type->IsClassTypeSymbol()"class type expected");
1722     ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type);
1723     ClassTypeSymbol* vmtPtrHolderClass = classType->VmtPtrHolderClass();
1724     if (classType != vmtPtrHolderClass)
1725     {
1726         thisPtr = emitter.CreateBitCast(thisPtrvmtPtrHolderClass->AddPointer(GetSpan()ModuleId())->IrType(emitter));
1727     }
1728     void* vmtPtr = emitter.GetVmtPtr(thisPtrvmtPtrHolderClass->VmtPtrIndex()classType->VmtPtrType(emitter));
1729     void* className = emitter.GetClassName(vmtPtrGetClassNameVmtIndexOffset());
1730     emitter.Stack().Push(className);
1731     DestroyTemporaries(emitter);
1732 }
1733 
1734 void BoundTypeNameExpression::Store(Emitter& emitterOperationFlags flags)
1735 {
1736     throw Exception("cannot store to typename expression"GetSpan()ModuleId());
1737 }
1738 
1739 void BoundTypeNameExpression::Accept(BoundNodeVisitor& visitor)
1740 {
1741     visitor.Visit(*this);
1742 }
1743 
1744 bool BoundTypeNameExpression::ContainsExceptionCapture() const
1745 {
1746     if (BoundExpression::ContainsExceptionCapture())
1747     {
1748         return true;
1749     }
1750     return classPtr->ContainsExceptionCapture();
1751 }
1752 
1753 BoundTypeIdExpression::BoundTypeIdExpression(std::std::unique_ptr<BoundExpression>&&classPtr_TypeSymbol*ulongType_):
1754     BoundExpression(classPtr_->GetSpan()classPtr_->ModuleId()BoundNodeType::boundTypeIdExpressionulongType_)classPtr(std::move(classPtr_))
1755 {
1756     classPtr->MoveTemporaryDestructorCallsTo(*this);
1757 }
1758 
1759 BoundExpression* BoundTypeIdExpression::Clone()
1760 {
1761     std::unique_ptr<BoundExpression> clonedClassPtr;
1762     clonedClassPtr.reset(classPtr->Clone());
1763     return new BoundTypeIdExpression(std::move(clonedClassPtr)GetType());
1764 }
1765 
1766 void BoundTypeIdExpression::Load(Emitter& emitterOperationFlags flags)
1767 {
1768     classPtr->Load(emitterOperationFlags::none);
1769     void* thisPtr = emitter.Stack().Pop();
1770     TypeSymbol* classPtrType = static_cast<TypeSymbol*>(classPtr->GetType());
1771     Assert(classPtrType->IsPointerType()"pointer type expected");
1772     TypeSymbol* type = classPtrType->BaseType();
1773     Assert(type->IsClassTypeSymbol()"class type expected");
1774     ClassTypeSymbol* classType = static_cast<ClassTypeSymbol*>(type);
1775     ClassTypeSymbol* vmtPtrHolderClass = classType->VmtPtrHolderClass();
1776     if (classType != vmtPtrHolderClass)
1777     {
1778         thisPtr = emitter.CreateBitCast(thisPtrvmtPtrHolderClass->AddPointer(GetSpan()ModuleId())->IrType(emitter));
1779     }
1780     void* vmtPtr = emitter.GetVmtPtr(thisPtrvmtPtrHolderClass->VmtPtrIndex()classType->VmtPtrType(emitter));
1781     void* classIdPtr = emitter.GetClassIdPtr(vmtPtrGetClassIdVmtIndexOffset());
1782     void* classId = emitter.CreatePtrToInt(emitter.CreateLoad(classIdPtr)emitter.GetIrTypeForULong());
1783     emitter.Stack().Push(classId);
1784     DestroyTemporaries(emitter);
1785 }
1786 
1787 void BoundTypeIdExpression::Store(Emitter& emitterOperationFlags flags)
1788 {
1789     throw Exception("cannot store to typeid expression"GetSpan()ModuleId());
1790 }
1791 
1792 void BoundTypeIdExpression::Accept(BoundNodeVisitor& visitor)
1793 {
1794     visitor.Visit(*this);
1795 }
1796 
1797 bool BoundTypeIdExpression::ContainsExceptionCapture() const
1798 {
1799     if (BoundExpression::ContainsExceptionCapture())
1800     {
1801         return true;
1802     }
1803     return classPtr->ContainsExceptionCapture();
1804 }
1805 
1806 BoundBitCast::BoundBitCast(std::std::unique_ptr<BoundExpression>&&expr_TypeSymbol*type_):
1807     BoundExpression(expr_->GetSpan()expr_->ModuleId()BoundNodeType::boundBitCasttype_)expr(std::move(expr_))
1808 {
1809     expr->MoveTemporaryDestructorCallsTo(*this);
1810 }
1811 
1812 BoundExpression* BoundBitCast::Clone()
1813 {
1814     return new BoundBitCast(std::unique_ptr<BoundExpression>(expr->Clone())GetType());
1815 }
1816 
1817 void BoundBitCast::Load(Emitter& emitterOperationFlags flags)
1818 {
1819     expr->Load(emitterOperationFlags::none);
1820     void* value = emitter.Stack().Pop();
1821     void* casted = emitter.CreateBitCast(valueGetType()->IrType(emitter));
1822     emitter.Stack().Push(casted);
1823     DestroyTemporaries(emitter);
1824 }
1825 
1826 void BoundBitCast::Store(Emitter& emitterOperationFlags flags)
1827 {
1828     throw Exception("cannot store to bit cast"GetSpan()ModuleId());
1829 }
1830 
1831 void BoundBitCast::Accept(BoundNodeVisitor& visitor)
1832 {
1833     visitor.Visit(*this);
1834 }
1835 
1836 bool BoundBitCast::ContainsExceptionCapture() const
1837 {
1838     if (BoundExpression::ContainsExceptionCapture())
1839     {
1840         return true;
1841     }
1842     return expr->ContainsExceptionCapture();
1843 }
1844 
1845 BoundFunctionPtr::BoundFunctionPtr(const Span& span_const boost::uuids::uuid& moduleId_FunctionSymbol* function_TypeSymbol* type_) :
1846     BoundExpression(span_moduleId_BoundNodeType::boundFunctionPtrtype_)function(function_)
1847 {
1848 }
1849 
1850 BoundExpression* BoundFunctionPtr::Clone()
1851 {
1852     return new BoundFunctionPtr(GetSpan()ModuleId()functionGetType());
1853 }
1854 
1855 void BoundFunctionPtr::Load(Emitter& emitterOperationFlags flags)
1856 {
1857     void* irObject = emitter.GetOrInsertFunction(ToUtf8(function->MangledName())function->IrType(emitter)function->DontThrow());
1858     emitter.Stack().Push(irObject);
1859     DestroyTemporaries(emitter);
1860 }
1861 
1862 void BoundFunctionPtr::Store(Emitter& emitterOperationFlags flags)
1863 {
1864     throw Exception("cannot store to function ptr expression"GetSpan()ModuleId());
1865 }
1866 
1867 void BoundFunctionPtr::Accept(BoundNodeVisitor& visitor)
1868 {
1869     visitor.Visit(*this);
1870 }
1871 
1872 BoundDisjunction::BoundDisjunction(const Span& span_const boost::uuids::uuid& moduleId_std::std::unique_ptr<BoundExpression>&&left_std::std::unique_ptr<BoundExpression>&&right_TypeSymbol*boolType_):
1873     BoundExpression(span_moduleId_BoundNodeType::boundDisjunctionboolType_)left(std::move(left_))right(std::move(right_))
1874 {
1875 }
1876 
1877 BoundExpression* BoundDisjunction::Clone()
1878 {
1879     return new BoundDisjunction(GetSpan()ModuleId()std::unique_ptr<BoundExpression>(left->Clone())std::unique_ptr<BoundExpression>(right->Clone())GetType());
1880 }
1881 
1882 void BoundDisjunction::Load(Emitter& emitterOperationFlags flags)
1883 {
1884     temporary->Load(emitterOperationFlags::addr);
1885     void* temp = emitter.Stack().Pop();
1886     left->Load(emitterOperationFlags::none);
1887     void* leftValue = emitter.Stack().Pop();
1888     void* trueBlock = emitter.CreateBasicBlock("true");
1889     void* rightBlock = emitter.CreateBasicBlock("right");
1890     void* falseBlock = emitter.CreateBasicBlock("false");
1891     void* nextBlock = emitter.CreateBasicBlock("next");
1892     emitter.CreateCondBr(leftValuetrueBlockrightBlock);
1893     emitter.SetCurrentBasicBlock(rightBlock);
1894     right->Load(emitterOperationFlags::none);
1895     void* rightValue = emitter.Stack().Pop();
1896     emitter.CreateCondBr(rightValuetrueBlockfalseBlock);
1897     emitter.SetCurrentBasicBlock(trueBlock);
1898     emitter.CreateStore(emitter.CreateIrValueForBool(true)temp);
1899     emitter.CreateBr(nextBlock);
1900     emitter.SetCurrentBasicBlock(falseBlock);
1901     emitter.CreateStore(emitter.CreateIrValueForBool(false)temp);
1902     emitter.CreateBr(nextBlock);
1903     emitter.SetCurrentBasicBlock(nextBlock);
1904     void* value = emitter.CreateLoad(temp);
1905     emitter.Stack().Push(value);
1906     DestroyTemporaries(emitter);
1907 }
1908 
1909 void BoundDisjunction::Store(Emitter& emitterOperationFlags flags)
1910 {
1911     throw Exception("cannot store to disjunction"GetSpan()ModuleId());
1912 }
1913 
1914 void BoundDisjunction::Accept(BoundNodeVisitor& visitor)
1915 {
1916     visitor.Visit(*this);
1917 }
1918 
1919 void BoundDisjunction::SetTemporary(BoundLocalVariable* temporary_)
1920 {
1921     temporary.reset(temporary_);
1922 }
1923 
1924 bool BoundDisjunction::ContainsExceptionCapture() const
1925 {
1926     if (BoundExpression::ContainsExceptionCapture())
1927     {
1928         return true;
1929     }
1930     if (left->ContainsExceptionCapture())
1931     {
1932         return true;
1933     }
1934     if (right->ContainsExceptionCapture())
1935     {
1936         return true;
1937     }
1938     return false;
1939 }
1940 
1941 BoundConjunction::BoundConjunction(const Span& span_const boost::uuids::uuid& moduleId_std::std::unique_ptr<BoundExpression>&&left_std::std::unique_ptr<BoundExpression>&&right_TypeSymbol*boolType_):
1942     BoundExpression(span_moduleId_BoundNodeType::boundConjunctionboolType_)left(std::move(left_))right(std::move(right_))
1943 {
1944 }
1945 
1946 BoundExpression* BoundConjunction::Clone()
1947 {
1948     return new BoundConjunction(GetSpan()ModuleId()std::unique_ptr<BoundExpression>(left->Clone())std::unique_ptr<BoundExpression>(right->Clone())GetType());
1949 }
1950 
1951 void BoundConjunction::Load(Emitter& emitterOperationFlags flags)
1952 {
1953     temporary->Load(emitterOperationFlags::addr);
1954     void* temp = emitter.Stack().Pop();
1955     left->Load(emitterOperationFlags::none);
1956     void* leftValue = emitter.Stack().Pop();
1957     void* trueBlock = emitter.CreateBasicBlock("true");
1958     void* rightBlock = emitter.CreateBasicBlock("right");
1959     void* falseBlock = emitter.CreateBasicBlock("false");
1960     void* nextBlock = emitter.CreateBasicBlock("next");
1961     emitter.CreateCondBr(leftValuerightBlockfalseBlock);
1962     emitter.SetCurrentBasicBlock(rightBlock);
1963     right->Load(emitterOperationFlags::none);
1964     void* rightValue = emitter.Stack().Pop();
1965     emitter.CreateCondBr(rightValuetrueBlockfalseBlock);
1966     emitter.SetCurrentBasicBlock(trueBlock);
1967     emitter.CreateStore(emitter.CreateIrValueForBool(true)temp);
1968     emitter.CreateBr(nextBlock);
1969     emitter.SetCurrentBasicBlock(falseBlock);
1970     emitter.CreateStore(emitter.CreateIrValueForBool(false)temp);
1971     emitter.CreateBr(nextBlock);
1972     emitter.SetCurrentBasicBlock(nextBlock);
1973     void* value = emitter.CreateLoad(temp);
1974     emitter.Stack().Push(value);
1975     DestroyTemporaries(emitter);
1976 }
1977 
1978 void BoundConjunction::Store(Emitter& emitterOperationFlags flags)
1979 {
1980     throw Exception("cannot store to conjunction"GetSpan()ModuleId());
1981 }
1982 
1983 void BoundConjunction::Accept(BoundNodeVisitor& visitor)
1984 {
1985     visitor.Visit(*this);
1986 }
1987 
1988 void BoundConjunction::SetTemporary(BoundLocalVariable* temporary_)
1989 {
1990     temporary.reset(temporary_);
1991 }
1992 
1993 bool BoundConjunction::ContainsExceptionCapture() const
1994 {
1995     if (BoundExpression::ContainsExceptionCapture())
1996     {
1997         return true;
1998     }
1999     if (left->ContainsExceptionCapture())
2000     {
2001         return true;
2002     }
2003     if (right->ContainsExceptionCapture())
2004     {
2005         return true;
2006     }
2007     return false;
2008 }
2009 
2010 BoundTypeExpression::BoundTypeExpression(const Span& span_const boost::uuids::uuid& moduleId_TypeSymbol* type_) :
2011     BoundExpression(span_moduleId_BoundNodeType::boundTypeExpressiontype_)
2012 {
2013 }
2014 
2015 BoundExpression* BoundTypeExpression::Clone()
2016 {
2017     return new BoundTypeExpression(GetSpan()ModuleId()GetType());
2018 }
2019 
2020 void BoundTypeExpression::Load(Emitter& emitterOperationFlags flags)
2021 {
2022     throw Exception("cannot load from a type"GetSpan()ModuleId());
2023 }
2024 
2025 void BoundTypeExpression::Store(Emitter& emitterOperationFlags flags)
2026 {
2027     throw Exception("cannot store to a type"GetSpan()ModuleId());
2028 }
2029 
2030 void BoundTypeExpression::Accept(BoundNodeVisitor& visitor)
2031 {
2032     throw Exception("cannot visit a type"GetSpan()ModuleId());
2033 }
2034 
2035 TypeSymbol* CreateNamespaceTypeSymbol(NamespaceSymbol* ns)
2036 {
2037     TypeSymbol* nsTypeSymbol = new NamespaceTypeSymbol(ns);
2038     ns->GetModule()->GetSymbolTable().SetTypeIdFor(nsTypeSymbol);
2039     return nsTypeSymbol;
2040 }
2041 
2042 BoundNamespaceExpression::BoundNamespaceExpression(const Span& span_const boost::uuids::uuid& moduleId_NamespaceSymbol* ns_) :
2043     BoundExpression(span_moduleId_BoundNodeType::boundNamespaceExpressionCreateNamespaceTypeSymbol(ns_))ns(ns_)
2044 {
2045     nsType.reset(GetType());
2046 }
2047 
2048 BoundExpression* BoundNamespaceExpression::Clone()
2049 {
2050     return new BoundNamespaceExpression(GetSpan()ModuleId()ns);
2051 }
2052 
2053 void BoundNamespaceExpression::Load(Emitter& emitterOperationFlags flags)
2054 {
2055     throw Exception("cannot load from a namespace"GetSpan()ModuleId());
2056 }
2057 
2058 void BoundNamespaceExpression::Store(Emitter& emitterOperationFlags flags)
2059 {
2060     throw Exception("cannot store to a namespace"GetSpan()ModuleId());
2061 }
2062 
2063 void BoundNamespaceExpression::Accept(BoundNodeVisitor& visitor)
2064 {
2065     throw Exception("cannot visit a namespace"GetSpan()ModuleId());
2066 }
2067 
2068 TypeSymbol* CreateFunctionGroupTypeSymbol(FunctionGroupSymbol* functionGroupSymbolvoid* boundFunctionGroupExpression)
2069 {
2070     TypeSymbol* functionGroupTypeSymbol = new FunctionGroupTypeSymbol(functionGroupSymbolboundFunctionGroupExpression);
2071     functionGroupTypeSymbol->SetModule(functionGroupSymbol->GetModule());
2072     functionGroupSymbol->GetModule()->GetSymbolTable().SetTypeIdFor(functionGroupTypeSymbol);
2073     return functionGroupTypeSymbol;
2074 }
2075 
2076 BoundFunctionGroupExpression::BoundFunctionGroupExpression(const Span& span_const boost::uuids::uuid& moduleId_FunctionGroupSymbol* functionGroupSymbol_) :
2077     BoundExpression(span_moduleId_BoundNodeType::boundFunctionGroupExpressionCreateFunctionGroupTypeSymbol(functionGroupSymbol_this))
2078     functionGroupSymbol(functionGroupSymbol_)scopeQualified(false)qualifiedScope(nullptr)
2079 {
2080     functionGroupType.reset(GetType());
2081 }
2082 
2083 BoundExpression* BoundFunctionGroupExpression::Clone()
2084 {
2085     BoundFunctionGroupExpression* clone = new BoundFunctionGroupExpression(GetSpan()ModuleId()functionGroupSymbol);
2086     if (classPtr)
2087     {
2088         clone->classPtr.reset(classPtr->Clone());
2089     }
2090     clone->scopeQualified = scopeQualified;
2091     clone->qualifiedScope = qualifiedScope;
2092     return clone;
2093 }
2094 
2095 void BoundFunctionGroupExpression::Load(Emitter& emitterOperationFlags flags)
2096 {
2097     if (classPtr)
2098     {
2099         classPtr->Load(emitterOperationFlags::none);
2100     }
2101     else
2102     {
2103         emitter.Stack().Push(nullptr);
2104     }
2105 }
2106 
2107 void BoundFunctionGroupExpression::Store(Emitter& emitterOperationFlags flags)
2108 {
2109     throw Exception("cannot store to a function group"GetSpan()ModuleId());
2110 }
2111 
2112 void BoundFunctionGroupExpression::Accept(BoundNodeVisitor& visitor)
2113 {
2114     throw Exception("cannot visit a function group"GetSpan()ModuleId());
2115 }
2116 
2117 void BoundFunctionGroupExpression::SetClassPtr(std::std::unique_ptr<BoundExpression>&&classPtr_)
2118 {
2119     classPtr = std::move(classPtr_);
2120 }
2121 
2122 void BoundFunctionGroupExpression::SetTemplateArgumentTypes(const std::std::vector<TypeSymbol*>&templateArgumentTypes_)
2123 {
2124     templateArgumentTypes = templateArgumentTypes_;
2125 }
2126 
2127 TypeSymbol* CreateMemberExpressionTypeSymbol(const Span& spanconst boost::uuids::uuid& moduleId_const std::u32string& namevoid* boundMemberExpression)
2128 {
2129     TypeSymbol* memberExpressionTypeSymbol = new MemberExpressionTypeSymbol(spanmoduleId_nameboundMemberExpression);
2130     Module* module = GetRootModuleForCurrentThread();
2131     memberExpressionTypeSymbol->SetModule(module);
2132     module->GetSymbolTable().SetTypeIdFor(memberExpressionTypeSymbol);
2133     return memberExpressionTypeSymbol;
2134 }
2135 
2136 BoundMemberExpression::BoundMemberExpression(const Span& span_const boost::uuids::uuid& moduleId_std::std::unique_ptr<BoundExpression>&&classPtr_std::std::unique_ptr<BoundExpression>&&member_):
2137     BoundExpression(span_moduleId_BoundNodeType::boundMemberExpressionCreateMemberExpressionTypeSymbol(span_member_->ModuleId()member_->GetType()->Name()this))classPtr(std::move(classPtr_))member(std::move(member_))
2138 {
2139     memberExpressionType.reset(GetType());
2140     classPtr->MoveTemporaryDestructorCallsTo(*this);
2141 }
2142 
2143 BoundExpression* BoundMemberExpression::Clone()
2144 {
2145     return new BoundMemberExpression(GetSpan()ModuleId()std::unique_ptr<BoundExpression>(classPtr->Clone())std::unique_ptr<BoundExpression>(member->Clone()));
2146 }
2147 
2148 void BoundMemberExpression::Load(Emitter& emitterOperationFlags flags)
2149 {
2150     if (classPtr)
2151     {
2152         classPtr->Load(emitterOperationFlags::none);
2153     }
2154     else
2155     {
2156         emitter.Stack().Push(nullptr);
2157     }
2158 }
2159 
2160 void BoundMemberExpression::Store(Emitter& emitterOperationFlags flags)
2161 {
2162     throw Exception("cannot store to a member expression"GetSpan()ModuleId());
2163 }
2164 
2165 void BoundMemberExpression::Accept(BoundNodeVisitor& visitor)
2166 {
2167     throw Exception("cannot visit a member expression"GetSpan()ModuleId());
2168 }
2169 
2170 } } // namespace cmajor::binder