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