1
2
3
4
5
6 #ifndef CMAJOR_CODEGENLLVM_LLVMCODEGENERATOR_INCLUDED
7 #define CMAJOR_CODEGENLLVM_LLVMCODEGENERATOR_INCLUDED
8 #include <cmajor/codegenllvm/CodeGenLlvmApi.hpp>
9 #include <cmajor/codegenbase/CodeGenerator.hpp>
10 #include <cmajor/ir/Emitter.hpp>
11 #include <cmajor/binder/BoundNodeVisitor.hpp>
12 #include <cmajor/symbols/SymbolTable.hpp>
13 #include <cmajor/binder/BoundClass.hpp>
14 #include <cmajor/binder/BoundStatement.hpp>
15
16 namespace cmajor { namespace codegenllvm {
17
18 using namespace cmajor::binder;
19
20 struct Cleanup
21 {
22 Cleanup(void* cleanupBlock_, void* handlerBlock_, Pad* currentPad_) : cleanupBlock(cleanupBlock_), handlerBlock(handlerBlock_), currentPad(currentPad_) {}
23 void* cleanupBlock;
24 void* handlerBlock;
25 Pad* currentPad;
26 std::vector<std::std::unique_ptr<BoundFunctionCall>>destructors;
27 };
28
29 class LlvmCodeGenerator : public cmajor::codegenbase::CodeGenerator, public BoundNodeVisitor, public cmajor::ir::EmittingDelegate
30 {
31 public:
32 LlvmCodeGenerator(cmajor::ir::EmittingContext& emittingContext_);
33 LlvmCodeGenerator(const LlvmCodeGenerator&) = delete;
34 LlvmCodeGenerator& operator=(const LlvmCodeGenerator&) = delete;
35 void GenerateCode(void* boundCompileUnit) override;
36 void Visit(BoundCompileUnit& boundCompileUnit) override;
37 void Visit(BoundNamespace& boundNamespace) override;
38 void Visit(BoundClass& boundClass) override;
39 void Visit(BoundEnumTypeDefinition& boundEnumTypeDefinition) override;
40 void Visit(BoundFunction& boundFunction) override;
41 void Visit(BoundSequenceStatement& boundSequenceStatement) override;
42 void Visit(BoundCompoundStatement& boundCompoundStatement) override;
43 void Visit(BoundIfStatement& boundIfStatement) override;
44 void Visit(BoundWhileStatement& boundWhileStatement) override;
45 void Visit(BoundDoStatement& boundDoStatement) override;
46 void Visit(BoundForStatement& boundForStatement) override;
47 void Visit(BoundSwitchStatement& boundSwitchStatement) override;
48 void Visit(BoundCaseStatement& boundCaseStatement) override;
49 void Visit(BoundDefaultStatement& boundDefaultStatement) override;
50 void Visit(BoundConstructionStatement& boundConstructionStatement) override;
51 void Visit(BoundAssignmentStatement& boundAssignmentStatement) override;
52 void Visit(BoundExpressionStatement& boundExpressionStatement) override;
53 void Visit(BoundInitializationStatement& boundInitializationStatement) override;
54 void Visit(BoundEmptyStatement& boundEmptyStatement) override;
55 void Visit(BoundSetVmtPtrStatement& boundSetVmtPtrStatement) override;
56 void Visit(BoundThrowStatement& boundThrowStatement) override;
57 void Visit(BoundParameter& boundParameter) override;
58 void Visit(BoundLocalVariable& boundLocalVariable) override;
59 void Visit(BoundMemberVariable& boundMemberVariable) override;
60 void Visit(BoundConstant& boundConstant) override;
61 void Visit(BoundEnumConstant& boundEnumConstant) override;
62 void Visit(BoundLiteral& boundLiteral) override;
63 void Visit(BoundTemporary& boundTemporary) override;
64 void Visit(BoundSizeOfExpression& boundSizeOfExpression) override;
65 void Visit(BoundAddressOfExpression& boundAddressOfExpression) override;
66 void Visit(BoundDereferenceExpression& boundDereferenceExpression) override;
67 void Visit(BoundReferenceToPointerExpression& boundReferenceToPointerExpression) override;
68 void Visit(BoundFunctionCall& boundFunctionCall) override;
69 void Visit(BoundDelegateCall& boundDelegateCall) override;
70 void Visit(BoundClassDelegateCall& boundClassDelegateCall) override;
71 void Visit(BoundConversion& boundConversion) override;
72 void Visit(BoundConstructExpression& boundConstructExpression) override;
73 void Visit(BoundConstructAndReturnTemporaryExpression& boundConstructAndReturnTemporaryExpression) override;
74 void Visit(BoundClassOrClassDelegateConversionResult& boundClassOrClassDelegateConversionResult) override;
75 void Visit(BoundIsExpression& boundIsExpression) override;
76 void Visit(BoundAsExpression& boundAsExpression) override;
77 void Visit(BoundTypeNameExpression& boundTypeNameExpression) override;
78 void Visit(BoundBitCast& boundBitCast) override;
79 void Visit(BoundFunctionPtr& boundFunctionPtr) override;
80 void Visit(BoundDisjunction& boundDisjunction) override;
81 void Visit(BoundConjunction& boundConjunction) override;
82 void Visit(BoundGlobalVariable& boundGlobalVariable) override;
83 void* GetGlobalStringPtr(int stringId) override;
84 void* GetGlobalWStringConstant(int stringId) override;
85 void* GetGlobalUStringConstant(int stringId) override;
86 void* GetGlobalUuidConstant(int uuidId) override;
87 void SetLineNumber(int32_t lineNumber) override;
88 void* HandlerBlock() override;
89 void* CleanupBlock() override;
90 bool NewCleanupNeeded() override;
91 std::string GetSourceFilePath(const Span& span, const boost::uuids::uuid& moduleId) override;
92 cmajor::ir::Pad* CurrentPad() override;
93 void* CreateClassDIType(void* classPtr) override;
94 void CreateExitFunctionCall();
95 void GenerateEnterFunctionCode(BoundFunction& boundFunction);
96 void GenerateExitFunctionCode(BoundFunction& boundFunction);
97 void GenerateInitUnwindInfoFunction(BoundCompileUnit& boundCompileUnit);
98 void GenerateInitCompileUnitFunction(BoundCompileUnit& boundCompileUnit);
99 void GenerateGlobalInitFuncion(BoundCompileUnit& boundCompileUnit);
100 virtual void* GetPersonalityFunction() const = 0;
101 virtual void GenerateCodeForCleanups() = 0;
102 void SetTarget(BoundStatement* labeledStatement);
103 void ExitBlocks(BoundCompoundStatement* targetBlock);
104 void GenJumpingBoolCode();
105 void ClearFlags();
106 int Install(const std::string& str) override;
107 int Install(const std::u16string& str) override;
108 int Install(const std::u32string& str) override;
109 void MoveAllocaIntoEntryBlock(void* allocaInst);
110 void Optimize(int optimizationLevel, const std::string& bcFilePath, const std::string& optBCFilePath);
111 void* EntryBasicBlock() const { return entryBasicBlock; }
112 protected:
113 cmajor::symbols::SymbolTable* symbolTable;
114 cmajor::symbols::Module* symbolsModule;
115 cmajor::ir::Emitter* emitter;
116 cmajor::ir::EmittingContext* emittingContext;
117 void* module;
118 bool debugInfo;
119 BoundCompileUnit* compileUnit;
120 BoundClass* currentClass;
121 BoundFunction* currentFunction;
122 std::stack<BoundClass*> classStack;
123 std::unordered_map<int, void*> utf8stringMap;
124 std::unordered_map<int, void*> utf16stringMap;
125 std::unordered_map<int, void*> utf32stringMap;
126 std::unordered_map<int, void*> uuidMap;
127 void* trueBlock;
128 void* falseBlock;
129 void* breakTarget;
130 void* continueTarget;
131 void* handlerBlock;
132 void* cleanupBlock;
133 void* entryBasicBlock;
134 bool newCleanupNeeded;
135 Pad* currentPad;
136 int prevLineNumber;
137 bool destructorCallGenerated;
138 bool lastInstructionWasRet;
139 bool basicBlockOpen;
140 void* lastAlloca;
141 int compoundLevel;
142 std::string compileUnitId;
143 BoundStatement* sequenceSecond;
144 BoundCompoundStatement* currentBlock;
145 std::vector<std::std::unique_ptr<Cleanup>>cleanups;
146 std::vector<std::std::unique_ptr<Pad>>pads;
147 std::unordered_map<BoundStatement*, void*> labeledStatementMap;
148 void* function;
149 std::unordered_map<BoundCompoundStatement*, std::std::vector<std::std::unique_ptr<BoundFunctionCall>>>blockDestructionMap;
150 std::vector<BoundCompoundStatement*> blocks;
151 bool genJumpingBoolCode;
152 BoundCompoundStatement* breakTargetBlock;
153 BoundCompoundStatement* continueTargetBlock;
154 void* defaultDest;
155 std::std::unordered_map<IntegralValue, void*, IntegralValueHash>*currentCaseMap;
156 std::set<FunctionSymbol*> compileUnitFunctions;
157 };
158
159 } }
160
161 #endif // CMAJOR_CODEGENLLVM_LLVMCODEGENERATOR_INCLUDED