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