]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/spirit/example/qi/compiler_tutorial/conjure3/compiler.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / spirit / example / qi / compiler_tutorial / conjure3 / compiler.hpp
CommitLineData
7c673cae
FG
1/*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6=============================================================================*/
7#if !defined(BOOST_SPIRIT_CONJURE_COMPILER_HPP)
8#define BOOST_SPIRIT_CONJURE_COMPILER_HPP
9
10#include "ast.hpp"
11#include "error_handler.hpp"
12#include "vm.hpp"
13#include <map>
14
15#include <boost/function.hpp>
16#include <boost/shared_ptr.hpp>
1e59de90
TL
17#include <boost/phoenix/core.hpp>
18#include <boost/phoenix/function.hpp>
19#include <boost/phoenix/operator.hpp>
7c673cae
FG
20#include <boost/iterator/transform_iterator.hpp>
21
22#include <llvm/DerivedTypes.h>
23#include <llvm/Constants.h>
24#include <llvm/LLVMContext.h>
25#include <llvm/Module.h>
26#include <llvm/PassManager.h>
27#include <llvm/Analysis/Verifier.h>
28#include <llvm/Analysis/Passes.h>
29#include <llvm/Transforms/Scalar.h>
30#include <llvm/Support/IRBuilder.h>
31
32namespace client { namespace code_gen
33{
34 unsigned const int_size = 32;
35 struct compiler;
36 struct llvm_compiler;
37
38 ///////////////////////////////////////////////////////////////////////////
39 // The Value (light abstraction of an LLVM::Value)
40 ///////////////////////////////////////////////////////////////////////////
41 struct value
42 {
43 value();
44 value(value const& rhs);
45
46 value& operator=(value const& rhs);
47 bool is_lvalue() const;
48 bool is_valid() const;
49 operator bool() const;
50
51 value& assign(value const& rhs);
52
53 void name(char const* id);
54 void name(std::string const& id);
55
56 friend value operator-(value a);
57 friend value operator!(value a);
58 friend value operator+(value a, value b);
59 friend value operator-(value a, value b);
60 friend value operator*(value a, value b);
61 friend value operator/(value a, value b);
62 friend value operator%(value a, value b);
63
64 friend value operator&(value a, value b);
65 friend value operator|(value a, value b);
66 friend value operator^(value a, value b);
67 friend value operator<<(value a, value b);
68 friend value operator>>(value a, value b);
69
70 friend value operator==(value a, value b);
71 friend value operator!=(value a, value b);
72 friend value operator<(value a, value b);
73 friend value operator<=(value a, value b);
74 friend value operator>(value a, value b);
75 friend value operator>=(value a, value b);
76
77 private:
78
79 struct to_llvm_value;
80 friend struct to_llvm_value;
81 friend struct llvm_compiler;
82
83 value(
84 llvm::Value* v,
85 bool is_lvalue_,
86 llvm::IRBuilder<>* builder);
87
88 llvm::LLVMContext& context() const
89 { return llvm::getGlobalContext(); }
90
91 operator llvm::Value*() const;
92
93 llvm::Value* v;
94 bool is_lvalue_;
95 llvm::IRBuilder<>* builder;
96 };
97
98 ///////////////////////////////////////////////////////////////////////////
99 // The Basic Block (light abstraction of an LLVM::BasicBlock)
100 ///////////////////////////////////////////////////////////////////////////
101 struct function;
102
103 struct basic_block
104 {
105 basic_block()
106 : b(0) {}
107
108 bool has_terminator() const;
109 bool is_valid() const;
110
111 private:
112
113 basic_block(llvm::BasicBlock* b)
114 : b(b) {}
115
116 operator llvm::BasicBlock*() const
117 { return b; }
118
119 friend struct llvm_compiler;
120 friend struct function;
121 llvm::BasicBlock* b;
122 };
123
124 ///////////////////////////////////////////////////////////////////////////
125 // The Function (light abstraction of an LLVM::Function)
126 ///////////////////////////////////////////////////////////////////////////
127 struct llvm_compiler;
128
129 struct function
130 {
131 private:
132
133 struct to_value;
134 typedef llvm::Function::arg_iterator arg_iterator;
135 typedef boost::transform_iterator<
136 to_value, arg_iterator>
137 arg_val_iterator;
138
139 public:
140
141 typedef boost::iterator_range<arg_val_iterator> arg_range;
142
143 function()
144 : f(0), c(c) {}
145
146 std::string name() const;
147
148 std::size_t arg_size() const;
149 arg_range args() const;
150
151 void add(basic_block const& b);
152 void erase_from_parent();
153 basic_block last_block();
154 bool empty() const;
155
156 bool is_valid() const;
157 void verify() const;
158
159 private:
160
161 function(llvm::Function* f, llvm_compiler* c)
162 : f(f), c(c) {}
163
164 operator llvm::Function*() const;
165
166 friend struct llvm_compiler;
167 llvm::Function* f;
168 llvm_compiler* c;
169 };
170
171 ///////////////////////////////////////////////////////////////////////////
172 // The LLVM Compiler. Lower level compiler (does not deal with ASTs)
173 ///////////////////////////////////////////////////////////////////////////
174 struct llvm_compiler
175 {
176 llvm_compiler(vmachine& vm)
177 : llvm_builder(context())
178 , vm(vm)
179 , fpm(vm.module())
180 { init_fpm(); }
181
182 value val() { return value(); }
183 value val(unsigned int x);
184 value val(int x);
185 value val(bool x);
186
187 value var(char const* name);
188 value var(std::string const& name);
189
190 template <typename Container>
191 value call(function callee, Container const& args);
192
193 function get_function(char const* name);
194 function get_function(std::string const& name);
195 function get_current_function();
196
197 function declare_function(
198 bool void_return
199 , std::string const& name
200 , std::size_t nargs);
201
202 basic_block make_basic_block(
203 char const* name
204 , function parent = function()
205 , basic_block before = basic_block());
206
207 basic_block get_insert_block();
208 void set_insert_point(basic_block b);
209
210 void conditional_branch(
211 value cond, basic_block true_br, basic_block false_br);
212 void branch(basic_block b);
213
214 void return_();
215 void return_(value v);
216
217 void optimize_function(function f);
218
219 protected:
220
221 llvm::LLVMContext& context() const
222 { return llvm::getGlobalContext(); }
223
224 llvm::IRBuilder<>& builder()
225 { return llvm_builder; }
226
227 private:
228
229 friend struct function::to_value;
230
231 value val(llvm::Value* v);
232
233 template <typename C>
234 llvm::Value* call_impl(
235 function callee,
236 C const& args);
237
238 void init_fpm();
239 llvm::IRBuilder<> llvm_builder;
240 vmachine& vm;
241 llvm::FunctionPassManager fpm;
242 };
243
244 ///////////////////////////////////////////////////////////////////////////
245 // The main compiler. Generates code from our AST.
246 ///////////////////////////////////////////////////////////////////////////
247 struct compiler : llvm_compiler
248 {
249 typedef value result_type;
250
251 template <typename ErrorHandler>
252 compiler(vmachine& vm, ErrorHandler& error_handler_)
253 : llvm_compiler(vm)
254 {
255 using namespace boost::phoenix::arg_names;
256 namespace phx = boost::phoenix;
257 using boost::phoenix::function;
258
259 error_handler = function<ErrorHandler>(error_handler_)(
260 "Error! ", _2, phx::cref(error_handler_.iters)[_1]);
261 }
262
263 value operator()(ast::nil) { BOOST_ASSERT(0); return val(); }
264 value operator()(unsigned int x);
265 value operator()(bool x);
266 value operator()(ast::primary_expr const& x);
267 value operator()(ast::identifier const& x);
268 value operator()(ast::unary_expr const& x);
269 value operator()(ast::function_call const& x);
270 value operator()(ast::expression const& x);
271 value operator()(ast::assignment const& x);
272
273 bool operator()(ast::variable_declaration const& x);
274 bool operator()(ast::statement_list const& x);
275 bool operator()(ast::statement const& x);
276 bool operator()(ast::if_statement const& x);
277 bool operator()(ast::while_statement const& x);
278 bool operator()(ast::return_statement const& x);
279 bool operator()(ast::function const& x);
280 bool operator()(ast::function_list const& x);
281
282 private:
283
284 value compile_binary_expression(
285 value lhs, value rhs, token_ids::type op);
286
287 value compile_expression(
288 int min_precedence,
289 value lhs,
290 std::list<ast::operation>::const_iterator& rest_begin,
291 std::list<ast::operation>::const_iterator rest_end);
292
293 struct statement_compiler;
294 statement_compiler& as_statement();
295
296 function function_decl(ast::function const& x);
297 void function_allocas(ast::function const& x, function function);
298
299 boost::function<
300 void(int tag, std::string const& what)>
301 error_handler;
302
303 bool void_return;
304 std::string current_function_name;
305 std::map<std::string, value> locals;
306 basic_block return_block;
307 value return_var;
308 };
309}}
310
311#endif