On Wed, May 4, 2016 at 10:49 PM, David Malcolm <dmalc...@redhat.com> wrote: > In order to faithfully load RTL dumps that contain references to > source locations, the RTL frontend needs to be able to parse file > and line information and turn then into location_t values. > > Unfortunately, the libcpp API makes it rather fiddly to create > location_t values from a sequence of arbitrary file/line pairs: the > API assumes that the locations are created in ascending order as > if we were parsing the source file, but as we read an RTL dump, > the insns could be jumping forwards and backwards in lines and > between files. Also, if we want to support column numbers, the > presence of a very high column number could exceed the bits available > in a line_map_ordinary for storing it. > > The JIT has some code for handling this, in gcc/jit/jit-playback.[ch], > (since the JIT support source location information, and doesn't impose > any ordering requirement on users of the API). > > This patch moves the relevant code from > gcc/jit/jit-playback.[ch] > into a new pair of files: > gcc/deferred-locations.[ch] > > The idea is that a deferred_locations instances manages these > "deferred locations"; they are created, and then all of the location_t > values are created at once by calling > deferred_locations::add_to_line_table > After this call, the actual location_t values can be read from out of > deferred_location instances. > > There are some suboptimal parts of the code (some linear searches, and > the use of gc), but it's mostly a move of existing code from out of the > jit subdirectory and into "gcc" proper for reuse by the RTL frontend. > > This is likely to be useful for the gimple frontend as well. > > OK for trunk?
The LTO FE faces similar issues - see lto-streamer-in.c Richard. > gcc/ChangeLog: > * Makefile.in (OBJS): Add deferred-locations.o. > * deferred-locations.c: New file, adapted from parts of > jit/jit-playback.c. > * deferred-locations.h: New file, adapted from parts of > jit/jit-playback.h. > > gcc/jit/ChangeLog: > * jit-common.h: Include deferred-locations.h. > (gcc::jit::playback::source_file): Remove forward decl. > (gcc::jit::playback::source_line): Likewise. > (gcc::jit::playback::location): Replace forward decl, with > a typedef, aliasing deferred_location. > * jit-playback.c (gcc::jit::playback::context::context): Remove > create call on m_source_files. > (line_comparator): Move to deferred-locations.c. > (location_comparator): Likewise. > (handle_locations): Move logic to deferred-locations.c, as > deferred_locations::add_to_line_table. > (get_recording_loc): New function. > (gcc::jit::playback::context::add_error): Call get_recording_loc > as a function, rather than as a method. > (gcc::jit::playback::context::add_error_va): Likewise. > (gcc::jit::playback::context::get_source_file): Update return type > to reflect move of source_file to deferred-locations.h. > Replace body with a call to m_deferred_locations.get_source_file. > (gcc::jit::playback::source_file::source_file): Move to > deferred-locations.h, losing the namespaces. > (gcc::jit::playback::source_file::finalizer): Likewise. > (gcc::jit::playback::source_file::get_source_line): Likewise. > (gcc::jit::playback::source_line::source_line): Likewise. > (gcc::jit::playback::source_line::finalizer): Likewise. > (gcc::jit::playback::source_line::get_location): Likewise. > (gcc::jit::playback::location::location): Likewise, renaming to > deferred_location. > * jit-playback.h: Include deferred-locations.h. > (gcc::jit::playback::context::m_source_files): Replace field with > m_deferred_locations. > (gcc::jit::playback::source_file): Move to deferred-locations.h, > losing the namespaces. > (gcc::jit::playback::source_line): Likewise. > (gcc::jit::playback::location): Likewise, renaming to > deferred_location. Eliminate get_recording_loc accessor and > m_recording_loc field in favor of get_user_data and m_user_data > respectively. > --- > gcc/Makefile.in | 1 + > gcc/deferred-locations.c | 240 > +++++++++++++++++++++++++++++++++++++++++++++++ > gcc/deferred-locations.h | 139 +++++++++++++++++++++++++++ > gcc/jit/jit-common.h | 5 +- > gcc/jit/jit-playback.c | 194 ++++---------------------------------- > gcc/jit/jit-playback.h | 73 +------------- > 6 files changed, 402 insertions(+), 250 deletions(-) > create mode 100644 gcc/deferred-locations.c > create mode 100644 gcc/deferred-locations.h > > diff --git a/gcc/Makefile.in b/gcc/Makefile.in > index 6c5adc0..c61f303 100644 > --- a/gcc/Makefile.in > +++ b/gcc/Makefile.in > @@ -1239,6 +1239,7 @@ OBJS = \ > dce.o \ > ddg.o \ > debug.o \ > + deferred-locations.o \ > df-core.o \ > df-problems.o \ > df-scan.o \ > diff --git a/gcc/deferred-locations.c b/gcc/deferred-locations.c > new file mode 100644 > index 0000000..cd02938 > --- /dev/null > +++ b/gcc/deferred-locations.c > @@ -0,0 +1,240 @@ > +/* Dealing with the linemap API. > + Copyright (C) 2013-2016 Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +You should have received a copy of the GNU General Public License > +along with GCC; see the file COPYING3. If not see > +<http://www.gnu.org/licenses/>. */ > + > +#include "config.h" > +#include "system.h" > +#include "coretypes.h" > +#include "input.h" > +#include "deferred-locations.h" > +#include "stringpool.h" > +#include "tree.h" > + > +/* The wrapper subclasses are GC-managed, but can own non-GC memory. > + Provide this finalization hook for calling then they are collected, > + which calls the finalizer vfunc. This allows them to call "release" > + on any vec<> within them. */ > + > +static void > +wrapper_finalizer (void *ptr) > +{ > + wrapper *w = reinterpret_cast <wrapper *> (ptr); > + w->finalizer (); > +} > + > +/* wrapper subclasses are GC-managed: > + allocate them using ggc_internal_cleared_alloc. */ > + > +void * > +wrapper::operator new (size_t sz) > +{ > + return ggc_internal_cleared_alloc (sz, wrapper_finalizer, 0, 1); > + > +} > + > +/* Constructor for source_file. */ > + > +source_file::source_file (tree filename) : > + m_source_lines (), > + m_filename (filename) > +{ > +} > + > +/* Don't leak vec's internal buffer (in non-GC heap) when we are > + GC-ed. */ > + > +void > +source_file::finalizer () > +{ > + m_source_lines.release (); > +} > + > +/* Construct a source_line for the given line > + within this source file, if one doesn't exist already. */ > + > +source_line * > +source_file::get_source_line (int line_num) > +{ > + /* Locate the line. > + For simplicitly, this is currently a linear search. > + Replace with a hash if this shows up in the profile. */ > + int i; > + source_line *line; > + > + FOR_EACH_VEC_ELT (m_source_lines, i, line) > + if (line->get_line_num () == line_num) > + return line; > + > + /* Not found. */ > + line = new source_line (this, line_num); > + m_source_lines.safe_push (line); > + return line; > +} > + > +const char * > +source_file::get_filename () const > +{ > + return IDENTIFIER_POINTER (m_filename); > +} > + > +/* Constructor for source_line. */ > + > +source_line::source_line (source_file *file, int line_num) : > + m_locations (), > + m_source_file (file), > + m_line_num (line_num) > +{ > +} > + > +/* Don't leak vec's internal buffer (in non-GC heap) when we are > + GC-ed. */ > + > +void > +source_line::finalizer () > +{ > + m_locations.release (); > +} > + > +/* Construct a location for the given column > + within this line of a specific source file, if one doesn't exist > + already. */ > + > +deferred_location * > +source_line::get_location (void *user_data, int column_num) > +{ > + int i; > + deferred_location *loc; > + > + /* Another linear search that probably should be a hash table. */ > + FOR_EACH_VEC_ELT (m_locations, i, loc) > + if (loc->get_column_num () == column_num) > + return loc; > + > + /* Not found. */ > + loc = new deferred_location (user_data, this, column_num); > + m_locations.safe_push (loc); > + return loc; > +} > + > +/* Constructor for deferred_location. */ > +deferred_location::deferred_location (void *user_data, > + source_line *line, > + int column_num) : > + m_srcloc (UNKNOWN_LOCATION), > + m_user_data (user_data), > + m_line (line), > + m_column_num(column_num) > +{ > +} > + > +/* qsort comparator for comparing pairs of source_line *, > + ordering them by line number. */ > + > +static int > +line_comparator (const void *lhs, const void *rhs) > +{ > + const source_line *line_lhs = *static_cast<const source_line * const*> > (lhs); > + const source_line *line_rhs = *static_cast<const source_line * const*> > (rhs); > + return line_lhs->get_line_num () - line_rhs->get_line_num (); > +} > + > +/* qsort comparator for comparing pairs of deferred_location *, > + ordering them by column number. */ > + > +static int > +location_comparator (const void *lhs, const void *rhs) > +{ > + const deferred_location *loc_lhs = \ > + *static_cast<const deferred_location * const *> (lhs); > + const deferred_location *loc_rhs = \ > + *static_cast<const deferred_location * const *> (rhs); > + return loc_lhs->get_column_num () - loc_rhs->get_column_num (); > +} > + > +/* class deferred_locations */ > + > +deferred_locations::deferred_locations () > +{ > + m_source_files.create (0); > +} > + > +/* Construct a source_file for the given source > + filename, if it doesn't exist already. */ > + > +source_file * > +deferred_locations::get_source_file (const char *filename) > +{ > + /* Locate the file. > + For simplicitly, this is currently a linear search. > + Replace with a hash if this shows up in the profile. */ > + int i; > + source_file *file; > + tree ident_filename = get_identifier (filename); > + > + FOR_EACH_VEC_ELT (m_source_files, i, file) > + if (file->filename_as_tree () == ident_filename) > + return file; > + > + /* Not found. */ > + file = new source_file (ident_filename); > + m_source_files.safe_push (file); > + return file; > + > +} > + > +void > +deferred_locations::add_to_line_table () > +{ > + int i; > + source_file *file; > + > + FOR_EACH_VEC_ELT (m_source_files, i, file) > + { > + linemap_add (line_table, LC_ENTER, false, file->get_filename (), 0); > + > + /* Sort lines by ascending line numbers. */ > + file->m_source_lines.qsort (&line_comparator); > + > + int j; > + source_line *line; > + FOR_EACH_VEC_ELT (file->m_source_lines, j, line) > + { > + int k; > + deferred_location *loc; > + > + /* Sort locations in line by ascending column numbers. */ > + line->m_locations.qsort (&location_comparator); > + > + /* Determine maximum column within this line. */ > + gcc_assert (line->m_locations.length () > 0); > + deferred_location *final_column = > + line->m_locations[line->m_locations.length () - 1]; > + int max_col = final_column->get_column_num (); > + > + linemap_line_start (line_table, line->get_line_num (), max_col); > + FOR_EACH_VEC_ELT (line->m_locations, k, loc) > + { > + loc->m_srcloc = > + linemap_position_for_column (line_table, loc->get_column_num > ()); > + } > + } > + > + linemap_add (line_table, LC_LEAVE, false, NULL, 0); > + } > + > +} > diff --git a/gcc/deferred-locations.h b/gcc/deferred-locations.h > new file mode 100644 > index 0000000..209cb0d > --- /dev/null > +++ b/gcc/deferred-locations.h > @@ -0,0 +1,139 @@ > +/* Dealing with the linemap API. > + Copyright (C) 2013-2016 Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +You should have received a copy of the GNU General Public License > +along with GCC; see the file COPYING3. If not see > +<http://www.gnu.org/licenses/>. */ > + > +#ifndef GCC_DEFERRED_LOCATIONS_H > +#define GCC_DEFERRED_LOCATIONS_H > + > +/* Dealing with the linemap API. > + > + libcpp requires locations to be created as if by > + a tokenizer, creating them by filename, in ascending order of > + line/column, whereas the libgccjit API doesn't impose any such > constraints: > + we allow client code to create locations in arbitrary orders. > + > + To square this circle, we need to cache all location creation, > + grouping things up by filename/line, and then creating the linemap > + entries in a post-processing phase. */ > + > +/* A temporary wrapper object. > + These objects are (mostly) only valid during replay. > + We allocate them on the GC heap, so that they will be cleaned > + the next time the GC collects. */ > +class wrapper > +{ > +public: > + /* Allocate in the GC heap. */ > + void *operator new (size_t sz); > + > + /* Some wrapper subclasses contain vec<> and so need to > + release them when they are GC-ed. */ > + virtual void finalizer () { } > +}; > + > +class source_file; > +class source_line; > +class deferred_location; > + > +/* A set of locations, all sharing a filename */ > +class source_file : public wrapper > +{ > +public: > + source_file (tree filename); > + void finalizer (); > + > + source_line * > + get_source_line (int line_num); > + > + tree filename_as_tree () const { return m_filename; } > + > + const char *get_filename () const; > + > + vec<source_line *> m_source_lines; > + > +private: > + tree m_filename; > +}; > + > +/* A source line, with one or more locations of interest. */ > +class source_line : public wrapper > +{ > +public: > + source_line (source_file *file, int line_num); > + void finalizer (); > + > + deferred_location * > + get_location (void *user_data, int column_num); > + > + int get_line_num () const { return m_line_num; } > + > + vec<deferred_location *> m_locations; > + > +private: > + source_file *m_source_file; > + int m_line_num; > +}; > + > +/* A specific location on a source line. This is what we expose > + to the JIT client API. */ > +class deferred_location : public wrapper > +{ > +public: > + deferred_location (void *user_data, source_line *line, int column_num); > + > + int get_column_num () const { return m_column_num; } > + > + void *get_user_data () const { return m_user_data; } > + > + source_location m_srcloc; > + > +private: > + void *m_user_data; > + source_line *m_line; > + int m_column_num; > +}; > + > +/* A class for managing the deferred creation of location_t values. > + > + Locations are created in two phases: > + > + - first phase: creation of source_file instances (via > + deferred_locations::get_source_file), from which source_line > + instances can be created (via source_file::get_source_line), from > + which deferred_location instances can be created (via > + source_line::get_location). > + > + - second phase: call deferred_location::add_to_line_table, which > + walks all of the above and populates line_table, filling in > + the various deferred_location instances with source_location > + (aka location_t) values. */ > + > +class deferred_locations > +{ > + public: > + deferred_locations (); > + > + source_file *get_source_file (const char *filename); > + > + void add_to_line_table (); > + > + private: > + auto_vec<source_file *> m_source_files; > +}; > + > +#endif /* #ifndef GCC_DEFERRED_LOCATIONS_H */ > diff --git a/gcc/jit/jit-common.h b/gcc/jit/jit-common.h > index 8a6cd74..0a10cdf 100644 > --- a/gcc/jit/jit-common.h > +++ b/gcc/jit/jit-common.h > @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see > #include "tree.h" > #include "inchash.h" > #include "tree-iterator.h" > +#include "deferred-locations.h" > > #ifdef GCC_VERSION > #if GCC_VERSION >= 4001 > @@ -146,9 +147,7 @@ namespace playback { > class rvalue; > class lvalue; > class param; > - class source_file; > - class source_line; > - class location; > + typedef deferred_location location; > class case_; > > /* End of playback types. */ > diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c > index 579230d..f17c55b 100644 > --- a/gcc/jit/jit-playback.c > +++ b/gcc/jit/jit-playback.c > @@ -85,7 +85,6 @@ playback::context::context (recording::context *ctxt) > JIT_LOG_SCOPE (get_logger ()); > m_functions.create (0); > m_globals.create (0); > - m_source_files.create (0); > m_cached_locations.create (0); > } > > @@ -2705,32 +2704,6 @@ get_path_so_file () const > return m_tempdir->get_path_so_file (); > } > > -/* qsort comparator for comparing pairs of playback::source_line *, > - ordering them by line number. */ > - > -static int > -line_comparator (const void *lhs, const void *rhs) > -{ > - const playback::source_line *line_lhs = \ > - *static_cast<const playback::source_line * const*> (lhs); > - const playback::source_line *line_rhs = \ > - *static_cast<const playback::source_line * const*> (rhs); > - return line_lhs->get_line_num () - line_rhs->get_line_num (); > -} > - > -/* qsort comparator for comparing pairs of playback::location *, > - ordering them by column number. */ > - > -static int > -location_comparator (const void *lhs, const void *rhs) > -{ > - const playback::location *loc_lhs = \ > - *static_cast<const playback::location * const *> (lhs); > - const playback::location *loc_rhs = \ > - *static_cast<const playback::location * const *> (rhs); > - return loc_lhs->get_column_num () - loc_rhs->get_column_num (); > -} > - > /* Our API allows locations to be created in arbitrary orders, but the > linemap API requires locations to be created in ascending order > as if we were tokenizing files. > @@ -2748,47 +2721,13 @@ handle_locations () > > line_table is a global. */ > JIT_LOG_SCOPE (get_logger ()); > - int i; > - source_file *file; > - > - FOR_EACH_VEC_ELT (m_source_files, i, file) > - { > - linemap_add (line_table, LC_ENTER, false, file->get_filename (), 0); > - > - /* Sort lines by ascending line numbers. */ > - file->m_source_lines.qsort (&line_comparator); > - > - int j; > - source_line *line; > - FOR_EACH_VEC_ELT (file->m_source_lines, j, line) > - { > - int k; > - location *loc; > - > - /* Sort locations in line by ascending column numbers. */ > - line->m_locations.qsort (&location_comparator); > - > - /* Determine maximum column within this line. */ > - gcc_assert (line->m_locations.length () > 0); > - location *final_column = > - line->m_locations[line->m_locations.length () - 1]; > - int max_col = final_column->get_column_num (); > - > - linemap_line_start (line_table, line->get_line_num (), max_col); > - FOR_EACH_VEC_ELT (line->m_locations, k, loc) > - { > - loc->m_srcloc = \ > - linemap_position_for_column (line_table, loc->get_column_num > ()); > - } > - } > - > - linemap_add (line_table, LC_LEAVE, false, NULL, 0); > - } > > + m_deferred_locations.add_to_line_table (); > /* line_table should now be populated; every playback::location should > now have an m_srcloc. */ > > /* Now assign them to tree nodes as appropriate. */ > + int i; > std::pair<tree, location *> *cached_location; > > FOR_EACH_VEC_ELT (m_cached_locations, i, cached_location) > @@ -2808,6 +2747,17 @@ handle_locations () > } > } > > +/* Return the recording::location for playback::location LOC. > + Return NULL if LOC is NULL. */ > + > +static recording::location * > +get_recording_loc (playback::location *loc) > +{ > + if (!loc) > + return NULL; > + return reinterpret_cast <recording::location *> (loc->get_user_data ()); > +} > + > /* We handle errors on a playback::context by adding them to the > corresponding recording::context. */ > > @@ -2817,8 +2767,7 @@ add_error (location *loc, const char *fmt, ...) > { > va_list ap; > va_start (ap, fmt); > - m_recording_ctxt->add_error_va (loc ? loc->get_recording_loc () : NULL, > - fmt, ap); > + m_recording_ctxt->add_error_va (get_recording_loc (loc), fmt, ap); > va_end (ap); > } > > @@ -2829,8 +2778,7 @@ void > playback::context:: > add_error_va (location *loc, const char *fmt, va_list ap) > { > - m_recording_ctxt->add_error_va (loc ? loc->get_recording_loc () : NULL, > - fmt, ap); > + m_recording_ctxt->add_error_va (get_recording_loc (loc), fmt, ap); > } > > /* Dealing with the linemap API. */ > @@ -2868,120 +2816,14 @@ set_tree_location (tree t, location *loc) > } > > > -/* Construct a playback::source_file for the given source > +/* Construct a source_file for the given source > filename, if it doesn't exist already. */ > > -playback::source_file * > +source_file * > playback::context:: > get_source_file (const char *filename) > { > - /* Locate the file. > - For simplicitly, this is currently a linear search. > - Replace with a hash if this shows up in the profile. */ > - int i; > - source_file *file; > - tree ident_filename = get_identifier (filename); > - > - FOR_EACH_VEC_ELT (m_source_files, i, file) > - if (file->filename_as_tree () == ident_filename) > - return file; > - > - /* Not found. */ > - file = new source_file (ident_filename); > - m_source_files.safe_push (file); > - return file; > -} > - > -/* Constructor for gcc::jit::playback::source_file. */ > - > -playback::source_file::source_file (tree filename) : > - m_source_lines (), > - m_filename (filename) > -{ > -} > - > -/* Don't leak vec's internal buffer (in non-GC heap) when we are > - GC-ed. */ > - > -void > -playback::source_file::finalizer () > -{ > - m_source_lines.release (); > -} > - > -/* Construct a playback::source_line for the given line > - within this source file, if one doesn't exist already. */ > - > -playback::source_line * > -playback::source_file:: > -get_source_line (int line_num) > -{ > - /* Locate the line. > - For simplicitly, this is currently a linear search. > - Replace with a hash if this shows up in the profile. */ > - int i; > - source_line *line; > - > - FOR_EACH_VEC_ELT (m_source_lines, i, line) > - if (line->get_line_num () == line_num) > - return line; > - > - /* Not found. */ > - line = new source_line (this, line_num); > - m_source_lines.safe_push (line); > - return line; > -} > - > -/* Constructor for gcc::jit::playback::source_line. */ > - > -playback::source_line::source_line (source_file *file, int line_num) : > - m_locations (), > - m_source_file (file), > - m_line_num (line_num) > -{ > -} > - > -/* Don't leak vec's internal buffer (in non-GC heap) when we are > - GC-ed. */ > - > -void > -playback::source_line::finalizer () > -{ > - m_locations.release (); > -} > - > -/* Construct a playback::location for the given column > - within this line of a specific source file, if one doesn't exist > - already. */ > - > -playback::location * > -playback::source_line:: > -get_location (recording::location *rloc, int column_num) > -{ > - int i; > - location *loc; > - > - /* Another linear search that probably should be a hash table. */ > - FOR_EACH_VEC_ELT (m_locations, i, loc) > - if (loc->get_column_num () == column_num) > - return loc; > - > - /* Not found. */ > - loc = new location (rloc, this, column_num); > - m_locations.safe_push (loc); > - return loc; > -} > - > -/* Constructor for gcc::jit::playback::location. */ > - > -playback::location::location (recording::location *loc, > - source_line *line, > - int column_num) : > - m_srcloc (UNKNOWN_LOCATION), > - m_recording_loc (loc), > - m_line (line), > - m_column_num(column_num) > -{ > + return m_deferred_locations.get_source_file (filename); > } > > /* The active gcc::jit::playback::context instance. This is a singleton, > diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h > index 7519bc4..86118d9 100644 > --- a/gcc/jit/jit-playback.h > +++ b/gcc/jit/jit-playback.h > @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see > #include <utility> // for std::pair > > #include "timevar.h" > +#include "deferred-locations.h" > > #include "jit-recording.h" > > @@ -305,7 +306,7 @@ private: > tree m_const_char_ptr; > > /* Source location handling. */ > - auto_vec<source_file *> m_source_files; > + deferred_locations m_deferred_locations; > > auto_vec<std::pair<tree, location *> > m_cached_locations; > }; > @@ -603,76 +604,6 @@ public: > {} > }; > > -/* Dealing with the linemap API. > - > - It appears that libcpp requires locations to be created as if by > - a tokenizer, creating them by filename, in ascending order of > - line/column, whereas our API doesn't impose any such constraints: > - we allow client code to create locations in arbitrary orders. > - > - To square this circle, we need to cache all location creation, > - grouping things up by filename/line, and then creating the linemap > - entries in a post-processing phase. */ > - > -/* A set of locations, all sharing a filename */ > -class source_file : public wrapper > -{ > -public: > - source_file (tree filename); > - void finalizer (); > - > - source_line * > - get_source_line (int line_num); > - > - tree filename_as_tree () const { return m_filename; } > - > - const char* > - get_filename () const { return IDENTIFIER_POINTER (m_filename); } > - > - vec<source_line *> m_source_lines; > - > -private: > - tree m_filename; > -}; > - > -/* A source line, with one or more locations of interest. */ > -class source_line : public wrapper > -{ > -public: > - source_line (source_file *file, int line_num); > - void finalizer (); > - > - location * > - get_location (recording::location *rloc, int column_num); > - > - int get_line_num () const { return m_line_num; } > - > - vec<location *> m_locations; > - > -private: > - source_file *m_source_file; > - int m_line_num; > -}; > - > -/* A specific location on a source line. This is what we expose > - to the client API. */ > -class location : public wrapper > -{ > -public: > - location (recording::location *loc, source_line *line, int column_num); > - > - int get_column_num () const { return m_column_num; } > - > - recording::location *get_recording_loc () const { return m_recording_loc; } > - > - source_location m_srcloc; > - > -private: > - recording::location *m_recording_loc; > - source_line *m_line; > - int m_column_num; > -}; > - > } // namespace gcc::jit::playback > > extern playback::context *active_playback_ctxt; > -- > 1.8.5.3 >