Line data Source code
1 : /* Internals of libgccjit: classes for playing back recorded API calls.
2 : Copyright (C) 2013-2026 Free Software Foundation, Inc.
3 : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 :
5 : This file is part of GCC.
6 :
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.
11 :
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.
16 :
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/>. */
20 :
21 : #ifndef JIT_PLAYBACK_H
22 : #define JIT_PLAYBACK_H
23 :
24 : #include <string>
25 : #include <utility> // for std::pair
26 : #include <vector>
27 :
28 : #include "timevar.h"
29 : #include "varasm.h"
30 :
31 : #include "jit-recording.h"
32 : #include "jit-target.h"
33 :
34 : namespace diagnostics
35 : {
36 : class context;
37 : struct diagnostic_info;
38 : }
39 :
40 : namespace gcc {
41 :
42 : namespace jit {
43 :
44 : const char* fn_attribute_to_string (gcc_jit_fn_attribute attr);
45 : const char* variable_attribute_to_string (gcc_jit_variable_attribute attr);
46 :
47 : /**********************************************************************
48 : Playback.
49 : **********************************************************************/
50 :
51 : namespace playback {
52 :
53 : void
54 : set_variable_string_attribute (
55 : const std::vector<std::pair<gcc_jit_variable_attribute,
56 : std::string>> &attributes,
57 : tree decl);
58 :
59 : /* playback::context is an abstract base class.
60 :
61 : The three concrete subclasses are:
62 : - playback::compile_to_memory
63 : - playback::compile_to_file.
64 : - playback::populate_target_info */
65 :
66 : class context : public log_user
67 : {
68 : public:
69 : context (::gcc::jit::recording::context *ctxt);
70 : ~context ();
71 :
72 : void gt_ggc_mx ();
73 :
74 : void replay ();
75 :
76 : location *
77 : new_location (recording::location *rloc,
78 : const char *filename,
79 : int line,
80 : int column);
81 :
82 : type *
83 : get_type (enum gcc_jit_types type);
84 :
85 : void
86 : set_output_ident (const char* ident);
87 :
88 : type *
89 : new_array_type (location *loc,
90 : type *element_type,
91 : uint64_t num_elements);
92 :
93 : field *
94 : new_field (location *loc,
95 : type *type,
96 : const char *name);
97 :
98 : field *
99 : new_bitfield (location *loc,
100 : type *type,
101 : int width,
102 : const char *name);
103 :
104 : compound_type *
105 : new_compound_type (location *loc,
106 : const char *name,
107 : bool is_struct); /* else is union */
108 :
109 : type *
110 : new_function_type (type *return_type,
111 : const auto_vec<type *> *param_types,
112 : int is_variadic);
113 :
114 : param *
115 : new_param (location *loc,
116 : type *type,
117 : const char *name);
118 :
119 : function *
120 : new_function (location *loc,
121 : enum gcc_jit_function_kind kind,
122 : type *return_type,
123 : const char *name,
124 : const auto_vec<param *> *params,
125 : int is_variadic,
126 : enum built_in_function builtin_id,
127 : const std::vector<gcc_jit_fn_attribute> &attributes,
128 : const std::vector<std::pair<gcc_jit_fn_attribute,
129 : std::string>> &string_attributes,
130 : const std::vector<std::pair<gcc_jit_fn_attribute,
131 : std::vector<int>>>
132 : &int_array_attributes,
133 : bool is_target_builtin);
134 :
135 : lvalue *
136 : new_global (location *loc,
137 : enum gcc_jit_global_kind kind,
138 : type *type,
139 : const char *name,
140 : enum global_var_flags flags,
141 : const std::vector<std::pair<gcc_jit_variable_attribute,
142 : std::string>> &attributes,
143 : bool readonly);
144 :
145 : lvalue *
146 : new_global_initialized (location *loc,
147 : enum gcc_jit_global_kind kind,
148 : type *type,
149 : size_t element_size,
150 : size_t initializer_num_elem,
151 : const void *initializer,
152 : const char *name,
153 : enum global_var_flags flags,
154 : const std::vector<std::pair<
155 : gcc_jit_variable_attribute,
156 : std::string>>
157 : &attributes,
158 : bool readonly);
159 :
160 : rvalue *
161 : new_ctor (location *log,
162 : type *type,
163 : const auto_vec<field*> *fields,
164 : const auto_vec<rvalue*> *rvalues);
165 :
166 :
167 : void
168 : global_set_init_rvalue (lvalue* variable,
169 : rvalue* init);
170 :
171 : template <typename HOST_TYPE>
172 : rvalue *
173 : new_rvalue_from_const (type *type,
174 : HOST_TYPE value);
175 :
176 : rvalue *
177 : new_sizeof (type *type);
178 :
179 : rvalue *
180 : new_alignof (type *type);
181 :
182 : rvalue *
183 : new_string_literal (const char *value);
184 :
185 : rvalue *
186 : new_rvalue_from_vector (location *loc,
187 : type *type,
188 : const auto_vec<rvalue *> &elements);
189 :
190 : rvalue *
191 : new_rvalue_vector_perm (location *loc,
192 : rvalue* elements1,
193 : rvalue* elements2,
194 : rvalue* mask);
195 :
196 : rvalue *
197 : new_unary_op (location *loc,
198 : enum gcc_jit_unary_op op,
199 : type *result_type,
200 : rvalue *a);
201 :
202 : rvalue *
203 : new_binary_op (location *loc,
204 : enum gcc_jit_binary_op op,
205 : type *result_type,
206 : rvalue *a, rvalue *b);
207 :
208 : rvalue *
209 : new_comparison (location *loc,
210 : enum gcc_jit_comparison op,
211 : rvalue *a, rvalue *b, type *vec_result_type);
212 :
213 : rvalue *
214 : new_call (location *loc,
215 : function *func,
216 : const auto_vec<rvalue *> *args,
217 : bool require_tail_call);
218 :
219 : rvalue *
220 : new_call_through_ptr (location *loc,
221 : rvalue *fn_ptr,
222 : const auto_vec<rvalue *> *args,
223 : bool require_tail_call);
224 :
225 : rvalue *
226 : new_cast (location *loc,
227 : rvalue *expr,
228 : type *type_);
229 :
230 : rvalue *
231 : new_bitcast (location *loc,
232 : rvalue *expr,
233 : type *type_);
234 :
235 : lvalue *
236 : new_array_access (location *loc,
237 : rvalue *ptr,
238 : rvalue *index);
239 :
240 : rvalue *
241 : convert_vector (location *loc,
242 : rvalue *vector,
243 : type *type);
244 : lvalue *
245 : new_vector_access (location *loc,
246 : rvalue *vector,
247 : rvalue *index);
248 :
249 : void
250 : set_str_option (enum gcc_jit_str_option opt,
251 : const char *value);
252 :
253 : void
254 : set_int_option (enum gcc_jit_int_option opt,
255 : int value);
256 :
257 : void
258 : set_bool_option (enum gcc_jit_bool_option opt,
259 : int value);
260 :
261 : const char *
262 1331 : get_str_option (enum gcc_jit_str_option opt) const
263 : {
264 1331 : return m_recording_ctxt->get_str_option (opt);
265 : }
266 :
267 : int
268 1331 : get_int_option (enum gcc_jit_int_option opt) const
269 : {
270 1331 : return m_recording_ctxt->get_int_option (opt);
271 : }
272 :
273 : int
274 29027 : get_bool_option (enum gcc_jit_bool_option opt) const
275 : {
276 28009 : return m_recording_ctxt->get_bool_option (opt);
277 : }
278 :
279 : int
280 1139 : get_inner_bool_option (enum inner_bool_option opt) const
281 : {
282 1139 : return m_recording_ctxt->get_inner_bool_option (opt);
283 : }
284 :
285 13120 : builtins_manager *get_builtins_manager () const
286 : {
287 13120 : return m_recording_ctxt->get_builtins_manager ();
288 : }
289 :
290 : void
291 : compile ();
292 :
293 : void
294 : add_error (location *loc, const char *fmt, ...)
295 : GNU_PRINTF(3, 4);
296 :
297 : void
298 : add_error_va (location *loc, const char *fmt, va_list ap)
299 : GNU_PRINTF(3, 0);
300 :
301 : const char *
302 : get_first_error () const;
303 :
304 : void
305 : add_diagnostic (const char *text,
306 : const diagnostics::diagnostic_info &diagnostic);
307 :
308 : void
309 : set_tree_location (tree t, location *loc);
310 :
311 : tree
312 : new_field_access (location *loc,
313 : tree datum,
314 : field *field);
315 :
316 : tree
317 : new_dereference (tree ptr, location *loc);
318 :
319 : tree
320 : as_truth_value (tree expr, location *loc);
321 :
322 174279 : bool errors_occurred () const
323 : {
324 174279 : return m_recording_ctxt->errors_occurred ();
325 : }
326 :
327 6245 : timer *get_timer () const { return m_recording_ctxt->get_timer (); }
328 :
329 : void add_top_level_asm (const char *asm_stmts);
330 :
331 : target_info *get_target_info ()
332 : {
333 : return &m_target_info;
334 : }
335 :
336 32 : target_info *move_target_info ()
337 : {
338 32 : target_info *info = new target_info {std::move (m_target_info)};
339 32 : m_target_info = target_info{};
340 32 : return info;
341 : }
342 :
343 0 : bool get_abort_on_unsupported_target_builtin () const
344 : {
345 0 : return m_recording_ctxt->get_abort_on_unsupported_target_builtin ();
346 : }
347 :
348 : private:
349 : void dump_generated_code ();
350 :
351 : rvalue *
352 : build_call (location *loc,
353 : tree fn_ptr,
354 : const auto_vec<rvalue *> *args,
355 : bool require_tail_call);
356 :
357 : tree
358 : build_cast (location *loc,
359 : rvalue *expr,
360 : type *type_);
361 :
362 : source_file *
363 : get_source_file (const char *filename);
364 :
365 : tree
366 : get_tree_node_for_type (enum gcc_jit_types type_);
367 :
368 : void handle_locations ();
369 :
370 : void init_types ();
371 :
372 : const char * get_path_c_file () const;
373 : const char * get_path_s_file () const;
374 : const char * get_path_so_file () const;
375 :
376 : tree
377 : global_new_decl (location *loc,
378 : enum gcc_jit_global_kind kind,
379 : type *type,
380 : const char *name,
381 : enum global_var_flags flags,
382 : const std::vector<std::pair<gcc_jit_variable_attribute,
383 : std::string>> &attributes,
384 : bool readonly);
385 : lvalue *
386 : global_finalize_lvalue (tree inner);
387 :
388 : private:
389 :
390 : /* Functions for implementing "compile". */
391 :
392 : void lock ();
393 : void unlock ();
394 : struct scoped_lock;
395 :
396 : void
397 : make_fake_args (vec <char *> *argvec,
398 : const char *ctxt_progname,
399 : vec <recording::requested_dump> *requested_dumps);
400 :
401 : void
402 : extract_any_requested_dumps
403 : (vec <recording::requested_dump> *requested_dumps);
404 :
405 : char *
406 : read_dump_file (const char *path);
407 :
408 : virtual void postprocess (const char *ctxt_progname) = 0;
409 :
410 : protected:
411 147 : tempdir *get_tempdir () { return m_tempdir; }
412 :
413 : void
414 : convert_to_dso (const char *ctxt_progname);
415 :
416 : void
417 : invoke_driver (const char *ctxt_progname,
418 : const char *input_file,
419 : const char *output_file,
420 : timevar_id_t tv_id,
421 : bool shared,
422 : bool run_linker);
423 :
424 : void
425 : add_multilib_driver_arguments (vec <char *> *argvec);
426 :
427 : result *
428 : dlopen_built_dso ();
429 :
430 : private:
431 : void
432 : invoke_embedded_driver (const vec <char *> *argvec);
433 :
434 : void
435 : invoke_external_driver (const char *ctxt_progname,
436 : vec <char *> *argvec);
437 :
438 : private:
439 : ::gcc::jit::recording::context *m_recording_ctxt;
440 :
441 : tempdir *m_tempdir;
442 :
443 : auto_vec<function *> m_functions;
444 : auto_vec<tree> m_globals;
445 : tree m_const_char_ptr;
446 :
447 : /* Source location handling. */
448 : auto_vec<source_file *> m_source_files;
449 :
450 : auto_vec<std::pair<tree, location *> > m_cached_locations;
451 :
452 : target_info m_target_info;
453 : };
454 :
455 1173 : class compile_to_memory : public context
456 : {
457 : public:
458 : compile_to_memory (recording::context *ctxt);
459 : void postprocess (const char *ctxt_progname) final override;
460 :
461 1173 : result *get_result_obj () const { return m_result; }
462 :
463 : private:
464 : result *m_result;
465 : };
466 :
467 126 : class compile_to_file : public context
468 : {
469 : public:
470 : compile_to_file (recording::context *ctxt,
471 : enum gcc_jit_output_kind output_kind,
472 : const char *output_path);
473 : void postprocess (const char *ctxt_progname) final override;
474 :
475 : private:
476 : void
477 : copy_file (const char *src_path,
478 : const char *dst_path);
479 :
480 : private:
481 : enum gcc_jit_output_kind m_output_kind;
482 : const char *m_output_path;
483 : };
484 :
485 32 : class populate_target_info : public context
486 : {
487 : public:
488 32 : populate_target_info (recording::context *ctxt) : context (ctxt)
489 : {
490 : }
491 :
492 32 : void postprocess (const char *) final override
493 : {
494 32 : }
495 : };
496 :
497 :
498 : /* A temporary wrapper object.
499 : These objects are (mostly) only valid during replay.
500 : We allocate them on the GC heap, so that they will be cleaned
501 : the next time the GC collects.
502 : The exception is the "function" class, which is tracked and marked by
503 : the jit::context, since it needs to stay alive during post-processing
504 : (when the GC could run). */
505 25000 : class wrapper
506 : {
507 : public:
508 : /* Allocate in the GC heap. */
509 : void *operator new (size_t sz);
510 :
511 : /* Some wrapper subclasses contain vec<> and so need to
512 : release them when they are GC-ed. */
513 56088 : virtual void finalizer () { }
514 :
515 : };
516 :
517 : class type : public wrapper
518 : {
519 : public:
520 17660 : type (tree inner)
521 10789 : : m_inner(inner)
522 : {}
523 :
524 77482 : tree as_tree () const { return m_inner; }
525 :
526 1306 : type *get_pointer () const { return new type (build_pointer_type (m_inner)); }
527 :
528 585 : type *get_const () const
529 : {
530 585 : return new type (build_qualified_type (m_inner, TYPE_QUAL_CONST));
531 : }
532 :
533 115 : type *get_volatile () const
534 : {
535 115 : return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE));
536 : }
537 :
538 10 : type *get_restrict () const
539 : {
540 10 : return new type (build_qualified_type (m_inner, TYPE_QUAL_RESTRICT));
541 : }
542 :
543 : type *get_aligned (size_t alignment_in_bytes) const;
544 : type *get_vector (size_t num_units) const;
545 :
546 : private:
547 : tree m_inner;
548 : };
549 :
550 : class compound_type : public type
551 : {
552 : public:
553 602 : compound_type (tree inner)
554 602 : : type (inner)
555 : {}
556 :
557 : void set_fields (const auto_vec<field *> *fields);
558 : };
559 :
560 : class field : public wrapper
561 : {
562 : public:
563 1808 : field (tree inner)
564 90 : : m_inner(inner)
565 : {}
566 :
567 4304 : tree as_tree () const { return m_inner; }
568 :
569 : private:
570 : tree m_inner;
571 : };
572 :
573 : class bitfield : public field {};
574 :
575 : class function : public wrapper
576 : {
577 : public:
578 : function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
579 :
580 : void gt_ggc_mx ();
581 : void finalizer () final override;
582 :
583 : tree get_return_type_as_tree () const;
584 :
585 10284 : tree as_fndecl () const { return m_inner_fndecl; }
586 :
587 : enum gcc_jit_function_kind get_kind () const { return m_kind; }
588 :
589 : lvalue *
590 : new_local (location *loc,
591 : type *type,
592 : const char *name,
593 : const std::vector<std::pair<gcc_jit_variable_attribute,
594 : std::string>> &attributes);
595 :
596 : block*
597 : new_block (const char *name);
598 :
599 : rvalue *
600 : get_address (location *loc);
601 :
602 : void
603 : build_stmt_list ();
604 :
605 : void
606 : postprocess ();
607 :
608 : public:
609 : context *m_ctxt;
610 :
611 : public:
612 : void
613 929 : set_tree_location (tree t, location *loc)
614 : {
615 21 : m_ctxt->set_tree_location (t, loc);
616 21 : }
617 :
618 : private:
619 : tree m_inner_fndecl;
620 : tree m_inner_block;
621 : tree m_inner_bind_expr;
622 : enum gcc_jit_function_kind m_kind;
623 : tree m_stmt_list;
624 : tree_stmt_iterator m_stmt_iter;
625 : vec<block *> m_blocks;
626 : };
627 :
628 : struct case_
629 : {
630 80 : case_ (rvalue *min_value, rvalue *max_value, block *dest_block)
631 80 : : m_min_value (min_value),
632 80 : m_max_value (max_value),
633 80 : m_dest_block (dest_block)
634 : {}
635 :
636 : rvalue *m_min_value;
637 : rvalue *m_max_value;
638 : block *m_dest_block;
639 : };
640 :
641 : struct asm_operand
642 : {
643 100 : asm_operand (const char *asm_symbolic_name,
644 : const char *constraint,
645 : tree expr)
646 100 : : m_asm_symbolic_name (asm_symbolic_name),
647 100 : m_constraint (constraint),
648 100 : m_expr (expr)
649 : {}
650 :
651 : const char *m_asm_symbolic_name;
652 : const char *m_constraint;
653 : tree m_expr;
654 : };
655 :
656 : class block : public wrapper
657 : {
658 : public:
659 : block (function *func,
660 : const char *name);
661 :
662 : void finalizer () final override;
663 :
664 8918 : tree as_label_decl () const { return m_label_decl; }
665 :
666 100 : function *get_function () const { return m_func; }
667 :
668 : void
669 : add_eval (location *loc,
670 : rvalue *rvalue);
671 :
672 : void
673 : add_assignment (location *loc,
674 : lvalue *lvalue,
675 : rvalue *rvalue);
676 :
677 : void
678 : add_comment (location *loc,
679 : const char *text);
680 :
681 : void
682 : add_conditional (location *loc,
683 : rvalue *boolval,
684 : block *on_true,
685 : block *on_false);
686 :
687 : block *
688 : add_block (location *loc,
689 : const char *name);
690 :
691 : void
692 : add_jump (location *loc,
693 : block *target);
694 :
695 : void
696 : add_return (location *loc,
697 : rvalue *rvalue);
698 :
699 : void
700 : add_switch (location *loc,
701 : rvalue *expr,
702 : block *default_block,
703 : const auto_vec <case_> *cases);
704 :
705 : void
706 : add_extended_asm (location *loc,
707 : const char *asm_template,
708 : bool is_volatile,
709 : bool is_inline,
710 : const auto_vec <asm_operand> *outputs,
711 : const auto_vec <asm_operand> *inputs,
712 : const auto_vec <const char *> *clobbers,
713 : const auto_vec <block *> *goto_blocks);
714 :
715 : private:
716 : void
717 908 : set_tree_location (tree t, location *loc)
718 : {
719 899 : m_func->set_tree_location (t, loc);
720 908 : }
721 :
722 11536 : void add_stmt (tree stmt)
723 : {
724 : /* TODO: use one stmt_list per block. */
725 11280 : m_stmts.safe_push (stmt);
726 : }
727 :
728 : private:
729 : function *m_func;
730 : tree m_label_decl;
731 : vec<tree> m_stmts;
732 :
733 : public: // for now
734 : tree m_label_expr;
735 :
736 : friend class function;
737 : };
738 :
739 : class rvalue : public wrapper
740 : {
741 : public:
742 37554 : rvalue (context *ctxt, tree inner)
743 37554 : : m_ctxt (ctxt),
744 37554 : m_inner (inner)
745 : {
746 : /* Pre-mark tree nodes with TREE_VISITED so that they can be
747 : deeply unshared during gimplification (including across
748 : functions); this requires LANG_HOOKS_DEEP_UNSHARING to be true. */
749 12295 : TREE_VISITED (inner) = 1;
750 : }
751 :
752 : rvalue *
753 : as_rvalue () { return this; }
754 :
755 43945 : tree as_tree () const { return m_inner; }
756 :
757 4750 : context *get_context () const { return m_ctxt; }
758 :
759 : type *
760 509 : get_type () { return new type (TREE_TYPE (m_inner)); }
761 :
762 : rvalue *
763 : access_field (location *loc,
764 : field *field);
765 :
766 : lvalue *
767 : dereference_field (location *loc,
768 : field *field);
769 :
770 : lvalue *
771 : dereference (location *loc);
772 :
773 : private:
774 : context *m_ctxt;
775 : tree m_inner;
776 : };
777 :
778 : class lvalue : public rvalue
779 : {
780 : public:
781 22691 : lvalue (context *ctxt, tree inner)
782 2221 : : rvalue(ctxt, inner)
783 : {}
784 :
785 : lvalue *
786 : as_lvalue () { return this; }
787 :
788 : lvalue *
789 : access_field (location *loc,
790 : field *field);
791 :
792 : rvalue *
793 : get_address (location *loc);
794 :
795 : void
796 15 : set_tls_model (enum tls_model tls_model)
797 : {
798 15 : set_decl_tls_model (as_tree (), tls_model);
799 15 : }
800 :
801 : void
802 5 : set_link_section (const char* name)
803 : {
804 5 : set_decl_section_name (as_tree (), name);
805 5 : }
806 :
807 : void
808 20 : set_register_name (const char* reg_name)
809 : {
810 20 : set_user_assembler_name (as_tree (), reg_name);
811 20 : DECL_REGISTER (as_tree ()) = 1;
812 20 : DECL_HARD_REGISTER (as_tree ()) = 1;
813 20 : }
814 :
815 : void
816 10 : set_alignment (int alignment)
817 : {
818 10 : SET_DECL_ALIGN (as_tree (), alignment * BITS_PER_UNIT);
819 10 : DECL_USER_ALIGN (as_tree ()) = 1;
820 10 : }
821 :
822 : private:
823 : bool mark_addressable (location *loc);
824 : };
825 :
826 : class param : public lvalue
827 : {
828 : public:
829 16518 : param (context *ctxt, tree inner)
830 16518 : : lvalue(ctxt, inner)
831 : {}
832 : };
833 :
834 : /* Dealing with the linemap API.
835 :
836 : It appears that libcpp requires locations to be created as if by
837 : a tokenizer, creating them by filename, in ascending order of
838 : line/column, whereas our API doesn't impose any such constraints:
839 : we allow client code to create locations in arbitrary orders.
840 :
841 : To square this circle, we need to cache all location creation,
842 : grouping things up by filename/line, and then creating the linemap
843 : entries in a post-processing phase. */
844 :
845 : /* A set of locations, all sharing a filename */
846 : class source_file : public wrapper
847 : {
848 : public:
849 : source_file (tree filename);
850 : void finalizer () final override;
851 :
852 : source_line *
853 : get_source_line (int line_num);
854 :
855 1671 : tree filename_as_tree () const { return m_filename; }
856 :
857 : const char*
858 62 : get_filename () const { return IDENTIFIER_POINTER (m_filename); }
859 :
860 : vec<source_line *> m_source_lines;
861 :
862 : private:
863 : tree m_filename;
864 : };
865 :
866 : /* A source line, with one or more locations of interest. */
867 : class source_line : public wrapper
868 : {
869 : public:
870 : source_line (source_file *file, int line_num);
871 : void finalizer () final override;
872 :
873 : location *
874 : get_location (recording::location *rloc, int column_num);
875 :
876 7404 : int get_line_num () const { return m_line_num; }
877 :
878 : vec<location *> m_locations;
879 :
880 : private:
881 : source_file *m_source_file ATTRIBUTE_UNUSED;
882 : int m_line_num;
883 : };
884 :
885 : /* A specific location on a source line. This is what we expose
886 : to the client API. */
887 : class location : public wrapper
888 : {
889 : public:
890 : location (recording::location *loc, source_line *line, int column_num);
891 :
892 5769 : int get_column_num () const { return m_column_num; }
893 :
894 0 : recording::location *get_recording_loc () const { return m_recording_loc; }
895 :
896 : location_t m_srcloc;
897 :
898 : private:
899 : recording::location *m_recording_loc;
900 : source_line *m_line ATTRIBUTE_UNUSED;
901 : int m_column_num;
902 : };
903 :
904 : } // namespace gcc::jit::playback
905 :
906 : extern playback::context *active_playback_ctxt;
907 :
908 : } // namespace gcc::jit
909 :
910 : } // namespace gcc
911 :
912 : extern hash_map<nofree_string_hash, tree> target_builtins;
913 :
914 : #endif /* JIT_PLAYBACK_H */
|