1
2
3
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(emitter, OperationFlags::none);
49 }
50 }
51
52 BoundParameter::BoundParameter(const Span& span_, const boost::uuids::uuid& moduleId_, ParameterSymbol* parameterSymbol_) :
53 BoundExpression(span_, moduleId_, BoundNodeType::boundParameter, parameterSymbol_->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& emitter, OperationFlags 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& emitter, OperationFlags 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(value, ptr);
103 }
104 else
105 {
106 emitter.CreateStore(value, parameterSymbol->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::boundLocalVariable, localVariableSymbol_->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& emitter, OperationFlags 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& emitter, OperationFlags 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(value, ptr);
167 }
168 else
169 {
170 emitter.CreateStore(value, localVariableSymbol->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::boundMemberVariable, memberVariableSymbol_->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& emitter, OperationFlags 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(emitter, OperationFlags::none);
213 }
214 }
215 emitter.Stack().Push(classType->StaticObject(emitter, false));
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(emitter, OperationFlags::none);
224 }
225 void* ptr = emitter.Stack().Pop();
226 void* memberVariablePtr = emitter.GetMemberVariablePtr(ptr, memberVariableSymbol->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& emitter, OperationFlags 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(emitter, OperationFlags::none);
268 }
269 }
270 emitter.Stack().Push(classType->StaticObject(emitter, false));
271 }
272 else
273 {
274 classPtr->Load(emitter, OperationFlags::none);
275 }
276 void* ptr = emitter.Stack().Pop();
277 void* memberVariablePtr = emitter.GetMemberVariablePtr(ptr, memberVariableSymbol->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(value, ptr);
287 }
288 else
289 {
290 emitter.CreateStore(value, memberVariablePtr);
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::boundConstant, constantSymbol_->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& emitter, OperationFlags 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(emitter, false));
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& emitter, OperationFlags 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::boundEnumConstant, enumConstantSymbol_->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& emitter, OperationFlags 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& emitter, OperationFlags 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::boundLiteral, type_), 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& emitter, OperationFlags 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& emitter, OperationFlags 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::boundGlobalVariable, globalVariableSymbol_->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& emitter, OperationFlags 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& emitter, OperationFlags 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(value, loadedPtr);
489 }
490 else
491 {
492 emitter.CreateStore(value, ptr);
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::boundTemporary, rvalueExpr_->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& emitter, OperationFlags flags)
526 {
527 rvalueExpr->Load(emitter, OperationFlags::none);
528 if (!backingStore)
529 {
530 throw Exception("backing store of temporary not set", GetSpan(), ModuleId());
531 }
532 backingStore->Store(emitter, OperationFlags::none);
533 if ((flags & OperationFlags::addr) != OperationFlags::none)
534 {
535 backingStore->Load(emitter, OperationFlags::addr);
536 }
537 else if ((flags & OperationFlags::deref) != OperationFlags::none)
538 {
539 backingStore->Load(emitter, SetDerefCount(OperationFlags::deref, GetDerefCount(flags) + 1));
540 }
541 else
542 {
543 backingStore->Load(emitter, OperationFlags::none);
544 }
545 DestroyTemporaries(emitter);
546 }
547
548 void BoundTemporary::Store(Emitter& emitter, OperationFlags 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::boundSizeOfExpression, type_), 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& emitter, OperationFlags 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& emitter, OperationFlags 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::boundAddressOfExpression, type_), 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& emitter, OperationFlags flags)
627 {
628 if (subject->GetBoundNodeType() != BoundNodeType::boundDereferenceExpression)
629 {
630 subject->Load(emitter, OperationFlags::addr);
631 }
632 else
633 {
634 BoundDereferenceExpression* derefExpr = static_cast<BoundDereferenceExpression*>(subject.get());
635 derefExpr->Subject()->Load(emitter, flags);
636 }
637 DestroyTemporaries(emitter);
638 }
639
640 void BoundAddressOfExpression::Store(Emitter& emitter, OperationFlags flags)
641 {
642 if (subject->GetBoundNodeType() != BoundNodeType::boundDereferenceExpression)
643 {
644 subject->Store(emitter, flags);
645 }
646 else
647 {
648 BoundDereferenceExpression* derefExpr = static_cast<BoundDereferenceExpression*>(subject.get());
649 derefExpr->Subject()->Store(emitter, flags);
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::boundDereferenceExpression, type_), 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& emitter, OperationFlags flags)
691 {
692 if (subject->GetBoundNodeType() != BoundNodeType::boundAddressOfExpression)
693 {
694 if (GetDerefCount(flags) == 0 && (flags & OperationFlags::addr) != OperationFlags::none)
695 {
696 subject->Load(emitter, OperationFlags::none);
697 }
698 else
699 {
700 subject->Load(emitter, SetDerefCount(OperationFlags::deref, GetDerefCount(flags) + 1));
701 }
702 }
703 else
704 {
705 BoundAddressOfExpression* addressOfExpr = static_cast<BoundAddressOfExpression*>(subject.get());
706 addressOfExpr->Subject()->Load(emitter, flags);
707 }
708 DestroyTemporaries(emitter);
709 }
710
711 void BoundDereferenceExpression::Store(Emitter& emitter, OperationFlags flags)
712 {
713 if (subject->GetBoundNodeType() != BoundNodeType::boundAddressOfExpression)
714 {
715 subject->Store(emitter, SetDerefCount(OperationFlags::deref | (flags & OperationFlags::functionCallFlags), GetDerefCount(flags) + 1));
716 }
717 else
718 {
719 BoundAddressOfExpression* addressOfExpr = static_cast<BoundAddressOfExpression*>(subject.get());
720 addressOfExpr->Subject()->Store(emitter, flags | (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::boundReferenceToPointerExpression, type_), 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& emitter, OperationFlags flags)
757 {
758 subject->Load(emitter, flags);
759 DestroyTemporaries(emitter);
760 }
761
762 void BoundReferenceToPointerExpression::Store(Emitter& emitter, OperationFlags flags)
763 {
764 subject->Store(emitter, flags);
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::boundFunctionCall, functionSymbol_->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& emitter, OperationFlags 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(emitter, genObjects, flags, GetSpan(), 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(emitter, genObjects, callFlags, interfaceMemberFunction, GetSpan(), ModuleId());
895 }
896 else
897 {
898 functionSymbol->GenerateCall(emitter, genObjects, callFlags, GetSpan(), 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& emitter, OperationFlags 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(emitter, genObjects, callFlags | OperationFlags::addr, GetSpan(), ModuleId());
941 void* ptr = emitter.Stack().Pop();
942 emitter.CreateStore(value, ptr);
943 }
944 else
945 {
946 functionSymbol->GenerateCall(emitter, genObjects, callFlags, GetSpan(), 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(value, ptr);
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::boundDelegateCall, delegateType_->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& emitter, OperationFlags 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(emitter, genObjects, callFlags, GetSpan(), 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& emitter, OperationFlags 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(emitter, genObjects, callFlags, GetSpan(), 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(value, ptr);
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::boundClassDelegateCall, classDelegateType_->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& emitter, OperationFlags 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(emitter, genObjects, callFlags, GetSpan(), 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& emitter, OperationFlags 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(emitter, genObjects, callFlags, GetSpan(), 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(value, ptr);
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::boundConstructExpression, resultType_), 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& emitter, OperationFlags 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(emitter, OperationFlags::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& emitter, OperationFlags 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::boundConstructAndReturnTemporary, boundTemporary_->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& emitter, OperationFlags flags)
1326 {
1327 constructorCall->Load(emitter, OperationFlags::none);
1328 if (boundTemporary->GetType()->IsClassTypeSymbol() || boundTemporary->GetType()->GetSymbolType() == SymbolType::classDelegateTypeSymbol)
1329 {
1330 flags = flags | OperationFlags::addr;
1331 }
1332 boundTemporary->Load(emitter, flags);
1333 DestroyTemporaries(emitter);
1334 }
1335
1336 void BoundConstructAndReturnTemporaryExpression::Store(Emitter& emitter, OperationFlags 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::boundClassOrClassDelegateConversionResult, conversionResult_->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& emitter, OperationFlags flags)
1376 {
1377 conversionFunctionCall->Load(emitter, OperationFlags::none);
1378 conversionResult->Load(emitter, flags);
1379 }
1380
1381 void BoundClassOrClassDelegateConversionResult::Store(Emitter& emitter, OperationFlags 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::boundConversion, conversionFun_->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& emitter, OperationFlags flags)
1432 {
1433 sourceExpr->Load(emitter, flags);
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(emitter, genObjects, OperationFlags::none, GetSpan(), ModuleId());
1441 DestroyTemporaries(emitter);
1442 }
1443
1444 void BoundConversion::Store(Emitter& emitter, OperationFlags 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::boundIsExpression, boolType_), 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), rightClassType, GetType(),
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& emitter, OperationFlags flags)
1498 {
1499 if (GetBackEnd() == BackEnd::llvm || GetBackEnd() == BackEnd::cmcpp)
1500 {
1501 expr->Load(emitter, OperationFlags::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(thisPtr, leftVmtPtrHolderClass->AddPointer(GetSpan(), ModuleId())->IrType(emitter));
1512 }
1513 void* vmtPtr = emitter.GetVmtPtr(thisPtr, leftVmtPtrHolderClass->VmtPtrIndex(), leftClassType->VmtPtrType(emitter));
1514 void* leftClassIdPtr = emitter.GetClassIdPtr(vmtPtr, GetClassIdVmtIndexOffset());
1515 void* rightClassTypeVmtObject = rightClassType->VmtObject(emitter, false);
1516 void* rightClassIdPtr = emitter.GetClassIdPtr(rightClassTypeVmtObject, GetClassIdVmtIndexOffset());
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(retType, paramTypes);
1522 void* dynamicInitAndCompareFn = emitter.GetOrInsertFunction("DynamicInitVmtsAndCompare", dynamicInitAndCompareFnType, true);
1523 std::vector<void*> args;
1524 args.push_back(emitter.CreateBitCast(leftClassIdPtr, emitter.GetIrTypeForVoidPtrType()));
1525 args.push_back(emitter.CreateBitCast(rightClassIdPtr, emitter.GetIrTypeForVoidPtrType()));
1526 emitter.Stack().Push(emitter.CreateCall(dynamicInitAndCompareFn, args));
1527 DestroyTemporaries(emitter);
1528 }
1529 else if (GetBackEnd() == BackEnd::cmsx)
1530 {
1531 expr->Load(emitter, OperationFlags::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(thisPtr, leftVmtPtrHolderClass->AddPointer(GetSpan(), ModuleId())->IrType(emitter));
1542 }
1543 void* vmtPtr = emitter.GetVmtPtr(thisPtr, leftVmtPtrHolderClass->VmtPtrIndex(), leftClassType->VmtPtrType(emitter));
1544 void* leftClassIdPtr = emitter.GetClassIdPtr(vmtPtr, GetClassIdVmtIndexOffset());
1545 void* leftClassId = emitter.CreatePtrToInt(emitter.CreateLoad(leftClassIdPtr), emitter.GetIrTypeForULong());
1546 void* rightClassTypeVmtObject = rightClassType->VmtObject(emitter, false);
1547 void* rightClassIdPtr = emitter.GetClassIdPtr(rightClassTypeVmtObject, GetClassIdVmtIndexOffset());
1548 void* rightClassId = emitter.CreatePtrToInt(emitter.CreateLoad(rightClassIdPtr), emitter.GetIrTypeForULong());
1549 void* remainder = emitter.CreateURem(leftClassId, rightClassId);
1550 void* remainderIsZero = emitter.CreateICmpEQ(remainder, emitter.CreateDefaultIrValueForULong());
1551 emitter.Stack().Push(remainderIsZero);
1552 DestroyTemporaries(emitter);
1553 }
1554 }
1555
1556 void BoundIsExpression::Store(Emitter& emitter, OperationFlags 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::boundAsExpression, rightClassType_->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), rightClassType, std::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& emitter, OperationFlags flags)
1595 {
1596 if (GetBackEnd() == BackEnd::llvm || GetBackEnd() == BackEnd::cmcpp)
1597 {
1598 expr->Load(emitter, OperationFlags::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(thisPtr, leftVmtPtrHolderClass->AddPointer(GetSpan(), ModuleId())->IrType(emitter));
1609 }
1610 void* vmtPtr = emitter.GetVmtPtr(thisPtr, leftVmtPtrHolderClass->VmtPtrIndex(), leftClassType->VmtPtrType(emitter));
1611 void* leftClassIdPtr = emitter.GetClassIdPtr(vmtPtr, GetClassIdVmtIndexOffset());
1612 void* rightClassTypeVmtObject = rightClassType->VmtObject(emitter, false);
1613 void* rightClassIdPtr = emitter.GetClassIdPtr(rightClassTypeVmtObject, GetClassIdVmtIndexOffset());
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(retType, paramTypes);
1620 void* dynamicInitAndCompareFn = emitter.GetOrInsertFunction("DynamicInitVmtsAndCompare", dynamicInitAndCompareFnType, true);
1621 std::vector<void*> args;
1622 args.push_back(emitter.CreateBitCast(leftClassIdPtr, emitter.GetIrTypeForVoidPtrType()));
1623 args.push_back(emitter.CreateBitCast(rightClassIdPtr, emitter.GetIrTypeForVoidPtrType()));
1624 emitter.Stack().Push(emitter.CreateCall(dynamicInitAndCompareFn, args));
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(remainderIsZero, trueBlock, falseBlock);
1630 emitter.SetCurrentBasicBlock(trueBlock);
1631 emitter.Stack().Push(emitter.CreateBitCast(thisPtr, rightClassType->AddPointer(GetSpan(), ModuleId())->IrType(emitter)));
1632 variable->Store(emitter, OperationFlags::none);
1633 emitter.CreateBr(continueBlock);
1634 emitter.SetCurrentBasicBlock(falseBlock);
1635 emitter.Stack().Push(emitter.CreateDefaultIrValueForPtrType(rightClassType->AddPointer(GetSpan(), ModuleId())->IrType(emitter)));
1636 variable->Store(emitter, OperationFlags::none);
1637 emitter.CreateBr(continueBlock);
1638 emitter.SetCurrentBasicBlock(continueBlock);
1639 variable->Load(emitter, OperationFlags::none);
1640 DestroyTemporaries(emitter);
1641 }
1642 else if (GetBackEnd() == BackEnd::cmsx)
1643 {
1644 expr->Load(emitter, OperationFlags::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(thisPtr, leftVmtPtrHolderClass->AddPointer(GetSpan(), ModuleId())->IrType(emitter));
1655 }
1656 void* vmtPtr = emitter.GetVmtPtr(thisPtr, leftVmtPtrHolderClass->VmtPtrIndex(), leftClassType->VmtPtrType(emitter));
1657 void* leftClassIdPtr = emitter.GetClassIdPtr(vmtPtr, GetClassIdVmtIndexOffset());
1658 void* leftClassId = emitter.CreatePtrToInt(emitter.CreateLoad(leftClassIdPtr), emitter.GetIrTypeForULong());
1659 void* rightClassTypeVmtObject = rightClassType->VmtObject(emitter, false);
1660 void* rightClassIdPtr = emitter.GetClassIdPtr(rightClassTypeVmtObject, GetClassIdVmtIndexOffset());
1661 void* rightClassId = emitter.CreatePtrToInt(emitter.CreateLoad(rightClassIdPtr), emitter.GetIrTypeForULong());
1662 void* remainder = emitter.CreateURem(leftClassId, rightClassId);
1663 void* remainderIsZero = emitter.CreateICmpEQ(remainder, emitter.CreateDefaultIrValueForULong());
1664 void* trueBlock = emitter.CreateBasicBlock("true");
1665 void* falseBlock = emitter.CreateBasicBlock("false");
1666 void* continueBlock = emitter.CreateBasicBlock("continue");
1667 emitter.CreateCondBr(remainderIsZero, trueBlock, falseBlock);
1668 emitter.SetCurrentBasicBlock(trueBlock);
1669 emitter.Stack().Push(emitter.CreateBitCast(thisPtr, rightClassType->AddPointer(GetSpan(), ModuleId())->IrType(emitter)));
1670 variable->Store(emitter, OperationFlags::none);
1671 emitter.CreateBr(continueBlock);
1672 emitter.SetCurrentBasicBlock(falseBlock);
1673 emitter.Stack().Push(emitter.CreateDefaultIrValueForPtrType(rightClassType->AddPointer(GetSpan(), ModuleId())->IrType(emitter)));
1674 variable->Store(emitter, OperationFlags::none);
1675 emitter.CreateBr(continueBlock);
1676 emitter.SetCurrentBasicBlock(continueBlock);
1677 variable->Load(emitter, OperationFlags::none);
1678 DestroyTemporaries(emitter);
1679 }
1680 }
1681
1682 void BoundAsExpression::Store(Emitter& emitter, OperationFlags 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::boundTypeNameExpression, constCharPtrType_), 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& emitter, OperationFlags flags)
1715 {
1716 classPtr->Load(emitter, OperationFlags::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(thisPtr, vmtPtrHolderClass->AddPointer(GetSpan(), ModuleId())->IrType(emitter));
1727 }
1728 void* vmtPtr = emitter.GetVmtPtr(thisPtr, vmtPtrHolderClass->VmtPtrIndex(), classType->VmtPtrType(emitter));
1729 void* className = emitter.GetClassName(vmtPtr, GetClassNameVmtIndexOffset());
1730 emitter.Stack().Push(className);
1731 DestroyTemporaries(emitter);
1732 }
1733
1734 void BoundTypeNameExpression::Store(Emitter& emitter, OperationFlags 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::boundTypeIdExpression, ulongType_), 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& emitter, OperationFlags flags)
1767 {
1768 classPtr->Load(emitter, OperationFlags::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(thisPtr, vmtPtrHolderClass->AddPointer(GetSpan(), ModuleId())->IrType(emitter));
1779 }
1780 void* vmtPtr = emitter.GetVmtPtr(thisPtr, vmtPtrHolderClass->VmtPtrIndex(), classType->VmtPtrType(emitter));
1781 void* classIdPtr = emitter.GetClassIdPtr(vmtPtr, GetClassIdVmtIndexOffset());
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& emitter, OperationFlags 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::boundBitCast, type_), 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& emitter, OperationFlags flags)
1818 {
1819 expr->Load(emitter, OperationFlags::none);
1820 void* value = emitter.Stack().Pop();
1821 void* casted = emitter.CreateBitCast(value, GetType()->IrType(emitter));
1822 emitter.Stack().Push(casted);
1823 DestroyTemporaries(emitter);
1824 }
1825
1826 void BoundBitCast::Store(Emitter& emitter, OperationFlags 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::boundFunctionPtr, type_), function(function_)
1847 {
1848 }
1849
1850 BoundExpression* BoundFunctionPtr::Clone()
1851 {
1852 return new BoundFunctionPtr(GetSpan(), ModuleId(), function, GetType());
1853 }
1854
1855 void BoundFunctionPtr::Load(Emitter& emitter, OperationFlags 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& emitter, OperationFlags 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::boundDisjunction, boolType_), 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& emitter, OperationFlags flags)
1883 {
1884 temporary->Load(emitter, OperationFlags::addr);
1885 void* temp = emitter.Stack().Pop();
1886 left->Load(emitter, OperationFlags::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(leftValue, trueBlock, rightBlock);
1893 emitter.SetCurrentBasicBlock(rightBlock);
1894 right->Load(emitter, OperationFlags::none);
1895 void* rightValue = emitter.Stack().Pop();
1896 emitter.CreateCondBr(rightValue, trueBlock, falseBlock);
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& emitter, OperationFlags 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::boundConjunction, boolType_), 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& emitter, OperationFlags flags)
1952 {
1953 temporary->Load(emitter, OperationFlags::addr);
1954 void* temp = emitter.Stack().Pop();
1955 left->Load(emitter, OperationFlags::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(leftValue, rightBlock, falseBlock);
1962 emitter.SetCurrentBasicBlock(rightBlock);
1963 right->Load(emitter, OperationFlags::none);
1964 void* rightValue = emitter.Stack().Pop();
1965 emitter.CreateCondBr(rightValue, trueBlock, falseBlock);
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& emitter, OperationFlags 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::boundTypeExpression, type_)
2012 {
2013 }
2014
2015 BoundExpression* BoundTypeExpression::Clone()
2016 {
2017 return new BoundTypeExpression(GetSpan(), ModuleId(), GetType());
2018 }
2019
2020 void BoundTypeExpression::Load(Emitter& emitter, OperationFlags flags)
2021 {
2022 throw Exception("cannot load from a type", GetSpan(), ModuleId());
2023 }
2024
2025 void BoundTypeExpression::Store(Emitter& emitter, OperationFlags 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::boundNamespaceExpression, CreateNamespaceTypeSymbol(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& emitter, OperationFlags flags)
2054 {
2055 throw Exception("cannot load from a namespace", GetSpan(), ModuleId());
2056 }
2057
2058 void BoundNamespaceExpression::Store(Emitter& emitter, OperationFlags 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* functionGroupSymbol, void* boundFunctionGroupExpression)
2069 {
2070 TypeSymbol* functionGroupTypeSymbol = new FunctionGroupTypeSymbol(functionGroupSymbol, boundFunctionGroupExpression);
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::boundFunctionGroupExpression, CreateFunctionGroupTypeSymbol(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& emitter, OperationFlags flags)
2096 {
2097 if (classPtr)
2098 {
2099 classPtr->Load(emitter, OperationFlags::none);
2100 }
2101 else
2102 {
2103 emitter.Stack().Push(nullptr);
2104 }
2105 }
2106
2107 void BoundFunctionGroupExpression::Store(Emitter& emitter, OperationFlags 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& span, const boost::uuids::uuid& moduleId_, const std::u32string& name, void* boundMemberExpression)
2128 {
2129 TypeSymbol* memberExpressionTypeSymbol = new MemberExpressionTypeSymbol(span, moduleId_, name, boundMemberExpression);
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::boundMemberExpression, CreateMemberExpressionTypeSymbol(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& emitter, OperationFlags flags)
2149 {
2150 if (classPtr)
2151 {
2152 classPtr->Load(emitter, OperationFlags::none);
2153 }
2154 else
2155 {
2156 emitter.Stack().Push(nullptr);
2157 }
2158 }
2159
2160 void BoundMemberExpression::Store(Emitter& emitter, OperationFlags 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 } }