jit: Add checking for dereference of void *
[official-gcc.git] / gcc / jit / jit-playback.h
blob4d087de33d1ad2a662184f39965100772893bca0
1 /* Internals of libgccjit: classes for playing back recorded API calls.
2 Copyright (C) 2013-2015 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #ifndef JIT_PLAYBACK_H
22 #define JIT_PLAYBACK_H
24 #include <utility> // for std::pair
26 #include "jit-recording.h"
28 namespace gcc {
30 namespace jit {
32 /**********************************************************************
33 Playback.
34 **********************************************************************/
36 namespace playback {
38 class context
40 public:
41 context (::gcc::jit::recording::context *ctxt);
42 ~context ();
44 void gt_ggc_mx ();
46 void replay ();
48 location *
49 new_location (recording::location *rloc,
50 const char *filename,
51 int line,
52 int column);
54 type *
55 get_type (enum gcc_jit_types type);
57 type *
58 new_array_type (location *loc,
59 type *element_type,
60 int num_elements);
62 field *
63 new_field (location *loc,
64 type *type,
65 const char *name);
67 compound_type *
68 new_compound_type (location *loc,
69 const char *name,
70 bool is_struct); /* else is union */
72 type *
73 new_function_type (type *return_type,
74 const auto_vec<type *> *param_types,
75 int is_variadic);
77 param *
78 new_param (location *loc,
79 type *type,
80 const char *name);
82 function *
83 new_function (location *loc,
84 enum gcc_jit_function_kind kind,
85 type *return_type,
86 const char *name,
87 const auto_vec<param *> *params,
88 int is_variadic,
89 enum built_in_function builtin_id);
91 lvalue *
92 new_global (location *loc,
93 type *type,
94 const char *name);
96 rvalue *
97 new_rvalue_from_int (type *type,
98 int value);
100 rvalue *
101 new_rvalue_from_double (type *type,
102 double value);
104 rvalue *
105 new_rvalue_from_ptr (type *type,
106 void *value);
108 rvalue *
109 new_string_literal (const char *value);
111 rvalue *
112 new_unary_op (location *loc,
113 enum gcc_jit_unary_op op,
114 type *result_type,
115 rvalue *a);
117 rvalue *
118 new_binary_op (location *loc,
119 enum gcc_jit_binary_op op,
120 type *result_type,
121 rvalue *a, rvalue *b);
123 rvalue *
124 new_comparison (location *loc,
125 enum gcc_jit_comparison op,
126 rvalue *a, rvalue *b);
128 rvalue *
129 new_call (location *loc,
130 function *func,
131 const auto_vec<rvalue *> *args);
133 rvalue *
134 new_call_through_ptr (location *loc,
135 rvalue *fn_ptr,
136 const auto_vec<rvalue *> *args);
138 rvalue *
139 new_cast (location *loc,
140 rvalue *expr,
141 type *type_);
143 lvalue *
144 new_array_access (location *loc,
145 rvalue *ptr,
146 rvalue *index);
148 void
149 set_str_option (enum gcc_jit_str_option opt,
150 const char *value);
152 void
153 set_int_option (enum gcc_jit_int_option opt,
154 int value);
156 void
157 set_bool_option (enum gcc_jit_bool_option opt,
158 int value);
160 const char *
161 get_str_option (enum gcc_jit_str_option opt) const
163 return m_recording_ctxt->get_str_option (opt);
167 get_int_option (enum gcc_jit_int_option opt) const
169 return m_recording_ctxt->get_int_option (opt);
173 get_bool_option (enum gcc_jit_bool_option opt) const
175 return m_recording_ctxt->get_bool_option (opt);
178 builtins_manager *get_builtins_manager () const
180 return m_recording_ctxt->get_builtins_manager ();
183 result *
184 compile ();
186 void
187 add_error (location *loc, const char *fmt, ...)
188 GNU_PRINTF(3, 4);
190 void
191 add_error_va (location *loc, const char *fmt, va_list ap)
192 GNU_PRINTF(3, 0);
194 const char *
195 get_first_error () const;
197 void
198 set_tree_location (tree t, location *loc);
200 tree
201 new_field_access (location *loc,
202 tree datum,
203 field *field);
205 tree
206 new_dereference (tree ptr, location *loc);
208 tree
209 as_truth_value (tree expr, location *loc);
211 bool errors_occurred () const
213 return m_recording_ctxt->errors_occurred ();
216 private:
217 void dump_generated_code ();
219 rvalue *
220 build_call (location *loc,
221 tree fn_ptr,
222 const auto_vec<rvalue *> *args);
224 tree
225 build_cast (location *loc,
226 rvalue *expr,
227 type *type_);
229 source_file *
230 get_source_file (const char *filename);
232 void handle_locations ();
234 const char * get_path_c_file () const;
235 const char * get_path_s_file () const;
236 const char * get_path_so_file () const;
238 private:
240 /* Functions for implementing "compile". */
242 void acquire_mutex ();
243 void release_mutex ();
245 void
246 make_fake_args (vec <char *> *argvec,
247 const char *ctxt_progname,
248 vec <recording::requested_dump> *requested_dumps);
250 void
251 extract_any_requested_dumps
252 (vec <recording::requested_dump> *requested_dumps);
254 char *
255 read_dump_file (const char *path);
257 void
258 convert_to_dso (const char *ctxt_progname);
260 result *
261 dlopen_built_dso ();
263 private:
264 ::gcc::jit::recording::context *m_recording_ctxt;
266 tempdir *m_tempdir;
268 auto_vec<function *> m_functions;
269 tree m_char_array_type_node;
270 tree m_const_char_ptr;
272 /* Source location handling. */
273 auto_vec<source_file *> m_source_files;
275 auto_vec<std::pair<tree, location *> > m_cached_locations;
278 /* A temporary wrapper object.
279 These objects are (mostly) only valid during replay.
280 We allocate them on the GC heap, so that they will be cleaned
281 the next time the GC collects.
282 The exception is the "function" class, which is tracked and marked by
283 the jit::context, since it needs to stay alive during post-processing
284 (when the GC could run). */
285 class wrapper
287 public:
288 /* Allocate in the GC heap. */
289 void *operator new (size_t sz);
291 /* Some wrapper subclasses contain vec<> and so need to
292 release them when they are GC-ed. */
293 virtual void finalizer () { }
297 class type : public wrapper
299 public:
300 type (tree inner)
301 : m_inner(inner)
304 tree as_tree () const { return m_inner; }
306 type *get_pointer () const { return new type (build_pointer_type (m_inner)); }
308 type *get_const () const
310 return new type (build_qualified_type (m_inner, TYPE_QUAL_CONST));
313 type *get_volatile () const
315 return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE));
318 private:
319 tree m_inner;
322 class compound_type : public type
324 public:
325 compound_type (tree inner)
326 : type (inner)
329 void set_fields (const auto_vec<field *> *fields);
332 class field : public wrapper
334 public:
335 field (tree inner)
336 : m_inner(inner)
339 tree as_tree () const { return m_inner; }
341 private:
342 tree m_inner;
345 class function : public wrapper
347 public:
348 function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
350 void gt_ggc_mx ();
351 void finalizer ();
353 tree get_return_type_as_tree () const;
355 tree as_fndecl () const { return m_inner_fndecl; }
357 enum gcc_jit_function_kind get_kind () const { return m_kind; }
359 lvalue *
360 new_local (location *loc,
361 type *type,
362 const char *name);
364 block*
365 new_block (const char *name);
367 void
368 build_stmt_list ();
370 void
371 postprocess ();
373 public:
374 context *m_ctxt;
376 public:
377 void
378 set_tree_location (tree t, location *loc)
380 m_ctxt->set_tree_location (t, loc);
383 private:
384 tree m_inner_fndecl;
385 tree m_inner_block;
386 tree m_inner_bind_expr;
387 enum gcc_jit_function_kind m_kind;
388 tree m_stmt_list;
389 tree_stmt_iterator m_stmt_iter;
390 vec<block *> m_blocks;
393 class block : public wrapper
395 public:
396 block (function *func,
397 const char *name);
399 void finalizer ();
401 tree as_label_decl () const { return m_label_decl; }
403 void
404 add_eval (location *loc,
405 rvalue *rvalue);
407 void
408 add_assignment (location *loc,
409 lvalue *lvalue,
410 rvalue *rvalue);
412 void
413 add_comment (location *loc,
414 const char *text);
416 void
417 add_conditional (location *loc,
418 rvalue *boolval,
419 block *on_true,
420 block *on_false);
422 block *
423 add_block (location *loc,
424 const char *name);
426 void
427 add_jump (location *loc,
428 block *target);
430 void
431 add_return (location *loc,
432 rvalue *rvalue);
434 private:
435 void
436 set_tree_location (tree t, location *loc)
438 m_func->set_tree_location (t, loc);
441 void add_stmt (tree stmt)
443 /* TODO: use one stmt_list per block. */
444 m_stmts.safe_push (stmt);
447 private:
448 function *m_func;
449 tree m_label_decl;
450 vec<tree> m_stmts;
452 public: // for now
453 tree m_label_expr;
455 friend class function;
458 class rvalue : public wrapper
460 public:
461 rvalue (context *ctxt, tree inner)
462 : m_ctxt (ctxt),
463 m_inner (inner)
466 rvalue *
467 as_rvalue () { return this; }
469 tree as_tree () const { return m_inner; }
471 context *get_context () const { return m_ctxt; }
473 type *
474 get_type () { return new type (TREE_TYPE (m_inner)); }
476 rvalue *
477 access_field (location *loc,
478 field *field);
480 lvalue *
481 dereference_field (location *loc,
482 field *field);
484 lvalue *
485 dereference (location *loc);
487 private:
488 context *m_ctxt;
489 tree m_inner;
492 class lvalue : public rvalue
494 public:
495 lvalue (context *ctxt, tree inner)
496 : rvalue(ctxt, inner)
499 lvalue *
500 as_lvalue () { return this; }
502 lvalue *
503 access_field (location *loc,
504 field *field);
506 rvalue *
507 get_address (location *loc);
511 class param : public lvalue
513 public:
514 param (context *ctxt, tree inner)
515 : lvalue(ctxt, inner)
519 /* Dealing with the linemap API.
521 It appears that libcpp requires locations to be created as if by
522 a tokenizer, creating them by filename, in ascending order of
523 line/column, whereas our API doesn't impose any such constraints:
524 we allow client code to create locations in arbitrary orders.
526 To square this circle, we need to cache all location creation,
527 grouping things up by filename/line, and then creating the linemap
528 entries in a post-processing phase. */
530 /* A set of locations, all sharing a filename */
531 class source_file : public wrapper
533 public:
534 source_file (tree filename);
535 void finalizer ();
537 source_line *
538 get_source_line (int line_num);
540 tree filename_as_tree () const { return m_filename; }
542 const char*
543 get_filename () const { return IDENTIFIER_POINTER (m_filename); }
545 vec<source_line *> m_source_lines;
547 private:
548 tree m_filename;
551 /* A source line, with one or more locations of interest. */
552 class source_line : public wrapper
554 public:
555 source_line (source_file *file, int line_num);
556 void finalizer ();
558 location *
559 get_location (recording::location *rloc, int column_num);
561 int get_line_num () const { return m_line_num; }
563 vec<location *> m_locations;
565 private:
566 source_file *m_source_file;
567 int m_line_num;
570 /* A specific location on a source line. This is what we expose
571 to the client API. */
572 class location : public wrapper
574 public:
575 location (recording::location *loc, source_line *line, int column_num);
577 int get_column_num () const { return m_column_num; }
579 recording::location *get_recording_loc () const { return m_recording_loc; }
581 source_location m_srcloc;
583 private:
584 recording::location *m_recording_loc;
585 source_line *m_line;
586 int m_column_num;
589 } // namespace gcc::jit::playback
591 extern playback::context *active_playback_ctxt;
593 } // namespace gcc::jit
595 } // namespace gcc
597 #endif /* JIT_PLAYBACK_H */