summaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2015-11-13 16:29:59 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2015-11-13 16:29:59 +0000
commitebedc9a3414d842274607b77597759bd36e0f3e0 (patch)
treed1ab10c369a8f1ec9f67e1e8cb70acef36897f21 /libcpp
parent1ba91a49a97955057bb8a07b42feb901ee9cee4e (diff)
downloadgcc-ebedc9a3414d842274607b77597759bd36e0f3e0.tar.gz
Source range tracking in libcpp and C FE, with bit-packing optimization
This patch combines: [PATCH 05/10] Add ranges to libcpp tokens (via ad-hoc data, unoptimized) [PATCH 06/10] Track expression ranges in C frontend [PATCH 07/10] Add plugin to recursively dump the source-ranges in a tree (v2) [PATCH 08/10] Wire things up so that libcpp users get token underlines [PATCH 09/10] Delay some resolution of ad-hoc locations, preserving ranges [PATCH 10/10] Compress short ranges into source_location [PATCH] libcpp: add examples to source_location description along with fixes for the nits identified during review. gcc/ChangeLog: * Makefile.in (OBJS): Add gcc-rich-location.o. * diagnostic.c (diagnostic_append_note): Pass line_table to rich_location ctor. (emit_diagnostic): Likewise. (inform): Likewise. (inform_n): Likewise. (warning): Likewise. (warning_at): Likewise. (warning_n): Likewise. (pedwarn): Likewise. (permerror): Likewise. (error): Likewise. (error_n): Likewise. (error_at): Likewise. (sorry): Likewise. (fatal_error): Likewise. (internal_error): Likewise. (internal_error_no_backtrace): Likewise. (source_range::debug): Likewise. * gcc-rich-location.c: New file. * gcc-rich-location.h: New file. * genmatch.c (fatal_at): Pass line_table to rich_location ctor. (warning_at): Likewise. * gimple.h (gimple_set_block): Use set_block function. * input.c (dump_line_table_statistics): Dump stats on how many ranges were optimized vs how many needed ad-hoc table. (write_digit_row): Add "map" param; use its range_bits to calculate the per-character offset. (dump_location_info): Print the range and column bits for each ordinary map. Use the range bits to calculate the per-character offset. Pass the map as a new param to the various calls to write_digit_row. Eliminate uses of ORDINARY_MAP_NUMBER_OF_COLUMN_BITS. * print-tree.c (print_node): Print any source range information. * rtl-error.c (diagnostic_for_asm): Likewise. * toplev.c (general_init): Initialize line_table's default_range_bits. * tree-cfg.c (move_block_to_fn): Likewise. (move_block_to_fn): Likewise. * tree-inline.c (copy_phis_for_bb): Likewise. * tree.c (tree_set_block): Likewise. (get_pure_location): New function. (set_source_range): New functions. (set_block): New function. (set_source_range): New functions. * tree.h (CAN_HAVE_RANGE_P): New. (EXPR_LOCATION_RANGE): New. (EXPR_HAS_RANGE): New. (get_expr_source_range): New inline function. (DECL_LOCATION_RANGE): New. (set_source_range): New decls. (get_decl_source_range): New inline function. gcc/ada/ChangeLog: * gcc-interface/trans.c (Sloc_to_locus): Add line_table param when calling linemap_position_for_line_and_column. gcc/c-family/ChangeLog: * c-common.c (c_fully_fold_internal): Capture existing souce_range, and store it on the result. * c-opts.c (c_common_init_options): Set global_dc->colorize_source_p. gcc/c/ChangeLog: * c-decl.c (warn_defaults_to): Pass line_table to rich_location ctor. * c-errors.c (pedwarn_c99): Likewise. (pedwarn_c90): Likewise. * c-parser.c (set_c_expr_source_range): New functions. (c_token::get_range): New method. (c_token::get_finish): New method. (c_parser_expr_no_commas): Call set_c_expr_source_range on the ret based on the range from the start of the LHS to the end of the RHS. (c_parser_conditional_expression): Likewise, based on the range from the start of the cond.value to the end of exp2.value. (c_parser_binary_expression): Call set_c_expr_source_range on the stack values for TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR. (c_parser_cast_expression): Call set_c_expr_source_range on ret based on the cast_loc through to the end of the expr. (c_parser_unary_expression): Likewise, based on the op_loc through to the end of op. (c_parser_sizeof_expression) Likewise, based on the start of the sizeof token through to either the closing paren or the end of expr. (c_parser_postfix_expression): Likewise, using the token range, or from the open paren through to the close paren for parenthesized expressions. (c_parser_postfix_expression_after_primary): Likewise, for various kinds of expression. * c-tree.h (struct c_expr): Add field "src_range". (c_expr::get_start): New method. (c_expr::get_finish): New method. (set_c_expr_source_range): New decls. * c-typeck.c (parser_build_unary_op): Call set_c_expr_source_range on ret for prefix unary ops. (parser_build_binary_op): Likewise, running from the start of arg1.value through to the end of arg2.value. gcc/cp/ChangeLog: * error.c (pedwarn_cxx98): Pass line_table to rich_location ctor. gcc/fortran/ChangeLog: * error.c (gfc_warning): Pass line_table to rich_location ctor. (gfc_warning_now_at): Likewise. (gfc_warning_now): Likewise. (gfc_error_now): Likewise. (gfc_fatal_error): Likewise. (gfc_error): Likewise. (gfc_internal_error): Likewise. gcc/testsuite/ChangeLog: * gcc.dg/diagnostic-token-ranges.c: New file. * gcc.dg/diagnostic-tree-expr-ranges-2.c: New file. * gcc.dg/plugin/diagnostic-test-expressions-1.c: New file. * gcc.dg/plugin/diagnostic-test-show-trees-1.c: New file. * gcc.dg/plugin/diagnostic_plugin_show_trees.c: New file. * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c (get_loc): Add line_table param when calling linemap_position_for_line_and_column. (test_show_locus): Pass line_table to rich_location ctors. (plugin_init): Remove setting of global_dc->colorize_source_p. * gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c: New file. * gcc.dg/plugin/plugin.exp (plugin_test_list): Add diagnostic_plugin_test_tree_expression_range.c, diagnostic-test-expressions-1.c, diagnostic_plugin_show_trees.c, and diagnostic-test-show-trees-1.c. libcpp/ChangeLog: * errors.c (cpp_diagnostic): Pass pfile->line_table to rich_location ctor. (cpp_diagnostic_with_line): Likewise. * include/cpplib.h (struct cpp_token): Update comment for src_loc to indicate that the range of the token is "baked into" the source_location. * include/line-map.h (source_location): Update the descriptive comment to reflect the packing scheme for short ranges, adding worked examples of location encoding. (struct line_map_ordinary): Drop field "column_bits" in favor of field "m_column_and_range_bits"; add field "m_range_bits". (ORDINARY_MAP_NUMBER_OF_COLUMN_BITS): Delete. (location_adhoc_data): Add source_range field. (struct line_maps): Add fields "default_range_bits", "num_optimized_ranges" and "num_unoptimized_ranges". (get_combined_adhoc_loc): Add source_range param. (get_range_from_loc): New declaration. (pure_location_p): New prototype. (COMBINE_LOCATION_DATA): Add source_range param. (SOURCE_LINE): Update for renaming of column_bits. (SOURCE_COLUMN): Likewise. Shift the column right by the map's range_bits. (LAST_SOURCE_LINE_LOCATION): Update for renaming of column_bits. (linemap_position_for_line_and_column): Add line_maps * params. (rich_location::rich_location): Likewise. * lex.c (_cpp_lex_direct): Capture the range of the token, baking it into token->src_loc via a call to COMBINE_LOCATION_DATA. * line-map.c (LINE_MAP_MAX_COLUMN_NUMBER): Reduce from 1U << 17 to 1U << 12. (location_adhoc_data_hash): Add the src_range into the hash value. (location_adhoc_data_eq): Require equality of the src_range values. (can_be_stored_compactly_p): New function. (get_combined_adhoc_loc): Add src_range param, and store it, via a bit-packing scheme for short ranges, otherwise within the lookaside table. Remove the requirement that data is non-NULL. (get_range_from_adhoc_loc): New function. (get_range_from_loc): New function. (pure_location_p): New function. (linemap_add): Ensure that start_location has zero for the range_bits, unless we're past LINE_MAP_MAX_LOCATION_WITH_COLS. Initialize range_bits to zero. Assert that the start_location is "pure". (linemap_line_start): Assert that the column_and_range_bits >= range_bits. Update determinination of whether we need to start a new map using the effective column bits, without the range bits. Use the set's default_range_bits in new maps, apart from those with column_bits == 0, which should also have 0 range_bits. Increase the column bits for new maps by the range bits. When adding lines to an existing map, use set->highest_line directly rather than offsetting highest by SOURCE_COLUMN. Add assertions to sanity-check the return value. (linemap_position_for_column): Offset to_column by range_bits. Update set->highest_location if necessary. (linemap_position_for_line_and_column): Add line_maps * param. Update the calculation to offset the column by range_bits, and conditionalize it on being <= LINE_MAP_MAX_LOCATION_WITH_COLS. Bound it by LINEMAPS_MACRO_LOWEST_LOCATION. Update set->highest_location if necessary. (linemap_position_for_loc_and_offset): Handle ad-hoc locations; pass "set" to linemap_position_for_line_and_column. (linemap_macro_map_loc_unwind_toward_spelling): Add line_maps param. Handle ad-hoc locations. (linemap_location_in_system_header_p): Pass on "set" to call to linemap_macro_map_loc_unwind_toward_spelling. (linemap_macro_loc_to_spelling_point): Retain ad-hoc locations. Pass on "set" to call to linemap_macro_map_loc_unwind_toward_spelling. (linemap_resolve_location): Retain ad-hoc locations. Pass on "set" to call to linemap_macro_map_loc_unwind_toward_spelling. (linemap_unwind_toward_expansion): Pass on "set" to call to linemap_macro_map_loc_unwind_toward_spelling. (linemap_expand_location): Extract the data pointer before extracting the location. (rich_location::rich_location): Add line_maps param; use it to extract the range from the source_location. * location-example.txt: Regenerate, showing new representation. From-SVN: r230331
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog82
-rw-r--r--libcpp/errors.c4
-rw-r--r--libcpp/include/cpplib.h3
-rw-r--r--libcpp/include/line-map.h219
-rw-r--r--libcpp/lex.c13
-rw-r--r--libcpp/line-map.c274
-rw-r--r--libcpp/location-example.txt188
7 files changed, 622 insertions, 161 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 57ac5bfbde1..5a87c1791c4 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,85 @@
+2015-11-13 David Malcolm <dmalcolm@redhat.com>
+
+ * errors.c (cpp_diagnostic): Pass pfile->line_table to
+ rich_location ctor.
+ (cpp_diagnostic_with_line): Likewise.
+ * include/cpplib.h (struct cpp_token): Update comment for src_loc
+ to indicate that the range of the token is "baked into" the
+ source_location.
+ * include/line-map.h (source_location): Update the descriptive
+ comment to reflect the packing scheme for short ranges, adding
+ worked examples of location encoding.
+ (struct line_map_ordinary): Drop field "column_bits" in favor
+ of field "m_column_and_range_bits"; add field "m_range_bits".
+ (ORDINARY_MAP_NUMBER_OF_COLUMN_BITS): Delete.
+ (location_adhoc_data): Add source_range field.
+ (struct line_maps): Add fields "default_range_bits",
+ "num_optimized_ranges" and "num_unoptimized_ranges".
+ (get_combined_adhoc_loc): Add source_range param.
+ (get_range_from_loc): New declaration.
+ (pure_location_p): New prototype.
+ (COMBINE_LOCATION_DATA): Add source_range param.
+ (SOURCE_LINE): Update for renaming of column_bits.
+ (SOURCE_COLUMN): Likewise. Shift the column right by the map's
+ range_bits.
+ (LAST_SOURCE_LINE_LOCATION): Update for renaming of column_bits.
+ (linemap_position_for_line_and_column): Add line_maps * params.
+ (rich_location::rich_location): Likewise.
+ * lex.c (_cpp_lex_direct): Capture the range of the token, baking
+ it into token->src_loc via a call to COMBINE_LOCATION_DATA.
+ * line-map.c (LINE_MAP_MAX_COLUMN_NUMBER): Reduce from 1U << 17 to
+ 1U << 12.
+ (location_adhoc_data_hash): Add the src_range into
+ the hash value.
+ (location_adhoc_data_eq): Require equality of the src_range
+ values.
+ (can_be_stored_compactly_p): New function.
+ (get_combined_adhoc_loc): Add src_range param, and store it,
+ via a bit-packing scheme for short ranges, otherwise within the
+ lookaside table. Remove the requirement that data is non-NULL.
+ (get_range_from_adhoc_loc): New function.
+ (get_range_from_loc): New function.
+ (pure_location_p): New function.
+ (linemap_add): Ensure that start_location has zero for the
+ range_bits, unless we're past LINE_MAP_MAX_LOCATION_WITH_COLS.
+ Initialize range_bits to zero. Assert that the start_location
+ is "pure".
+ (linemap_line_start): Assert that the
+ column_and_range_bits >= range_bits.
+ Update determinination of whether we need to start a new map
+ using the effective column bits, without the range bits.
+ Use the set's default_range_bits in new maps, apart from
+ those with column_bits == 0, which should also have 0 range_bits.
+ Increase the column bits for new maps by the range bits.
+ When adding lines to an existing map, use set->highest_line
+ directly rather than offsetting highest by SOURCE_COLUMN.
+ Add assertions to sanity-check the return value.
+ (linemap_position_for_column): Offset to_column by range_bits.
+ Update set->highest_location if necessary.
+ (linemap_position_for_line_and_column): Add line_maps * param.
+ Update the calculation to offset the column by range_bits, and
+ conditionalize it on being <= LINE_MAP_MAX_LOCATION_WITH_COLS.
+ Bound it by LINEMAPS_MACRO_LOWEST_LOCATION. Update
+ set->highest_location if necessary.
+ (linemap_position_for_loc_and_offset): Handle ad-hoc locations;
+ pass "set" to linemap_position_for_line_and_column.
+ (linemap_macro_map_loc_unwind_toward_spelling): Add line_maps
+ param. Handle ad-hoc locations.
+ (linemap_location_in_system_header_p): Pass on "set" to call to
+ linemap_macro_map_loc_unwind_toward_spelling.
+ (linemap_macro_loc_to_spelling_point): Retain ad-hoc locations.
+ Pass on "set" to call to
+ linemap_macro_map_loc_unwind_toward_spelling.
+ (linemap_resolve_location): Retain ad-hoc locations. Pass on
+ "set" to call to linemap_macro_map_loc_unwind_toward_spelling.
+ (linemap_unwind_toward_expansion): Pass on "set" to call to
+ linemap_macro_map_loc_unwind_toward_spelling.
+ (linemap_expand_location): Extract the data pointer before
+ extracting the location.
+ (rich_location::rich_location): Add line_maps param; use it to
+ extract the range from the source_location.
+ * location-example.txt: Regenerate, showing new representation.
+
2015-11-06 David Malcolm <dmalcolm@redhat.com>
* errors.c (cpp_diagnostic): Update for change in signature
diff --git a/libcpp/errors.c b/libcpp/errors.c
index c351c112ad1..8790e10f5c8 100644
--- a/libcpp/errors.c
+++ b/libcpp/errors.c
@@ -57,7 +57,7 @@ cpp_diagnostic (cpp_reader * pfile, int level, int reason,
if (!pfile->cb.error)
abort ();
- rich_location richloc (src_loc);
+ rich_location richloc (pfile->line_table, src_loc);
ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap);
return ret;
@@ -140,7 +140,7 @@ cpp_diagnostic_with_line (cpp_reader * pfile, int level, int reason,
if (!pfile->cb.error)
abort ();
- rich_location richloc (src_loc);
+ rich_location richloc (pfile->line_table, src_loc);
richloc.override_column (column);
ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap);
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index a2bdfa0c808..f5c2a21e952 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -237,7 +237,8 @@ struct GTY(()) cpp_identifier {
/* A preprocessing token. This has been carefully packed and should
occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */
struct GTY(()) cpp_token {
- source_location src_loc; /* Location of first char of token. */
+ source_location src_loc; /* Location of first char of token,
+ together with range of full token. */
ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */
unsigned short flags; /* flags - see above */
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index c9340a6eaef..e7608f1e468 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -47,7 +47,8 @@ enum lc_reason
typedef unsigned int linenum_type;
/* The typedef "source_location" is a key within the location database,
- identifying a source location or macro expansion.
+ identifying a source location or macro expansion, along with range
+ information, and (optionally) a pointer for use by gcc.
This key only has meaning in relation to a line_maps instance. Within
gcc there is a single line_maps instance: "line_table", declared in
@@ -69,13 +70,48 @@ typedef unsigned int linenum_type;
| ordmap[0]->start_location) | first line in ordmap 0
-----------+-------------------------------+-------------------------------
| ordmap[1]->start_location | First line in ordmap 1
- | ordmap[1]->start_location+1 | First column in that line
- | ordmap[1]->start_location+2 | 2nd column in that line
- | | Subsequent lines are offset by
- | | (1 << column_bits),
- | | e.g. 128 for 7 bits, with a
- | | column value of 0 representing
- | | "the whole line".
+ | ordmap[1]->start_location+32 | First column in that line
+ | (assuming range_bits == 5) |
+ | ordmap[1]->start_location+64 | 2nd column in that line
+ | ordmap[1]->start_location+4096| Second line in ordmap 1
+ | (assuming column_bits == 12)
+ |
+ | Subsequent lines are offset by (1 << column_bits),
+ | e.g. 4096 for 12 bits, with a column value of 0 representing
+ | "the whole line".
+ |
+ | Within a line, the low "range_bits" (typically 5) are used for
+ | storing short ranges, so that there's an offset of
+ | (1 << range_bits) between individual columns within a line,
+ | typically 32.
+ | The low range_bits store the offset of the end point from the
+ | start point, and the start point is found by masking away
+ | the range bits.
+ |
+ | For example:
+ | ordmap[1]->start_location+64 "2nd column in that line"
+ | above means a caret at that location, with a range
+ | starting and finishing at the same place (the range bits
+ | are 0), a range of length 1.
+ |
+ | By contrast:
+ | ordmap[1]->start_location+68
+ | has range bits 0x4, meaning a caret with a range starting at
+ | that location, but with endpoint 4 columns further on: a range
+ | of length 5.
+ |
+ | Ranges that have caret != start, or have an endpoint too
+ | far away to fit in range_bits are instead stored as ad-hoc
+ | locations. Hence for range_bits == 5 we can compactly store
+ | tokens of length <= 32 without needing to use the ad-hoc
+ | table.
+ |
+ | This packing scheme means we effectively have
+ | (column_bits - range_bits)
+ | of bits for the columns, typically (12 - 5) = 7, for 128
+ | columns; longer line widths are accomodated by starting a
+ | new ordmap with a higher column_bits.
+ |
| ordmap[2]->start_location-1 | Final location in ordmap 1
-----------+-------------------------------+-------------------------------
| ordmap[2]->start_location | First line in ordmap 2
@@ -127,8 +163,101 @@ typedef unsigned int linenum_type;
0xffffffff | UINT_MAX |
-----------+-------------------------------+-------------------------------
- To see how this works in practice, see the worked example in
- libcpp/location-example.txt. */
+ Examples of location encoding.
+
+ Packed ranges
+ =============
+
+ Consider encoding the location of a token "foo", seen underlined here
+ on line 523, within an ordinary line_map that starts at line 500:
+
+ 11111111112
+ 12345678901234567890
+ 522
+ 523 return foo + bar;
+ ^~~
+ 524
+
+ The location's caret and start are both at line 523, column 11; the
+ location's finish is on the same line, at column 13 (an offset of 2
+ columns, for length 3).
+
+ Line 523 is offset 23 from the starting line of the ordinary line_map.
+
+ caret == start, and the offset of the finish fits within 5 bits, so
+ this can be stored as a packed range.
+
+ This is encoded as:
+ ordmap->start
+ + (line_offset << ordmap->m_column_and_range_bits)
+ + (column << ordmap->m_range_bits)
+ + (range_offset);
+ i.e. (for line offset 23, column 11, range offset 2):
+ ordmap->start
+ + (23 << 12)
+ + (11 << 5)
+ + 2;
+ i.e.:
+ ordmap->start + 0x17162
+ assuming that the line_map uses the default of 7 bits for columns and
+ 5 bits for packed range (giving 12 bits for m_column_and_range_bits).
+
+
+ "Pure" locations
+ ================
+
+ These are a special case of the above, where
+ caret == start == finish
+ They are stored as packed ranges with offset == 0.
+ For example, the location of the "f" of "foo" could be stored
+ as above, but with range offset 0, giving:
+ ordmap->start
+ + (23 << 12)
+ + (11 << 5)
+ + 0;
+ i.e.:
+ ordmap->start + 0x17160
+
+
+ Unoptimized ranges
+ ==================
+
+ Consider encoding the location of the binary expression
+ below:
+
+ 11111111112
+ 12345678901234567890
+ 521
+ 523 return foo + bar;
+ ~~~~^~~~~
+ 523
+
+ The location's caret is at the "+", line 523 column 15, but starts
+ earlier, at the "f" of "foo" at column 11. The finish is at the "r"
+ of "bar" at column 19.
+
+ This can't be stored as a packed range since start != caret.
+ Hence it is stored as an ad-hoc location e.g. 0x80000003.
+
+ Stripping off the top bit gives us an index into the ad-hoc
+ lookaside table:
+
+ line_table->location_adhoc_data_map.data[0x3]
+
+ from which the caret, start and finish can be looked up,
+ encoded as "pure" locations:
+
+ start == ordmap->start + (23 << 12) + (11 << 5)
+ == ordmap->start + 0x17160 (as above; the "f" of "foo")
+
+ caret == ordmap->start + (23 << 12) + (15 << 5)
+ == ordmap->start + 0x171e0
+
+ finish == ordmap->start + (23 << 12) + (19 << 5)
+ == ordmap->start + 0x17260
+
+ To further see how source_location works in practice, see the
+ worked example in libcpp/location-example.txt. */
typedef unsigned int source_location;
/* A range of source locations.
@@ -217,8 +346,9 @@ struct GTY((tag ("0"), desc ("%h.reason == LC_ENTER_MACRO ? 2 : 1"))) line_map {
Physical source file TO_FILE at line TO_LINE at column 0 is represented
by the logical START_LOCATION. TO_LINE+L at column C is represented by
- START_LOCATION+(L*(1<<column_bits))+C, as long as C<(1<<column_bits),
- and the result_location is less than the next line_map's start_location.
+ START_LOCATION+(L*(1<<m_column_and_range_bits))+(C*1<<m_range_bits), as
+ long as C<(1<<effective range bits), and the result_location is less than
+ the next line_map's start_location.
(The top line is line 1 and the leftmost column is column 1; line/column 0
means "entire file/line" or "unknown line/column" or "not applicable".)
@@ -238,8 +368,24 @@ struct GTY((tag ("1"))) line_map_ordinary : public line_map {
cpp_buffer. */
unsigned char sysp;
- /* Number of the low-order source_location bits used for a column number. */
- unsigned int column_bits : 8;
+ /* Number of the low-order source_location bits used for column numbers
+ and ranges. */
+ unsigned int m_column_and_range_bits : 8;
+
+ /* Number of the low-order "column" bits used for storing short ranges
+ inline, rather than in the ad-hoc table.
+ MSB LSB
+ 31 0
+ +-------------------------+-------------------------------------------+
+ | |<---map->column_and_range_bits (e.g. 12)-->|
+ +-------------------------+-----------------------+-------------------+
+ | | column_and_range_bits | map->range_bits |
+ | | - range_bits | |
+ +-------------------------+-----------------------+-------------------+
+ | row bits | effective column bits | short range bits |
+ | | (e.g. 7) | (e.g. 5) |
+ +-------------------------+-----------------------+-------------------+ */
+ unsigned int m_range_bits : 8;
};
/* This is the highest possible source location encoded within an
@@ -435,15 +581,6 @@ ORDINARY_MAP_IN_SYSTEM_HEADER_P (const line_map_ordinary *ord_map)
return ord_map->sysp;
}
-/* Get the number of the low-order source_location bits used for a
- column number within ordinary map MAP. */
-
-inline unsigned char
-ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (const line_map_ordinary *ord_map)
-{
- return ord_map->column_bits;
-}
-
/* Get the filename of ordinary map MAP. */
inline const char *
@@ -524,9 +661,11 @@ struct GTY(()) maps_info_macro {
unsigned int cache;
};
-/* Data structure to associate an arbitrary data to a source location. */
+/* Data structure to associate a source_range together with an arbitrary
+ data pointer with a source location. */
struct GTY(()) location_adhoc_data {
source_location locus;
+ source_range src_range;
void * GTY((skip)) data;
};
@@ -588,6 +727,12 @@ struct GTY(()) line_maps {
/* True if we've seen a #line or # 44 "file" directive. */
bool seen_line_directive;
+
+ /* The default value of range_bits in ordinary line maps. */
+ unsigned int default_range_bits;
+
+ unsigned int num_optimized_ranges;
+ unsigned int num_unoptimized_ranges;
};
/* Returns the number of allocated maps so far. MAP_KIND shall be TRUE
@@ -825,11 +970,15 @@ LINEMAPS_LAST_ALLOCATED_MACRO_MAP (const line_maps *set)
extern void location_adhoc_data_fini (struct line_maps *);
extern source_location get_combined_adhoc_loc (struct line_maps *,
- source_location, void *);
+ source_location,
+ source_range,
+ void *);
extern void *get_data_from_adhoc_loc (struct line_maps *, source_location);
extern source_location get_location_from_adhoc_loc (struct line_maps *,
source_location);
+extern source_range get_range_from_loc (line_maps *set, source_location loc);
+
/* Get whether location LOC is an ad-hoc location. */
inline bool
@@ -838,14 +987,21 @@ IS_ADHOC_LOC (source_location loc)
return (loc & MAX_SOURCE_LOCATION) != loc;
}
+/* Get whether location LOC is a "pure" location, or
+ whether it is an ad-hoc location, or embeds range information. */
+
+bool
+pure_location_p (line_maps *set, source_location loc);
+
/* Combine LOC and BLOCK, giving a combined adhoc location. */
inline source_location
COMBINE_LOCATION_DATA (struct line_maps *set,
source_location loc,
+ source_range src_range,
void *block)
{
- return get_combined_adhoc_loc (set, loc, block);
+ return get_combined_adhoc_loc (set, loc, src_range, block);
}
extern void rebuild_location_adhoc_htab (struct line_maps *);
@@ -931,7 +1087,7 @@ inline linenum_type
SOURCE_LINE (const line_map_ordinary *ord_map, source_location loc)
{
return ((loc - ord_map->start_location)
- >> ord_map->column_bits) + ord_map->to_line;
+ >> ord_map->m_column_and_range_bits) + ord_map->to_line;
}
/* Convert a map and source_location to source column number. */
@@ -939,7 +1095,7 @@ inline linenum_type
SOURCE_COLUMN (const line_map_ordinary *ord_map, source_location loc)
{
return ((loc - ord_map->start_location)
- & ((1 << ord_map->column_bits) - 1));
+ & ((1 << ord_map->m_column_and_range_bits) - 1)) >> ord_map->m_range_bits;
}
/* Return the location of the last source line within an ordinary
@@ -949,7 +1105,7 @@ LAST_SOURCE_LINE_LOCATION (const line_map_ordinary *map)
{
return (((map[1].start_location - 1
- map->start_location)
- & ~((1 << map->column_bits) - 1))
+ & ~((1 << map->m_column_and_range_bits) - 1))
+ map->start_location);
}
@@ -999,7 +1155,8 @@ linemap_position_for_column (struct line_maps *, unsigned int);
/* Encode and return a source location from a given line and
column. */
source_location
-linemap_position_for_line_and_column (const line_map_ordinary *,
+linemap_position_for_line_and_column (line_maps *set,
+ const line_map_ordinary *,
linenum_type, unsigned int);
/* Encode and return a source_location starting from location LOC and
@@ -1187,7 +1344,7 @@ class rich_location
/* Constructors. */
/* Constructing from a location. */
- rich_location (source_location loc);
+ rich_location (line_maps *set, source_location loc);
/* Constructing from a source_range. */
rich_location (source_range src_range);
diff --git a/libcpp/lex.c b/libcpp/lex.c
index 7e97bc2b289..d9b428ad8d8 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -2723,6 +2723,19 @@ _cpp_lex_direct (cpp_reader *pfile)
break;
}
+ source_range tok_range;
+ tok_range.m_start = result->src_loc;
+ if (result->src_loc >= RESERVED_LOCATION_COUNT)
+ tok_range.m_finish
+ = linemap_position_for_column (pfile->line_table,
+ CPP_BUF_COLUMN (buffer, buffer->cur));
+ else
+ tok_range.m_finish = tok_range.m_start;
+
+ result->src_loc = COMBINE_LOCATION_DATA (pfile->line_table,
+ result->src_loc,
+ tok_range, NULL);
+
return result;
}
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 3c19f93b7a5..c5aa4223b1b 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -27,9 +27,9 @@ along with this program; see the file COPYING3. If not see
#include "hashtab.h"
/* Do not track column numbers higher than this one. As a result, the
- range of column_bits is [7, 18] (or 0 if column numbers are
+ range of column_bits is [12, 18] (or 0 if column numbers are
disabled). */
-const unsigned int LINE_MAP_MAX_COLUMN_NUMBER = (1U << 17);
+const unsigned int LINE_MAP_MAX_COLUMN_NUMBER = (1U << 12);
/* Do not track column numbers if locations get higher than this. */
const source_location LINE_MAP_MAX_LOCATION_WITH_COLS = 0x60000000;
@@ -46,7 +46,7 @@ static const line_map_macro* linemap_macro_map_lookup (struct line_maps *,
static source_location linemap_macro_map_loc_to_def_point
(const line_map_macro *, source_location);
static source_location linemap_macro_map_loc_unwind_toward_spelling
-(const line_map_macro *, source_location);
+(line_maps *set, const line_map_macro *, source_location);
static source_location linemap_macro_map_loc_to_exp_point
(const line_map_macro *, source_location);
static source_location linemap_macro_loc_to_spelling_point
@@ -69,7 +69,10 @@ location_adhoc_data_hash (const void *l)
{
const struct location_adhoc_data *lb =
(const struct location_adhoc_data *) l;
- return (hashval_t) lb->locus + (size_t) lb->data;
+ return ((hashval_t) lb->locus
+ + (hashval_t) lb->src_range.m_start
+ + (hashval_t) lb->src_range.m_finish
+ + (size_t) lb->data);
}
/* Compare function for location_adhoc_data hashtable. */
@@ -81,7 +84,10 @@ location_adhoc_data_eq (const void *l1, const void *l2)
(const struct location_adhoc_data *) l1;
const struct location_adhoc_data *lb2 =
(const struct location_adhoc_data *) l2;
- return lb1->locus == lb2->locus && lb1->data == lb2->data;
+ return (lb1->locus == lb2->locus
+ && lb1->src_range.m_start == lb2->src_range.m_start
+ && lb1->src_range.m_finish == lb2->src_range.m_finish
+ && lb1->data == lb2->data);
}
/* Update the hashtable when location_adhoc_data is reallocated. */
@@ -106,23 +112,103 @@ rebuild_location_adhoc_htab (struct line_maps *set)
set->location_adhoc_data_map.data + i, INSERT);
}
+/* Helper function for get_combined_adhoc_loc.
+ Can the given LOCUS + SRC_RANGE and DATA pointer be stored compactly
+ within a source_location, without needing to use an ad-hoc location. */
+
+static bool
+can_be_stored_compactly_p (struct line_maps *set,
+ source_location locus,
+ source_range src_range,
+ void *data)
+{
+ /* If there's an ad-hoc pointer, we can't store it directly in the
+ source_location, we need the lookaside. */
+ if (data)
+ return false;
+
+ /* We only store ranges that begin at the locus and that are sufficiently
+ "sane". */
+ if (src_range.m_start != locus)
+ return false;
+
+ if (src_range.m_finish < src_range.m_start)
+ return false;
+
+ if (src_range.m_start < RESERVED_LOCATION_COUNT)
+ return false;
+
+ if (locus >= LINE_MAP_MAX_LOCATION_WITH_COLS)
+ return false;
+
+ /* All 3 locations must be within ordinary maps, typically, the same
+ ordinary map. */
+ source_location lowest_macro_loc = LINEMAPS_MACRO_LOWEST_LOCATION (set);
+ if (locus >= lowest_macro_loc)
+ return false;
+ if (src_range.m_start >= lowest_macro_loc)
+ return false;
+ if (src_range.m_finish >= lowest_macro_loc)
+ return false;
+
+ /* Passed all tests. */
+ return true;
+}
+
/* Combine LOCUS and DATA to a combined adhoc loc. */
source_location
get_combined_adhoc_loc (struct line_maps *set,
- source_location locus, void *data)
+ source_location locus,
+ source_range src_range,
+ void *data)
{
struct location_adhoc_data lb;
struct location_adhoc_data **slot;
- linemap_assert (data);
-
if (IS_ADHOC_LOC (locus))
locus
= set->location_adhoc_data_map.data[locus & MAX_SOURCE_LOCATION].locus;
if (locus == 0 && data == NULL)
return 0;
+
+ /* Any ordinary locations ought to be "pure" at this point: no
+ compressed ranges. */
+ linemap_assert (locus < RESERVED_LOCATION_COUNT
+ || locus >= LINE_MAP_MAX_LOCATION_WITH_COLS
+ || locus >= LINEMAPS_MACRO_LOWEST_LOCATION (set)
+ || pure_location_p (set, locus));
+
+ /* Consider short-range optimization. */
+ if (can_be_stored_compactly_p (set, locus, src_range, data))
+ {
+ /* The low bits ought to be clear. */
+ linemap_assert (pure_location_p (set, locus));
+ const line_map *map = linemap_lookup (set, locus);
+ const line_map_ordinary *ordmap = linemap_check_ordinary (map);
+ unsigned int int_diff = src_range.m_finish - src_range.m_start;
+ unsigned int col_diff = (int_diff >> ordmap->m_range_bits);
+ if (col_diff < (1U << ordmap->m_range_bits))
+ {
+ source_location packed = locus | col_diff;
+ set->num_optimized_ranges++;
+ return packed;
+ }
+ }
+
+ /* We can also compactly store the reserved locations
+ when locus == start == finish (and data is NULL). */
+ if (locus < RESERVED_LOCATION_COUNT
+ && locus == src_range.m_start
+ && locus == src_range.m_finish
+ && !data)
+ return locus;
+
+ if (!data)
+ set->num_unoptimized_ranges++;
+
lb.locus = locus;
+ lb.src_range = src_range;
lb.data = data;
slot = (struct location_adhoc_data **)
htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
@@ -177,6 +263,60 @@ get_location_from_adhoc_loc (struct line_maps *set, source_location loc)
return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
}
+/* Return the source_range for adhoc location LOC. */
+
+static source_range
+get_range_from_adhoc_loc (struct line_maps *set, source_location loc)
+{
+ linemap_assert (IS_ADHOC_LOC (loc));
+ return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].src_range;
+}
+
+/* Get the source_range of location LOC, either from the ad-hoc
+ lookaside table, or embedded inside LOC itself. */
+
+source_range
+get_range_from_loc (struct line_maps *set,
+ source_location loc)
+{
+ if (IS_ADHOC_LOC (loc))
+ return get_range_from_adhoc_loc (set, loc);
+
+ /* For ordinary maps, extract packed range. */
+ if (loc >= RESERVED_LOCATION_COUNT
+ && loc < LINEMAPS_MACRO_LOWEST_LOCATION (set)
+ && loc <= LINE_MAP_MAX_LOCATION_WITH_COLS)
+ {
+ const line_map *map = linemap_lookup (set, loc);
+ const line_map_ordinary *ordmap = linemap_check_ordinary (map);
+ source_range result;
+ int offset = loc & ((1 << ordmap->m_range_bits) - 1);
+ result.m_start = loc - offset;
+ result.m_finish = result.m_start + (offset << ordmap->m_range_bits);
+ return result;
+ }
+
+ return source_range::from_location (loc);
+}
+
+/* Get whether location LOC is a "pure" location, or
+ whether it is an ad-hoc location, or embeds range information. */
+
+bool
+pure_location_p (line_maps *set, source_location loc)
+{
+ if (IS_ADHOC_LOC (loc))
+ return false;
+
+ const line_map *map = linemap_lookup (set, loc);
+ const line_map_ordinary *ordmap = linemap_check_ordinary (map);
+
+ if (loc & ((1U << ordmap->m_range_bits) - 1))
+ return false;
+
+ return true;
+}
+
/* Finalize the location_adhoc_data structure. */
void
location_adhoc_data_fini (struct line_maps *set)
@@ -319,7 +459,19 @@ const struct line_map *
linemap_add (struct line_maps *set, enum lc_reason reason,
unsigned int sysp, const char *to_file, linenum_type to_line)
{
- source_location start_location = set->highest_location + 1;
+ /* Generate a start_location above the current highest_location.
+ If possible, make the low range bits be zero. */
+ source_location start_location;
+ if (set->highest_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
+ {
+ start_location = set->highest_location + (1 << set->default_range_bits);
+ if (set->default_range_bits)
+ start_location &= ~((1 << set->default_range_bits) - 1);
+ linemap_assert (0 == (start_location
+ & ((1 << set->default_range_bits) - 1)));
+ }
+ else
+ start_location = set->highest_location + 1;
linemap_assert (!(LINEMAPS_ORDINARY_USED (set)
&& (start_location
@@ -398,11 +550,18 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
map->to_file = to_file;
map->to_line = to_line;
LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1;
- map->column_bits = 0;
+ map->m_column_and_range_bits = 0;
+ map->m_range_bits = 0;
set->highest_location = start_location;
set->highest_line = start_location;
set->max_column_hint = 0;
+ /* This assertion is placed after set->highest_location has
+ been updated, since the latter affects
+ linemap_location_from_macro_expansion_p, which ultimately affects
+ pure_location_p. */
+ linemap_assert (pure_location_p (set, start_location));
+
if (reason == LC_ENTER)
{
map->included_from =
@@ -549,13 +708,14 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
SOURCE_LINE (map, set->highest_line);
int line_delta = to_line - last_line;
bool add_map = false;
+ linemap_assert (map->m_column_and_range_bits >= map->m_range_bits);
+ int effective_column_bits = map->m_column_and_range_bits - map->m_range_bits;
if (line_delta < 0
|| (line_delta > 10
- && line_delta * ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) > 1000)
- || (max_column_hint >= (1U << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map)))
- || (max_column_hint <= 80
- && ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) >= 10)
+ && line_delta * map->m_column_and_range_bits > 1000)
+ || (max_column_hint >= (1U << effective_column_bits))
+ || (max_column_hint <= 80 && effective_column_bits >= 10)
|| (highest > LINE_MAP_MAX_LOCATION_WITH_COLS
&& (set->max_column_hint || highest >= LINE_MAP_MAX_SOURCE_LOCATION)))
add_map = true;
@@ -564,22 +724,27 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
if (add_map)
{
int column_bits;
+ int range_bits;
if (max_column_hint > LINE_MAP_MAX_COLUMN_NUMBER
|| highest > LINE_MAP_MAX_LOCATION_WITH_COLS)
{
/* If the column number is ridiculous or we've allocated a huge
- number of source_locations, give up on column numbers. */
+ number of source_locations, give up on column numbers
+ (and on packed ranges). */
max_column_hint = 0;
column_bits = 0;
+ range_bits = 0;
if (highest > LINE_MAP_MAX_SOURCE_LOCATION)
return 0;
}
else
{
column_bits = 7;
+ range_bits = set->default_range_bits;
while (max_column_hint >= (1U << column_bits))
column_bits++;
max_column_hint = 1U << column_bits;
+ column_bits += range_bits;
}
/* Allocate the new line_map. However, if the current map only has a
single line we can sometimes just increase its column_bits instead. */
@@ -592,14 +757,14 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
ORDINARY_MAP_IN_SYSTEM_HEADER_P (map),
ORDINARY_MAP_FILE_NAME (map),
to_line)));
- map->column_bits = column_bits;
+ map->m_column_and_range_bits = column_bits;
+ map->m_range_bits = range_bits;
r = (MAP_START_LOCATION (map)
+ ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
<< column_bits));
}
else
- r = highest - SOURCE_COLUMN (map, highest)
- + (line_delta << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map));
+ r = set->highest_line + (line_delta << map->m_column_and_range_bits);
/* Locations of ordinary tokens are always lower than locations of
macro tokens. */
@@ -610,6 +775,18 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
if (r > set->highest_location)
set->highest_location = r;
set->max_column_hint = max_column_hint;
+
+ /* At this point, we expect one of:
+ (a) the normal case: a "pure" location with 0 range bits, or
+ (b) we've gone past LINE_MAP_MAX_LOCATION_WITH_COLS so can't track
+ columns anymore (or ranges), or
+ (c) we're in a region with a column hint exceeding
+ LINE_MAP_MAX_COLUMN_NUMBER, so column-tracking is off,
+ with column_bits == 0. */
+ linemap_assert (pure_location_p (set, r)
+ || r >= LINE_MAP_MAX_LOCATION_WITH_COLS
+ || map->m_column_and_range_bits == 0);
+ linemap_assert (SOURCE_LINE (map, r) == to_line);
return r;
}
@@ -640,7 +817,8 @@ linemap_position_for_column (struct line_maps *set, unsigned int to_column)
r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
}
}
- r = r + to_column;
+ line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
+ r = r + (to_column << map->m_range_bits);
if (r >= set->highest_location)
set->highest_location = r;
return r;
@@ -650,16 +828,25 @@ linemap_position_for_column (struct line_maps *set, unsigned int to_column)
column. */
source_location
-linemap_position_for_line_and_column (const line_map_ordinary *ord_map,
+linemap_position_for_line_and_column (line_maps *set,
+ const line_map_ordinary *ord_map,
linenum_type line,
unsigned column)
{
linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
- return (MAP_START_LOCATION (ord_map)
- + ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
- << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (ord_map))
- + (column & ((1 << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (ord_map)) - 1)));
+ source_location r = MAP_START_LOCATION (ord_map);
+ r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
+ << ord_map->m_column_and_range_bits);
+ if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS)
+ r += ((column & ((1 << ord_map->m_column_and_range_bits) - 1))
+ << ord_map->m_range_bits);
+ source_location upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set);
+ if (r >= upper_limit)
+ r = upper_limit - 1;
+ if (r > set->highest_location)
+ set->highest_location = r;
+ return r;
}
/* Encode and return a source_location starting from location LOC and
@@ -673,6 +860,9 @@ linemap_position_for_loc_and_offset (struct line_maps *set,
{
const line_map_ordinary * map = NULL;
+ if (IS_ADHOC_LOC (loc))
+ loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+
/* This function does not support virtual locations yet. */
if (linemap_assert_fails
(!linemap_location_from_macro_expansion_p (set, loc)))
@@ -711,11 +901,11 @@ linemap_position_for_loc_and_offset (struct line_maps *set,
}
offset += column;
- if (linemap_assert_fails (offset < (1u << map->column_bits)))
+ if (linemap_assert_fails (offset < (1u << map->m_column_and_range_bits)))
return loc;
source_location r =
- linemap_position_for_line_and_column (map, line, offset);
+ linemap_position_for_line_and_column (set, map, line, offset);
if (linemap_assert_fails (r <= set->highest_location)
|| linemap_assert_fails (map == linemap_lookup (set, r)))
return loc;
@@ -893,14 +1083,19 @@ linemap_macro_map_loc_to_def_point (const line_map_macro *map,
In other words, this returns the xI location presented in the
comments of line_map_macro above. */
source_location
-linemap_macro_map_loc_unwind_toward_spelling (const line_map_macro* map,
+linemap_macro_map_loc_unwind_toward_spelling (line_maps *set,
+ const line_map_macro* map,
source_location location)
{
unsigned token_no;
+ if (IS_ADHOC_LOC (location))
+ location = get_location_from_adhoc_loc (set, location);
+
linemap_assert (linemap_macro_expansion_map_p (map)
&& location >= MAP_START_LOCATION (map));
linemap_assert (location >= RESERVED_LOCATION_COUNT);
+ linemap_assert (!IS_ADHOC_LOC (location));
token_no = location - MAP_START_LOCATION (map);
linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
@@ -1010,7 +1205,7 @@ linemap_location_in_system_header_p (struct line_maps *set,
/* It's a token resulting from a macro expansion. */
source_location loc =
- linemap_macro_map_loc_unwind_toward_spelling (macro_map, location);
+ linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, location);
if (loc < RESERVED_LOCATION_COUNT)
/* This token might come from a built-in macro. Let's
look at where that macro got expanded. */
@@ -1183,11 +1378,6 @@ linemap_macro_loc_to_spelling_point (struct line_maps *set,
const line_map_ordinary **original_map)
{
struct line_map *map;
-
- if (IS_ADHOC_LOC (location))
- location = set->location_adhoc_data_map.data[location
- & MAX_SOURCE_LOCATION].locus;
-
linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
while (true)
@@ -1198,7 +1388,7 @@ linemap_macro_loc_to_spelling_point (struct line_maps *set,
location
= linemap_macro_map_loc_unwind_toward_spelling
- (linemap_check_macro (map),
+ (set, linemap_check_macro (map),
location);
}
@@ -1341,10 +1531,11 @@ linemap_resolve_location (struct line_maps *set,
enum location_resolution_kind lrk,
const line_map_ordinary **map)
{
+ source_location locus = loc;
if (IS_ADHOC_LOC (loc))
- loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+ locus = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
- if (loc < RESERVED_LOCATION_COUNT)
+ if (locus < RESERVED_LOCATION_COUNT)
{
/* A reserved location wasn't encoded in a map. Let's return a
NULL map here, just like what linemap_ordinary_map_lookup
@@ -1396,7 +1587,7 @@ linemap_unwind_toward_expansion (struct line_maps *set,
loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
resolved_location =
- linemap_macro_map_loc_unwind_toward_spelling (macro_map, loc);
+ linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, loc);
resolved_map = linemap_lookup (set, resolved_location);
if (!linemap_macro_expansion_map_p (resolved_map))
@@ -1478,9 +1669,9 @@ linemap_expand_location (struct line_maps *set,
memset (&xloc, 0, sizeof (xloc));
if (IS_ADHOC_LOC (loc))
{
- loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
xloc.data
= set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
+ loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
}
if (loc < RESERVED_LOCATION_COUNT)
@@ -1760,13 +1951,14 @@ line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary,
/* Construct a rich_location with location LOC as its initial range. */
-rich_location::rich_location (source_location loc) :
+rich_location::rich_location (line_maps *set, source_location loc) :
m_loc (loc),
m_num_ranges (0),
m_have_expanded_location (false)
{
- /* Set up the 0th range: */
- add_range (loc, loc, true);
+ /* Set up the 0th range, extracting any range from LOC. */
+ source_range src_range = get_range_from_loc (set, loc);
+ add_range (src_range, true);
m_ranges[0].m_caret = lazily_expand_location ();
}
diff --git a/libcpp/location-example.txt b/libcpp/location-example.txt
index a5f95b2baf8..14b5c2e284a 100644
--- a/libcpp/location-example.txt
+++ b/libcpp/location-example.txt
@@ -30,142 +30,154 @@ RESERVED LOCATIONS
source_location interval: 0 <= loc < 2
ORDINARY MAP: 0
- source_location interval: 2 <= loc < 3
+ source_location interval: 32 <= loc < 64
file: test.c
starting at line: 1
- column bits: 7
-test.c: 1|loc: 2|#include "test.h"
- |00000001111111111
- |34567890123456789
+ column bits: 12
+ range bits: 5
+test.c: 1|loc: 32|#include "test.h"
+ |69269258258148147
+ |46802468024680246
ORDINARY MAP: 1
- source_location interval: 3 <= loc < 4
+ source_location interval: 64 <= loc < 96
file: <built-in>
starting at line: 0
column bits: 0
+ range bits: 0
ORDINARY MAP: 2
- source_location interval: 4 <= loc < 5
+ source_location interval: 96 <= loc < 128
file: <command-line>
starting at line: 0
column bits: 0
+ range bits: 0
ORDINARY MAP: 3
- source_location interval: 5 <= loc < 5005
+ source_location interval: 128 <= loc < 160128
file: /usr/include/stdc-predef.h
starting at line: 1
- column bits: 7
+ column bits: 12
+ range bits: 5
(contents of /usr/include/stdc-predef.h snipped for brevity)
ORDINARY MAP: 4
- source_location interval: 5005 <= loc < 5006
+ source_location interval: 160128 <= loc < 160160
file: <command-line>
- starting at line: 1
- column bits: 7
+ starting at line: 32
+ column bits: 12
+ range bits: 5
ORDINARY MAP: 5
- source_location interval: 5006 <= loc < 5134
+ source_location interval: 160160 <= loc < 164256
file: test.c
starting at line: 1
- column bits: 7
-test.c: 1|loc: 5006|#include "test.h"
- |55555555555555555
+ column bits: 12
+ range bits: 5
+test.c: 1|loc:160160|#include "test.h"
|00000000000000000
- |00011111111112222
- |78901234567890123
+ |12223334445556667
+ |92582581481470470
+ |24680246802468024
ORDINARY MAP: 6
- source_location interval: 5134 <= loc < 5416
+ source_location interval: 164256 <= loc < 173280
file: test.h
starting at line: 1
- column bits: 7
-test.h: 1|loc: 5134|extern int foo ();
- |555555555555555555
- |111111111111111111
- |333334444444444555
- |567890123456789012
-test.h: 2|loc: 5262|
+ column bits: 12
+ range bits: 5
+test.h: 1|loc:164256|extern int foo ();
+ |444444444444444444
+ |233344455566677788
+ |825814814704703603
+ |802468024680246802
+test.h: 2|loc:168352|
|
|
|
|
-test.h: 3|loc: 5390|#define PLUS(A, B) A + B
- |555555555555555555555555
- |333333333444444444444444
- |999999999000000000011111
- |123456789012345678901234
+test.h: 3|loc:172448|#define PLUS(A, B) A + B
+ |222222222222222223333333
+ |455566677788889990001112
+ |814704703603692692582581
+ |024680246802468024680246
ORDINARY MAP: 7
- source_location interval: 5416 <= loc < 6314
+ source_location interval: 173280 <= loc < 202016
file: test.c
starting at line: 2
- column bits: 7
-test.c: 2|loc: 5416|
+ column bits: 12
+ range bits: 5
+test.c: 2|loc:173280|
|
|
|
|
-test.c: 3|loc: 5544|int
- |555
- |555
+test.c: 3|loc:177376|int
+ |777
|444
- |567
-test.c: 4|loc: 5672|main (int argc, char **argv)
- |5555555555555555555555555555
- |6666666666666666666666666667
- |7777777888888888899999999990
- |3456789012345678901234567890
-test.c: 5|loc: 5800|{
+ |047
+ |802
+test.c: 4|loc:181472|main (int argc, char **argv)
+ |1111111111111111222222222222
+ |5556666777888999000111222333
+ |0360369269258258148147047036
+ |4680246802468024680246802468
+test.c: 5|loc:185568|{
|5
- |8
- |0
- |1
-test.c: 6|loc: 5928| int a = PLUS (1,2);
- |555555555555555555555
- |999999999999999999999
- |233333333334444444444
- |901234567890123456789
-test.c: 7|loc: 6056| int b = PLUS (3,4);
- |666666666666666666666
- |000000000000000000000
- |555666666666677777777
- |789012345678901234567
-test.c: 8|loc: 6184| return 0;
- |66666666666
- |11111111111
- |88888999999
- |56789012345
-test.c: 9|loc: 6312|}
|6
- |3
+ |0
+ |0
+test.c: 6|loc:189664| int a = PLUS (1,2);
+ |999999999900000000000
+ |677788899900011122233
+ |926925825814814704703
+ |680246802468024680246
+test.c: 7|loc:193760| int b = PLUS (3,4);
+ |333333344444444444444
+ |788899900011122233344
+ |925825814814704703603
+ |246802468024680246802
+test.c: 8|loc:197856| return 0;
+ |77778888888
+ |89990001112
+ |82581481470
+ |80246802468
+test.c: 9|loc:201952|}
|1
- |3
+ |9
+ |8
+ |4
UNALLOCATED LOCATIONS
- source_location interval: 6314 <= loc < 2147483633
+ source_location interval: 202016 <= loc < 2147483633
MACRO 1: PLUS (7 tokens)
source_location interval: 2147483633 <= loc < 2147483640
-test.c:7:11: note: expansion point is location 6067
+test.c:7:11: note: expansion point is location 194115
int b = PLUS (3,4);
- ^
+ ^~~~
+
map->start_location: 2147483633
macro_locations:
- 0: 6073, 5410
-test.c:7:17: note: token 0 has x-location == 6073
+ 0: 194304, 173088
+test.c:7:17: note: token 0 has x-location == 194304
int b = PLUS (3,4);
^
-test.c:7:17: note: token 0 has y-location == 5410
- 1: 5412, 5412
+
+test.c:7:17: note: token 0 has y-location == 173088
+ 1: 173152, 173152
In file included from test.c:1:0:
-test.h:3:22: note: token 1 has x-location == y-location == 5412
+test.h:3:22: note: token 1 has x-location == y-location == 173152
#define PLUS(A, B) A + B
^
- 2: 6075, 5414
-test.c:7:19: note: token 2 has x-location == 6075
+
+ 2: 194368, 173216
+test.c:7:19: note: token 2 has x-location == 194368
int b = PLUS (3,4);
^
-test.c:7:19: note: token 2 has y-location == 5414
+
+test.c:7:19: note: token 2 has y-location == 173216
3: 0, 2947526575
cc1: note: token 3 has x-location == 0
cc1: note: token 3 has y-location == 2947526575
@@ -178,26 +190,30 @@ x-location == y-location == 2947526575 encodes token # 800042942
MACRO 0: PLUS (7 tokens)
source_location interval: 2147483640 <= loc < 2147483647
-test.c:6:11: note: expansion point is location 5939
+test.c:6:11: note: expansion point is location 190019
int a = PLUS (1,2);
- ^
+ ^~~~
+
map->start_location: 2147483640
macro_locations:
- 0: 5945, 5410
-test.c:6:17: note: token 0 has x-location == 5945
+ 0: 190208, 173088
+test.c:6:17: note: token 0 has x-location == 190208
int a = PLUS (1,2);
^
-test.c:6:17: note: token 0 has y-location == 5410
- 1: 5412, 5412
+
+test.c:6:17: note: token 0 has y-location == 173088
+ 1: 173152, 173152
In file included from test.c:1:0:
-test.h:3:22: note: token 1 has x-location == y-location == 5412
+test.h:3:22: note: token 1 has x-location == y-location == 173152
#define PLUS(A, B) A + B
^
- 2: 5947, 5414
-test.c:6:19: note: token 2 has x-location == 5947
+
+ 2: 190272, 173216
+test.c:6:19: note: token 2 has x-location == 190272
int a = PLUS (1,2);
^
-test.c:6:19: note: token 2 has y-location == 5414
+
+test.c:6:19: note: token 2 has y-location == 173216
3: 0, 2947526575
cc1: note: token 3 has x-location == 0
cc1: note: token 3 has y-location == 2947526575