1
2
3
4
5
6 #include <cmajor/symbols/EnumSymbol.hpp>
7 #include <cmajor/symbols/SymbolTable.hpp>
8 #include <cmajor/symbols/SymbolWriter.hpp>
9 #include <cmajor/symbols/SymbolReader.hpp>
10 #include <cmajor/symbols/Exception.hpp>
11 #include <cmajor/symbols/SymbolCollector.hpp>
12 #include <cmajor/symbols/Module.hpp>
13 #include <soulng/util/Unicode.hpp>
14 #include <boost/uuid/uuid_io.hpp>
15
16 namespace cmajor { namespace symbols {
17
18 using namespace soulng::unicode;
19
20 EnumTypeSymbol::EnumTypeSymbol(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
21 TypeSymbol(SymbolType::enumTypeSymbol, span_, sourceModuleId_, name_), underlyingType()
22 {
23 }
24
25 void EnumTypeSymbol::Write(SymbolWriter& writer)
26 {
27 TypeSymbol::Write(writer);
28 writer.GetBinaryWriter().Write(underlyingType->TypeId());
29 }
30
31 void EnumTypeSymbol::Read(SymbolReader& reader)
32 {
33 TypeSymbol::Read(reader);
34 boost::uuids::uuid underlyingTypeId;
35 reader.GetBinaryReader().ReadUuid(underlyingTypeId);
36 reader.GetSymbolTable()->EmplaceTypeRequest(reader, this, underlyingTypeId, 0);
37 }
38
39 void EnumTypeSymbol::EmplaceType(TypeSymbol* typeSymbol, int index)
40 {
41 Assert(index == 0, "invalid emplace type index");
42 underlyingType = typeSymbol;
43 }
44
45 std::string EnumTypeSymbol::Syntax() const
46 {
47 std::string syntax = GetSpecifierStr();
48 if (!syntax.empty())
49 {
50 syntax.append(1, ' ');
51 }
52 syntax.append("enum ");
53 syntax.append(ToUtf8(DocName()));
54 syntax.append(1, ';');
55 return syntax;
56 }
57
58 void EnumTypeSymbol::Accept(SymbolCollector* collector)
59 {
60 if (IsProject() && Access() == SymbolAccess::public_)
61 {
62 collector->AddEnumeratedType(this);
63 }
64 }
65
66 void EnumTypeSymbol::CollectMembers(SymbolCollector* collector)
67 {
68 TypeSymbol::Accept(collector);
69 }
70
71 void EnumTypeSymbol::Dump(CodeFormatter& formatter)
72 {
73 formatter.WriteLine(ToUtf8(Name()));
74 formatter.WriteLine("full name: " + ToUtf8(FullNameWithSpecifiers()));
75 formatter.WriteLine("underlying type: " + ToUtf8(underlyingType->FullName()));
76 formatter.WriteLine("typeid: " + boost::uuids::to_string(TypeId()));
77 formatter.WriteLine("enumeration constants:");
78 formatter.IncIndent();
79 SymbolCollector collector;
80 TypeSymbol::Accept(&collector);
81 for (EnumConstantSymbol* enumConstant : collector.EnumerationConstants())
82 {
83 formatter.WriteLine();
84 enumConstant->Dump(formatter);
85 }
86 formatter.DecIndent();
87 }
88
89 void EnumTypeSymbol::SetSpecifiers(Specifiers specifiers)
90 {
91 Specifiers accessSpecifiers = specifiers & Specifiers::access_;
92 SetAccess(accessSpecifiers);
93 if ((specifiers & Specifiers::static_) != Specifiers::none)
94 {
95 throw Exception("enumerated type cannot be static", GetSpan(), SourceModuleId());
96 }
97 if ((specifiers & Specifiers::virtual_) != Specifiers::none)
98 {
99 throw Exception("enumerated type cannot be virtual", GetSpan(), SourceModuleId());
100 }
101 if ((specifiers & Specifiers::override_) != Specifiers::none)
102 {
103 throw Exception("enumerated type cannot be override", GetSpan(), SourceModuleId());
104 }
105 if ((specifiers & Specifiers::abstract_) != Specifiers::none)
106 {
107 throw Exception("enumerated type cannot be abstract", GetSpan(), SourceModuleId());
108 }
109 if ((specifiers & Specifiers::inline_) != Specifiers::none)
110 {
111 throw Exception("enumerated type cannot be inline", GetSpan(), SourceModuleId());
112 }
113 if ((specifiers & Specifiers::explicit_) != Specifiers::none)
114 {
115 throw Exception("enumerated type cannot be explicit", GetSpan(), SourceModuleId());
116 }
117 if ((specifiers & Specifiers::external_) != Specifiers::none)
118 {
119 throw Exception("enumerated type cannot be external", GetSpan(), SourceModuleId());
120 }
121 if ((specifiers & Specifiers::suppress_) != Specifiers::none)
122 {
123 throw Exception("enumerated type cannot be suppressed", GetSpan(), SourceModuleId());
124 }
125 if ((specifiers & Specifiers::default_) != Specifiers::none)
126 {
127 throw Exception("enumerated type cannot be default", GetSpan(), SourceModuleId());
128 }
129 if ((specifiers & Specifiers::constexpr_) != Specifiers::none)
130 {
131 throw Exception("enumerated type cannot be constexpr", GetSpan(), SourceModuleId());
132 }
133 if ((specifiers & Specifiers::cdecl_) != Specifiers::none)
134 {
135 throw Exception("enumerated type cannot be cdecl", GetSpan(), SourceModuleId());
136 }
137 if ((specifiers & Specifiers::nothrow_) != Specifiers::none)
138 {
139 throw Exception("enumerated type cannot be nothrow", GetSpan(), SourceModuleId());
140 }
141 if ((specifiers & Specifiers::throw_) != Specifiers::none)
142 {
143 throw Exception("enumerated type cannot be throw", GetSpan(), SourceModuleId());
144 }
145 if ((specifiers & Specifiers::new_) != Specifiers::none)
146 {
147 throw Exception("enumerated type cannot be new", GetSpan(), SourceModuleId());
148 }
149 if ((specifiers & Specifiers::const_) != Specifiers::none)
150 {
151 throw Exception("enumerated type cannot be const", GetSpan(), SourceModuleId());
152 }
153 if ((specifiers & Specifiers::unit_test_) != Specifiers::none)
154 {
155 throw Exception("enumerated type cannot be unit_test", GetSpan(), SourceModuleId());
156 }
157 }
158
159 std::std::vector<EnumConstantSymbol*>EnumTypeSymbol::GetEnumConstants()
160 {
161 SymbolCollector collector;
162 TypeSymbol::Accept(&collector);
163 return collector.EnumerationConstants();
164 }
165
166 ValueType EnumTypeSymbol::GetValueType() const
167 {
168 return underlyingType->GetValueType();
169 }
170
171 Value* EnumTypeSymbol::MakeValue() const
172 {
173 return underlyingType->MakeValue();
174 }
175
176 std::u32string EnumTypeSymbol::Id() const
177 {
178 return MangledName();
179 }
180
181 void* EnumTypeSymbol::CreateDIType(Emitter& emitter)
182 {
183 uint64_t sizeInBits = SizeInBits(emitter);
184 uint32_t alignInBits = AlignmentInBits(emitter);
185 std::vector<void*> elements;
186 std::vector<EnumConstantSymbol*> enumConstants = GetEnumConstants();
187 for (EnumConstantSymbol* enumConstant : enumConstants)
188 {
189 int64_t value = 0;
190 if (underlyingType->IsUnsignedType())
191 {
192 Value* val = enumConstant->GetValue()->As(GetRootModuleForCurrentThread()->GetSymbolTable().GetTypeByName(U"ulong"), false, GetSpan(), SourceModuleId(), true);
193 if (val)
194 {
195 ULongValue* ulongValue = static_cast<ULongValue*>(val);
196 value = static_cast<int64_t>(ulongValue->GetValue());
197 }
198 }
199 else
200 {
201 Value* val = enumConstant->GetValue()->As(GetRootModuleForCurrentThread()->GetSymbolTable().GetTypeByName(U"long"), false, GetSpan(), SourceModuleId(), true);
202 if (val)
203 {
204 LongValue* longValue = static_cast<LongValue*>(val);
205 value = longValue->GetValue();
206 }
207 }
208 elements.push_back(emitter.CreateDITypeForEnumConstant(ToUtf8(enumConstant->Name()), value));
209 }
210 return emitter.CreateDITypeForEnumType(ToUtf8(Name()), ToUtf8(MangledName()), GetSpan(), SourceModuleId(), elements, sizeInBits, alignInBits, underlyingType->GetDIType(emitter));
211 }
212
213 void EnumTypeSymbol::Check()
214 {
215 TypeSymbol::Check();
216 if (!underlyingType)
217 {
218 throw SymbolCheckException( "enumerated type symbol has no underlying type", GetSpan(), SourceModuleId());
219 }
220 }
221
222 EnumConstantSymbol::EnumConstantSymbol(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
223 Symbol(SymbolType::enumConstantSymbol, span_, sourceModuleId_, name_), evaluating(false)
224 {
225 }
226
227 void EnumConstantSymbol::SetValue(Value* value_)
228 {
229 value.reset(value_);
230 }
231
232 void EnumConstantSymbol::Accept(SymbolCollector* collector)
233 {
234 if (IsProject())
235 {
236 collector->AddEnumerationConstant(this);
237 }
238 }
239
240 void EnumConstantSymbol::Dump(CodeFormatter& formatter)
241 {
242 formatter.WriteLine(ToUtf8(Name()));
243 formatter.WriteLine("value: " + value->ToString());
244 }
245
246 void EnumConstantSymbol::Write(SymbolWriter& writer)
247 {
248 Symbol::Write(writer);
249 WriteValue(value.get(), writer.GetBinaryWriter());
250 writer.GetBinaryWriter().Write(strValue);
251 }
252
253 void EnumConstantSymbol::Read(SymbolReader& reader)
254 {
255 Symbol::Read(reader);
256 value = ReadValue(reader.GetBinaryReader(), GetSpan(), SourceModuleId());
257 strValue = reader.GetBinaryReader().ReadUtf32String();
258 }
259
260 EnumTypeDefaultConstructor::EnumTypeDefaultConstructor(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
261 FunctionSymbol(SymbolType::enumTypeDefaultConstructor, span_, sourceModuleId_, name_), underlyingTypeDefaultConstructor(nullptr)
262 {
263 }
264
265 EnumTypeDefaultConstructor::EnumTypeDefaultConstructor(EnumTypeSymbol* enumType_) :
266 FunctionSymbol(SymbolType::enumTypeDefaultConstructor, enumType_->GetSpan(), enumType_->SourceModuleId(), U"enumTypeDefaultConstructor"), underlyingTypeDefaultConstructor(nullptr)
267 {
268 SetGroupName(U"@constructor");
269 SetAccess(SymbolAccess::public_);
270 ParameterSymbol* thisParam = new ParameterSymbol(enumType_->GetSpan(), enumType_->SourceModuleId(), U"this");
271 thisParam->SetType(enumType_->AddPointer(Span(), boost::uuids::nil_uuid()));
272 AddMember(thisParam);
273 ComputeName();
274 TypeSymbol* underlyingType = enumType_->UnderlyingType();
275 Assert(underlyingType->IsBasicTypeSymbol(), "basic type expected");
276 BasicTypeSymbol* basicTypeSymbol = static_cast<BasicTypeSymbol*>(underlyingType);
277 underlyingTypeDefaultConstructor = basicTypeSymbol->DefaultConstructor();
278 }
279
280 void EnumTypeDefaultConstructor::Write(SymbolWriter& writer)
281 {
282 FunctionSymbol::Write(writer);
283 Assert(underlyingTypeDefaultConstructor, "underlying default constructor not set");
284 const boost::uuids::uuid& defaultConstructorId = underlyingTypeDefaultConstructor->FunctionId();
285 writer.GetBinaryWriter().Write(defaultConstructorId);
286 }
287
288 void EnumTypeDefaultConstructor::Read(SymbolReader& reader)
289 {
290 FunctionSymbol::Read(reader);
291 boost::uuids::uuid defaultConstructorId;
292 reader.GetBinaryReader().ReadUuid(defaultConstructorId);
293 reader.GetSymbolTable()->EmplaceFunctionRequest(reader, this, defaultConstructorId, 0);
294 }
295
296 void EnumTypeDefaultConstructor::EmplaceFunction(FunctionSymbol* functionSymbol, int index)
297 {
298 if (index == 0)
299 {
300 underlyingTypeDefaultConstructor = functionSymbol;
301 }
302 else
303 {
304 Assert(false, "invalid emplace function index");
305 }
306 }
307
308 void EnumTypeDefaultConstructor::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
309 {
310 Assert(underlyingTypeDefaultConstructor, "underlying default constructor not set");
311 underlyingTypeDefaultConstructor->GenerateCall(emitter, genObjects, flags, span, moduleId);
312 }
313
314 void EnumTypeDefaultConstructor::Check()
315 {
316 FunctionSymbol::Check();
317 if (!underlyingTypeDefaultConstructor)
318 {
319 throw SymbolCheckException("enumerated type default constructor has no underlying type default constructor", GetSpan(), SourceModuleId());
320 }
321 }
322
323 EnumTypeCopyConstructor::EnumTypeCopyConstructor(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
324 FunctionSymbol(SymbolType::enumTypeCopyConstructor, span_, sourceModuleId_, name_), underlyingTypeCopyConstructor(nullptr)
325 {
326 }
327
328 EnumTypeCopyConstructor::EnumTypeCopyConstructor(EnumTypeSymbol* enumType_) :
329 FunctionSymbol(SymbolType::enumTypeCopyConstructor, enumType_->GetSpan(), enumType_->SourceModuleId(), U"enumTypeCopyConstructor"), underlyingTypeCopyConstructor(nullptr)
330 {
331 SetGroupName(U"@constructor");
332 SetAccess(SymbolAccess::public_);
333 ParameterSymbol* thisParam = new ParameterSymbol(enumType_->GetSpan(), enumType_->SourceModuleId(), U"this");
334 thisParam->SetType(enumType_->AddPointer(Span(), boost::uuids::nil_uuid()));
335 AddMember(thisParam);
336 ParameterSymbol* thatParam = new ParameterSymbol(enumType_->GetSpan(), enumType_->SourceModuleId(), U"that");
337 thatParam->SetType(enumType_);
338 AddMember(thatParam);
339 ComputeName();
340 TypeSymbol* underlyingType = enumType_->UnderlyingType();
341 Assert(underlyingType->IsBasicTypeSymbol(), "basic type expected");
342 BasicTypeSymbol* basicTypeSymbol = static_cast<BasicTypeSymbol*>(underlyingType);
343 underlyingTypeCopyConstructor = basicTypeSymbol->CopyConstructor();
344 }
345
346 void EnumTypeCopyConstructor::Write(SymbolWriter& writer)
347 {
348 FunctionSymbol::Write(writer);
349 Assert(underlyingTypeCopyConstructor, "underlying copy constructor not set");
350 const boost::uuids::uuid& copyConstructorId = underlyingTypeCopyConstructor->FunctionId();
351 writer.GetBinaryWriter().Write(copyConstructorId);
352 }
353
354 void EnumTypeCopyConstructor::Read(SymbolReader& reader)
355 {
356 FunctionSymbol::Read(reader);
357 boost::uuids::uuid copyConstructorId;
358 reader.GetBinaryReader().ReadUuid(copyConstructorId);
359 reader.GetSymbolTable()->EmplaceFunctionRequest(reader, this, copyConstructorId, 0);
360 }
361
362 void EnumTypeCopyConstructor::EmplaceFunction(FunctionSymbol* functionSymbol, int index)
363 {
364 if (index == 0)
365 {
366 underlyingTypeCopyConstructor = functionSymbol;
367 }
368 else
369 {
370 Assert(false, "invalid emplace function index");
371 }
372 }
373
374 void EnumTypeCopyConstructor::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
375 {
376 Assert(underlyingTypeCopyConstructor, "underlying copy constructor not set");
377 underlyingTypeCopyConstructor->GenerateCall(emitter, genObjects, flags, span, moduleId);
378 }
379
380 void EnumTypeCopyConstructor::Check()
381 {
382 FunctionSymbol::Check();
383 if (!underlyingTypeCopyConstructor)
384 {
385 throw SymbolCheckException("enumerated type copy constructor has no underlying type copy constructor", GetSpan(), SourceModuleId());
386 }
387 }
388
389 EnumTypeMoveConstructor::EnumTypeMoveConstructor(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
390 FunctionSymbol(SymbolType::enumTypeMoveConstructor, span_, sourceModuleId_, name_), underlyingTypeMoveConstructor(nullptr)
391 {
392 }
393
394 EnumTypeMoveConstructor::EnumTypeMoveConstructor(EnumTypeSymbol* enumType_) :
395 FunctionSymbol(SymbolType::enumTypeMoveConstructor, enumType_->GetSpan(), enumType_->SourceModuleId(), U"enumTypeMoveConstructor"), underlyingTypeMoveConstructor(nullptr)
396 {
397 SetGroupName(U"@constructor");
398 SetAccess(SymbolAccess::public_);
399 ParameterSymbol* thisParam = new ParameterSymbol(enumType_->GetSpan(), enumType_->SourceModuleId(), U"this");
400 thisParam->SetType(enumType_->AddPointer(Span(), boost::uuids::nil_uuid()));
401 AddMember(thisParam);
402 ParameterSymbol* thatParam = new ParameterSymbol(enumType_->GetSpan(), enumType_->SourceModuleId(), U"that");
403 thatParam->SetType(enumType_->AddRvalueReference(Span(), boost::uuids::nil_uuid()));
404 AddMember(thatParam);
405 ComputeName();
406 TypeSymbol* underlyingType = enumType_->UnderlyingType();
407 Assert(underlyingType->IsBasicTypeSymbol(), "basic type expected");
408 BasicTypeSymbol* basicTypeSymbol = static_cast<BasicTypeSymbol*>(underlyingType);
409 underlyingTypeMoveConstructor = basicTypeSymbol->MoveConstructor();
410 }
411
412 void EnumTypeMoveConstructor::Write(SymbolWriter& writer)
413 {
414 FunctionSymbol::Write(writer);
415 Assert(underlyingTypeMoveConstructor, "underlying move constructor not set");
416 const boost::uuids::uuid& moveConstructorId = underlyingTypeMoveConstructor->FunctionId();
417 writer.GetBinaryWriter().Write(moveConstructorId);
418 }
419
420 void EnumTypeMoveConstructor::Read(SymbolReader& reader)
421 {
422 FunctionSymbol::Read(reader);
423 boost::uuids::uuid moveConstructorId;
424 reader.GetBinaryReader().ReadUuid(moveConstructorId);
425 reader.GetSymbolTable()->EmplaceFunctionRequest(reader, this, moveConstructorId, 0);
426 }
427
428 void EnumTypeMoveConstructor::EmplaceFunction(FunctionSymbol* functionSymbol, int index)
429 {
430 if (index == 0)
431 {
432 underlyingTypeMoveConstructor = functionSymbol;
433 }
434 else
435 {
436 Assert(false, "invalid emplace function index");
437 }
438 }
439
440 void EnumTypeMoveConstructor::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
441 {
442 Assert(underlyingTypeMoveConstructor, "underlying move constructor not set");
443 underlyingTypeMoveConstructor->GenerateCall(emitter, genObjects, flags, span, moduleId);
444 }
445
446 void EnumTypeMoveConstructor::Check()
447 {
448 FunctionSymbol::Check();
449 if (!underlyingTypeMoveConstructor)
450 {
451 throw SymbolCheckException("enumerated type move constructor has no underlying type move constructor", GetSpan(), SourceModuleId());
452 }
453 }
454
455 EnumTypeCopyAssignment::EnumTypeCopyAssignment(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
456 FunctionSymbol(SymbolType::enumTypeCopyAssignment, span_, sourceModuleId_, name_), underlyingTypeCopyAssignment(nullptr)
457 {
458 }
459
460 EnumTypeCopyAssignment::EnumTypeCopyAssignment(EnumTypeSymbol* enumType_, TypeSymbol* voidType_) :
461 FunctionSymbol(SymbolType::enumTypeCopyAssignment, enumType_->GetSpan(), enumType_->SourceModuleId(), U"enumTypeCopyAssignment"), underlyingTypeCopyAssignment(nullptr)
462 {
463 SetGroupName(U"operator=");
464 SetAccess(SymbolAccess::public_);
465 ParameterSymbol* thisParam = new ParameterSymbol(enumType_->GetSpan(), enumType_->SourceModuleId(), U"this");
466 thisParam->SetType(enumType_->AddPointer(Span(), boost::uuids::nil_uuid()));
467 AddMember(thisParam);
468 ParameterSymbol* thatParam = new ParameterSymbol(enumType_->GetSpan(), enumType_->SourceModuleId(), U"that");
469 thatParam->SetType(enumType_);
470 AddMember(thatParam);
471 SetReturnType(voidType_);
472 ComputeName();
473 TypeSymbol* underlyingType = enumType_->UnderlyingType();
474 Assert(underlyingType->IsBasicTypeSymbol(), "basic type expected");
475 BasicTypeSymbol* basicTypeSymbol = static_cast<BasicTypeSymbol*>(underlyingType);
476 underlyingTypeCopyAssignment = basicTypeSymbol->CopyAssignment();
477 }
478
479 void EnumTypeCopyAssignment::Write(SymbolWriter& writer)
480 {
481 FunctionSymbol::Write(writer);
482 Assert(underlyingTypeCopyAssignment, "underlying copy assignment not set");
483 const boost::uuids::uuid& copyAssignmentId = underlyingTypeCopyAssignment->FunctionId();
484 writer.GetBinaryWriter().Write(copyAssignmentId);
485 }
486
487 void EnumTypeCopyAssignment::Read(SymbolReader& reader)
488 {
489 FunctionSymbol::Read(reader);
490 boost::uuids::uuid copyAssignmentId;
491 reader.GetBinaryReader().ReadUuid(copyAssignmentId);
492 reader.GetSymbolTable()->EmplaceFunctionRequest(reader, this, copyAssignmentId, 0);
493 }
494
495 void EnumTypeCopyAssignment::EmplaceFunction(FunctionSymbol* functionSymbol, int index)
496 {
497 if (index == 0)
498 {
499 underlyingTypeCopyAssignment = functionSymbol;
500 }
501 else
502 {
503 Assert(false, "invalid emplace function index");
504 }
505 }
506
507 void EnumTypeCopyAssignment::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
508 {
509 Assert(underlyingTypeCopyAssignment, "underlying copy assignment not set");
510 underlyingTypeCopyAssignment->GenerateCall(emitter, genObjects, flags, span, moduleId);
511 }
512
513 void EnumTypeCopyAssignment::Check()
514 {
515 FunctionSymbol::Check();
516 if (!underlyingTypeCopyAssignment)
517 {
518 throw SymbolCheckException("enumerated type copy assignment has no underlying type copy assignment", GetSpan(), SourceModuleId());
519 }
520 }
521
522 EnumTypeMoveAssignment::EnumTypeMoveAssignment(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
523 FunctionSymbol(SymbolType::enumTypeMoveAssignment, span_, sourceModuleId_, name_), underlyingTypeMoveAssignment(nullptr)
524 {
525 }
526
527 EnumTypeMoveAssignment::EnumTypeMoveAssignment(EnumTypeSymbol* enumType_, TypeSymbol* voidType_) :
528 FunctionSymbol(SymbolType::enumTypeMoveAssignment, enumType_->GetSpan(), enumType_->SourceModuleId(), U"enumTypeMoveAssignment"), underlyingTypeMoveAssignment(nullptr)
529 {
530 SetGroupName(U"operator=");
531 SetAccess(SymbolAccess::public_);
532 ParameterSymbol* thisParam = new ParameterSymbol(enumType_->GetSpan(), enumType_->SourceModuleId(), U"this");
533 thisParam->SetType(enumType_->AddPointer(Span(), boost::uuids::nil_uuid()));
534 AddMember(thisParam);
535 ParameterSymbol* thatParam = new ParameterSymbol(enumType_->GetSpan(), enumType_->SourceModuleId(), U"that");
536 thatParam->SetType(enumType_->AddRvalueReference(Span(), boost::uuids::nil_uuid()));
537 AddMember(thatParam);
538 SetReturnType(voidType_);
539 ComputeName();
540 TypeSymbol* underlyingType = enumType_->UnderlyingType();
541 Assert(underlyingType->IsBasicTypeSymbol(), "basic type expected");
542 BasicTypeSymbol* basicTypeSymbol = static_cast<BasicTypeSymbol*>(underlyingType);
543 underlyingTypeMoveAssignment = basicTypeSymbol->MoveAssignment();
544 }
545
546 void EnumTypeMoveAssignment::Write(SymbolWriter& writer)
547 {
548 FunctionSymbol::Write(writer);
549 Assert(underlyingTypeMoveAssignment, "underlying move assignment not set");
550 const boost::uuids::uuid& moveAssignmentId = underlyingTypeMoveAssignment->FunctionId();
551 writer.GetBinaryWriter().Write(moveAssignmentId);
552 }
553
554 void EnumTypeMoveAssignment::Read(SymbolReader& reader)
555 {
556 FunctionSymbol::Read(reader);
557 boost::uuids::uuid moveAssignmentId;
558 reader.GetBinaryReader().ReadUuid(moveAssignmentId);
559 reader.GetSymbolTable()->EmplaceFunctionRequest(reader, this, moveAssignmentId, 0);
560 }
561
562 void EnumTypeMoveAssignment::EmplaceFunction(FunctionSymbol* functionSymbol, int index)
563 {
564 if (index == 0)
565 {
566 underlyingTypeMoveAssignment = functionSymbol;
567 }
568 else
569 {
570 Assert(false, "invalid emplace function index");
571 }
572 }
573
574 void EnumTypeMoveAssignment::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
575 {
576 Assert(underlyingTypeMoveAssignment, "underlying move assignment not set");
577 underlyingTypeMoveAssignment->GenerateCall(emitter, genObjects, flags, span, moduleId);
578 }
579
580 void EnumTypeMoveAssignment::Check()
581 {
582 FunctionSymbol::Check();
583 if (!underlyingTypeMoveAssignment)
584 {
585 throw SymbolCheckException( "enumerated type move assignment has no underlying type move assignment", GetSpan(), SourceModuleId());
586 }
587 }
588
589 EnumTypeReturn::EnumTypeReturn(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
590 FunctionSymbol(SymbolType::enumTypeReturn, span_, sourceModuleId_, name_), underlyingTypeReturn(nullptr)
591 {
592 }
593
594 EnumTypeReturn::EnumTypeReturn(EnumTypeSymbol* enumType_) :
595 FunctionSymbol(SymbolType::enumTypeReturn, enumType_->GetSpan(), enumType_->SourceModuleId(), U"enumTypeReturn"), underlyingTypeReturn(nullptr)
596 {
597 SetGroupName(U"@return");
598 SetAccess(SymbolAccess::public_);
599 ParameterSymbol* valueParam = new ParameterSymbol(enumType_->GetSpan(), enumType_->SourceModuleId(), U"value");
600 valueParam->SetType(enumType_);
601 AddMember(valueParam);
602 SetReturnType(enumType_);
603 ComputeName();
604 TypeSymbol* underlyingType = enumType_->UnderlyingType();
605 Assert(underlyingType->IsBasicTypeSymbol(), "basic type expected");
606 BasicTypeSymbol* basicTypeSymbol = static_cast<BasicTypeSymbol*>(underlyingType);
607 underlyingTypeReturn = basicTypeSymbol->ReturnFun();
608 }
609
610 void EnumTypeReturn::Write(SymbolWriter& writer)
611 {
612 FunctionSymbol::Write(writer);
613 Assert(underlyingTypeReturn, "underlying return not set");
614 const boost::uuids::uuid& returnId = underlyingTypeReturn->FunctionId();
615 writer.GetBinaryWriter().Write(returnId);
616 }
617
618 void EnumTypeReturn::Read(SymbolReader& reader)
619 {
620 FunctionSymbol::Read(reader);
621 boost::uuids::uuid returnId;
622 reader.GetBinaryReader().ReadUuid(returnId);
623 reader.GetSymbolTable()->EmplaceFunctionRequest(reader, this, returnId, 0);
624 }
625
626 void EnumTypeReturn::EmplaceFunction(FunctionSymbol* functionSymbol, int index)
627 {
628 if (index == 0)
629 {
630 underlyingTypeReturn = functionSymbol;
631 }
632 else
633 {
634 Assert(false, "invalid emplace function index");
635 }
636 }
637
638 void EnumTypeReturn::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
639 {
640 Assert(underlyingTypeReturn, "underlying return not set");
641 underlyingTypeReturn->GenerateCall(emitter, genObjects, flags, span, moduleId);
642 }
643
644 void EnumTypeReturn::Check()
645 {
646 FunctionSymbol::Check();
647 if (!underlyingTypeReturn)
648 {
649 throw SymbolCheckException("enumerated type return has no underlying type return", GetSpan(), SourceModuleId());
650 }
651 }
652
653 EnumTypeEqualityOp::EnumTypeEqualityOp(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
654 FunctionSymbol(SymbolType::enumTypeEquality, span_, sourceModuleId_, name_), underlyingTypeEquality(nullptr)
655 {
656 }
657
658 EnumTypeEqualityOp::EnumTypeEqualityOp(EnumTypeSymbol* enumType_, TypeSymbol* boolType_) :
659 FunctionSymbol(SymbolType::enumTypeEquality, enumType_->GetSpan(), enumType_->SourceModuleId(), U"enumTypeEquality"), underlyingTypeEquality(nullptr)
660 {
661 SetGroupName(U"operator==");
662 SetAccess(SymbolAccess::public_);
663 ParameterSymbol* leftParam = new ParameterSymbol(enumType_->GetSpan(), enumType_->SourceModuleId(), U"left");
664 leftParam->SetType(enumType_);
665 AddMember(leftParam);
666 ParameterSymbol* rightParam = new ParameterSymbol(enumType_->GetSpan(), enumType_->SourceModuleId(), U"right");
667 rightParam->SetType(enumType_);
668 AddMember(rightParam);
669 SetReturnType(boolType_);
670 ComputeName();
671 TypeSymbol* underlyingType = enumType_->UnderlyingType();
672 Assert(underlyingType->IsBasicTypeSymbol(), "basic type expected");
673 BasicTypeSymbol* basicTypeSymbol = static_cast<BasicTypeSymbol*>(underlyingType);
674 underlyingTypeEquality = basicTypeSymbol->EqualityOp();
675 }
676
677 void EnumTypeEqualityOp::Write(SymbolWriter& writer)
678 {
679 FunctionSymbol::Write(writer);
680 Assert(underlyingTypeEquality, "underlying equality not set");
681 const boost::uuids::uuid& equalityId = underlyingTypeEquality->FunctionId();
682 writer.GetBinaryWriter().Write(equalityId);
683 }
684
685 void EnumTypeEqualityOp::Read(SymbolReader& reader)
686 {
687 FunctionSymbol::Read(reader);
688 boost::uuids::uuid equalityId;
689 reader.GetBinaryReader().ReadUuid(equalityId);
690 reader.GetSymbolTable()->EmplaceFunctionRequest(reader, this, equalityId, 0);
691 }
692
693 void EnumTypeEqualityOp::EmplaceFunction(FunctionSymbol* functionSymbol, int index)
694 {
695 if (index == 0)
696 {
697 underlyingTypeEquality = functionSymbol;
698 }
699 else
700 {
701 Assert(false, "invalid emplace function index");
702 }
703 }
704
705 void EnumTypeEqualityOp::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
706 {
707 Assert(underlyingTypeEquality, "underlying equality not set");
708 underlyingTypeEquality->GenerateCall(emitter, genObjects, flags, span, moduleId);
709 }
710
711 void EnumTypeEqualityOp::Check()
712 {
713 FunctionSymbol::Check();
714 if (!underlyingTypeEquality)
715 {
716 throw SymbolCheckException("enumerated type equality operation has no underlying type equality operation", GetSpan(), SourceModuleId());
717 }
718 }
719
720 EnumTypeToUnderlyingTypeConversion::EnumTypeToUnderlyingTypeConversion(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_) :
721 FunctionSymbol(SymbolType::enumTypeToUnderlyingType, span_, sourceModuleId_, name_), sourceType(), targetType()
722 {
723 SetGroupName(U"@conversion");
724 }
725
726 EnumTypeToUnderlyingTypeConversion::EnumTypeToUnderlyingTypeConversion(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_, TypeSymbol* sourceType_, TypeSymbol* targetType_) :
727 FunctionSymbol(SymbolType::enumTypeToUnderlyingType, span_, sourceModuleId_, name_), sourceType(sourceType_), targetType(targetType_)
728 {
729 SetConversion();
730 SetGroupName(U"@conversion");
731 SetConversionSourceType(sourceType->PlainType(GetSpan(), SourceModuleId()));
732 SetConversionTargetType(targetType->PlainType(GetSpan(), SourceModuleId()));
733 }
734
735 void EnumTypeToUnderlyingTypeConversion::Write(SymbolWriter& writer)
736 {
737 FunctionSymbol::Write(writer);
738 writer.GetBinaryWriter().Write(sourceType->TypeId());
739 writer.GetBinaryWriter().Write(targetType->TypeId());
740 }
741
742 void EnumTypeToUnderlyingTypeConversion::Read(SymbolReader& reader)
743 {
744 FunctionSymbol::Read(reader);
745 boost::uuids::uuid sourceTypeId;
746 reader.GetBinaryReader().ReadUuid(sourceTypeId);
747 reader.GetSymbolTable()->EmplaceTypeRequest(reader, this, sourceTypeId, 1);
748 boost::uuids::uuid targetTypeId;
749 reader.GetBinaryReader().ReadUuid(targetTypeId);
750 reader.GetSymbolTable()->EmplaceTypeRequest(reader, this, targetTypeId, 2);
751 }
752
753 void EnumTypeToUnderlyingTypeConversion::EmplaceType(TypeSymbol* typeSymbol, int index)
754 {
755 if (index == 1)
756 {
757 sourceType = typeSymbol;
758 }
759 else if (index == 2)
760 {
761 targetType = typeSymbol;
762 }
763 else
764 {
765 FunctionSymbol::EmplaceType(typeSymbol, index);
766 }
767 }
768
769 void EnumTypeToUnderlyingTypeConversion::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
770 {
771 }
772
773 void EnumTypeToUnderlyingTypeConversion::Check()
774 {
775 FunctionSymbol::Check();
776 if (!sourceType)
777 {
778 throw SymbolCheckException("enum type to underlying type conversion has no source type", GetSpan(), SourceModuleId());
779 }
780 if (!targetType)
781 {
782 throw SymbolCheckException("enum type to underlying type conversion has no target type", GetSpan(), SourceModuleId());
783 }
784 }
785
786 UnderlyingTypeToEnumTypeConversion::UnderlyingTypeToEnumTypeConversion(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_)
787 : FunctionSymbol(SymbolType::underlyingToEnumType, span_, sourceModuleId_, name_), sourceType(), targetType()
788 {
789 SetGroupName(U"@conversion");
790 }
791
792 UnderlyingTypeToEnumTypeConversion::UnderlyingTypeToEnumTypeConversion(const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_, TypeSymbol* sourceType_, TypeSymbol* targetType_)
793 : FunctionSymbol(SymbolType::underlyingToEnumType, span_, sourceModuleId_, name_), sourceType(sourceType_), targetType(targetType_)
794 {
795 SetConversion();
796 SetGroupName(U"@conversion");
797 SetConversionSourceType(sourceType->PlainType(GetSpan(), SourceModuleId()));
798 SetConversionTargetType(targetType->PlainType(GetSpan(), SourceModuleId()));
799 }
800
801 void UnderlyingTypeToEnumTypeConversion::Write(SymbolWriter& writer)
802 {
803 FunctionSymbol::Write(writer);
804 writer.GetBinaryWriter().Write(sourceType->TypeId());
805 writer.GetBinaryWriter().Write(targetType->TypeId());
806 }
807
808 void UnderlyingTypeToEnumTypeConversion::Read(SymbolReader& reader)
809 {
810 FunctionSymbol::Read(reader);
811 boost::uuids::uuid sourceTypeId;
812 reader.GetBinaryReader().ReadUuid(sourceTypeId);
813 reader.GetSymbolTable()->EmplaceTypeRequest(reader, this, sourceTypeId, 1);
814 boost::uuids::uuid targetTypeId;
815 reader.GetBinaryReader().ReadUuid(targetTypeId);
816 reader.GetSymbolTable()->EmplaceTypeRequest(reader, this, targetTypeId, 2);
817 }
818
819 void UnderlyingTypeToEnumTypeConversion::EmplaceType(TypeSymbol* typeSymbol, int index)
820 {
821 if (index == 1)
822 {
823 sourceType = typeSymbol;
824 }
825 else if (index == 2)
826 {
827 targetType = typeSymbol;
828 }
829 else
830 {
831 FunctionSymbol::EmplaceType(typeSymbol, index);
832 }
833 }
834
835 void UnderlyingTypeToEnumTypeConversion::GenerateCall(Emitter& emitter, std::std::vector<GenObject*>&genObjects, OperationFlagsflags, constSpan&span, constboost::uuids::uuid& moduleId)
836 {
837 }
838
839 void UnderlyingTypeToEnumTypeConversion::Check()
840 {
841 FunctionSymbol::Check();
842 if (!sourceType)
843 {
844 throw SymbolCheckException("underlying type to enum type conversion has no source type", GetSpan(), SourceModuleId());
845 }
846 if (!targetType)
847 {
848 throw SymbolCheckException("underlying type to enum type conversion has no target type", GetSpan(), SourceModuleId());
849 }
850 }
851
852 } }