1
2
3
4
5
6 #include <cmajor/symbols/DelegateSymbol.hpp>
7 #include <cmajor/symbols/VariableSymbol.hpp>
8 #include <cmajor/symbols/SymbolTable.hpp>
9 #include <cmajor/symbols/SymbolWriter.hpp>
10 #include <cmajor/symbols/SymbolReader.hpp>
11 #include <cmajor/symbols/Exception.hpp>
12 #include <cmajor/symbols/SymbolCollector.hpp>
13 #include <cmajor/symbols/Module.hpp>
14 #include <cmajor/symbols/GlobalFlags.hpp>
15 #include <soulng/util/Unicode.hpp>
16 #include <boost/uuid/uuid_io.hpp>
17
18 namespace cmajor { namespace symbols {
19
20 using namespace soulng::unicode;
21
22 DelegateTypeSymbol::DelegateTypeSymbol(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
23 TypeSymbol(SymbolType::delegateTypeSymbol, span_, sourceModuleId_, name_), returnType(), parameters()
24 {
25 }
26
27 void DelegateTypeSymbol::Write(SymbolWriter& writer)
28 {
29 TypeSymbol::Write(writer);
30 const boost::uuids::uuid& returnTypeId = returnType->TypeId();
31 writer.GetBinaryWriter().Write(returnTypeId);
32 bool hasReturnParam = returnParam != nullptr;
33 writer.GetBinaryWriter().Write(hasReturnParam);
34 if (hasReturnParam)
35 {
36 writer.Write(returnParam.get());
37 }
38 }
39
40 void DelegateTypeSymbol::Read(SymbolReader& reader)
41 {
42 TypeSymbol::Read(reader);
43 boost::uuids::uuid returnTypeId;
44 reader.GetBinaryReader().ReadUuid(returnTypeId);
45 reader.GetSymbolTable()->EmplaceTypeRequest(reader, this, returnTypeId, 0);
46 bool hasReturnParam = reader.GetBinaryReader().ReadBool();
47 if (hasReturnParam)
48 {
49 returnParam.reset(reader.ReadParameterSymbol(this));
50 }
51 }
52
53 void DelegateTypeSymbol::EmplaceType(TypeSymbol* typeSymbol, int index)
54 {
55 Assert(index == 0, "invalid emplace type index");
56 returnType = typeSymbol;
57 }
58
59 void DelegateTypeSymbol::AddMember(Symbol* member)
60 {
61 TypeSymbol::AddMember(member);
62 if (member->GetSymbolType() == SymbolType::parameterSymbol)
63 {
64 parameters.push_back(static_cast<ParameterSymbol*>(member));
65 }
66 }
67
68 std::string DelegateTypeSymbol::Syntax() const
69 {
70 std::string syntax = GetSpecifierStr();
71 if (!syntax.empty())
72 {
73 syntax.append(1, ' ');
74 }
75 syntax.append("delegate ");
76 syntax.append(ToUtf8(ReturnType()->DocName()));
77 syntax.append(1, ' ');
78 syntax.append(ToUtf8(DocName()));
79 syntax.append(1, '(');
80 bool first = true;
81 for (ParameterSymbol* param : parameters)
82 {
83 if (first)
84 {
85 first = false;
86 }
87 else
88 {
89 syntax.append(", ");
90 }
91 syntax.append(ToUtf8(param->GetType()->DocName()));
92 syntax.append(1, ' ');
93 syntax.append(ToUtf8(param->DocName()));
94 }
95 syntax.append(");");
96 return syntax;
97 }
98
99 std::u32string DelegateTypeSymbol::Id() const
100 {
101 return MangledName();
102 }
103
104 void DelegateTypeSymbol::Accept(SymbolCollector* collector)
105 {
106 if (IsProject() && Access() == SymbolAccess::public_)
107 {
108 collector->AddDelegate(this);
109 }
110 }
111
112 void DelegateTypeSymbol::Dump(CodeFormatter& formatter)
113 {
114 formatter.WriteLine(ToUtf8(Name()));
115 formatter.WriteLine("full name: " + ToUtf8(FullNameWithSpecifiers()));
116 formatter.WriteLine("typeid: " + boost::uuids::to_string(TypeId()));
117 }
118
119 void* DelegateTypeSymbol::IrType(Emitter& emitter)
120 {
121 void* localIrType = emitter.GetIrTypeByTypeId(TypeId());
122 if (!localIrType)
123 {
124 void* retType = emitter.GetIrTypeForVoid();
125 if (!returnType->IsVoidType() && !ReturnsClassInterfaceOrClassDelegateByValue())
126 {
127 retType = returnType->IrType(emitter);
128 }
129 std::vector<void*> paramTypes;
130 int np = parameters.size();
131 for (int i = 0; i < np; ++i)
132 {
133 ParameterSymbol* parameter = parameters[i];
134 paramTypes.push_back(parameter->GetType()->IrType(emitter));
135 }
136 if (returnParam)
137 {
138 paramTypes.push_back(returnParam->GetType()->IrType(emitter));
139 }
140 localIrType = emitter.GetIrTypeForDelegateType(retType, paramTypes);
141 emitter.SetIrTypeByTypeId(TypeId(), localIrType);
142 }
143 return localIrType;
144 }
145
146 void* DelegateTypeSymbol::CreateDefaultIrValue(Emitter& emitter)
147 {
148 return emitter.CreateDefaultIrValueForDelegateType(IrType(emitter));
149 }
150
151 void DelegateTypeSymbol::SetSpecifiers(Specifiers specifiers)
152 {
153 Specifiers accessSpecifiers = specifiers & Specifiers::access_;
154 SetAccess(accessSpecifiers);
155 if ((specifiers & Specifiers::static_) != Specifiers::none)
156 {
157 throw Exception("delegate cannot be static", GetSpan(), SourceModuleId());
158 }
159 if ((specifiers & Specifiers::virtual_) != Specifiers::none)
160 {
161 throw Exception("delegate cannot be virtual", GetSpan(), SourceModuleId());
162 }
163 if ((specifiers & Specifiers::override_) != Specifiers::none)
164 {
165 throw Exception("delegate cannot be override", GetSpan(), SourceModuleId());
166 }
167 if ((specifiers & Specifiers::abstract_) != Specifiers::none)
168 {
169 throw Exception("delegate cannot be abstract", GetSpan(), SourceModuleId());
170 }
171 if ((specifiers & Specifiers::inline_) != Specifiers::none)
172 {
173 throw Exception("delegate cannot be inline", GetSpan(), SourceModuleId());
174 }
175 if ((specifiers & Specifiers::explicit_) != Specifiers::none)
176 {
177 throw Exception("delegate cannot be explicit", GetSpan(), SourceModuleId());
178 }
179 if ((specifiers & Specifiers::external_) != Specifiers::none)
180 {
181 throw Exception("delegate cannot be external", GetSpan(), SourceModuleId());
182 }
183 if ((specifiers & Specifiers::suppress_) != Specifiers::none)
184 {
185 throw Exception("delegate cannot be suppressed", GetSpan(), SourceModuleId());
186 }
187 if ((specifiers & Specifiers::default_) != Specifiers::none)
188 {
189 throw Exception("delegate cannot be default", GetSpan(), SourceModuleId());
190 }
191 if ((specifiers & Specifiers::constexpr_) != Specifiers::none)
192 {
193 throw Exception("delegate cannot be constexpr", GetSpan(), SourceModuleId());
194 }
195 if ((specifiers & Specifiers::cdecl_) != Specifiers::none)
196 {
197 throw Exception("delegate cannot be cdecl", GetSpan(), SourceModuleId());
198 }
199 if ((specifiers & Specifiers::nothrow_) != Specifiers::none)
200 {
201 SetNothrow();
202 }
203 if ((specifiers & Specifiers::throw_) != Specifiers::none)
204 {
205 if (IsNothrow())
206 {
207 throw Exception("delegate cannot be throw and nothrow at the same time", GetSpan(), SourceModuleId());
208 }
209 }
210 if ((specifiers & Specifiers::new_) != Specifiers::none)
211 {
212 throw Exception("delegate cannot be new", GetSpan(), SourceModuleId());
213 }
214 if ((specifiers & Specifiers::const_) != Specifiers::none)
215 {
216 throw Exception("delegate cannot be const", GetSpan(), SourceModuleId());
217 }
218 if ((specifiers & Specifiers::unit_test_) != Specifiers::none)
219 {
220 throw Exception("delegate cannot be unit_test", GetSpan(), SourceModuleId());
221 }
222 }
223
224 bool DelegateTypeSymbol::ReturnsClassInterfaceOrClassDelegateByValue() const
225 {
226 return returnType->IsClassTypeSymbol() || returnType->GetSymbolType() == SymbolType::classDelegateTypeSymbol || returnType->GetSymbolType() == SymbolType::interfaceTypeSymbol;
227 }
228
229 void DelegateTypeSymbol::SetReturnParam(ParameterSymbol* returnParam_)
230 {
231 returnParam.reset(returnParam_);
232 }
233
234 void DelegateTypeSymbol::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
235 {
236 void* callee = nullptr;
237 int na = genObjects.size();
238 for (int i = 0; i < na; ++i)
239 {
240 GenObject* genObject = genObjects[i];
241 genObject->Load(emitter, flags & OperationFlags::functionCallFlags);
242 if (i == 0)
243 {
244 callee = emitter.Stack().Pop();
245 }
246 }
247 std::vector<void*> args;
248 int n = parameters.size();
249 if (ReturnsClassInterfaceOrClassDelegateByValue())
250 {
251 ++n;
252 }
253 args.resize(n);
254 for (int i = 0; i < n; ++i)
255 {
256 void* arg = emitter.Stack().Pop();
257 args[n - i - 1] = arg;
258 }
259 emitter.SetCurrentDebugLocation(span);
260 void* handlerBlock = emitter.HandlerBlock();
261 void* cleanupBlock = emitter.CleanupBlock();
262 bool newCleanupNeeded = emitter.NewCleanupNeeded();
263 Pad* currentPad = emitter.CurrentPad();
264 std::vector<void*> bundles;
265 if (currentPad != nullptr)
266 {
267 bundles.push_back(currentPad->value);
268 }
269 if (returnType->GetSymbolType() != SymbolType::voidTypeSymbol && !ReturnsClassInterfaceOrClassDelegateByValue())
270 {
271 if (IsNothrow() || (!handlerBlock && !cleanupBlock && !newCleanupNeeded))
272 {
273 if (currentPad == nullptr)
274 {
275 emitter.Stack().Push(emitter.CreateCall(callee, args));
276 }
277 else
278 {
279 void* callInst = emitter.CreateCallInst(callee, args, bundles, span);
280 emitter.Stack().Push(callInst);
281 }
282 }
283 else
284 {
285 void* nextBlock = nullptr;
286 if (GetBackEnd() == BackEnd::llvm || GetBackEnd() == BackEnd::cmcpp)
287 {
288 nextBlock = emitter.CreateBasicBlock("next");
289 }
290 if (newCleanupNeeded)
291 {
292 emitter.CreateCleanup();
293 cleanupBlock = emitter.CleanupBlock();
294 }
295 void* unwindBlock = cleanupBlock;
296 if (unwindBlock == nullptr)
297 {
298 unwindBlock = handlerBlock;
299 Assert(unwindBlock, "no unwind block");
300 }
301 if (currentPad == nullptr)
302 {
303 emitter.Stack().Push(emitter.CreateInvoke(callee, nextBlock, unwindBlock, args));
304 }
305 else
306 {
307 void* invokeInst = emitter.CreateInvokeInst(callee, nextBlock, unwindBlock, args, bundles, span);
308 emitter.Stack().Push(invokeInst);
309 }
310 if (GetBackEnd() == BackEnd::llvm || GetBackEnd() == BackEnd::cmcpp)
311 {
312 emitter.SetCurrentBasicBlock(nextBlock);
313 }
314 }
315 }
316 else
317 {
318 if (IsNothrow() || (!handlerBlock && !cleanupBlock && !newCleanupNeeded))
319 {
320 if (currentPad == nullptr)
321 {
322 emitter.CreateCall(callee, args);
323 }
324 else
325 {
326 emitter.CreateCallInst(callee, args, bundles, span);
327 }
328 }
329 else
330 {
331 void* nextBlock = nullptr;
332 if (GetBackEnd() == BackEnd::llvm || GetBackEnd() == BackEnd::cmcpp)
333 {
334 nextBlock = emitter.CreateBasicBlock("next");
335 }
336 if (newCleanupNeeded)
337 {
338 emitter.CreateCleanup();
339 cleanupBlock = emitter.CleanupBlock();
340 }
341 void* unwindBlock = cleanupBlock;
342 if (unwindBlock == nullptr)
343 {
344 unwindBlock = handlerBlock;
345 Assert(unwindBlock, "no unwind block");
346 }
347 if (currentPad == nullptr)
348 {
349 emitter.CreateInvoke(callee, nextBlock, unwindBlock, args);
350 }
351 else
352 {
353 emitter.CreateInvokeInst(callee, nextBlock, unwindBlock, args, bundles, span);
354 }
355 if (GetBackEnd() == BackEnd::llvm || GetBackEnd() == BackEnd::cmcpp)
356 {
357 emitter.SetCurrentBasicBlock(nextBlock);
358 }
359 }
360 }
361 }
362
363 void DelegateTypeSymbol::Check()
364 {
365 TypeSymbol::Check();
366 if (!returnType)
367 {
368 throw SymbolCheckException("delegate type symbol has no return type", GetSpan(), SourceModuleId());
369 }
370 }
371
372 std::string DelegateTypeSymbol::GetSymbolHelp() const
373 {
374 std::string help = "(";
375 help.append(GetSymbolCategoryDescription()).append(") ");
376 help.append(ToUtf8(ReturnType()->FullName())).append(" ").append(ToUtf8(FullName())).append("(");
377 bool first = true;
378 for (ParameterSymbol* param : parameters)
379 {
380 if (first)
381 {
382 first = false;
383 }
384 else
385 {
386 help.append(", ");
387 }
388 help.append(ToUtf8(param->GetType()->FullName())).append(" ").append(ToUtf8(param->Name()));
389 }
390 help.append(")");
391 return help;
392 }
393
394 DelegateTypeDefaultConstructor::DelegateTypeDefaultConstructor(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
395 FunctionSymbol(SymbolType::delegateTypeDefaultConstructor, span_, sourceModuleId_, name_)
396 {
397 }
398
399 DelegateTypeDefaultConstructor::DelegateTypeDefaultConstructor(DelegateTypeSymbol* delegateType_) :
400 FunctionSymbol(SymbolType::delegateTypeDefaultConstructor, delegateType_->GetSpan(), delegateType_->SourceModuleId(), U"@constructor"), delegateType(delegateType_)
401 {
402 SetGroupName(U"@constructor");
403 SetAccess(SymbolAccess::public_);
404 ParameterSymbol* thisParam = new ParameterSymbol(delegateType->GetSpan(), delegateType->SourceModuleId(), U"this");
405 thisParam->SetType(delegateType->AddPointer(Span(), boost::uuids::nil_uuid()));
406 AddMember(thisParam);
407 ComputeName();
408 }
409
410 void DelegateTypeDefaultConstructor::Write(SymbolWriter& writer)
411 {
412 FunctionSymbol::Write(writer);
413 writer.GetBinaryWriter().Write(delegateType->TypeId());
414 }
415
416 void DelegateTypeDefaultConstructor::Read(SymbolReader& reader)
417 {
418 FunctionSymbol::Read(reader);
419 boost::uuids::uuid typeId;
420 reader.GetBinaryReader().ReadUuid(typeId);
421 reader.GetSymbolTable()->EmplaceTypeRequest(reader, this, typeId, 1);
422 }
423
424 void DelegateTypeDefaultConstructor::EmplaceType(TypeSymbol* typeSymbol, int index)
425 {
426 if (index == 1)
427 {
428 Assert(typeSymbol->GetSymbolType() == SymbolType::delegateTypeSymbol, "delegate type symbol expected");
429 delegateType = static_cast<DelegateTypeSymbol*>(typeSymbol);
430 }
431 else
432 {
433 FunctionSymbol::EmplaceType(typeSymbol, index);
434 }
435 }
436
437 void DelegateTypeDefaultConstructor::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
438 {
439 Assert(genObjects.size() == 1, "default constructor needs one object");
440 emitter.Stack().Push(delegateType->CreateDefaultIrValue(emitter));
441 genObjects[0]->Store(emitter, OperationFlags::none);
442 }
443
444 void DelegateTypeDefaultConstructor::Check()
445 {
446 FunctionSymbol::Check();
447 if (!delegateType)
448 {
449 throw SymbolCheckException("delegate type default constructor has no delegate type", GetSpan(), SourceModuleId());
450 }
451 }
452
453 DelegateTypeCopyConstructor::DelegateTypeCopyConstructor(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
454 FunctionSymbol(SymbolType::delegateTypeCopyConstructor, span_, sourceModuleId_, name_)
455 {
456 }
457
458 DelegateTypeCopyConstructor::DelegateTypeCopyConstructor(DelegateTypeSymbol* delegateType) : FunctionSymbol(SymbolType::delegateTypeCopyConstructor,
459 delegateType->GetSpan(), delegateType->SourceModuleId(), U"@constructor")
460 {
461 SetGroupName(U"@constructor");
462 SetAccess(SymbolAccess::public_);
463 ParameterSymbol* thisParam = new ParameterSymbol(delegateType->GetSpan(), delegateType->SourceModuleId(), U"this");
464 thisParam->SetType(delegateType->AddPointer(Span(), boost::uuids::nil_uuid()));
465 AddMember(thisParam);
466 ParameterSymbol* thatParam = new ParameterSymbol(delegateType->GetSpan(), delegateType->SourceModuleId(), U"that");
467 thatParam->SetType(delegateType);
468 AddMember(thatParam);
469 ComputeName();
470 }
471
472 void DelegateTypeCopyConstructor::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
473 {
474 Assert(genObjects.size() == 2, "copy constructor needs two objects");
475 genObjects[1]->Load(emitter, OperationFlags::none);
476 genObjects[0]->Store(emitter, OperationFlags::none);
477 }
478
479 DelegateTypeMoveConstructor::DelegateTypeMoveConstructor(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
480 FunctionSymbol(SymbolType::delegateTypeMoveConstructor, span_, sourceModuleId_, name_)
481 {
482 }
483
484 DelegateTypeMoveConstructor::DelegateTypeMoveConstructor(DelegateTypeSymbol* delegateType) :
485 FunctionSymbol(SymbolType::delegateTypeMoveConstructor, delegateType->GetSpan(), delegateType->SourceModuleId(), U"@constructor")
486 {
487 SetGroupName(U"@constructor");
488 SetAccess(SymbolAccess::public_);
489 ParameterSymbol* thisParam = new ParameterSymbol(delegateType->GetSpan(), delegateType->SourceModuleId(), U"this");
490 thisParam->SetType(delegateType->AddPointer(Span(), boost::uuids::nil_uuid()));
491 AddMember(thisParam);
492 ParameterSymbol* thatParam = new ParameterSymbol(delegateType->GetSpan(), delegateType->SourceModuleId(), U"that");
493 thatParam->SetType(delegateType->AddRvalueReference(Span(), boost::uuids::nil_uuid()));
494 AddMember(thatParam);
495 ComputeName();
496 }
497
498 void DelegateTypeMoveConstructor::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
499 {
500 Assert(genObjects.size() == 2, "move constructor needs two objects");
501 genObjects[1]->Load(emitter, OperationFlags::none);
502 void* rvalueRefValue = emitter.Stack().Pop();
503 emitter.Stack().Push(emitter.CreateLoad(rvalueRefValue));
504 genObjects[0]->Store(emitter, OperationFlags::none);
505 }
506
507 DelegateTypeCopyAssignment::DelegateTypeCopyAssignment(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
508 FunctionSymbol(SymbolType::delegateTypeCopyAssignment, span_, sourceModuleId_, name_)
509 {
510 }
511
512 DelegateTypeCopyAssignment::DelegateTypeCopyAssignment(DelegateTypeSymbol* delegateType, TypeSymbol* voidType) :
513 FunctionSymbol(SymbolType::delegateTypeCopyAssignment, delegateType->GetSpan(), delegateType->SourceModuleId(), U"operator=")
514 {
515 SetGroupName(U"operator=");
516 SetAccess(SymbolAccess::public_);
517 ParameterSymbol* thisParam = new ParameterSymbol(delegateType->GetSpan(), delegateType->SourceModuleId(), U"this");
518 thisParam->SetType(delegateType->AddPointer(Span(), boost::uuids::nil_uuid()));
519 AddMember(thisParam);
520 ParameterSymbol* thatParam = new ParameterSymbol(delegateType->GetSpan(), delegateType->SourceModuleId(), U"that");
521 thatParam->SetType(delegateType);
522 AddMember(thatParam);
523 SetReturnType(voidType);
524 ComputeName();
525 }
526
527 void DelegateTypeCopyAssignment::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
528 {
529 Assert(genObjects.size() == 2, "copy assignment needs two objects");
530 genObjects[1]->Load(emitter, OperationFlags::none);
531 genObjects[0]->Store(emitter, OperationFlags::none);
532 }
533
534 DelegateTypeMoveAssignment::DelegateTypeMoveAssignment(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
535 FunctionSymbol(SymbolType::delegateTypeMoveAssignment, span_, sourceModuleId_, name_)
536 {
537 }
538
539 DelegateTypeMoveAssignment::DelegateTypeMoveAssignment(DelegateTypeSymbol* delegateType, TypeSymbol* voidType) :
540 FunctionSymbol(SymbolType::delegateTypeMoveAssignment, delegateType->GetSpan(), delegateType->SourceModuleId(), U"operator=")
541 {
542 SetGroupName(U"operator=");
543 SetAccess(SymbolAccess::public_);
544 ParameterSymbol* thisParam = new ParameterSymbol(delegateType->GetSpan(), delegateType->SourceModuleId(), U"this");
545 thisParam->SetType(delegateType->AddPointer(Span(), boost::uuids::nil_uuid()));
546 AddMember(thisParam);
547 ParameterSymbol* thatParam = new ParameterSymbol(delegateType->GetSpan(), delegateType->SourceModuleId(), U"that");
548 thatParam->SetType(delegateType->AddRvalueReference(Span(), boost::uuids::nil_uuid()));
549 AddMember(thatParam);
550 SetReturnType(voidType);
551 ComputeName();
552 }
553
554 void DelegateTypeMoveAssignment::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
555 {
556 Assert(genObjects.size() == 2, "move assignment needs two objects");
557 genObjects[1]->Load(emitter, OperationFlags::none);
558 void* rvalueRefValue = emitter.Stack().Pop();
559 emitter.Stack().Push(emitter.CreateLoad(rvalueRefValue));
560 genObjects[0]->Store(emitter, OperationFlags::none);
561 }
562
563 DelegateTypeReturn::DelegateTypeReturn(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
564 FunctionSymbol(SymbolType::delegateTypeReturn, span_, sourceModuleId_, name_)
565 {
566 }
567
568 DelegateTypeReturn::DelegateTypeReturn(DelegateTypeSymbol* delegateType) : FunctionSymbol(SymbolType::delegateTypeReturn, delegateType->GetSpan(), delegateType->SourceModuleId(), U"@return")
569 {
570 SetGroupName(U"@return");
571 ParameterSymbol* valueParam = new ParameterSymbol(delegateType->GetSpan(), delegateType->SourceModuleId(), U"value");
572 valueParam->SetType(delegateType);
573 AddMember(valueParam);
574 SetReturnType(delegateType);
575 ComputeName();
576 }
577
578 void DelegateTypeReturn::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
579 {
580 Assert(genObjects.size() == 1, "return needs one object");
581 genObjects[0]->Load(emitter, OperationFlags::none);
582 }
583
584 DelegateTypeEquality::DelegateTypeEquality(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
585 FunctionSymbol(SymbolType::delegateTypeEquality, span_, sourceModuleId_, name_)
586 {
587 }
588
589 DelegateTypeEquality::DelegateTypeEquality(DelegateTypeSymbol* delegateType, TypeSymbol* boolType)
590 : FunctionSymbol(SymbolType::delegateTypeEquality, delegateType->GetSpan(), delegateType->SourceModuleId(), U"operator==")
591 {
592 SetGroupName(U"operator==");
593 SetAccess(SymbolAccess::public_);
594 ParameterSymbol* leftParam = new ParameterSymbol(delegateType->GetSpan(), delegateType->SourceModuleId(), U"left");
595 leftParam->SetType(delegateType);
596 AddMember(leftParam);
597 ParameterSymbol* rightParam = new ParameterSymbol(delegateType->GetSpan(), delegateType->SourceModuleId(), U"right");
598 rightParam->SetType(delegateType);
599 AddMember(rightParam);
600 SetReturnType(boolType);
601 ComputeName();
602 }
603
604 void DelegateTypeEquality::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
605 {
606 Assert(genObjects.size() == 2, "operator== needs two objects");
607 genObjects[0]->Load(emitter, OperationFlags::none);
608 void* left = emitter.Stack().Pop();
609 genObjects[1]->Load(emitter, OperationFlags::none);
610 void* right = emitter.Stack().Pop();
611 emitter.Stack().Push(emitter.CreateICmpEQ(left, right));
612 }
613
614 FunctionToDelegateConversion::FunctionToDelegateConversion(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
615 FunctionSymbol(SymbolType::functionToDelegateSymbol, span_, sourceModuleId_, name_), sourceType(nullptr), targetType(nullptr), function(nullptr)
616 {
617 }
618
619 FunctionToDelegateConversion::FunctionToDelegateConversion(TypeSymbol* sourceType_, TypeSymbol* targetType_, FunctionSymbol* function_) :
620 FunctionSymbol(SymbolType::functionToDelegateSymbol, function_->GetSpan(), function_->SourceModuleId(), U"@conversion"), sourceType(sourceType_), targetType(targetType_), function(function_)
621 {
622 SetConversion();
623 SetConversionSourceType(sourceType->PlainType(GetSpan(), SourceModuleId()));
624 SetConversionTargetType(targetType->PlainType(GetSpan(), SourceModuleId()));
625 }
626
627 void FunctionToDelegateConversion::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
628 {
629 emitter.Stack().Pop();
630 emitter.Stack().Push(emitter.GetOrInsertFunction(ToUtf8(function->MangledName()), function->IrType(emitter), function->DontThrow()));
631 }
632
633 void FunctionToDelegateConversion::Check()
634 {
635 FunctionSymbol::Check();
636 if (!sourceType)
637 {
638 throw SymbolCheckException("function to delegate conversion has no source type", GetSpan(), SourceModuleId());
639 }
640 if (!targetType)
641 {
642 throw SymbolCheckException("function to delegate conversion has no target type", GetSpan(), SourceModuleId());
643 }
644 if (!function)
645 {
646 throw SymbolCheckException("function to delegate conversion has no function", GetSpan(), SourceModuleId());
647 }
648 }
649
650 DelegateToVoidPtrConversion::DelegateToVoidPtrConversion(TypeSymbol* delegateType_, TypeSymbol* voidPtrType_) :
651 FunctionSymbol(delegateType_->GetSpan(), delegateType_->SourceModuleId(), U"dlg2voidptr"), delegateType(delegateType_), voidPtrType(voidPtrType_)
652 {
653 SetConversion();
654 SetGroupName(U"@conversion");
655 SetAccess(SymbolAccess::public_);
656 SetConversionSourceType(delegateType->PlainType(GetSpan(), SourceModuleId()));
657 SetConversionTargetType(voidPtrType->PlainType(GetSpan(), SourceModuleId()));
658 }
659
660 void DelegateToVoidPtrConversion::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
661 {
662 emitter.SetCurrentDebugLocation(span);
663 void* value = emitter.Stack().Pop();
664 emitter.Stack().Push(emitter.CreateBitCast(value, voidPtrType->IrType(emitter)));
665 }
666
667 VoidPtrToDelegateConversion::VoidPtrToDelegateConversion(TypeSymbol* voidPtrType_, TypeSymbol* delegateType_, TypeSymbol* ulongType_) :
668 FunctionSymbol(delegateType_->GetSpan(), delegateType_->SourceModuleId(), U"voidptr2dlg"), voidPtrType(voidPtrType_), delegateType(delegateType_), ulongType(ulongType_)
669 {
670 SetConversion();
671 SetGroupName(U"@conversion");
672 SetAccess(SymbolAccess::public_);
673 SetConversionSourceType(delegateType->PlainType(GetSpan(), SourceModuleId()));
674 SetConversionTargetType(voidPtrType->PlainType(GetSpan(), SourceModuleId()));
675 }
676
677 void VoidPtrToDelegateConversion::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
678 {
679 emitter.SetCurrentDebugLocation(span);
680 void* value = emitter.Stack().Pop();
681 void* ulongValue = emitter.CreatePtrToInt(value, ulongType->IrType(emitter));
682 emitter.Stack().Push(emitter.CreateIntToPtr(ulongValue, delegateType->IrType(emitter)));
683 }
684
685 ClassDelegateTypeSymbol::ClassDelegateTypeSymbol(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
686 TypeSymbol(SymbolType::classDelegateTypeSymbol, span_, sourceModuleId_, name_), returnType(nullptr), parameters(), delegateType(nullptr), objectDelegatePairType(nullptr),
687 copyConstructor(nullptr)
688 {
689 }
690
691 void ClassDelegateTypeSymbol::Write(SymbolWriter& writer)
692 {
693 TypeSymbol::Write(writer);
694 const boost::uuids::uuid& returnTypeId = returnType->TypeId();
695 writer.GetBinaryWriter().Write(returnTypeId);
696 }
697
698 void ClassDelegateTypeSymbol::Read(SymbolReader& reader)
699 {
700 TypeSymbol::Read(reader);
701 boost::uuids::uuid returnTypeId;
702 reader.GetBinaryReader().ReadUuid(returnTypeId);
703 reader.GetSymbolTable()->EmplaceTypeRequest(reader, this, returnTypeId, -1);
704 }
705
706 void ClassDelegateTypeSymbol::EmplaceType(TypeSymbol* typeSymbol, int index)
707 {
708 if (index == -1)
709 {
710 returnType = typeSymbol;
711 }
712 else
713 {
714 TypeSymbol::EmplaceType(typeSymbol, index);
715 }
716 }
717
718 void ClassDelegateTypeSymbol::AddMember(Symbol* member)
719 {
720 TypeSymbol::AddMember(member);
721 if (member->GetSymbolType() == SymbolType::parameterSymbol)
722 {
723 parameters.push_back(static_cast<ParameterSymbol*>(member));
724 }
725 else if (member->GetSymbolType() == SymbolType::delegateTypeSymbol)
726 {
727 delegateType = static_cast<DelegateTypeSymbol*>(member);
728 }
729 else if (member->GetSymbolType() == SymbolType::classTypeSymbol)
730 {
731 objectDelegatePairType = static_cast<ClassTypeSymbol*>(member);
732 }
733 else if (member->IsFunctionSymbol())
734 {
735 FunctionSymbol* functionSymbol = static_cast<FunctionSymbol*>(member);
736 if (functionSymbol->IsClassDelegateCopyConstructor())
737 {
738 copyConstructor = functionSymbol;
739 }
740 }
741 }
742
743 std::string ClassDelegateTypeSymbol::Syntax() const
744 {
745 std::string syntax = GetSpecifierStr();
746 if (!syntax.empty())
747 {
748 syntax.append(1, ' ');
749 }
750 syntax.append("class delegate ");
751 syntax.append(ToUtf8(ReturnType()->DocName()));
752 syntax.append(1, ' ');
753 syntax.append(ToUtf8(DocName()));
754 syntax.append(1, '(');
755 bool first = true;
756 for (ParameterSymbol* param : parameters)
757 {
758 if (first)
759 {
760 first = false;
761 }
762 else
763 {
764 syntax.append(", ");
765 }
766 syntax.append(ToUtf8(param->GetType()->DocName()));
767 syntax.append(1, ' ');
768 syntax.append(ToUtf8(param->DocName()));
769 }
770 syntax.append(");");
771 return syntax;
772 }
773
774 std::string ClassDelegateTypeSymbol::GetSymbolHelp() const
775 {
776 std::string help = "(";
777 help.append(GetSymbolCategoryDescription()).append(") ");
778 help.append(ToUtf8(ReturnType()->FullName())).append(" ").append(ToUtf8(FullName())).append("(");
779 bool first = true;
780 for (ParameterSymbol* param : parameters)
781 {
782 if (first)
783 {
784 first = false;
785 }
786 else
787 {
788 help.append(", ");
789 }
790 help.append(ToUtf8(param->GetType()->FullName())).append(" ").append(ToUtf8(param->Name()));
791 }
792 help.append(")");
793 return help;
794 }
795
796 std::u32string ClassDelegateTypeSymbol::Id() const
797 {
798 return MangledName();
799 }
800
801 void ClassDelegateTypeSymbol::Accept(SymbolCollector* collector)
802 {
803 if (IsProject() && Access() == SymbolAccess::public_)
804 {
805 collector->AddClassDelegate(this);
806 }
807 }
808
809 void ClassDelegateTypeSymbol::Dump(CodeFormatter& formatter)
810 {
811 formatter.WriteLine(ToUtf8(Name()));
812 formatter.WriteLine("full name: " + ToUtf8(FullNameWithSpecifiers()));
813 formatter.WriteLine("typeid: " + boost::uuids::to_string(TypeId()));
814 }
815
816 void* ClassDelegateTypeSymbol::IrType(Emitter& emitter)
817 {
818 void* localIrType = emitter.GetIrTypeByTypeId(TypeId());
819 if (!localIrType)
820 {
821 std::vector<void*> elementTypes;
822 elementTypes.push_back(emitter.GetIrTypeForVoidPtrType());
823 elementTypes.push_back(delegateType->IrType(emitter));
824 localIrType = emitter.GetIrTypeForStructType(elementTypes);
825 emitter.SetIrTypeByTypeId(TypeId(), localIrType);
826 }
827 return localIrType;
828 }
829
830 void* ClassDelegateTypeSymbol::CreateDefaultIrValue(Emitter& emitter)
831 {
832 std::vector<void*> constants;
833 constants.push_back(emitter.CreateDefaultIrValueForVoidPtrType());
834 constants.push_back(delegateType->CreateDefaultIrValue(emitter));
835 return emitter.CreateDefaultIrValueForStruct(IrType(emitter), constants);
836 }
837
838 bool ClassDelegateTypeSymbol::ReturnsClassInterfaceOrClassDelegateByValue() const
839 {
840 return returnType->IsClassTypeSymbol() || returnType->GetSymbolType() == SymbolType::classDelegateTypeSymbol || returnType->GetSymbolType() == SymbolType::interfaceTypeSymbol;
841 }
842
843 void ClassDelegateTypeSymbol::SetReturnParam(ParameterSymbol* returnParam_)
844 {
845 returnParam.reset(returnParam_);
846 }
847
848 void ClassDelegateTypeSymbol::SetSpecifiers(Specifiers specifiers)
849 {
850 Specifiers accessSpecifiers = specifiers & Specifiers::access_;
851 SetAccess(accessSpecifiers);
852 if ((specifiers & Specifiers::static_) != Specifiers::none)
853 {
854 throw Exception("class delegate cannot be static", GetSpan(), SourceModuleId());
855 }
856 if ((specifiers & Specifiers::virtual_) != Specifiers::none)
857 {
858 throw Exception("class delegate cannot be virtual", GetSpan(), SourceModuleId());
859 }
860 if ((specifiers & Specifiers::override_) != Specifiers::none)
861 {
862 throw Exception("class delegate cannot be override", GetSpan(), SourceModuleId());
863 }
864 if ((specifiers & Specifiers::abstract_) != Specifiers::none)
865 {
866 throw Exception("class delegate cannot be abstract", GetSpan(), SourceModuleId());
867 }
868 if ((specifiers & Specifiers::inline_) != Specifiers::none)
869 {
870 throw Exception("class delegate cannot be inline", GetSpan(), SourceModuleId());
871 }
872 if ((specifiers & Specifiers::explicit_) != Specifiers::none)
873 {
874 throw Exception("class delegate cannot be explicit", GetSpan(), SourceModuleId());
875 }
876 if ((specifiers & Specifiers::external_) != Specifiers::none)
877 {
878 throw Exception("class delegate cannot be external", GetSpan(), SourceModuleId());
879 }
880 if ((specifiers & Specifiers::suppress_) != Specifiers::none)
881 {
882 throw Exception("class delegate cannot be suppressed", GetSpan(), SourceModuleId());
883 }
884 if ((specifiers & Specifiers::default_) != Specifiers::none)
885 {
886 throw Exception("class delegate cannot be default", GetSpan(), SourceModuleId());
887 }
888 if ((specifiers & Specifiers::constexpr_) != Specifiers::none)
889 {
890 throw Exception("class delegate cannot be constexpr", GetSpan(), SourceModuleId());
891 }
892 if ((specifiers & Specifiers::cdecl_) != Specifiers::none)
893 {
894 throw Exception("class delegate cannot be cdecl", GetSpan(), SourceModuleId());
895 }
896 if ((specifiers & Specifiers::nothrow_) != Specifiers::none)
897 {
898 SetNothrow();
899 }
900 if ((specifiers & Specifiers::throw_) != Specifiers::none)
901 {
902 if (IsNothrow())
903 {
904 throw Exception("class delegate cannot be throw and nothrow at the same time", GetSpan(), SourceModuleId());
905 }
906 }
907 if ((specifiers & Specifiers::new_) != Specifiers::none)
908 {
909 throw Exception("class delegate cannot be new", GetSpan(), SourceModuleId());
910 }
911 if ((specifiers & Specifiers::const_) != Specifiers::none)
912 {
913 throw Exception("class delegate cannot be const", GetSpan(), SourceModuleId());
914 }
915 if ((specifiers & Specifiers::unit_test_) != Specifiers::none)
916 {
917 throw Exception("class delegate cannot be unit_test", GetSpan(), SourceModuleId());
918 }
919 }
920
921 void ClassDelegateTypeSymbol::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
922 {
923 Assert(!genObjects.empty(), "gen objects is empty");
924 genObjects[0]->Load(emitter, flags);
925 void* classDelegatePtr = emitter.Stack().Pop();
926 void* delegatePtr = emitter.GetDelegateFromClassDelegate(classDelegatePtr);
927 void* callee = emitter.CreateLoad(delegatePtr);
928 NativeValue calleeValue(callee);
929 void* objectPtr = emitter.GetObjectFromClassDelegate(classDelegatePtr);
930 void* object = emitter.CreateLoad(objectPtr);
931 NativeValue objectValue(object);
932 std::vector<GenObject*> classDelegateCallObjects;
933 classDelegateCallObjects.push_back(&calleeValue);
934 classDelegateCallObjects.push_back(&objectValue);
935 int na = genObjects.size();
936 for (int i = 1; i < na; ++i)
937 {
938 GenObject* genObject = genObjects[i];
939 classDelegateCallObjects.push_back(genObject);
940 }
941 delegateType->GenerateCall(emitter, classDelegateCallObjects, flags, span, moduleId);
942 }
943
944 void ClassDelegateTypeSymbol::Check()
945 {
946 TypeSymbol::Check();
947 if (!returnType)
948 {
949 throw SymbolCheckException("class delegate type symbol has no return type", GetSpan(), SourceModuleId());
950 }
951 if (!delegateType)
952 {
953 throw SymbolCheckException("class delegate type symbol has no delegate type", GetSpan(), SourceModuleId());
954 }
955 if (!objectDelegatePairType)
956 {
957 throw SymbolCheckException("class delegate type symbol has no object delegate pair type", GetSpan(), SourceModuleId());
958 }
959 if (!copyConstructor)
960 {
961 throw SymbolCheckException("class delegate type symbol has no copy constructor", GetSpan(), SourceModuleId());
962 }
963 }
964
965 ClassDelegateTypeDefaultConstructor::ClassDelegateTypeDefaultConstructor(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
966 FunctionSymbol(SymbolType::classDelegateTypeDefaultConstructor, span_, sourceModuleId_, name_)
967 {
968 }
969
970 ClassDelegateTypeDefaultConstructor::ClassDelegateTypeDefaultConstructor(ClassDelegateTypeSymbol* classDelegateType_) :
971 FunctionSymbol(SymbolType::classDelegateTypeDefaultConstructor, classDelegateType_->GetSpan(), classDelegateType_->SourceModuleId(), U"@constructor"), classDelegateType(classDelegateType_)
972 {
973 SetGroupName(U"@constructor");
974 SetAccess(SymbolAccess::public_);
975 ParameterSymbol* thisParam = new ParameterSymbol(classDelegateType_->GetSpan(), classDelegateType_->SourceModuleId(), U"this");
976 thisParam->SetType(classDelegateType->AddPointer(Span(), boost::uuids::nil_uuid()));
977 AddMember(thisParam);
978 ComputeName();
979 }
980
981 void ClassDelegateTypeDefaultConstructor::Write(SymbolWriter& writer)
982 {
983 FunctionSymbol::Write(writer);
984 writer.GetBinaryWriter().Write(classDelegateType->TypeId());
985 }
986
987 void ClassDelegateTypeDefaultConstructor::Read(SymbolReader& reader)
988 {
989 FunctionSymbol::Read(reader);
990 boost::uuids::uuid typeId;
991 reader.GetBinaryReader().ReadUuid(typeId);
992 reader.GetSymbolTable()->EmplaceTypeRequest(reader, this, typeId, 1);
993 }
994
995 void ClassDelegateTypeDefaultConstructor::EmplaceType(TypeSymbol* typeSymbol, int index)
996 {
997 if (index == 1)
998 {
999 Assert(typeSymbol->GetSymbolType() == SymbolType::classDelegateTypeSymbol, "class delegate type symbol expected");
1000 classDelegateType = static_cast<ClassDelegateTypeSymbol*>(typeSymbol);
1001 }
1002 else
1003 {
1004 FunctionSymbol::EmplaceType(typeSymbol, index);
1005 }
1006 }
1007
1008 void ClassDelegateTypeDefaultConstructor::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
1009 {
1010 Assert(genObjects.size() == 1, "default constructor needs one object");
1011 void* objectValue = emitter.CreateDefaultIrValueForVoidPtrType();
1012 genObjects[0]->Load(emitter, OperationFlags::none);
1013 void* ptr = emitter.Stack().Pop();
1014 void* objectPtr = emitter.GetObjectFromClassDelegate(ptr);
1015 emitter.CreateStore(objectValue, objectPtr);
1016 void* delegateValue = classDelegateType->DelegateType()->CreateDefaultIrValue(emitter);
1017 void* delegatePtr = emitter.GetDelegateFromClassDelegate(ptr);
1018 emitter.CreateStore(delegateValue, delegatePtr);
1019 }
1020
1021 void ClassDelegateTypeDefaultConstructor::Check()
1022 {
1023 FunctionSymbol::Check();
1024 if (!classDelegateType)
1025 {
1026 throw SymbolCheckException("class delegate type default constructor has no class delegate type", GetSpan(), SourceModuleId());
1027 }
1028 }
1029
1030 ClassDelegateTypeCopyConstructor::ClassDelegateTypeCopyConstructor(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
1031 FunctionSymbol(SymbolType::classDelegateTypeCopyConstructor, span_, sourceModuleId_, name_)
1032 {
1033 }
1034
1035 ClassDelegateTypeCopyConstructor::ClassDelegateTypeCopyConstructor(ClassDelegateTypeSymbol* classDelegateType) :
1036 FunctionSymbol(SymbolType::classDelegateTypeCopyConstructor, classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"@constructor")
1037 {
1038 SetGroupName(U"@constructor");
1039 SetAccess(SymbolAccess::public_);
1040 ParameterSymbol* thisParam = new ParameterSymbol(classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"this");
1041 thisParam->SetType(classDelegateType->AddPointer(Span(), boost::uuids::nil_uuid()));
1042 AddMember(thisParam);
1043 ParameterSymbol* thatParam = new ParameterSymbol(classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"that");
1044 thatParam->SetType(classDelegateType->AddConst(Span(), boost::uuids::nil_uuid())->AddLvalueReference(Span(), boost::uuids::nil_uuid()));
1045 AddMember(thatParam);
1046 ComputeName();
1047 }
1048
1049 void ClassDelegateTypeCopyConstructor::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
1050 {
1051 genObjects[1]->Load(emitter, OperationFlags::none);
1052 void* thatPtr = emitter.Stack().Pop();
1053 void* thatObjectPtr = emitter.GetObjectFromClassDelegate(thatPtr);
1054 void* objectValue = emitter.CreateLoad(thatObjectPtr);
1055 OperationFlags loadFlags = OperationFlags::none;
1056 if ((flags & OperationFlags::leaveFirstArg) != OperationFlags::none)
1057 {
1058 loadFlags = loadFlags | OperationFlags::leaveFirstArg;
1059 }
1060 genObjects[0]->Load(emitter, loadFlags);
1061 void* thisPtr = emitter.Stack().Pop();
1062 void* thisObjectPtr = emitter.GetObjectFromClassDelegate(thisPtr);
1063 emitter.CreateStore(objectValue, thisObjectPtr);
1064 void* thatDelegatePtr = emitter.GetDelegateFromClassDelegate(thatPtr);
1065 void* delegateValue = emitter.CreateLoad(thatDelegatePtr);
1066 void* thisDelegatePtr = emitter.GetDelegateFromClassDelegate(thisPtr);
1067 emitter.CreateStore(delegateValue, thisDelegatePtr);
1068 }
1069
1070 ClassDelegateTypeMoveConstructor::ClassDelegateTypeMoveConstructor(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
1071 FunctionSymbol(SymbolType::classDelegateTypeMoveConstructor, span_, sourceModuleId_, name_)
1072 {
1073 }
1074
1075 ClassDelegateTypeMoveConstructor::ClassDelegateTypeMoveConstructor(ClassDelegateTypeSymbol* classDelegateType) :
1076 FunctionSymbol(SymbolType::classDelegateTypeCopyConstructor, classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"@constructor")
1077 {
1078 SetGroupName(U"@constructor");
1079 SetAccess(SymbolAccess::public_);
1080 ParameterSymbol* thisParam = new ParameterSymbol(classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"this");
1081 thisParam->SetType(classDelegateType->AddPointer(Span(), boost::uuids::nil_uuid()));
1082 AddMember(thisParam);
1083 ParameterSymbol* thatParam = new ParameterSymbol(classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"that");
1084 thatParam->SetType(classDelegateType->AddRvalueReference(Span(), boost::uuids::nil_uuid()));
1085 AddMember(thatParam);
1086 ComputeName();
1087 }
1088
1089 void ClassDelegateTypeMoveConstructor::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
1090 {
1091 genObjects[1]->Load(emitter, OperationFlags::none);
1092 void* thatPtr = emitter.Stack().Pop();
1093 void* thatObjectPtr = emitter.GetObjectFromClassDelegate(thatPtr);
1094 void* objectValue = emitter.CreateLoad(thatObjectPtr);
1095 OperationFlags loadFlags = OperationFlags::none;
1096 if ((flags & OperationFlags::leaveFirstArg) != OperationFlags::none)
1097 {
1098 loadFlags = loadFlags | OperationFlags::leaveFirstArg;
1099 }
1100 genObjects[0]->Load(emitter, loadFlags);
1101 void* thisPtr = emitter.Stack().Pop();
1102 void* thisObjectPtr = emitter.GetObjectFromClassDelegate(thisPtr);
1103 emitter.CreateStore(objectValue, thisObjectPtr);
1104 void* thatDelegatePtr = emitter.GetDelegateFromClassDelegate(thatPtr);
1105 void* delegateValue = emitter.CreateLoad(thatDelegatePtr);
1106 void* thisDelegatePtr = emitter.GetDelegateFromClassDelegate(thisPtr);
1107 emitter.CreateStore(delegateValue, thisDelegatePtr);
1108 }
1109
1110 ClassDelegateTypeCopyAssignment::ClassDelegateTypeCopyAssignment(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
1111 FunctionSymbol(SymbolType::classDelegateTypeCopyAssignment, span_, sourceModuleId_, name_)
1112 {
1113 }
1114
1115 ClassDelegateTypeCopyAssignment::ClassDelegateTypeCopyAssignment(ClassDelegateTypeSymbol* classDelegateType, TypeSymbol* voidType) :
1116 FunctionSymbol(SymbolType::classDelegateTypeCopyAssignment, classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"operator=")
1117 {
1118 SetGroupName(U"operator=");
1119 SetAccess(SymbolAccess::public_);
1120 ParameterSymbol* thisParam = new ParameterSymbol(classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"this");
1121 thisParam->SetType(classDelegateType->AddPointer(Span(), boost::uuids::nil_uuid()));
1122 AddMember(thisParam);
1123 ParameterSymbol* thatParam = new ParameterSymbol(classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"that");
1124 thatParam->SetType(classDelegateType->AddConst(Span(), boost::uuids::nil_uuid())->AddLvalueReference(Span(), boost::uuids::nil_uuid()));
1125 AddMember(thatParam);
1126 SetReturnType(voidType);
1127 ComputeName();
1128 }
1129
1130 void ClassDelegateTypeCopyAssignment::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
1131 {
1132 genObjects[1]->Load(emitter, OperationFlags::none);
1133 void* thatPtr = emitter.Stack().Pop();
1134 void* thatObjectPtr = emitter.GetObjectFromClassDelegate(thatPtr);
1135 void* objectValue = emitter.CreateLoad(thatObjectPtr);
1136 genObjects[0]->Load(emitter, OperationFlags::none);
1137 void* thisPtr = emitter.Stack().Pop();
1138 void* thisObjectPtr = emitter.GetObjectFromClassDelegate(thisPtr);
1139 emitter.CreateStore(objectValue, thisObjectPtr);
1140 void* thatDelegatePtr = emitter.GetDelegateFromClassDelegate(thatPtr);
1141 void* delegateValue = emitter.CreateLoad(thatDelegatePtr);
1142 void* thisDelegatePtr = emitter.GetDelegateFromClassDelegate(thisPtr);
1143 emitter.CreateStore(delegateValue, thisDelegatePtr);
1144 }
1145
1146 ClassDelegateTypeMoveAssignment::ClassDelegateTypeMoveAssignment(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
1147 FunctionSymbol(SymbolType::classDelegateTypeMoveAssignment, span_, sourceModuleId_, name_)
1148 {
1149 }
1150
1151 ClassDelegateTypeMoveAssignment::ClassDelegateTypeMoveAssignment(ClassDelegateTypeSymbol* classDelegateType, TypeSymbol* voidType) :
1152 FunctionSymbol(SymbolType::classDelegateTypeMoveAssignment, classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"operator=")
1153 {
1154 SetGroupName(U"operator=");
1155 SetAccess(SymbolAccess::public_);
1156 ParameterSymbol* thisParam = new ParameterSymbol(classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"this");
1157 thisParam->SetType(classDelegateType->AddPointer(Span(), boost::uuids::nil_uuid()));
1158 AddMember(thisParam);
1159 ParameterSymbol* thatParam = new ParameterSymbol(classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"that");
1160 thatParam->SetType(classDelegateType->AddRvalueReference(Span(), boost::uuids::nil_uuid()));
1161 AddMember(thatParam);
1162 SetReturnType(voidType);
1163 ComputeName();
1164 }
1165
1166 void ClassDelegateTypeMoveAssignment::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
1167 {
1168 genObjects[1]->Load(emitter, OperationFlags::none);
1169 void* thatPtr = emitter.Stack().Pop();
1170 void* thatObjectPtr = emitter.GetObjectFromClassDelegate(thatPtr);
1171 void* objectValue = emitter.CreateLoad(thatObjectPtr);
1172 genObjects[0]->Load(emitter, OperationFlags::none);
1173 void* thisPtr = emitter.Stack().Pop();
1174 void* thisObjectPtr = emitter.GetObjectFromClassDelegate(thisPtr);
1175 emitter.CreateStore(objectValue, thisObjectPtr);
1176 void* thatDelegatePtr = emitter.GetDelegateFromClassDelegate(thatPtr);
1177 void* delegateValue = emitter.CreateLoad(thatDelegatePtr);
1178 void* thisDelegatePtr = emitter.GetDelegateFromClassDelegate(thisPtr);
1179 emitter.CreateStore(delegateValue, thisDelegatePtr);
1180 }
1181
1182 ClassDelegateTypeEquality::ClassDelegateTypeEquality(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
1183 FunctionSymbol(SymbolType::classDelegateTypeEquality, span_, sourceModuleId_, name_)
1184 {
1185 }
1186
1187 ClassDelegateTypeEquality::ClassDelegateTypeEquality(ClassDelegateTypeSymbol* classDelegateType, TypeSymbol* boolType) :
1188 FunctionSymbol(SymbolType::classDelegateTypeEquality, classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"operator==")
1189 {
1190 SetGroupName(U"operator==");
1191 SetAccess(SymbolAccess::public_);
1192 ParameterSymbol* leftParam = new ParameterSymbol(classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"left");
1193 leftParam->SetType(classDelegateType->AddConst(Span(), boost::uuids::nil_uuid())->AddLvalueReference(Span(), boost::uuids::nil_uuid()));
1194 AddMember(leftParam);
1195 ParameterSymbol* rightParam = new ParameterSymbol(classDelegateType->GetSpan(), classDelegateType->SourceModuleId(), U"right");
1196 rightParam->SetType(classDelegateType->AddConst(Span(), boost::uuids::nil_uuid())->AddLvalueReference(Span(), boost::uuids::nil_uuid()));
1197 AddMember(rightParam);
1198 SetReturnType(boolType);
1199 ComputeName();
1200 }
1201
1202 void ClassDelegateTypeEquality::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
1203 {
1204 genObjects[0]->Load(emitter, OperationFlags::none);
1205 void* leftPtr = emitter.Stack().Pop();
1206 void* leftObjectPtr = emitter.GetObjectFromClassDelegate(leftPtr);
1207 void* leftObjectValue = emitter.CreateLoad(leftObjectPtr);
1208 genObjects[1]->Load(emitter, OperationFlags::none);
1209 void* rightPtr = emitter.Stack().Pop();
1210 void* rightObjectPtr = emitter.GetObjectFromClassDelegate(rightPtr);
1211 void* rightObjectValue = emitter.CreateLoad(rightObjectPtr);
1212 void* objectsEqual = emitter.CreateICmpEQ(leftObjectValue, rightObjectValue);
1213 void* leftDelegatePtr = emitter.GetDelegateFromClassDelegate(leftPtr);
1214 void* leftDelegateValue = emitter.CreateLoad(leftDelegatePtr);
1215 void* rightDelegatePtr = emitter.GetDelegateFromClassDelegate(rightPtr);
1216 void* rightDelegateValue = emitter.CreateLoad(rightDelegatePtr);
1217 void* delegatesEqual = emitter.CreateICmpEQ(leftDelegateValue, rightDelegateValue);
1218 void* equal = emitter.CreateAnd(objectsEqual, delegatesEqual);
1219 emitter.Stack().Push(equal);
1220 }
1221
1222 MemberFunctionToClassDelegateConversion::MemberFunctionToClassDelegateConversion(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
1223 FunctionSymbol(SymbolType::memberFunctionToClassDelegateSymbol, span_, sourceModuleId_, name_), sourceType(nullptr), targetType(nullptr), function(nullptr)
1224 {
1225 }
1226
1227 MemberFunctionToClassDelegateConversion::MemberFunctionToClassDelegateConversion(const Span& span_, const boost::uuids::uuid& sourceModuleId_, TypeSymbol* sourceType_, ClassDelegateTypeSymbol* targetType_, FunctionSymbol* function_) :
1228 FunctionSymbol(SymbolType::memberFunctionToClassDelegateSymbol, span_, sourceModuleId_, U"@conversion"), sourceType(sourceType_), targetType(targetType_), function(function_)
1229 {
1230 SetConversion();
1231 SetConversionSourceType(sourceType->PlainType(GetSpan(), SourceModuleId()));
1232 SetConversionTargetType(targetType->PlainType(GetSpan(), SourceModuleId()));
1233 }
1234
1235 std::std::vector<LocalVariableSymbol*>MemberFunctionToClassDelegateConversion::CreateTemporariesTo(FunctionSymbol*currentFunction)
1236 {
1237 std::vector<LocalVariableSymbol*> temporaries;
1238 LocalVariableSymbol* objectDelegatePairVariable = currentFunction->CreateTemporary(targetType->ObjectDelegatePairType(), GetSpan(), SourceModuleId());
1239 temporaries.push_back(objectDelegatePairVariable);
1240 return temporaries;
1241 }
1242
1243 void MemberFunctionToClassDelegateConversion::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
1244 {
1245 Assert(genObjects.size() == 1, "MemberFunctionToClassDelegateConversion needs one temporary object");
1246 void* objectValue = emitter.Stack().Pop();
1247 if (!objectValue)
1248 {
1249 throw Exception("cannot construct class delegate because expression has no this pointer", span, moduleId);
1250 }
1251 void* objectValueAsVoidPtr = emitter.CreateBitCast(objectValue, emitter.GetIrTypeForVoidPtrType());
1252 void* memFunPtrValue = emitter.GetOrInsertFunction(ToUtf8(function->MangledName()), function->IrType(emitter), function->DontThrow());
1253 genObjects[0]->Load(emitter, OperationFlags::addr);
1254 void* ptr = emitter.Stack().Pop();
1255 void* objectPtr = emitter.GetObjectFromClassDelegate(ptr);
1256 emitter.CreateStore(objectValueAsVoidPtr, objectPtr);
1257 void* delegatePtr = emitter.GetDelegateFromClassDelegate(ptr);
1258 void* delegateValue = emitter.CreateBitCast(memFunPtrValue, targetType->DelegateType()->IrType(emitter));
1259 emitter.CreateStore(delegateValue, delegatePtr);
1260 emitter.Stack().Push(ptr);
1261 }
1262
1263 void MemberFunctionToClassDelegateConversion::Check()
1264 {
1265 FunctionSymbol::Check();
1266 if (!sourceType)
1267 {
1268 throw SymbolCheckException("member function to class delegate conversion has no source type", GetSpan(), SourceModuleId());
1269 }
1270 if (!targetType)
1271 {
1272 throw SymbolCheckException("member function to class delegate conversion has no target type", GetSpan(), SourceModuleId());
1273 }
1274 if (!function)
1275 {
1276 throw SymbolCheckException("member function to class delegate conversion has no function", GetSpan(), SourceModuleId());
1277 }
1278 }
1279
1280 } }