On Sun, Jun 14, 2026 at 9:39 PM Lewis Hyatt <[email protected]> wrote:
>
> Hello-
>
> Checking in on this one please. Thanks!
> https://gcc.gnu.org/pipermail/gcc-patches/2026-January/704680.html

Please add a function-level comment to linemap_add_raw_map.

OK with that change if there are no further comments from maintainers
in the next 48h.

Thanks,
Richard.


> -Lewis
>
> On Sun, May 31, 2026 at 11:07 AM Lewis Hyatt <[email protected]> wrote:
> >
> > Hello-
> >
> > https://gcc.gnu.org/pipermail/gcc-patches/2026-January/704680.html
> >
> > This patch is a prerequisite for an improvement to enable #pragma GCC
> > diagnostic in the LTO front end. The LTO front end parts have been
> > approved. I would appreciate if someone could please review the libcpp
> > part here? It is just adding a new interface for LTO to use, since LTO
> > needs to manipulate the line map structure in a new way. Thank you!
> >
> > -Lewis
> >
> > On Thu, Jan 1, 2026 at 12:01 PM Lewis Hyatt <[email protected]> wrote:
> > >
> > > The expected way to create a new map in a line_map object is to call
> > > linemap_add() and/or linemap_line_start(), which contain the necessary 
> > > logic
> > > to decide if a location can be encoded in the currently active map or if a
> > > new map is required, and, in the latter case, what properties the new map
> > > requires. This interface works well for the typical use case where a line
> > > map is built up incrementally as source lines are processed, but it does 
> > > not
> > > provide the user with precise control over the exact properties of the 
> > > newly
> > > added map (or even whether a map is added at all).
> > >
> > > That level of control will be needed for an upcoming change to the 
> > > approach
> > > to streaming location data for the LTO front end. Enable it by adding a 
> > > new
> > > function linemap_add_raw_map(), which simply allows the user (i.e., the 
> > > LTO
> > > front end) to add maps with the desired properties. The user is then
> > > responsible for making sure the resulting state makes sense.
> > >
> > > This patch adds self-tests for the new function, but does not otherwise 
> > > make
> > > any observable changes yet.
> > >
> > > gcc/ChangeLog:
> > >
> > >         * input.cc (test_accessing_ordinary_linemaps): Test new
> > >         line_map_add_raw_map() functionality.
> > >
> > > libcpp/ChangeLog:
> > >
> > >         * include/line-map.h (linemap_next_start_location): New function.
> > >         (linemap_add_raw_map): Declare new function.
> > >         * line-map.cc (linemap_add): Minor refactor to make use of
> > >         linemap_next_start_location().
> > >         (linemap_add_raw_map): New function.
> > >         (linemap_lookup): Update the comment for clarity.
> > > ---
> > >  libcpp/include/line-map.h | 26 +++++++++++++++++++----
> > >  libcpp/line-map.cc        | 44 ++++++++++++++++++++++++++++++++-------
> > >  gcc/input.cc              | 22 ++++++++++++++++++++
> > >  3 files changed, 81 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
> > > index 2cd54d0770e..4856e6b4cb8 100644
> > > --- a/libcpp/include/line-map.h
> > > +++ b/libcpp/include/line-map.h
> > > @@ -1071,6 +1071,15 @@ extern location_t linemap_line_start
> > >  /* Allocate a raw block of line maps, zero initialized.  */
> > >  extern line_map *line_map_new_raw (line_maps *, bool, line_map_uint_t);
> > >
> > > +/* Return the location_t at which a new line map with RANGE_BITS range 
> > > bits
> > > +   would begin, if it needs to begin at least at START_LOC.  */
> > > +inline location_t
> > > +linemap_next_start_location (location_t start_loc, int range_bits)
> > > +{
> > > +  const auto mask = (location_t (1) << range_bits) - 1;
> > > +  return (start_loc + mask) & ~mask;
> > > +}
> > > +
> > >  /* Add a mapping of logical source line to physical source file and
> > >     line number. This function creates an "ordinary map", which is a
> > >     map that records locations of tokens that are not part of macro
> > > @@ -1088,6 +1097,17 @@ extern const line_map *linemap_add
> > >    (class line_maps *, enum lc_reason, unsigned int sysp,
> > >     const char *to_file, linenum_type to_line);
> > >
> > > +/* Create a map with exactly the requested parameters.  Not intended for 
> > > general
> > > +   use, but useful for applications that need to work with linemap 
> > > internals
> > > +   directly.  NUM_LINES is the number of lines this map should be able 
> > > to hold;
> > > +   this just ensures that set->highest_location is set properly so that 
> > > the next
> > > +   added map will leave sufficient room for NUM_LINES lines in this map. 
> > >  */
> > > +extern line_map_ordinary *
> > > +linemap_add_raw_map (line_maps *set, lc_reason reason, location_t 
> > > start_loc,
> > > +                    unsigned int sysp, int column_and_range_bits,
> > > +                    int range_bits, const char *to_file, linenum_type 
> > > to_line,
> > > +                    line_map_uint_t num_lines);
> > > +
> > >  /* Create a macro map.  A macro map encodes source locations of tokens
> > >     that are part of a macro replacement-list, at a macro expansion
> > >     point. See the extensive comments of struct line_map and struct
> > > @@ -1128,10 +1148,8 @@ extern location_t linemap_module_restore
> > >
> > >  /* Given a logical source location, returns the map which the
> > >     corresponding (source file, line, column) triplet can be deduced
> > > -   from. Since the set is built chronologically, the logical lines are
> > > -   monotonic increasing, and so the list is sorted and we can use a
> > > -   binary search. If no line map have been allocated yet, this
> > > -   function returns NULL.  */
> > > +   from.  Since the start_location of each map is monotonic increasing,
> > > +   this can be done with binary search.  */
> > >  extern const line_map *linemap_lookup
> > >    (const line_maps *, location_t);
> > >
> > > diff --git a/libcpp/line-map.cc b/libcpp/line-map.cc
> > > index 2875bf2092b..eba6f201485 100644
> > > --- a/libcpp/line-map.cc
> > > +++ b/libcpp/line-map.cc
> > > @@ -576,9 +576,7 @@ linemap_add (line_maps *set, enum lc_reason reason,
> > >    unsigned range_bits = 0;
> > >    if (start_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
> > >      range_bits = set->default_range_bits;
> > > -  start_location += (loc_one << range_bits) - 1;
> > > -  start_location &=  ~((loc_one << range_bits) - 1);
> > > -
> > > +  start_location = linemap_next_start_location (start_location, 
> > > range_bits);
> > >    linemap_assert (!LINEMAPS_ORDINARY_USED (set)
> > >                   || (start_location
> > >                       >= MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP 
> > > (set))));
> > > @@ -712,6 +710,35 @@ linemap_add (line_maps *set, enum lc_reason reason,
> > >    return map;
> > >  }
> > >
> > > +line_map_ordinary *
> > > +linemap_add_raw_map (line_maps *set, lc_reason reason, location_t 
> > > start_loc,
> > > +                    unsigned int sysp, int column_and_range_bits,
> > > +                    int range_bits, const char *to_file, linenum_type 
> > > to_line,
> > > +                    line_map_uint_t num_lines)
> > > +{
> > > +  start_loc = linemap_next_start_location (start_loc, range_bits);
> > > +  gcc_assert (start_loc > set->highest_location);
> > > +  location_t last_loc = start_loc + (loc_one << column_and_range_bits) - 
> > > 1;
> > > +  if (num_lines > 1)
> > > +    last_loc += (num_lines - 1) << column_and_range_bits;
> > > +  if (last_loc >= LINE_MAP_MAX_LOCATION)
> > > +    return nullptr;
> > > +  const auto map = linemap_check_ordinary (new_linemap (set, start_loc));
> > > +  map->reason = reason;
> > > +  map->sysp = sysp;
> > > +  map->m_column_and_range_bits = column_and_range_bits;
> > > +  map->m_range_bits = range_bits;
> > > +  map->to_file = to_file;
> > > +  map->to_line = to_line;
> > > +  set->info_ordinary.m_cache = LINEMAPS_ORDINARY_USED (set) - 1;
> > > +  set->highest_location = last_loc;
> > > +  set->highest_line
> > > +    = start_loc + ((last_loc - start_loc)
> > > +                  & (line_map_uint_t (-1) << column_and_range_bits));
> > > +  set->max_column_hint = 1U << (column_and_range_bits - range_bits);
> > > +  return map;
> > > +}
> > > +
> > >  /* Create a location for a module NAME imported at FROM.  */
> > >
> > >  location_t
> > > @@ -1151,10 +1178,13 @@ linemap_lookup (const line_maps *set, location_t 
> > > line)
> > >    return linemap_ordinary_map_lookup (set, line);
> > >  }
> > >
> > > -/* Given a source location yielded by an ordinary map, returns that
> > > -   map.  Since the set is built chronologically, the logical lines are
> > > -   monotonic increasing, and so the list is sorted and we can use a
> > > -   binary search.  */
> > > +/* Given a source location yielded by an ordinary map, returns that map. 
> > >  Since
> > > +   the start_location of each map is larger than the prior one, this can 
> > > be done
> > > +   with binary search.  Note that the line maps are not necessarily 
> > > sorted by
> > > +   file name or by line number, although they often are, at least in a 
> > > local
> > > +   region, since things like #line directives, multiple includes, or
> > > +   manipulations outside the normal usage during parsing can all affect 
> > > the
> > > +   sorting.  But they are always sorted by start_location.  */
> > >
> > >  static const line_map_ordinary *
> > >  linemap_ordinary_map_lookup (const line_maps *set, location_t line)
> > > diff --git a/gcc/input.cc b/gcc/input.cc
> > > index 665dbe3d605..4836b450a13 100644
> > > --- a/gcc/input.cc
> > > +++ b/gcc/input.cc
> > > @@ -1363,6 +1363,28 @@ test_accessing_ordinary_linemaps (const 
> > > line_table_case &case_)
> > >    source_range src_range = get_range_from_loc (line_table, range_c_b_d);
> > >    ASSERT_EQ (loc_b, src_range.m_start);
> > >    ASSERT_EQ (loc_d, src_range.m_finish);
> > > +
> > > +  /* Verify raw line map usage.  The map should have the requested 
> > > properties,
> > > +     irrespective of limits like LINE_MAP_MAX_LOCATION_WITH_COLS.  */
> > > +  for (int sysp = 0; sysp != 3; ++sysp)
> > > +    {
> > > +      constexpr int column_bits = 8, range_bits = 7;
> > > +      const int line = 1 + sysp;
> > > +      const auto map = linemap_add_raw_map (line_table, LC_RENAME,
> > > +                                           line_table->highest_location 
> > > + 1,
> > > +                                           sysp, column_bits + 
> > > range_bits,
> > > +                                           range_bits, "foo2.c", line, 
> > > 1);
> > > +      ASSERT_NE (map, nullptr);
> > > +      ASSERT_EQ (map->reason, LC_RENAME);
> > > +      ASSERT_EQ (map->m_column_and_range_bits, column_bits + range_bits);
> > > +      ASSERT_EQ (map->m_range_bits, range_bits);
> > > +      const line_map_uint_t col = 200 + sysp;
> > > +      const location_t loc = MAP_START_LOCATION (map) + (col << 
> > > range_bits);
> > > +      ASSERT_GT (loc, line_table->highest_line);
> > > +      ASSERT_LT (loc, line_table->highest_location);
> > > +      ASSERT_EQ (in_system_header_at (loc), sysp);
> > > +      assert_loceq ("foo2.c", line, col, loc);
> > > +    }
> > >  }
> > >
> > >  /* Verify various properties of UNKNOWN_LOCATION.  */

Reply via email to