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
This commit is contained in:
parent
1ba91a49a9
commit
ebedc9a341
|
@ -1,3 +1,58 @@
|
||||||
|
2015-11-13 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2015-11-13 Alan Lawrence <alan.lawrence@arm.com>
|
2015-11-13 Alan Lawrence <alan.lawrence@arm.com>
|
||||||
|
|
||||||
PR tree-optimization/67682
|
PR tree-optimization/67682
|
||||||
|
|
|
@ -1263,6 +1263,7 @@ OBJS = \
|
||||||
fold-const-call.o \
|
fold-const-call.o \
|
||||||
function.o \
|
function.o \
|
||||||
fwprop.o \
|
fwprop.o \
|
||||||
|
gcc-rich-location.o \
|
||||||
gcse.o \
|
gcse.o \
|
||||||
gcse-common.o \
|
gcse-common.o \
|
||||||
ggc-common.o \
|
ggc-common.o \
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2015-11-13 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
* gcc-interface/trans.c (Sloc_to_locus): Add line_table param when
|
||||||
|
calling linemap_position_for_line_and_column.
|
||||||
|
|
||||||
2015-11-13 Hristian Kirtchev <kirtchev@adacore.com>
|
2015-11-13 Hristian Kirtchev <kirtchev@adacore.com>
|
||||||
|
|
||||||
* exp_attr.adb: Minor reformatting.
|
* exp_attr.adb: Minor reformatting.
|
||||||
|
|
|
@ -9650,7 +9650,8 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus, bool clear_column)
|
||||||
line = 1;
|
line = 1;
|
||||||
|
|
||||||
/* Translate the location. */
|
/* Translate the location. */
|
||||||
*locus = linemap_position_for_line_and_column (map, line, column);
|
*locus = linemap_position_for_line_and_column (line_table, map,
|
||||||
|
line, column);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2015-11-13 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2015-11-12 James Norris <jnorris@codesourcery.com>
|
2015-11-12 James Norris <jnorris@codesourcery.com>
|
||||||
Joseph Myers <joseph@codesourcery.com>
|
Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
|
|
|
@ -1187,6 +1187,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
|
||||||
bool op0_const_self = true, op1_const_self = true, op2_const_self = true;
|
bool op0_const_self = true, op1_const_self = true, op2_const_self = true;
|
||||||
bool nowarning = TREE_NO_WARNING (expr);
|
bool nowarning = TREE_NO_WARNING (expr);
|
||||||
bool unused_p;
|
bool unused_p;
|
||||||
|
source_range old_range;
|
||||||
|
|
||||||
/* This function is not relevant to C++ because C++ folds while
|
/* This function is not relevant to C++ because C++ folds while
|
||||||
parsing, and may need changes to be correct for C++ when C++
|
parsing, and may need changes to be correct for C++ when C++
|
||||||
|
@ -1202,6 +1203,9 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
|
||||||
|| code == SAVE_EXPR)
|
|| code == SAVE_EXPR)
|
||||||
return expr;
|
return expr;
|
||||||
|
|
||||||
|
if (IS_EXPR_CODE_CLASS (kind))
|
||||||
|
old_range = EXPR_LOCATION_RANGE (expr);
|
||||||
|
|
||||||
/* Operands of variable-length expressions (function calls) have
|
/* Operands of variable-length expressions (function calls) have
|
||||||
already been folded, as have __builtin_* function calls, and such
|
already been folded, as have __builtin_* function calls, and such
|
||||||
expressions cannot occur in constant expressions. */
|
expressions cannot occur in constant expressions. */
|
||||||
|
@ -1626,7 +1630,11 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
|
||||||
TREE_NO_WARNING (ret) = 1;
|
TREE_NO_WARNING (ret) = 1;
|
||||||
}
|
}
|
||||||
if (ret != expr)
|
if (ret != expr)
|
||||||
protected_set_expr_location (ret, loc);
|
{
|
||||||
|
protected_set_expr_location (ret, loc);
|
||||||
|
if (IS_EXPR_CODE_CLASS (kind))
|
||||||
|
set_source_range (ret, old_range.m_start, old_range.m_finish);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,6 +245,8 @@ c_common_init_options (unsigned int decoded_options_count,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global_dc->colorize_source_p = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle switch SCODE with argument ARG. VALUE is true, unless no-
|
/* Handle switch SCODE with argument ARG. VALUE is true, unless no-
|
||||||
|
|
|
@ -1,3 +1,40 @@
|
||||||
|
2015-11-13 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2015-11-13 Marek Polacek <polacek@redhat.com>
|
2015-11-13 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
PR c/68320
|
PR c/68320
|
||||||
|
|
|
@ -5278,7 +5278,7 @@ warn_defaults_to (location_t location, int opt, const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
rich_location richloc (location);
|
rich_location richloc (line_table, location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
|
||||||
|
|
|
@ -37,7 +37,7 @@ pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...)
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
bool warned = false;
|
bool warned = false;
|
||||||
rich_location richloc (location);
|
rich_location richloc (line_table, location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
/* If desired, issue the C99/C11 compat warning, which is more specific
|
/* If desired, issue the C99/C11 compat warning, which is more specific
|
||||||
|
@ -76,7 +76,7 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
rich_location richloc (location);
|
rich_location richloc (line_table, location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
/* Warnings such as -Wvla are the most specific ones. */
|
/* Warnings such as -Wvla are the most specific ones. */
|
||||||
|
|
|
@ -59,6 +59,23 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "gimple-expr.h"
|
#include "gimple-expr.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
set_c_expr_source_range (c_expr *expr,
|
||||||
|
location_t start, location_t finish)
|
||||||
|
{
|
||||||
|
expr->src_range.m_start = start;
|
||||||
|
expr->src_range.m_finish = finish;
|
||||||
|
set_source_range (expr->value, start, finish);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_c_expr_source_range (c_expr *expr,
|
||||||
|
source_range src_range)
|
||||||
|
{
|
||||||
|
expr->src_range = src_range;
|
||||||
|
set_source_range (expr->value, src_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Initialization routine for this file. */
|
/* Initialization routine for this file. */
|
||||||
|
|
||||||
|
@ -164,6 +181,16 @@ struct GTY (()) c_token {
|
||||||
location_t location;
|
location_t location;
|
||||||
/* The value associated with this token, if any. */
|
/* The value associated with this token, if any. */
|
||||||
tree value;
|
tree value;
|
||||||
|
|
||||||
|
source_range get_range () const
|
||||||
|
{
|
||||||
|
return get_range_from_loc (line_table, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
location_t get_finish () const
|
||||||
|
{
|
||||||
|
return get_range ().m_finish;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A parser structure recording information about the state and
|
/* A parser structure recording information about the state and
|
||||||
|
@ -6117,6 +6144,7 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
|
||||||
ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
|
ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
|
||||||
code, exp_location, rhs.value,
|
code, exp_location, rhs.value,
|
||||||
rhs.original_type);
|
rhs.original_type);
|
||||||
|
set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
|
||||||
if (code == NOP_EXPR)
|
if (code == NOP_EXPR)
|
||||||
ret.original_code = MODIFY_EXPR;
|
ret.original_code = MODIFY_EXPR;
|
||||||
else
|
else
|
||||||
|
@ -6147,7 +6175,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
|
||||||
tree omp_atomic_lhs)
|
tree omp_atomic_lhs)
|
||||||
{
|
{
|
||||||
struct c_expr cond, exp1, exp2, ret;
|
struct c_expr cond, exp1, exp2, ret;
|
||||||
location_t cond_loc, colon_loc, middle_loc;
|
location_t start, cond_loc, colon_loc, middle_loc;
|
||||||
|
|
||||||
gcc_assert (!after || c_dialect_objc ());
|
gcc_assert (!after || c_dialect_objc ());
|
||||||
|
|
||||||
|
@ -6155,6 +6183,10 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
|
||||||
|
|
||||||
if (c_parser_next_token_is_not (parser, CPP_QUERY))
|
if (c_parser_next_token_is_not (parser, CPP_QUERY))
|
||||||
return cond;
|
return cond;
|
||||||
|
if (cond.value != error_mark_node)
|
||||||
|
start = cond.get_start ();
|
||||||
|
else
|
||||||
|
start = UNKNOWN_LOCATION;
|
||||||
cond_loc = c_parser_peek_token (parser)->location;
|
cond_loc = c_parser_peek_token (parser)->location;
|
||||||
cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
|
cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
|
||||||
c_parser_consume_token (parser);
|
c_parser_consume_token (parser);
|
||||||
|
@ -6230,6 +6262,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
|
||||||
? t1
|
? t1
|
||||||
: NULL);
|
: NULL);
|
||||||
}
|
}
|
||||||
|
set_c_expr_source_range (&ret, start, exp2.get_finish ());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6382,6 +6415,7 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after,
|
||||||
{
|
{
|
||||||
enum c_parser_prec oprec;
|
enum c_parser_prec oprec;
|
||||||
enum tree_code ocode;
|
enum tree_code ocode;
|
||||||
|
source_range src_range;
|
||||||
if (parser->error)
|
if (parser->error)
|
||||||
goto out;
|
goto out;
|
||||||
switch (c_parser_peek_token (parser)->type)
|
switch (c_parser_peek_token (parser)->type)
|
||||||
|
@ -6470,6 +6504,7 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after,
|
||||||
switch (ocode)
|
switch (ocode)
|
||||||
{
|
{
|
||||||
case TRUTH_ANDIF_EXPR:
|
case TRUTH_ANDIF_EXPR:
|
||||||
|
src_range = stack[sp].expr.src_range;
|
||||||
stack[sp].expr
|
stack[sp].expr
|
||||||
= convert_lvalue_to_rvalue (stack[sp].loc,
|
= convert_lvalue_to_rvalue (stack[sp].loc,
|
||||||
stack[sp].expr, true, true);
|
stack[sp].expr, true, true);
|
||||||
|
@ -6477,8 +6512,10 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after,
|
||||||
(stack[sp].loc, default_conversion (stack[sp].expr.value));
|
(stack[sp].loc, default_conversion (stack[sp].expr.value));
|
||||||
c_inhibit_evaluation_warnings += (stack[sp].expr.value
|
c_inhibit_evaluation_warnings += (stack[sp].expr.value
|
||||||
== truthvalue_false_node);
|
== truthvalue_false_node);
|
||||||
|
set_c_expr_source_range (&stack[sp].expr, src_range);
|
||||||
break;
|
break;
|
||||||
case TRUTH_ORIF_EXPR:
|
case TRUTH_ORIF_EXPR:
|
||||||
|
src_range = stack[sp].expr.src_range;
|
||||||
stack[sp].expr
|
stack[sp].expr
|
||||||
= convert_lvalue_to_rvalue (stack[sp].loc,
|
= convert_lvalue_to_rvalue (stack[sp].loc,
|
||||||
stack[sp].expr, true, true);
|
stack[sp].expr, true, true);
|
||||||
|
@ -6486,6 +6523,7 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after,
|
||||||
(stack[sp].loc, default_conversion (stack[sp].expr.value));
|
(stack[sp].loc, default_conversion (stack[sp].expr.value));
|
||||||
c_inhibit_evaluation_warnings += (stack[sp].expr.value
|
c_inhibit_evaluation_warnings += (stack[sp].expr.value
|
||||||
== truthvalue_true_node);
|
== truthvalue_true_node);
|
||||||
|
set_c_expr_source_range (&stack[sp].expr, src_range);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -6554,6 +6592,8 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
|
||||||
expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
|
expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
|
||||||
}
|
}
|
||||||
ret.value = c_cast_expr (cast_loc, type_name, expr.value);
|
ret.value = c_cast_expr (cast_loc, type_name, expr.value);
|
||||||
|
if (ret.value && expr.value)
|
||||||
|
set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
|
||||||
ret.original_code = ERROR_MARK;
|
ret.original_code = ERROR_MARK;
|
||||||
ret.original_type = NULL;
|
ret.original_type = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -6603,6 +6643,7 @@ c_parser_unary_expression (c_parser *parser)
|
||||||
struct c_expr ret, op;
|
struct c_expr ret, op;
|
||||||
location_t op_loc = c_parser_peek_token (parser)->location;
|
location_t op_loc = c_parser_peek_token (parser)->location;
|
||||||
location_t exp_loc;
|
location_t exp_loc;
|
||||||
|
location_t finish;
|
||||||
ret.original_code = ERROR_MARK;
|
ret.original_code = ERROR_MARK;
|
||||||
ret.original_type = NULL;
|
ret.original_type = NULL;
|
||||||
switch (c_parser_peek_token (parser)->type)
|
switch (c_parser_peek_token (parser)->type)
|
||||||
|
@ -6642,8 +6683,10 @@ c_parser_unary_expression (c_parser *parser)
|
||||||
c_parser_consume_token (parser);
|
c_parser_consume_token (parser);
|
||||||
exp_loc = c_parser_peek_token (parser)->location;
|
exp_loc = c_parser_peek_token (parser)->location;
|
||||||
op = c_parser_cast_expression (parser, NULL);
|
op = c_parser_cast_expression (parser, NULL);
|
||||||
|
finish = op.get_finish ();
|
||||||
op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
|
op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
|
||||||
ret.value = build_indirect_ref (op_loc, op.value, RO_UNARY_STAR);
|
ret.value = build_indirect_ref (op_loc, op.value, RO_UNARY_STAR);
|
||||||
|
set_c_expr_source_range (&ret, op_loc, finish);
|
||||||
return ret;
|
return ret;
|
||||||
case CPP_PLUS:
|
case CPP_PLUS:
|
||||||
if (!c_dialect_objc () && !in_system_header_at (input_location))
|
if (!c_dialect_objc () && !in_system_header_at (input_location))
|
||||||
|
@ -6731,8 +6774,15 @@ static struct c_expr
|
||||||
c_parser_sizeof_expression (c_parser *parser)
|
c_parser_sizeof_expression (c_parser *parser)
|
||||||
{
|
{
|
||||||
struct c_expr expr;
|
struct c_expr expr;
|
||||||
|
struct c_expr result;
|
||||||
location_t expr_loc;
|
location_t expr_loc;
|
||||||
gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
|
gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
|
||||||
|
|
||||||
|
location_t start;
|
||||||
|
location_t finish = UNKNOWN_LOCATION;
|
||||||
|
|
||||||
|
start = c_parser_peek_token (parser)->location;
|
||||||
|
|
||||||
c_parser_consume_token (parser);
|
c_parser_consume_token (parser);
|
||||||
c_inhibit_evaluation_warnings++;
|
c_inhibit_evaluation_warnings++;
|
||||||
in_sizeof++;
|
in_sizeof++;
|
||||||
|
@ -6746,6 +6796,7 @@ c_parser_sizeof_expression (c_parser *parser)
|
||||||
expr_loc = c_parser_peek_token (parser)->location;
|
expr_loc = c_parser_peek_token (parser)->location;
|
||||||
type_name = c_parser_type_name (parser);
|
type_name = c_parser_type_name (parser);
|
||||||
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
|
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
|
||||||
|
finish = parser->tokens_buf[0].location;
|
||||||
if (type_name == NULL)
|
if (type_name == NULL)
|
||||||
{
|
{
|
||||||
struct c_expr ret;
|
struct c_expr ret;
|
||||||
|
@ -6761,17 +6812,19 @@ c_parser_sizeof_expression (c_parser *parser)
|
||||||
expr = c_parser_postfix_expression_after_paren_type (parser,
|
expr = c_parser_postfix_expression_after_paren_type (parser,
|
||||||
type_name,
|
type_name,
|
||||||
expr_loc);
|
expr_loc);
|
||||||
|
finish = expr.get_finish ();
|
||||||
goto sizeof_expr;
|
goto sizeof_expr;
|
||||||
}
|
}
|
||||||
/* sizeof ( type-name ). */
|
/* sizeof ( type-name ). */
|
||||||
c_inhibit_evaluation_warnings--;
|
c_inhibit_evaluation_warnings--;
|
||||||
in_sizeof--;
|
in_sizeof--;
|
||||||
return c_expr_sizeof_type (expr_loc, type_name);
|
result = c_expr_sizeof_type (expr_loc, type_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
expr_loc = c_parser_peek_token (parser)->location;
|
expr_loc = c_parser_peek_token (parser)->location;
|
||||||
expr = c_parser_unary_expression (parser);
|
expr = c_parser_unary_expression (parser);
|
||||||
|
finish = expr.get_finish ();
|
||||||
sizeof_expr:
|
sizeof_expr:
|
||||||
c_inhibit_evaluation_warnings--;
|
c_inhibit_evaluation_warnings--;
|
||||||
in_sizeof--;
|
in_sizeof--;
|
||||||
|
@ -6779,8 +6832,11 @@ c_parser_sizeof_expression (c_parser *parser)
|
||||||
if (TREE_CODE (expr.value) == COMPONENT_REF
|
if (TREE_CODE (expr.value) == COMPONENT_REF
|
||||||
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
|
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
|
||||||
error_at (expr_loc, "%<sizeof%> applied to a bit-field");
|
error_at (expr_loc, "%<sizeof%> applied to a bit-field");
|
||||||
return c_expr_sizeof_expr (expr_loc, expr);
|
result = c_expr_sizeof_expr (expr_loc, expr);
|
||||||
}
|
}
|
||||||
|
if (finish != UNKNOWN_LOCATION)
|
||||||
|
set_c_expr_source_range (&result, start, finish);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse an alignof expression. */
|
/* Parse an alignof expression. */
|
||||||
|
@ -7200,12 +7256,14 @@ c_parser_postfix_expression (c_parser *parser)
|
||||||
struct c_expr expr, e1;
|
struct c_expr expr, e1;
|
||||||
struct c_type_name *t1, *t2;
|
struct c_type_name *t1, *t2;
|
||||||
location_t loc = c_parser_peek_token (parser)->location;;
|
location_t loc = c_parser_peek_token (parser)->location;;
|
||||||
|
source_range tok_range = c_parser_peek_token (parser)->get_range ();
|
||||||
expr.original_code = ERROR_MARK;
|
expr.original_code = ERROR_MARK;
|
||||||
expr.original_type = NULL;
|
expr.original_type = NULL;
|
||||||
switch (c_parser_peek_token (parser)->type)
|
switch (c_parser_peek_token (parser)->type)
|
||||||
{
|
{
|
||||||
case CPP_NUMBER:
|
case CPP_NUMBER:
|
||||||
expr.value = c_parser_peek_token (parser)->value;
|
expr.value = c_parser_peek_token (parser)->value;
|
||||||
|
set_c_expr_source_range (&expr, tok_range);
|
||||||
loc = c_parser_peek_token (parser)->location;
|
loc = c_parser_peek_token (parser)->location;
|
||||||
c_parser_consume_token (parser);
|
c_parser_consume_token (parser);
|
||||||
if (TREE_CODE (expr.value) == FIXED_CST
|
if (TREE_CODE (expr.value) == FIXED_CST
|
||||||
|
@ -7220,6 +7278,7 @@ c_parser_postfix_expression (c_parser *parser)
|
||||||
case CPP_CHAR32:
|
case CPP_CHAR32:
|
||||||
case CPP_WCHAR:
|
case CPP_WCHAR:
|
||||||
expr.value = c_parser_peek_token (parser)->value;
|
expr.value = c_parser_peek_token (parser)->value;
|
||||||
|
set_c_expr_source_range (&expr, tok_range);
|
||||||
c_parser_consume_token (parser);
|
c_parser_consume_token (parser);
|
||||||
break;
|
break;
|
||||||
case CPP_STRING:
|
case CPP_STRING:
|
||||||
|
@ -7228,6 +7287,7 @@ c_parser_postfix_expression (c_parser *parser)
|
||||||
case CPP_WSTRING:
|
case CPP_WSTRING:
|
||||||
case CPP_UTF8STRING:
|
case CPP_UTF8STRING:
|
||||||
expr.value = c_parser_peek_token (parser)->value;
|
expr.value = c_parser_peek_token (parser)->value;
|
||||||
|
set_c_expr_source_range (&expr, tok_range);
|
||||||
expr.original_code = STRING_CST;
|
expr.original_code = STRING_CST;
|
||||||
c_parser_consume_token (parser);
|
c_parser_consume_token (parser);
|
||||||
break;
|
break;
|
||||||
|
@ -7235,6 +7295,7 @@ c_parser_postfix_expression (c_parser *parser)
|
||||||
gcc_assert (c_dialect_objc ());
|
gcc_assert (c_dialect_objc ());
|
||||||
expr.value
|
expr.value
|
||||||
= objc_build_string_object (c_parser_peek_token (parser)->value);
|
= objc_build_string_object (c_parser_peek_token (parser)->value);
|
||||||
|
set_c_expr_source_range (&expr, tok_range);
|
||||||
c_parser_consume_token (parser);
|
c_parser_consume_token (parser);
|
||||||
break;
|
break;
|
||||||
case CPP_NAME:
|
case CPP_NAME:
|
||||||
|
@ -7248,6 +7309,7 @@ c_parser_postfix_expression (c_parser *parser)
|
||||||
(c_parser_peek_token (parser)->type
|
(c_parser_peek_token (parser)->type
|
||||||
== CPP_OPEN_PAREN),
|
== CPP_OPEN_PAREN),
|
||||||
&expr.original_type);
|
&expr.original_type);
|
||||||
|
set_c_expr_source_range (&expr, tok_range);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case C_ID_CLASSNAME:
|
case C_ID_CLASSNAME:
|
||||||
|
@ -7336,6 +7398,7 @@ c_parser_postfix_expression (c_parser *parser)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* A parenthesized expression. */
|
/* A parenthesized expression. */
|
||||||
|
location_t loc_open_paren = c_parser_peek_token (parser)->location;
|
||||||
c_parser_consume_token (parser);
|
c_parser_consume_token (parser);
|
||||||
expr = c_parser_expression (parser);
|
expr = c_parser_expression (parser);
|
||||||
if (TREE_CODE (expr.value) == MODIFY_EXPR)
|
if (TREE_CODE (expr.value) == MODIFY_EXPR)
|
||||||
|
@ -7343,6 +7406,8 @@ c_parser_postfix_expression (c_parser *parser)
|
||||||
if (expr.original_code != C_MAYBE_CONST_EXPR)
|
if (expr.original_code != C_MAYBE_CONST_EXPR)
|
||||||
expr.original_code = ERROR_MARK;
|
expr.original_code = ERROR_MARK;
|
||||||
/* Don't change EXPR.ORIGINAL_TYPE. */
|
/* Don't change EXPR.ORIGINAL_TYPE. */
|
||||||
|
location_t loc_close_paren = c_parser_peek_token (parser)->location;
|
||||||
|
set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
|
||||||
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
|
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
|
||||||
"expected %<)%>");
|
"expected %<)%>");
|
||||||
}
|
}
|
||||||
|
@ -7933,6 +7998,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
||||||
vec<tree, va_gc> *exprlist;
|
vec<tree, va_gc> *exprlist;
|
||||||
vec<tree, va_gc> *origtypes = NULL;
|
vec<tree, va_gc> *origtypes = NULL;
|
||||||
vec<location_t> arg_loc = vNULL;
|
vec<location_t> arg_loc = vNULL;
|
||||||
|
location_t start;
|
||||||
|
location_t finish;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -7969,7 +8036,10 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
||||||
{
|
{
|
||||||
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
|
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
|
||||||
"expected %<]%>");
|
"expected %<]%>");
|
||||||
|
start = expr.get_start ();
|
||||||
|
finish = parser->tokens_buf[0].location;
|
||||||
expr.value = build_array_ref (op_loc, expr.value, idx);
|
expr.value = build_array_ref (op_loc, expr.value, idx);
|
||||||
|
set_c_expr_source_range (&expr, start, finish);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expr.original_code = ERROR_MARK;
|
expr.original_code = ERROR_MARK;
|
||||||
|
@ -8012,9 +8082,13 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
||||||
"%<memset%> used with constant zero length parameter; "
|
"%<memset%> used with constant zero length parameter; "
|
||||||
"this could be due to transposed parameters");
|
"this could be due to transposed parameters");
|
||||||
|
|
||||||
|
start = expr.get_start ();
|
||||||
|
finish = parser->tokens_buf[0].get_finish ();
|
||||||
expr.value
|
expr.value
|
||||||
= c_build_function_call_vec (expr_loc, arg_loc, expr.value,
|
= c_build_function_call_vec (expr_loc, arg_loc, expr.value,
|
||||||
exprlist, origtypes);
|
exprlist, origtypes);
|
||||||
|
set_c_expr_source_range (&expr, start, finish);
|
||||||
|
|
||||||
expr.original_code = ERROR_MARK;
|
expr.original_code = ERROR_MARK;
|
||||||
if (TREE_CODE (expr.value) == INTEGER_CST
|
if (TREE_CODE (expr.value) == INTEGER_CST
|
||||||
&& TREE_CODE (orig_expr.value) == FUNCTION_DECL
|
&& TREE_CODE (orig_expr.value) == FUNCTION_DECL
|
||||||
|
@ -8043,8 +8117,11 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
||||||
expr.original_type = NULL;
|
expr.original_type = NULL;
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
start = expr.get_start ();
|
||||||
|
finish = c_parser_peek_token (parser)->get_finish ();
|
||||||
c_parser_consume_token (parser);
|
c_parser_consume_token (parser);
|
||||||
expr.value = build_component_ref (op_loc, expr.value, ident);
|
expr.value = build_component_ref (op_loc, expr.value, ident);
|
||||||
|
set_c_expr_source_range (&expr, start, finish);
|
||||||
expr.original_code = ERROR_MARK;
|
expr.original_code = ERROR_MARK;
|
||||||
if (TREE_CODE (expr.value) != COMPONENT_REF)
|
if (TREE_CODE (expr.value) != COMPONENT_REF)
|
||||||
expr.original_type = NULL;
|
expr.original_type = NULL;
|
||||||
|
@ -8072,12 +8149,15 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
||||||
expr.original_type = NULL;
|
expr.original_type = NULL;
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
start = expr.get_start ();
|
||||||
|
finish = c_parser_peek_token (parser)->get_finish ();
|
||||||
c_parser_consume_token (parser);
|
c_parser_consume_token (parser);
|
||||||
expr.value = build_component_ref (op_loc,
|
expr.value = build_component_ref (op_loc,
|
||||||
build_indirect_ref (op_loc,
|
build_indirect_ref (op_loc,
|
||||||
expr.value,
|
expr.value,
|
||||||
RO_ARROW),
|
RO_ARROW),
|
||||||
ident);
|
ident);
|
||||||
|
set_c_expr_source_range (&expr, start, finish);
|
||||||
expr.original_code = ERROR_MARK;
|
expr.original_code = ERROR_MARK;
|
||||||
if (TREE_CODE (expr.value) != COMPONENT_REF)
|
if (TREE_CODE (expr.value) != COMPONENT_REF)
|
||||||
expr.original_type = NULL;
|
expr.original_type = NULL;
|
||||||
|
@ -8093,6 +8173,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
||||||
break;
|
break;
|
||||||
case CPP_PLUS_PLUS:
|
case CPP_PLUS_PLUS:
|
||||||
/* Postincrement. */
|
/* Postincrement. */
|
||||||
|
start = expr.get_start ();
|
||||||
|
finish = c_parser_peek_token (parser)->get_finish ();
|
||||||
c_parser_consume_token (parser);
|
c_parser_consume_token (parser);
|
||||||
/* If the expressions have array notations, we expand them. */
|
/* If the expressions have array notations, we expand them. */
|
||||||
if (flag_cilkplus
|
if (flag_cilkplus
|
||||||
|
@ -8104,11 +8186,14 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
||||||
expr.value = build_unary_op (op_loc,
|
expr.value = build_unary_op (op_loc,
|
||||||
POSTINCREMENT_EXPR, expr.value, 0);
|
POSTINCREMENT_EXPR, expr.value, 0);
|
||||||
}
|
}
|
||||||
|
set_c_expr_source_range (&expr, start, finish);
|
||||||
expr.original_code = ERROR_MARK;
|
expr.original_code = ERROR_MARK;
|
||||||
expr.original_type = NULL;
|
expr.original_type = NULL;
|
||||||
break;
|
break;
|
||||||
case CPP_MINUS_MINUS:
|
case CPP_MINUS_MINUS:
|
||||||
/* Postdecrement. */
|
/* Postdecrement. */
|
||||||
|
start = expr.get_start ();
|
||||||
|
finish = c_parser_peek_token (parser)->get_finish ();
|
||||||
c_parser_consume_token (parser);
|
c_parser_consume_token (parser);
|
||||||
/* If the expressions have array notations, we expand them. */
|
/* If the expressions have array notations, we expand them. */
|
||||||
if (flag_cilkplus
|
if (flag_cilkplus
|
||||||
|
@ -8120,6 +8205,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
||||||
expr.value = build_unary_op (op_loc,
|
expr.value = build_unary_op (op_loc,
|
||||||
POSTDECREMENT_EXPR, expr.value, 0);
|
POSTDECREMENT_EXPR, expr.value, 0);
|
||||||
}
|
}
|
||||||
|
set_c_expr_source_range (&expr, start, finish);
|
||||||
expr.original_code = ERROR_MARK;
|
expr.original_code = ERROR_MARK;
|
||||||
expr.original_type = NULL;
|
expr.original_type = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -132,6 +132,17 @@ struct c_expr
|
||||||
The type of an enum constant is a plain integer type, but this
|
The type of an enum constant is a plain integer type, but this
|
||||||
field will be the enum type. */
|
field will be the enum type. */
|
||||||
tree original_type;
|
tree original_type;
|
||||||
|
|
||||||
|
/* The source range of this expression. This is redundant
|
||||||
|
for node values that have locations, but not all node kinds
|
||||||
|
have locations (e.g. constants, and references to params, locals,
|
||||||
|
etc), so we stash a copy here. */
|
||||||
|
source_range src_range;
|
||||||
|
|
||||||
|
/* Access to the first and last locations within the source spelling
|
||||||
|
of this expression. */
|
||||||
|
location_t get_start () const { return src_range.m_start; }
|
||||||
|
location_t get_finish () const { return src_range.m_finish; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Type alias for struct c_expr. This allows to use the structure
|
/* Type alias for struct c_expr. This allows to use the structure
|
||||||
|
@ -708,4 +719,12 @@ extern void pedwarn_c90 (location_t, int opt, const char *, ...)
|
||||||
extern bool pedwarn_c99 (location_t, int opt, const char *, ...)
|
extern bool pedwarn_c99 (location_t, int opt, const char *, ...)
|
||||||
ATTRIBUTE_GCC_DIAG(3,4);
|
ATTRIBUTE_GCC_DIAG(3,4);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
set_c_expr_source_range (c_expr *expr,
|
||||||
|
location_t start, location_t finish);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
set_c_expr_source_range (c_expr *expr,
|
||||||
|
source_range src_range);
|
||||||
|
|
||||||
#endif /* ! GCC_C_TREE_H */
|
#endif /* ! GCC_C_TREE_H */
|
||||||
|
|
|
@ -3460,6 +3460,12 @@ parser_build_unary_op (location_t loc, enum tree_code code, struct c_expr arg)
|
||||||
overflow_warning (loc, result.value);
|
overflow_warning (loc, result.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We are typically called when parsing a prefix token at LOC acting on
|
||||||
|
ARG. Reflect this by updating the source range of the result to
|
||||||
|
start at LOC and end at the end of ARG. */
|
||||||
|
set_c_expr_source_range (&result,
|
||||||
|
loc, arg.get_finish ());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3497,6 +3503,10 @@ parser_build_binary_op (location_t location, enum tree_code code,
|
||||||
if (location != UNKNOWN_LOCATION)
|
if (location != UNKNOWN_LOCATION)
|
||||||
protected_set_expr_location (result.value, location);
|
protected_set_expr_location (result.value, location);
|
||||||
|
|
||||||
|
set_c_expr_source_range (&result,
|
||||||
|
arg1.get_start (),
|
||||||
|
arg2.get_finish ());
|
||||||
|
|
||||||
/* Check for cases such as x+y<<z which users are likely
|
/* Check for cases such as x+y<<z which users are likely
|
||||||
to misinterpret. */
|
to misinterpret. */
|
||||||
if (warn_parentheses)
|
if (warn_parentheses)
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2015-11-13 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
* error.c (pedwarn_cxx98): Pass line_table to rich_location ctor.
|
||||||
|
|
||||||
2015-11-12 James Norris <jnorris@codesourcery.com>
|
2015-11-12 James Norris <jnorris@codesourcery.com>
|
||||||
|
|
||||||
* parser.c (cp_parser_oacc_declare): Remove unused.
|
* parser.c (cp_parser_oacc_declare): Remove unused.
|
||||||
|
|
|
@ -3673,7 +3673,7 @@ pedwarn_cxx98 (location_t location, int opt, const char *gmsgid, ...)
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
bool ret;
|
bool ret;
|
||||||
rich_location richloc (location);
|
rich_location richloc (line_table, location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
|
||||||
|
|
|
@ -867,7 +867,7 @@ diagnostic_append_note (diagnostic_context *context,
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
const char *saved_prefix;
|
const char *saved_prefix;
|
||||||
rich_location richloc (location);
|
rich_location richloc (line_table, location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE);
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE);
|
||||||
|
@ -925,7 +925,7 @@ emit_diagnostic (diagnostic_t kind, location_t location, int opt,
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
bool ret;
|
bool ret;
|
||||||
rich_location richloc (location);
|
rich_location richloc (line_table, location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
if (kind == DK_PERMERROR)
|
if (kind == DK_PERMERROR)
|
||||||
|
@ -952,7 +952,7 @@ inform (location_t location, const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
rich_location richloc (location);
|
rich_location richloc (line_table, location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE);
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE);
|
||||||
|
@ -981,7 +981,7 @@ inform_n (location_t location, int n, const char *singular_gmsgid,
|
||||||
{
|
{
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
rich_location richloc (location);
|
rich_location richloc (line_table, location);
|
||||||
|
|
||||||
va_start (ap, plural_gmsgid);
|
va_start (ap, plural_gmsgid);
|
||||||
diagnostic_set_info_translated (&diagnostic,
|
diagnostic_set_info_translated (&diagnostic,
|
||||||
|
@ -1000,7 +1000,7 @@ warning (int opt, const char *gmsgid, ...)
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
bool ret;
|
bool ret;
|
||||||
rich_location richloc (input_location);
|
rich_location richloc (line_table, input_location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_WARNING);
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_WARNING);
|
||||||
|
@ -1021,7 +1021,7 @@ warning_at (location_t location, int opt, const char *gmsgid, ...)
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
bool ret;
|
bool ret;
|
||||||
rich_location richloc (location);
|
rich_location richloc (line_table, location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_WARNING);
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_WARNING);
|
||||||
|
@ -1059,7 +1059,7 @@ warning_n (location_t location, int opt, int n, const char *singular_gmsgid,
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
bool ret;
|
bool ret;
|
||||||
rich_location richloc (location);
|
rich_location richloc (line_table, location);
|
||||||
|
|
||||||
va_start (ap, plural_gmsgid);
|
va_start (ap, plural_gmsgid);
|
||||||
diagnostic_set_info_translated (&diagnostic,
|
diagnostic_set_info_translated (&diagnostic,
|
||||||
|
@ -1091,7 +1091,7 @@ pedwarn (location_t location, int opt, const char *gmsgid, ...)
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
bool ret;
|
bool ret;
|
||||||
rich_location richloc (location);
|
rich_location richloc (line_table, location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN);
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN);
|
||||||
|
@ -1114,7 +1114,7 @@ permerror (location_t location, const char *gmsgid, ...)
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
bool ret;
|
bool ret;
|
||||||
rich_location richloc (location);
|
rich_location richloc (line_table, location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
|
||||||
|
@ -1150,7 +1150,7 @@ error (const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
rich_location richloc (input_location);
|
rich_location richloc (line_table, input_location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ERROR);
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ERROR);
|
||||||
|
@ -1166,7 +1166,7 @@ error_n (location_t location, int n, const char *singular_gmsgid,
|
||||||
{
|
{
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
rich_location richloc (location);
|
rich_location richloc (line_table, location);
|
||||||
|
|
||||||
va_start (ap, plural_gmsgid);
|
va_start (ap, plural_gmsgid);
|
||||||
diagnostic_set_info_translated (&diagnostic,
|
diagnostic_set_info_translated (&diagnostic,
|
||||||
|
@ -1182,7 +1182,7 @@ error_at (location_t loc, const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
rich_location richloc (loc);
|
rich_location richloc (line_table, loc);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ERROR);
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ERROR);
|
||||||
|
@ -1213,7 +1213,7 @@ sorry (const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
rich_location richloc (input_location);
|
rich_location richloc (line_table, input_location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_SORRY);
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_SORRY);
|
||||||
|
@ -1237,7 +1237,7 @@ fatal_error (location_t loc, const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
rich_location richloc (loc);
|
rich_location richloc (line_table, loc);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_FATAL);
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_FATAL);
|
||||||
|
@ -1256,7 +1256,7 @@ internal_error (const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
rich_location richloc (input_location);
|
rich_location richloc (line_table, input_location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ICE);
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ICE);
|
||||||
|
@ -1274,7 +1274,7 @@ internal_error_no_backtrace (const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
rich_location richloc (input_location);
|
rich_location richloc (line_table, input_location);
|
||||||
|
|
||||||
va_start (ap, gmsgid);
|
va_start (ap, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ICE_NOBT);
|
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ICE_NOBT);
|
||||||
|
@ -1351,7 +1351,7 @@ real_abort (void)
|
||||||
DEBUG_FUNCTION void
|
DEBUG_FUNCTION void
|
||||||
source_range::debug (const char *msg) const
|
source_range::debug (const char *msg) const
|
||||||
{
|
{
|
||||||
rich_location richloc (m_start);
|
rich_location richloc (line_table, m_start);
|
||||||
richloc.add_range (m_start, m_finish, false);
|
richloc.add_range (m_start, m_finish, false);
|
||||||
inform_at_rich_loc (&richloc, "%s", msg);
|
inform_at_rich_loc (&richloc, "%s", msg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
2015-11-13 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2015-11-12 Steven G. Kargl <kargl@gcc.gnu.org>
|
2015-11-12 Steven G. Kargl <kargl@gcc.gnu.org>
|
||||||
|
|
||||||
PR fortran/68318
|
PR fortran/68318
|
||||||
|
|
|
@ -773,7 +773,7 @@ gfc_warning (int opt, const char *gmsgid, va_list ap)
|
||||||
va_copy (argp, ap);
|
va_copy (argp, ap);
|
||||||
|
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
rich_location rich_loc (UNKNOWN_LOCATION);
|
rich_location rich_loc (line_table, UNKNOWN_LOCATION);
|
||||||
bool fatal_errors = global_dc->fatal_errors;
|
bool fatal_errors = global_dc->fatal_errors;
|
||||||
pretty_printer *pp = global_dc->printer;
|
pretty_printer *pp = global_dc->printer;
|
||||||
output_buffer *tmp_buffer = pp->buffer;
|
output_buffer *tmp_buffer = pp->buffer;
|
||||||
|
@ -1120,7 +1120,7 @@ gfc_warning_now_at (location_t loc, int opt, const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
va_list argp;
|
va_list argp;
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
rich_location rich_loc (loc);
|
rich_location rich_loc (line_table, loc);
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
va_start (argp, gmsgid);
|
va_start (argp, gmsgid);
|
||||||
|
@ -1138,7 +1138,7 @@ gfc_warning_now (int opt, const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
va_list argp;
|
va_list argp;
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
rich_location rich_loc (UNKNOWN_LOCATION);
|
rich_location rich_loc (line_table, UNKNOWN_LOCATION);
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
va_start (argp, gmsgid);
|
va_start (argp, gmsgid);
|
||||||
|
@ -1158,7 +1158,7 @@ gfc_error_now (const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
va_list argp;
|
va_list argp;
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
rich_location rich_loc (UNKNOWN_LOCATION);
|
rich_location rich_loc (line_table, UNKNOWN_LOCATION);
|
||||||
|
|
||||||
error_buffer.flag = true;
|
error_buffer.flag = true;
|
||||||
|
|
||||||
|
@ -1176,7 +1176,7 @@ gfc_fatal_error (const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
va_list argp;
|
va_list argp;
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
rich_location rich_loc (UNKNOWN_LOCATION);
|
rich_location rich_loc (line_table, UNKNOWN_LOCATION);
|
||||||
|
|
||||||
va_start (argp, gmsgid);
|
va_start (argp, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_FATAL);
|
diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_FATAL);
|
||||||
|
@ -1242,7 +1242,7 @@ gfc_error (const char *gmsgid, va_list ap)
|
||||||
}
|
}
|
||||||
|
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
rich_location richloc (UNKNOWN_LOCATION);
|
rich_location richloc (line_table, UNKNOWN_LOCATION);
|
||||||
bool fatal_errors = global_dc->fatal_errors;
|
bool fatal_errors = global_dc->fatal_errors;
|
||||||
pretty_printer *pp = global_dc->printer;
|
pretty_printer *pp = global_dc->printer;
|
||||||
output_buffer *tmp_buffer = pp->buffer;
|
output_buffer *tmp_buffer = pp->buffer;
|
||||||
|
@ -1288,7 +1288,7 @@ gfc_internal_error (const char *gmsgid, ...)
|
||||||
{
|
{
|
||||||
va_list argp;
|
va_list argp;
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
rich_location rich_loc (UNKNOWN_LOCATION);
|
rich_location rich_loc (line_table, UNKNOWN_LOCATION);
|
||||||
|
|
||||||
va_start (argp, gmsgid);
|
va_start (argp, gmsgid);
|
||||||
diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ICE);
|
diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ICE);
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/* Implementation of gcc_rich_location class
|
||||||
|
Copyright (C) 2014-2015 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 "tm.h"
|
||||||
|
#include "rtl.h"
|
||||||
|
#include "hash-set.h"
|
||||||
|
#include "machmode.h"
|
||||||
|
#include "vec.h"
|
||||||
|
#include "double-int.h"
|
||||||
|
#include "input.h"
|
||||||
|
#include "alias.h"
|
||||||
|
#include "symtab.h"
|
||||||
|
#include "wide-int.h"
|
||||||
|
#include "inchash.h"
|
||||||
|
#include "tree-core.h"
|
||||||
|
#include "tree.h"
|
||||||
|
#include "diagnostic-core.h"
|
||||||
|
#include "gcc-rich-location.h"
|
||||||
|
#include "print-tree.h"
|
||||||
|
#include "pretty-print.h"
|
||||||
|
#include "intl.h"
|
||||||
|
#include "cpplib.h"
|
||||||
|
#include "diagnostic.h"
|
||||||
|
|
||||||
|
/* Extract any source range information from EXPR and write it
|
||||||
|
to *R. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
get_range_for_expr (tree expr, location_range *r)
|
||||||
|
{
|
||||||
|
if (EXPR_HAS_RANGE (expr))
|
||||||
|
{
|
||||||
|
source_range sr = EXPR_LOCATION_RANGE (expr);
|
||||||
|
|
||||||
|
/* Do we have meaningful data? */
|
||||||
|
if (sr.m_start && sr.m_finish)
|
||||||
|
{
|
||||||
|
r->m_start = expand_location (sr.m_start);
|
||||||
|
r->m_finish = expand_location (sr.m_finish);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a range to the rich_location, covering expression EXPR. */
|
||||||
|
|
||||||
|
void
|
||||||
|
gcc_rich_location::add_expr (tree expr)
|
||||||
|
{
|
||||||
|
gcc_assert (expr);
|
||||||
|
|
||||||
|
location_range r;
|
||||||
|
r.m_show_caret_p = false;
|
||||||
|
if (get_range_for_expr (expr, &r))
|
||||||
|
add_range (&r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If T is an expression, add a range for it to the rich_location. */
|
||||||
|
|
||||||
|
void
|
||||||
|
gcc_rich_location::maybe_add_expr (tree t)
|
||||||
|
{
|
||||||
|
if (EXPR_P (t))
|
||||||
|
add_expr (t);
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/* Declarations relating to class gcc_rich_location
|
||||||
|
Copyright (C) 2014-2015 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_RICH_LOCATION_H
|
||||||
|
#define GCC_RICH_LOCATION_H
|
||||||
|
|
||||||
|
/* A gcc_rich_location is libcpp's rich_location with additional
|
||||||
|
helper methods for working with gcc's types. */
|
||||||
|
class gcc_rich_location : public rich_location
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* Constructors. */
|
||||||
|
|
||||||
|
/* Constructing from a location. */
|
||||||
|
gcc_rich_location (source_location loc) :
|
||||||
|
rich_location (line_table, loc) {}
|
||||||
|
|
||||||
|
/* Constructing from a source_range. */
|
||||||
|
gcc_rich_location (source_range src_range) :
|
||||||
|
rich_location (src_range) {}
|
||||||
|
|
||||||
|
|
||||||
|
/* Methods for adding ranges via gcc entities. */
|
||||||
|
void
|
||||||
|
add_expr (tree expr);
|
||||||
|
|
||||||
|
void
|
||||||
|
maybe_add_expr (tree t);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* GCC_RICH_LOCATION_H */
|
|
@ -119,7 +119,7 @@ __attribute__((format (printf, 2, 3)))
|
||||||
#endif
|
#endif
|
||||||
fatal_at (const cpp_token *tk, const char *msg, ...)
|
fatal_at (const cpp_token *tk, const char *msg, ...)
|
||||||
{
|
{
|
||||||
rich_location richloc (tk->src_loc);
|
rich_location richloc (line_table, tk->src_loc);
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, msg);
|
va_start (ap, msg);
|
||||||
error_cb (NULL, CPP_DL_FATAL, 0, &richloc, msg, &ap);
|
error_cb (NULL, CPP_DL_FATAL, 0, &richloc, msg, &ap);
|
||||||
|
@ -132,7 +132,7 @@ __attribute__((format (printf, 2, 3)))
|
||||||
#endif
|
#endif
|
||||||
fatal_at (source_location loc, const char *msg, ...)
|
fatal_at (source_location loc, const char *msg, ...)
|
||||||
{
|
{
|
||||||
rich_location richloc (loc);
|
rich_location richloc (line_table, loc);
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, msg);
|
va_start (ap, msg);
|
||||||
error_cb (NULL, CPP_DL_FATAL, 0, &richloc, msg, &ap);
|
error_cb (NULL, CPP_DL_FATAL, 0, &richloc, msg, &ap);
|
||||||
|
@ -145,7 +145,7 @@ __attribute__((format (printf, 2, 3)))
|
||||||
#endif
|
#endif
|
||||||
warning_at (const cpp_token *tk, const char *msg, ...)
|
warning_at (const cpp_token *tk, const char *msg, ...)
|
||||||
{
|
{
|
||||||
rich_location richloc (tk->src_loc);
|
rich_location richloc (line_table, tk->src_loc);
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, msg);
|
va_start (ap, msg);
|
||||||
error_cb (NULL, CPP_DL_WARNING, 0, &richloc, msg, &ap);
|
error_cb (NULL, CPP_DL_WARNING, 0, &richloc, msg, &ap);
|
||||||
|
@ -158,7 +158,7 @@ __attribute__((format (printf, 2, 3)))
|
||||||
#endif
|
#endif
|
||||||
warning_at (source_location loc, const char *msg, ...)
|
warning_at (source_location loc, const char *msg, ...)
|
||||||
{
|
{
|
||||||
rich_location richloc (loc);
|
rich_location richloc (line_table, loc);
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, msg);
|
va_start (ap, msg);
|
||||||
error_cb (NULL, CPP_DL_WARNING, 0, &richloc, msg, &ap);
|
error_cb (NULL, CPP_DL_WARNING, 0, &richloc, msg, &ap);
|
||||||
|
|
|
@ -1740,11 +1740,7 @@ gimple_block (const gimple *g)
|
||||||
static inline void
|
static inline void
|
||||||
gimple_set_block (gimple *g, tree block)
|
gimple_set_block (gimple *g, tree block)
|
||||||
{
|
{
|
||||||
if (block)
|
g->location = set_block (g->location, block);
|
||||||
g->location =
|
|
||||||
COMBINE_LOCATION_DATA (line_table, g->location, block);
|
|
||||||
else
|
|
||||||
g->location = LOCATION_LOCUS (g->location);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
28
gcc/input.c
28
gcc/input.c
|
@ -887,6 +887,10 @@ dump_line_table_statistics (void)
|
||||||
STAT_LABEL (s.adhoc_table_size));
|
STAT_LABEL (s.adhoc_table_size));
|
||||||
fprintf (stderr, "Ad-hoc table entries used: %5ld\n",
|
fprintf (stderr, "Ad-hoc table entries used: %5ld\n",
|
||||||
s.adhoc_table_entries_used);
|
s.adhoc_table_entries_used);
|
||||||
|
fprintf (stderr, "optimized_ranges: %i\n",
|
||||||
|
line_table->num_optimized_ranges);
|
||||||
|
fprintf (stderr, "unoptimized_ranges: %i\n",
|
||||||
|
line_table->num_unoptimized_ranges);
|
||||||
|
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
|
@ -917,13 +921,14 @@ write_digit (FILE *stream, int digit)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_digit_row (FILE *stream, int indent,
|
write_digit_row (FILE *stream, int indent,
|
||||||
|
const line_map_ordinary *map,
|
||||||
source_location loc, int max_col, int divisor)
|
source_location loc, int max_col, int divisor)
|
||||||
{
|
{
|
||||||
fprintf (stream, "%*c", indent, ' ');
|
fprintf (stream, "%*c", indent, ' ');
|
||||||
fprintf (stream, "|");
|
fprintf (stream, "|");
|
||||||
for (int column = 1; column < max_col; column++)
|
for (int column = 1; column < max_col; column++)
|
||||||
{
|
{
|
||||||
source_location column_loc = loc + column;
|
source_location column_loc = loc + (column << map->m_range_bits);
|
||||||
write_digit (stream, column_loc / divisor);
|
write_digit (stream, column_loc / divisor);
|
||||||
}
|
}
|
||||||
fprintf (stream, "\n");
|
fprintf (stream, "\n");
|
||||||
|
@ -977,14 +982,20 @@ dump_location_info (FILE *stream)
|
||||||
fprintf (stream, " file: %s\n", ORDINARY_MAP_FILE_NAME (map));
|
fprintf (stream, " file: %s\n", ORDINARY_MAP_FILE_NAME (map));
|
||||||
fprintf (stream, " starting at line: %i\n",
|
fprintf (stream, " starting at line: %i\n",
|
||||||
ORDINARY_MAP_STARTING_LINE_NUMBER (map));
|
ORDINARY_MAP_STARTING_LINE_NUMBER (map));
|
||||||
|
fprintf (stream, " column and range bits: %i\n",
|
||||||
|
map->m_column_and_range_bits);
|
||||||
fprintf (stream, " column bits: %i\n",
|
fprintf (stream, " column bits: %i\n",
|
||||||
ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map));
|
map->m_column_and_range_bits - map->m_range_bits);
|
||||||
|
fprintf (stream, " range bits: %i\n",
|
||||||
|
map->m_range_bits);
|
||||||
|
|
||||||
/* Render the span of source lines that this "map" covers. */
|
/* Render the span of source lines that this "map" covers. */
|
||||||
for (source_location loc = MAP_START_LOCATION (map);
|
for (source_location loc = MAP_START_LOCATION (map);
|
||||||
loc < end_location;
|
loc < end_location;
|
||||||
loc++)
|
loc += (1 << map->m_range_bits) )
|
||||||
{
|
{
|
||||||
|
gcc_assert (pure_location_p (line_table, loc) );
|
||||||
|
|
||||||
expanded_location exploc
|
expanded_location exploc
|
||||||
= linemap_expand_location (line_table, map, loc);
|
= linemap_expand_location (line_table, map, loc);
|
||||||
|
|
||||||
|
@ -1008,8 +1019,7 @@ dump_location_info (FILE *stream)
|
||||||
Render the locations *within* the line, by underlining
|
Render the locations *within* the line, by underlining
|
||||||
it, showing the source_location numeric values
|
it, showing the source_location numeric values
|
||||||
at each column. */
|
at each column. */
|
||||||
int max_col
|
int max_col = (1 << map->m_column_and_range_bits) - 1;
|
||||||
= (1 << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map)) - 1;
|
|
||||||
if (max_col > line_size)
|
if (max_col > line_size)
|
||||||
max_col = line_size + 1;
|
max_col = line_size + 1;
|
||||||
|
|
||||||
|
@ -1017,17 +1027,17 @@ dump_location_info (FILE *stream)
|
||||||
|
|
||||||
/* Thousands. */
|
/* Thousands. */
|
||||||
if (end_location > 999)
|
if (end_location > 999)
|
||||||
write_digit_row (stream, indent, loc, max_col, 1000);
|
write_digit_row (stream, indent, map, loc, max_col, 1000);
|
||||||
|
|
||||||
/* Hundreds. */
|
/* Hundreds. */
|
||||||
if (end_location > 99)
|
if (end_location > 99)
|
||||||
write_digit_row (stream, indent, loc, max_col, 100);
|
write_digit_row (stream, indent, map, loc, max_col, 100);
|
||||||
|
|
||||||
/* Tens. */
|
/* Tens. */
|
||||||
write_digit_row (stream, indent, loc, max_col, 10);
|
write_digit_row (stream, indent, map, loc, max_col, 10);
|
||||||
|
|
||||||
/* Units. */
|
/* Units. */
|
||||||
write_digit_row (stream, indent, loc, max_col, 1);
|
write_digit_row (stream, indent, map, loc, max_col, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fprintf (stream, "\n");
|
fprintf (stream, "\n");
|
||||||
|
|
|
@ -938,6 +938,27 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
|
||||||
expanded_location xloc = expand_location (EXPR_LOCATION (node));
|
expanded_location xloc = expand_location (EXPR_LOCATION (node));
|
||||||
indent_to (file, indent+4);
|
indent_to (file, indent+4);
|
||||||
fprintf (file, "%s:%d:%d", xloc.file, xloc.line, xloc.column);
|
fprintf (file, "%s:%d:%d", xloc.file, xloc.line, xloc.column);
|
||||||
|
|
||||||
|
/* Print the range, if any */
|
||||||
|
source_range r = EXPR_LOCATION_RANGE (node);
|
||||||
|
if (r.m_start)
|
||||||
|
{
|
||||||
|
xloc = expand_location (r.m_start);
|
||||||
|
fprintf (file, " start: %s:%d:%d", xloc.file, xloc.line, xloc.column);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf (file, " start: unknown");
|
||||||
|
}
|
||||||
|
if (r.m_finish)
|
||||||
|
{
|
||||||
|
xloc = expand_location (r.m_finish);
|
||||||
|
fprintf (file, " finish: %s:%d:%d", xloc.file, xloc.line, xloc.column);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf (file, " finish: unknown");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (file, ">");
|
fprintf (file, ">");
|
||||||
|
|
|
@ -67,7 +67,7 @@ diagnostic_for_asm (const rtx_insn *insn, const char *msg, va_list *args_ptr,
|
||||||
diagnostic_t kind)
|
diagnostic_t kind)
|
||||||
{
|
{
|
||||||
diagnostic_info diagnostic;
|
diagnostic_info diagnostic;
|
||||||
rich_location richloc (location_for_asm (insn));
|
rich_location richloc (line_table, location_for_asm (insn));
|
||||||
|
|
||||||
diagnostic_set_info (&diagnostic, msg, args_ptr,
|
diagnostic_set_info (&diagnostic, msg, args_ptr,
|
||||||
&richloc, kind);
|
&richloc, kind);
|
||||||
|
|
|
@ -1,3 +1,22 @@
|
||||||
|
2015-11-13 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2015-11-13 Alan Lawrence <alan.lawrence@arm.com>
|
2015-11-13 Alan Lawrence <alan.lawrence@arm.com>
|
||||||
|
|
||||||
PR tree-optimization/67682
|
PR tree-optimization/67682
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
/* { dg-options "-fdiagnostics-show-caret -Wc++-compat" } */
|
||||||
|
|
||||||
|
/* Verify that various diagnostics show source code ranges. */
|
||||||
|
|
||||||
|
/* These ones merely use token ranges; they don't use tree ranges. */
|
||||||
|
|
||||||
|
void undeclared_identifier (void)
|
||||||
|
{
|
||||||
|
name; /* { dg-error "'name' undeclared" } */
|
||||||
|
/*
|
||||||
|
{ dg-begin-multiline-output "" }
|
||||||
|
name;
|
||||||
|
^~~~
|
||||||
|
{ dg-end-multiline-output "" }
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void unknown_type_name (void)
|
||||||
|
{
|
||||||
|
foo bar; /* { dg-error "unknown type name 'foo'" } */
|
||||||
|
/*
|
||||||
|
{ dg-begin-multiline-output "" }
|
||||||
|
foo bar;
|
||||||
|
^~~
|
||||||
|
{ dg-end-multiline-output "" }
|
||||||
|
*/
|
||||||
|
|
||||||
|
qux *baz; /* { dg-error "unknown type name 'qux'" } */
|
||||||
|
/*
|
||||||
|
{ dg-begin-multiline-output "" }
|
||||||
|
qux *baz;
|
||||||
|
^~~
|
||||||
|
{ dg-end-multiline-output "" }
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_identifier_conflicts_with_cplusplus (void)
|
||||||
|
{
|
||||||
|
int new; /* { dg-warning "identifier 'new' conflicts with" } */
|
||||||
|
/*
|
||||||
|
{ dg-begin-multiline-output "" }
|
||||||
|
int new;
|
||||||
|
^~~
|
||||||
|
{ dg-end-multiline-output "" }
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void
|
||||||
|
bogus_varargs (...); /* { dg-error "ISO C requires a named argument before '...'" } */
|
||||||
|
/*
|
||||||
|
{ dg-begin-multiline-output "" }
|
||||||
|
bogus_varargs (...);
|
||||||
|
^~~
|
||||||
|
{ dg-end-multiline-output "" }
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void
|
||||||
|
foo (unknown_type param); /* { dg-error "unknown type name 'unknown_type'" } */
|
||||||
|
/*
|
||||||
|
{ dg-begin-multiline-output "" }
|
||||||
|
foo (unknown_type param);
|
||||||
|
^~~~~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" }
|
||||||
|
*/
|
||||||
|
|
||||||
|
void wide_string_literal_in_asm (void)
|
||||||
|
{
|
||||||
|
asm (L"nop"); /* { dg-error "wide string literal in 'asm'" } */
|
||||||
|
/*
|
||||||
|
{ dg-begin-multiline-output "" }
|
||||||
|
asm (L"nop");
|
||||||
|
^~~~~~
|
||||||
|
{ dg-end-multiline-output "" }
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void break_and_continue_in_wrong_places (void)
|
||||||
|
{
|
||||||
|
if (0)
|
||||||
|
break; /* { dg-error "break statement not within loop or switch" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
break;
|
||||||
|
^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
if (1)
|
||||||
|
;
|
||||||
|
else
|
||||||
|
continue; /* { dg-error "continue statement not within a loop" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
continue;
|
||||||
|
^~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Various examples of bad type decls. */
|
||||||
|
|
||||||
|
int float bogus; /* { dg-error "two or more data types in declaration specifiers" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
int float bogus;
|
||||||
|
^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
long long long bogus2; /* { dg-error "'long long long' is too long for GCC" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
long long long bogus2;
|
||||||
|
^~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
long short bogus3; /* { dg-error "both 'long' and 'short' in declaration specifiers" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
long short bogus3;
|
||||||
|
^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
signed unsigned bogus4; /* { dg-error "both 'signed' and 'unsigned' in declaration specifiers" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
signed unsigned bogus4;
|
||||||
|
^~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
|
@ -0,0 +1,23 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-Wuninitialized -fdiagnostics-show-caret" } */
|
||||||
|
|
||||||
|
int test_uninit_1 (void)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
return result; /* { dg-warning "uninitialized" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
return result;
|
||||||
|
^~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_uninit_2 (void)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
result += 3; /* { dg-warning "uninitialized" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
result += 3;
|
||||||
|
~~~~~~~^~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -0,0 +1,422 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O -fdiagnostics-show-caret" } */
|
||||||
|
|
||||||
|
/* This is a collection of unittests to verify that we're correctly
|
||||||
|
capturing the source code ranges of various kinds of expression.
|
||||||
|
|
||||||
|
It uses the various "diagnostic_test_*_expression_range_plugin"
|
||||||
|
plugins which handles "__emit_expression_range" by generating a warning
|
||||||
|
at the given source range of the input argument. Each of the
|
||||||
|
different plugins do this at a different phase of the internal
|
||||||
|
representation (tree, gimple, etc), so we can verify that the
|
||||||
|
source code range information is valid at each phase.
|
||||||
|
|
||||||
|
We want to accept an expression of any type. To do this in C, we
|
||||||
|
use variadic arguments, but C requires at least one argument before
|
||||||
|
the ellipsis, so we have a dummy one. */
|
||||||
|
|
||||||
|
extern void __emit_expression_range (int dummy, ...);
|
||||||
|
|
||||||
|
int global;
|
||||||
|
|
||||||
|
void test_parentheses (int a, int b)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, (a + b) ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, (a + b) );
|
||||||
|
~~~^~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, (a + b) * (a - b) ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, (a + b) * (a - b) );
|
||||||
|
~~~~~~~~^~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, !(a && b) ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, !(a && b) );
|
||||||
|
^~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Postfix expressions. ************************************************/
|
||||||
|
|
||||||
|
void test_array_reference (int *arr)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, arr[100] ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, arr[100] );
|
||||||
|
~~~^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_function_call (int p, int q, int r)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, test_function_call (p, q, r) ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, test_function_call (p, q, r) );
|
||||||
|
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct test_struct
|
||||||
|
{
|
||||||
|
int field;
|
||||||
|
};
|
||||||
|
|
||||||
|
int test_structure_references (struct test_struct *ptr)
|
||||||
|
{
|
||||||
|
struct test_struct local;
|
||||||
|
local.field = 42;
|
||||||
|
|
||||||
|
__emit_expression_range (0, local.field ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, local.field );
|
||||||
|
~~~~~^~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, ptr->field ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, ptr->field );
|
||||||
|
~~~^~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_postfix_incdec (int i)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, i++ ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, i++ );
|
||||||
|
~^~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, i-- ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, i-- );
|
||||||
|
~^~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unary operators. ****************************************************/
|
||||||
|
|
||||||
|
int test_prefix_incdec (int i)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, ++i ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, ++i );
|
||||||
|
^~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, --i ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, --i );
|
||||||
|
^~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_address_operator (void)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, &global ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, &global );
|
||||||
|
^~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_indirection (int *ptr)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, *ptr ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, *ptr );
|
||||||
|
^~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_unary_minus (int i)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, -i ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, -i );
|
||||||
|
^~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_ones_complement (int i)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, ~i ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, ~i );
|
||||||
|
^~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_logical_negation (int flag)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, !flag ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, !flag );
|
||||||
|
^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Casts. ****************************************************/
|
||||||
|
|
||||||
|
void test_cast (void *ptr)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, (int *)ptr ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, (int *)ptr );
|
||||||
|
^~~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Binary operators. *******************************************/
|
||||||
|
|
||||||
|
void test_multiplicative_operators (int lhs, int rhs)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, lhs * rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs * rhs );
|
||||||
|
~~~~^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, lhs / rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs / rhs );
|
||||||
|
~~~~^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, lhs % rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs % rhs );
|
||||||
|
~~~~^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_additive_operators (int lhs, int rhs)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, lhs + rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs + rhs );
|
||||||
|
~~~~^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, lhs - rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs - rhs );
|
||||||
|
~~~~^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_shift_operators (int lhs, int rhs)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, lhs << rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs << rhs );
|
||||||
|
~~~~^~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, lhs >> rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs >> rhs );
|
||||||
|
~~~~^~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_relational_operators (int lhs, int rhs)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, lhs < rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs < rhs );
|
||||||
|
~~~~^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, lhs > rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs > rhs );
|
||||||
|
~~~~^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, lhs <= rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs <= rhs );
|
||||||
|
~~~~^~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, lhs >= rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs >= rhs );
|
||||||
|
~~~~^~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_equality_operators (int lhs, int rhs)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, lhs == rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs == rhs );
|
||||||
|
~~~~^~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, lhs != rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs != rhs );
|
||||||
|
~~~~^~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_bitwise_binary_operators (int lhs, int rhs)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, lhs & rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs & rhs );
|
||||||
|
~~~~^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, lhs ^ rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs ^ rhs );
|
||||||
|
~~~~^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, lhs | rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs | rhs );
|
||||||
|
~~~~^~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_logical_operators (int lhs, int rhs)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, lhs && rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs && rhs );
|
||||||
|
~~~~^~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, lhs || rhs ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, lhs || rhs );
|
||||||
|
~~~~^~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Conditional operator. *******************************************/
|
||||||
|
|
||||||
|
void test_conditional_operators (int flag, int on_true, int on_false)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, flag ? on_true : on_false ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, flag ? on_true : on_false );
|
||||||
|
~~~~~~~~~~~~~~~^~~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Assignment expressions. *******************************************/
|
||||||
|
|
||||||
|
void test_assignment_expressions (int dest, int other)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, dest = other ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, dest = other );
|
||||||
|
~~~~~^~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, dest *= other ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, dest *= other );
|
||||||
|
~~~~~^~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, dest /= other ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, dest /= other );
|
||||||
|
~~~~~^~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, dest %= other ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, dest %= other );
|
||||||
|
~~~~~^~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, dest += other ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, dest += other );
|
||||||
|
~~~~~^~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, dest -= other ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, dest -= other );
|
||||||
|
~~~~~^~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, dest <<= other ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, dest <<= other );
|
||||||
|
~~~~~^~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, dest >>= other ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, dest >>= other );
|
||||||
|
~~~~~^~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, dest &= other ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, dest &= other );
|
||||||
|
~~~~~^~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, dest ^= other ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, dest ^= other );
|
||||||
|
~~~~~^~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0, dest |= other ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, dest |= other );
|
||||||
|
~~~~~^~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comma operator. *******************************************/
|
||||||
|
|
||||||
|
void test_comma_operator (int a, int b)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, (a++, a + b) ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, (a++, a + b) );
|
||||||
|
~~~~^~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Examples of non-trivial expressions. ****************************/
|
||||||
|
|
||||||
|
extern double sqrt (double x);
|
||||||
|
|
||||||
|
void test_quadratic (double a, double b, double c)
|
||||||
|
{
|
||||||
|
__emit_expression_range (0, b * b - 4 * a * c ); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
__emit_expression_range (0, b * b - 4 * a * c );
|
||||||
|
~~~~~~^~~~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
__emit_expression_range (0,
|
||||||
|
(-b + sqrt (b * b - 4 * a * c))
|
||||||
|
/ (2 * a)); /* { dg-warning "range" } */
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
(-b + sqrt (b * b - 4 * a * c))
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
/ (2 * a));
|
||||||
|
^~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O -fdiagnostics-show-caret" } */
|
||||||
|
|
||||||
|
/* This is an example file for use with
|
||||||
|
diagnostic_plugin_show_trees.c.
|
||||||
|
|
||||||
|
The plugin handles "__show_tree" by recursively dumping
|
||||||
|
the internal structure of the second input argument.
|
||||||
|
|
||||||
|
We want to accept an expression of any type. To do this in C, we
|
||||||
|
use variadic arguments, but C requires at least one argument before
|
||||||
|
the ellipsis, so we have a dummy one. */
|
||||||
|
|
||||||
|
extern void __show_tree (int dummy, ...);
|
||||||
|
|
||||||
|
extern double sqrt (double x);
|
||||||
|
|
||||||
|
void test_quadratic (double a, double b, double c)
|
||||||
|
{
|
||||||
|
__show_tree (0,
|
||||||
|
(-b + sqrt (b * b - 4 * a * c))
|
||||||
|
/ (2 * a));
|
||||||
|
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
(-b + sqrt (b * b - 4 * a * c))
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
/ (2 * a));
|
||||||
|
^~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
(-b + sqrt (b * b - 4 * a * c))
|
||||||
|
~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
(-b + sqrt (b * b - 4 * a * c))
|
||||||
|
^~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
(-b + sqrt (b * b - 4 * a * c))
|
||||||
|
~~~~~~^~~~~~~~~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
(-b + sqrt (b * b - 4 * a * c))
|
||||||
|
~~^~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
(-b + sqrt (b * b - 4 * a * c))
|
||||||
|
~~~~~~^~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
(-b + sqrt (b * b - 4 * a * c))
|
||||||
|
~~^~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
|
||||||
|
/* { dg-begin-multiline-output "" }
|
||||||
|
/ (2 * a));
|
||||||
|
~~~^~~~
|
||||||
|
{ dg-end-multiline-output "" } */
|
||||||
|
}
|
|
@ -0,0 +1,174 @@
|
||||||
|
/* This plugin recursively dumps the source-code location ranges of
|
||||||
|
expressions, at the pre-gimplification tree stage. */
|
||||||
|
/* { dg-options "-O" } */
|
||||||
|
|
||||||
|
#include "gcc-plugin.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "coretypes.h"
|
||||||
|
#include "tm.h"
|
||||||
|
#include "tree.h"
|
||||||
|
#include "stringpool.h"
|
||||||
|
#include "toplev.h"
|
||||||
|
#include "basic-block.h"
|
||||||
|
#include "hash-table.h"
|
||||||
|
#include "vec.h"
|
||||||
|
#include "ggc.h"
|
||||||
|
#include "basic-block.h"
|
||||||
|
#include "tree-ssa-alias.h"
|
||||||
|
#include "internal-fn.h"
|
||||||
|
#include "gimple-fold.h"
|
||||||
|
#include "tree-eh.h"
|
||||||
|
#include "gimple-expr.h"
|
||||||
|
#include "is-a.h"
|
||||||
|
#include "gimple.h"
|
||||||
|
#include "gimple-iterator.h"
|
||||||
|
#include "tree.h"
|
||||||
|
#include "tree-pass.h"
|
||||||
|
#include "intl.h"
|
||||||
|
#include "plugin-version.h"
|
||||||
|
#include "diagnostic.h"
|
||||||
|
#include "context.h"
|
||||||
|
#include "gcc-rich-location.h"
|
||||||
|
#include "print-tree.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Hack: fails with linker error:
|
||||||
|
./diagnostic_plugin_show_trees.so: undefined symbol: _ZN17gcc_rich_location8add_exprEP9tree_node
|
||||||
|
since nothing in the tree is using gcc_rich_location::add_expr yet.
|
||||||
|
|
||||||
|
I've tried various workarounds (adding DEBUG_FUNCTION to the
|
||||||
|
method, taking its address), but can't seem to fix it that way.
|
||||||
|
So as a nasty workaround, the following material is copied&pasted
|
||||||
|
from gcc-rich-location.c: */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
get_range_for_expr (tree expr, location_range *r)
|
||||||
|
{
|
||||||
|
if (EXPR_HAS_RANGE (expr))
|
||||||
|
{
|
||||||
|
source_range sr = EXPR_LOCATION_RANGE (expr);
|
||||||
|
|
||||||
|
/* Do we have meaningful data? */
|
||||||
|
if (sr.m_start && sr.m_finish)
|
||||||
|
{
|
||||||
|
r->m_start = expand_location (sr.m_start);
|
||||||
|
r->m_finish = expand_location (sr.m_finish);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a range to the rich_location, covering expression EXPR. */
|
||||||
|
|
||||||
|
void
|
||||||
|
gcc_rich_location::add_expr (tree expr)
|
||||||
|
{
|
||||||
|
gcc_assert (expr);
|
||||||
|
|
||||||
|
location_range r;
|
||||||
|
r.m_show_caret_p = false;
|
||||||
|
if (get_range_for_expr (expr, &r))
|
||||||
|
add_range (&r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: end of material taken from gcc-rich-location.c */
|
||||||
|
|
||||||
|
int plugin_is_GPL_compatible;
|
||||||
|
|
||||||
|
static void
|
||||||
|
show_tree (tree node)
|
||||||
|
{
|
||||||
|
if (!CAN_HAVE_RANGE_P (node))
|
||||||
|
return;
|
||||||
|
|
||||||
|
gcc_rich_location richloc (EXPR_LOCATION (node));
|
||||||
|
richloc.add_expr (node);
|
||||||
|
|
||||||
|
if (richloc.get_num_locations () < 2)
|
||||||
|
{
|
||||||
|
error_at_rich_loc (&richloc, "range not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum tree_code code = TREE_CODE (node);
|
||||||
|
|
||||||
|
location_range *range = richloc.get_range (1);
|
||||||
|
inform_at_rich_loc (&richloc,
|
||||||
|
"%s at range %i:%i-%i:%i",
|
||||||
|
get_tree_code_name (code),
|
||||||
|
range->m_start.line,
|
||||||
|
range->m_start.column,
|
||||||
|
range->m_finish.line,
|
||||||
|
range->m_finish.column);
|
||||||
|
|
||||||
|
/* Recurse. */
|
||||||
|
int min_idx = 0;
|
||||||
|
int max_idx = TREE_OPERAND_LENGTH (node);
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case CALL_EXPR:
|
||||||
|
min_idx = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = min_idx; i < max_idx; i++)
|
||||||
|
show_tree (TREE_OPERAND (node, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
tree
|
||||||
|
cb_walk_tree_fn (tree * tp, int * walk_subtrees,
|
||||||
|
void * data ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
if (TREE_CODE (*tp) != CALL_EXPR)
|
||||||
|
return NULL_TREE;
|
||||||
|
|
||||||
|
tree call_expr = *tp;
|
||||||
|
tree fn = CALL_EXPR_FN (call_expr);
|
||||||
|
if (TREE_CODE (fn) != ADDR_EXPR)
|
||||||
|
return NULL_TREE;
|
||||||
|
fn = TREE_OPERAND (fn, 0);
|
||||||
|
if (TREE_CODE (fn) != FUNCTION_DECL)
|
||||||
|
return NULL_TREE;
|
||||||
|
if (strcmp (IDENTIFIER_POINTER (DECL_NAME (fn)), "__show_tree"))
|
||||||
|
return NULL_TREE;
|
||||||
|
|
||||||
|
/* Get arg 1; print it! */
|
||||||
|
tree arg = CALL_EXPR_ARG (call_expr, 1);
|
||||||
|
|
||||||
|
show_tree (arg);
|
||||||
|
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
callback (void *gcc_data, void *user_data)
|
||||||
|
{
|
||||||
|
tree fndecl = (tree)gcc_data;
|
||||||
|
walk_tree (&DECL_SAVED_TREE (fndecl), cb_walk_tree_fn, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
plugin_init (struct plugin_name_args *plugin_info,
|
||||||
|
struct plugin_gcc_version *version)
|
||||||
|
{
|
||||||
|
struct register_pass_info pass_info;
|
||||||
|
const char *plugin_name = plugin_info->base_name;
|
||||||
|
int argc = plugin_info->argc;
|
||||||
|
struct plugin_argument *argv = plugin_info->argv;
|
||||||
|
|
||||||
|
if (!plugin_default_version_check (version, &gcc_version))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
register_callback (plugin_name,
|
||||||
|
PLUGIN_PRE_GENERICIZE,
|
||||||
|
callback,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -109,7 +109,8 @@ get_loc (unsigned int line_num, unsigned int col_num)
|
||||||
|
|
||||||
/* Convert from 0-based column numbers to 1-based column numbers. */
|
/* Convert from 0-based column numbers to 1-based column numbers. */
|
||||||
source_location loc
|
source_location loc
|
||||||
= linemap_position_for_line_and_column (line_map,
|
= linemap_position_for_line_and_column (line_table,
|
||||||
|
line_map,
|
||||||
line_num, col_num + 1);
|
line_num, col_num + 1);
|
||||||
|
|
||||||
return loc;
|
return loc;
|
||||||
|
@ -163,7 +164,7 @@ test_show_locus (function *fun)
|
||||||
if (0 == strcmp (fnname, "test_simple"))
|
if (0 == strcmp (fnname, "test_simple"))
|
||||||
{
|
{
|
||||||
const int line = fnstart_line + 2;
|
const int line = fnstart_line + 2;
|
||||||
rich_location richloc (get_loc (line, 15));
|
rich_location richloc (line_table, get_loc (line, 15));
|
||||||
richloc.add_range (get_loc (line, 10), get_loc (line, 14), false);
|
richloc.add_range (get_loc (line, 10), get_loc (line, 14), false);
|
||||||
richloc.add_range (get_loc (line, 16), get_loc (line, 16), false);
|
richloc.add_range (get_loc (line, 16), get_loc (line, 16), false);
|
||||||
warning_at_rich_loc (&richloc, 0, "test");
|
warning_at_rich_loc (&richloc, 0, "test");
|
||||||
|
@ -172,7 +173,7 @@ test_show_locus (function *fun)
|
||||||
if (0 == strcmp (fnname, "test_simple_2"))
|
if (0 == strcmp (fnname, "test_simple_2"))
|
||||||
{
|
{
|
||||||
const int line = fnstart_line + 2;
|
const int line = fnstart_line + 2;
|
||||||
rich_location richloc (get_loc (line, 24));
|
rich_location richloc (line_table, get_loc (line, 24));
|
||||||
richloc.add_range (get_loc (line, 6),
|
richloc.add_range (get_loc (line, 6),
|
||||||
get_loc (line, 22), false);
|
get_loc (line, 22), false);
|
||||||
richloc.add_range (get_loc (line, 26),
|
richloc.add_range (get_loc (line, 26),
|
||||||
|
@ -183,7 +184,7 @@ test_show_locus (function *fun)
|
||||||
if (0 == strcmp (fnname, "test_multiline"))
|
if (0 == strcmp (fnname, "test_multiline"))
|
||||||
{
|
{
|
||||||
const int line = fnstart_line + 2;
|
const int line = fnstart_line + 2;
|
||||||
rich_location richloc (get_loc (line + 1, 7));
|
rich_location richloc (line_table, get_loc (line + 1, 7));
|
||||||
richloc.add_range (get_loc (line, 7),
|
richloc.add_range (get_loc (line, 7),
|
||||||
get_loc (line, 23), false);
|
get_loc (line, 23), false);
|
||||||
richloc.add_range (get_loc (line + 1, 9),
|
richloc.add_range (get_loc (line + 1, 9),
|
||||||
|
@ -194,7 +195,7 @@ test_show_locus (function *fun)
|
||||||
if (0 == strcmp (fnname, "test_many_lines"))
|
if (0 == strcmp (fnname, "test_many_lines"))
|
||||||
{
|
{
|
||||||
const int line = fnstart_line + 2;
|
const int line = fnstart_line + 2;
|
||||||
rich_location richloc (get_loc (line + 5, 7));
|
rich_location richloc (line_table, get_loc (line + 5, 7));
|
||||||
richloc.add_range (get_loc (line, 7),
|
richloc.add_range (get_loc (line, 7),
|
||||||
get_loc (line + 4, 65), false);
|
get_loc (line + 4, 65), false);
|
||||||
richloc.add_range (get_loc (line + 5, 9),
|
richloc.add_range (get_loc (line + 5, 9),
|
||||||
|
@ -223,7 +224,7 @@ test_show_locus (function *fun)
|
||||||
source_range src_range;
|
source_range src_range;
|
||||||
src_range.m_start = get_loc (line, 12);
|
src_range.m_start = get_loc (line, 12);
|
||||||
src_range.m_finish = get_loc (line, 20);
|
src_range.m_finish = get_loc (line, 20);
|
||||||
rich_location richloc (caret);
|
rich_location richloc (line_table, caret);
|
||||||
richloc.set_range (0, src_range, true, false);
|
richloc.set_range (0, src_range, true, false);
|
||||||
warning_at_rich_loc (&richloc, 0, "test");
|
warning_at_rich_loc (&richloc, 0, "test");
|
||||||
}
|
}
|
||||||
|
@ -237,7 +238,7 @@ test_show_locus (function *fun)
|
||||||
source_range src_range;
|
source_range src_range;
|
||||||
src_range.m_start = get_loc (line, 90);
|
src_range.m_start = get_loc (line, 90);
|
||||||
src_range.m_finish = get_loc (line, 98);
|
src_range.m_finish = get_loc (line, 98);
|
||||||
rich_location richloc (caret);
|
rich_location richloc (line_table, caret);
|
||||||
richloc.set_range (0, src_range, true, false);
|
richloc.set_range (0, src_range, true, false);
|
||||||
warning_at_rich_loc (&richloc, 0, "test");
|
warning_at_rich_loc (&richloc, 0, "test");
|
||||||
}
|
}
|
||||||
|
@ -248,7 +249,7 @@ test_show_locus (function *fun)
|
||||||
const int line = fnstart_line + 2;
|
const int line = fnstart_line + 2;
|
||||||
location_t caret_a = get_loc (line, 7);
|
location_t caret_a = get_loc (line, 7);
|
||||||
location_t caret_b = get_loc (line, 11);
|
location_t caret_b = get_loc (line, 11);
|
||||||
rich_location richloc (caret_a);
|
rich_location richloc (line_table, caret_a);
|
||||||
richloc.add_range (caret_b, caret_b, true);
|
richloc.add_range (caret_b, caret_b, true);
|
||||||
global_dc->caret_chars[0] = 'A';
|
global_dc->caret_chars[0] = 'A';
|
||||||
global_dc->caret_chars[1] = 'B';
|
global_dc->caret_chars[1] = 'B';
|
||||||
|
@ -269,7 +270,7 @@ test_show_locus (function *fun)
|
||||||
const int line = fnstart_line + 3;
|
const int line = fnstart_line + 3;
|
||||||
location_t caret_a = get_loc (line, 5);
|
location_t caret_a = get_loc (line, 5);
|
||||||
location_t caret_b = get_loc (line - 1, 19);
|
location_t caret_b = get_loc (line - 1, 19);
|
||||||
rich_location richloc (caret_a);
|
rich_location richloc (line_table, caret_a);
|
||||||
richloc.add_range (caret_b, caret_b, true);
|
richloc.add_range (caret_b, caret_b, true);
|
||||||
global_dc->caret_chars[0] = '1';
|
global_dc->caret_chars[0] = '1';
|
||||||
global_dc->caret_chars[1] = '2';
|
global_dc->caret_chars[1] = '2';
|
||||||
|
@ -304,11 +305,6 @@ plugin_init (struct plugin_name_args *plugin_info,
|
||||||
if (!plugin_default_version_check (version, &gcc_version))
|
if (!plugin_default_version_check (version, &gcc_version))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* For now, tell the dc to expect ranges and thus to colorize the source
|
|
||||||
lines, not just the carets/underlines. This will be redundant
|
|
||||||
once the C frontend generates ranges. */
|
|
||||||
global_dc->colorize_source_p = true;
|
|
||||||
|
|
||||||
for (int i = 0; i < argc; i++)
|
for (int i = 0; i < argc; i++)
|
||||||
{
|
{
|
||||||
if (0 == strcmp (argv[i].key, "color"))
|
if (0 == strcmp (argv[i].key, "color"))
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/* This plugin verifies the source-code location ranges of
|
||||||
|
expressions, at the pre-gimplification tree stage. */
|
||||||
|
/* { dg-options "-O" } */
|
||||||
|
|
||||||
|
#include "gcc-plugin.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "coretypes.h"
|
||||||
|
#include "tm.h"
|
||||||
|
#include "tree.h"
|
||||||
|
#include "stringpool.h"
|
||||||
|
#include "toplev.h"
|
||||||
|
#include "basic-block.h"
|
||||||
|
#include "hash-table.h"
|
||||||
|
#include "vec.h"
|
||||||
|
#include "ggc.h"
|
||||||
|
#include "basic-block.h"
|
||||||
|
#include "tree-ssa-alias.h"
|
||||||
|
#include "internal-fn.h"
|
||||||
|
#include "gimple-fold.h"
|
||||||
|
#include "tree-eh.h"
|
||||||
|
#include "gimple-expr.h"
|
||||||
|
#include "is-a.h"
|
||||||
|
#include "gimple.h"
|
||||||
|
#include "gimple-iterator.h"
|
||||||
|
#include "tree.h"
|
||||||
|
#include "tree-pass.h"
|
||||||
|
#include "intl.h"
|
||||||
|
#include "plugin-version.h"
|
||||||
|
#include "diagnostic.h"
|
||||||
|
#include "context.h"
|
||||||
|
#include "print-tree.h"
|
||||||
|
|
||||||
|
int plugin_is_GPL_compatible;
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_warning (location_t loc)
|
||||||
|
{
|
||||||
|
source_range src_range = get_range_from_loc (line_table, loc);
|
||||||
|
warning_at (loc, 0,
|
||||||
|
"tree range %i:%i-%i:%i",
|
||||||
|
LOCATION_LINE (src_range.m_start),
|
||||||
|
LOCATION_COLUMN (src_range.m_start),
|
||||||
|
LOCATION_LINE (src_range.m_finish),
|
||||||
|
LOCATION_COLUMN (src_range.m_finish));
|
||||||
|
}
|
||||||
|
|
||||||
|
tree
|
||||||
|
cb_walk_tree_fn (tree * tp, int * walk_subtrees,
|
||||||
|
void * data ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
if (TREE_CODE (*tp) != CALL_EXPR)
|
||||||
|
return NULL_TREE;
|
||||||
|
|
||||||
|
tree call_expr = *tp;
|
||||||
|
tree fn = CALL_EXPR_FN (call_expr);
|
||||||
|
if (TREE_CODE (fn) != ADDR_EXPR)
|
||||||
|
return NULL_TREE;
|
||||||
|
fn = TREE_OPERAND (fn, 0);
|
||||||
|
if (TREE_CODE (fn) != FUNCTION_DECL)
|
||||||
|
return NULL_TREE;
|
||||||
|
if (strcmp (IDENTIFIER_POINTER (DECL_NAME (fn)), "__emit_expression_range"))
|
||||||
|
return NULL_TREE;
|
||||||
|
|
||||||
|
/* Get arg 1; print it! */
|
||||||
|
tree arg = CALL_EXPR_ARG (call_expr, 1);
|
||||||
|
|
||||||
|
emit_warning (EXPR_LOCATION (arg));
|
||||||
|
|
||||||
|
return NULL_TREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
callback (void *gcc_data, void *user_data)
|
||||||
|
{
|
||||||
|
tree fndecl = (tree)gcc_data;
|
||||||
|
walk_tree (&DECL_SAVED_TREE (fndecl), cb_walk_tree_fn, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
plugin_init (struct plugin_name_args *plugin_info,
|
||||||
|
struct plugin_gcc_version *version)
|
||||||
|
{
|
||||||
|
struct register_pass_info pass_info;
|
||||||
|
const char *plugin_name = plugin_info->base_name;
|
||||||
|
int argc = plugin_info->argc;
|
||||||
|
struct plugin_argument *argv = plugin_info->argv;
|
||||||
|
|
||||||
|
if (!plugin_default_version_check (version, &gcc_version))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
register_callback (plugin_name,
|
||||||
|
PLUGIN_PRE_GENERICIZE,
|
||||||
|
callback,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -66,6 +66,10 @@ set plugin_test_list [list \
|
||||||
{ diagnostic_plugin_test_show_locus.c \
|
{ diagnostic_plugin_test_show_locus.c \
|
||||||
diagnostic-test-show-locus-bw.c \
|
diagnostic-test-show-locus-bw.c \
|
||||||
diagnostic-test-show-locus-color.c } \
|
diagnostic-test-show-locus-color.c } \
|
||||||
|
{ diagnostic_plugin_test_tree_expression_range.c \
|
||||||
|
diagnostic-test-expressions-1.c } \
|
||||||
|
{ diagnostic_plugin_show_trees.c \
|
||||||
|
diagnostic-test-show-trees-1.c } \
|
||||||
{ levenshtein_plugin.c levenshtein-test-1.c } \
|
{ levenshtein_plugin.c levenshtein-test-1.c } \
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -1130,6 +1130,7 @@ general_init (const char *argv0, bool init_signals)
|
||||||
linemap_init (line_table, BUILTINS_LOCATION);
|
linemap_init (line_table, BUILTINS_LOCATION);
|
||||||
line_table->reallocator = realloc_for_line_map;
|
line_table->reallocator = realloc_for_line_map;
|
||||||
line_table->round_alloc_size = ggc_round_alloc_size;
|
line_table->round_alloc_size = ggc_round_alloc_size;
|
||||||
|
line_table->default_range_bits = 5;
|
||||||
init_ttree ();
|
init_ttree ();
|
||||||
|
|
||||||
/* Initialize register usage now so switches may override. */
|
/* Initialize register usage now so switches may override. */
|
||||||
|
|
|
@ -6719,10 +6719,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
|
||||||
continue;
|
continue;
|
||||||
if (d->orig_block == NULL_TREE || block == d->orig_block)
|
if (d->orig_block == NULL_TREE || block == d->orig_block)
|
||||||
{
|
{
|
||||||
if (d->new_block == NULL_TREE)
|
locus = set_block (locus, d->new_block);
|
||||||
locus = LOCATION_LOCUS (locus);
|
|
||||||
else
|
|
||||||
locus = COMBINE_LOCATION_DATA (line_table, locus, d->new_block);
|
|
||||||
gimple_phi_arg_set_location (phi, i, locus);
|
gimple_phi_arg_set_location (phi, i, locus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6782,9 +6779,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
|
||||||
tree block = LOCATION_BLOCK (e->goto_locus);
|
tree block = LOCATION_BLOCK (e->goto_locus);
|
||||||
if (d->orig_block == NULL_TREE
|
if (d->orig_block == NULL_TREE
|
||||||
|| block == d->orig_block)
|
|| block == d->orig_block)
|
||||||
e->goto_locus = d->new_block ?
|
e->goto_locus = set_block (e->goto_locus, d->new_block);
|
||||||
COMBINE_LOCATION_DATA (line_table, e->goto_locus, d->new_block) :
|
|
||||||
LOCATION_LOCUS (e->goto_locus);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2348,10 +2348,7 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
|
||||||
tree *n;
|
tree *n;
|
||||||
n = id->decl_map->get (LOCATION_BLOCK (locus));
|
n = id->decl_map->get (LOCATION_BLOCK (locus));
|
||||||
gcc_assert (n);
|
gcc_assert (n);
|
||||||
if (*n)
|
locus = set_block (locus, *n);
|
||||||
locus = COMBINE_LOCATION_DATA (line_table, locus, *n);
|
|
||||||
else
|
|
||||||
locus = LOCATION_LOCUS (locus);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
locus = LOCATION_LOCUS (locus);
|
locus = LOCATION_LOCUS (locus);
|
||||||
|
|
60
gcc/tree.c
60
gcc/tree.c
|
@ -11789,10 +11789,7 @@ tree_set_block (tree t, tree b)
|
||||||
|
|
||||||
if (IS_EXPR_CODE_CLASS (c))
|
if (IS_EXPR_CODE_CLASS (c))
|
||||||
{
|
{
|
||||||
if (b)
|
t->exp.locus = set_block (t->exp.locus, b);
|
||||||
t->exp.locus = COMBINE_LOCATION_DATA (line_table, t->exp.locus, b);
|
|
||||||
else
|
|
||||||
t->exp.locus = LOCATION_LOCUS (t->exp.locus);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
|
@ -13813,5 +13810,60 @@ nonnull_arg_p (const_tree arg)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Given location LOC, strip away any packed range information
|
||||||
|
or ad-hoc information. */
|
||||||
|
|
||||||
|
static location_t
|
||||||
|
get_pure_location (location_t loc)
|
||||||
|
{
|
||||||
|
if (IS_ADHOC_LOC (loc))
|
||||||
|
loc
|
||||||
|
= line_table->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
|
||||||
|
|
||||||
|
if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (line_table))
|
||||||
|
return loc;
|
||||||
|
|
||||||
|
if (loc < RESERVED_LOCATION_COUNT)
|
||||||
|
return loc;
|
||||||
|
|
||||||
|
const line_map *map = linemap_lookup (line_table, loc);
|
||||||
|
const line_map_ordinary *ordmap = linemap_check_ordinary (map);
|
||||||
|
|
||||||
|
return loc & ~((1 << ordmap->m_range_bits) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Combine LOC and BLOCK to a combined adhoc loc, retaining any range
|
||||||
|
information. */
|
||||||
|
|
||||||
|
location_t
|
||||||
|
set_block (location_t loc, tree block)
|
||||||
|
{
|
||||||
|
location_t pure_loc = get_pure_location (loc);
|
||||||
|
source_range src_range = get_range_from_loc (line_table, loc);
|
||||||
|
return COMBINE_LOCATION_DATA (line_table, pure_loc, src_range, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_source_range (tree expr, location_t start, location_t finish)
|
||||||
|
{
|
||||||
|
source_range src_range;
|
||||||
|
src_range.m_start = start;
|
||||||
|
src_range.m_finish = finish;
|
||||||
|
set_source_range (expr, src_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_source_range (tree expr, source_range src_range)
|
||||||
|
{
|
||||||
|
if (!EXPR_P (expr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
location_t pure_loc = get_pure_location (EXPR_LOCATION (expr));
|
||||||
|
location_t adhoc = COMBINE_LOCATION_DATA (line_table,
|
||||||
|
pure_loc,
|
||||||
|
src_range,
|
||||||
|
NULL);
|
||||||
|
SET_EXPR_LOCATION (expr, adhoc);
|
||||||
|
}
|
||||||
|
|
||||||
#include "gt-tree.h"
|
#include "gt-tree.h"
|
||||||
|
|
33
gcc/tree.h
33
gcc/tree.h
|
@ -1096,10 +1096,25 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
|
||||||
#define EXPR_FILENAME(NODE) LOCATION_FILE (EXPR_CHECK ((NODE))->exp.locus)
|
#define EXPR_FILENAME(NODE) LOCATION_FILE (EXPR_CHECK ((NODE))->exp.locus)
|
||||||
#define EXPR_LINENO(NODE) LOCATION_LINE (EXPR_CHECK (NODE)->exp.locus)
|
#define EXPR_LINENO(NODE) LOCATION_LINE (EXPR_CHECK (NODE)->exp.locus)
|
||||||
|
|
||||||
|
#define CAN_HAVE_RANGE_P(NODE) (CAN_HAVE_LOCATION_P (NODE))
|
||||||
|
#define EXPR_LOCATION_RANGE(NODE) (get_expr_source_range (EXPR_CHECK ((NODE))))
|
||||||
|
|
||||||
|
#define EXPR_HAS_RANGE(NODE) \
|
||||||
|
(CAN_HAVE_RANGE_P (NODE) \
|
||||||
|
? EXPR_LOCATION_RANGE (NODE).m_start != UNKNOWN_LOCATION \
|
||||||
|
: false)
|
||||||
|
|
||||||
/* True if a tree is an expression or statement that can have a
|
/* True if a tree is an expression or statement that can have a
|
||||||
location. */
|
location. */
|
||||||
#define CAN_HAVE_LOCATION_P(NODE) ((NODE) && EXPR_P (NODE))
|
#define CAN_HAVE_LOCATION_P(NODE) ((NODE) && EXPR_P (NODE))
|
||||||
|
|
||||||
|
static inline source_range
|
||||||
|
get_expr_source_range (tree expr)
|
||||||
|
{
|
||||||
|
location_t loc = EXPR_LOCATION (expr);
|
||||||
|
return get_range_from_loc (line_table, loc);
|
||||||
|
}
|
||||||
|
|
||||||
extern void protected_set_expr_location (tree, location_t);
|
extern void protected_set_expr_location (tree, location_t);
|
||||||
|
|
||||||
/* In a TARGET_EXPR node. */
|
/* In a TARGET_EXPR node. */
|
||||||
|
@ -2172,6 +2187,9 @@ extern machine_mode element_mode (const_tree t);
|
||||||
#define DECL_IS_BUILTIN(DECL) \
|
#define DECL_IS_BUILTIN(DECL) \
|
||||||
(LOCATION_LOCUS (DECL_SOURCE_LOCATION (DECL)) <= BUILTINS_LOCATION)
|
(LOCATION_LOCUS (DECL_SOURCE_LOCATION (DECL)) <= BUILTINS_LOCATION)
|
||||||
|
|
||||||
|
#define DECL_LOCATION_RANGE(NODE) \
|
||||||
|
(get_decl_source_range (DECL_MINIMAL_CHECK (NODE)))
|
||||||
|
|
||||||
/* For FIELD_DECLs, this is the RECORD_TYPE, UNION_TYPE, or
|
/* For FIELD_DECLs, this is the RECORD_TYPE, UNION_TYPE, or
|
||||||
QUAL_UNION_TYPE node that the field is a member of. For VAR_DECL,
|
QUAL_UNION_TYPE node that the field is a member of. For VAR_DECL,
|
||||||
PARM_DECL, FUNCTION_DECL, LABEL_DECL, RESULT_DECL, and CONST_DECL
|
PARM_DECL, FUNCTION_DECL, LABEL_DECL, RESULT_DECL, and CONST_DECL
|
||||||
|
@ -5277,10 +5295,25 @@ type_with_alias_set_p (const_tree t)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern location_t set_block (location_t loc, tree block);
|
||||||
|
|
||||||
extern void gt_ggc_mx (tree &);
|
extern void gt_ggc_mx (tree &);
|
||||||
extern void gt_pch_nx (tree &);
|
extern void gt_pch_nx (tree &);
|
||||||
extern void gt_pch_nx (tree &, gt_pointer_operator, void *);
|
extern void gt_pch_nx (tree &, gt_pointer_operator, void *);
|
||||||
|
|
||||||
extern bool nonnull_arg_p (const_tree);
|
extern bool nonnull_arg_p (const_tree);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
set_source_range (tree expr, location_t start, location_t finish);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
set_source_range (tree expr, source_range src_range);
|
||||||
|
|
||||||
|
static inline source_range
|
||||||
|
get_decl_source_range (tree decl)
|
||||||
|
{
|
||||||
|
location_t loc = DECL_SOURCE_LOCATION (decl);
|
||||||
|
return get_range_from_loc (line_table, loc);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* GCC_TREE_H */
|
#endif /* GCC_TREE_H */
|
||||||
|
|
|
@ -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>
|
2015-11-06 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
* errors.c (cpp_diagnostic): Update for change in signature
|
* errors.c (cpp_diagnostic): Update for change in signature
|
||||||
|
|
|
@ -57,7 +57,7 @@ cpp_diagnostic (cpp_reader * pfile, int level, int reason,
|
||||||
|
|
||||||
if (!pfile->cb.error)
|
if (!pfile->cb.error)
|
||||||
abort ();
|
abort ();
|
||||||
rich_location richloc (src_loc);
|
rich_location richloc (pfile->line_table, src_loc);
|
||||||
ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap);
|
ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -140,7 +140,7 @@ cpp_diagnostic_with_line (cpp_reader * pfile, int level, int reason,
|
||||||
|
|
||||||
if (!pfile->cb.error)
|
if (!pfile->cb.error)
|
||||||
abort ();
|
abort ();
|
||||||
rich_location richloc (src_loc);
|
rich_location richloc (pfile->line_table, src_loc);
|
||||||
richloc.override_column (column);
|
richloc.override_column (column);
|
||||||
ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap);
|
ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap);
|
||||||
|
|
||||||
|
|
|
@ -237,7 +237,8 @@ struct GTY(()) cpp_identifier {
|
||||||
/* A preprocessing token. This has been carefully packed and should
|
/* A preprocessing token. This has been carefully packed and should
|
||||||
occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */
|
occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */
|
||||||
struct GTY(()) cpp_token {
|
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 */
|
ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */
|
||||||
unsigned short flags; /* flags - see above */
|
unsigned short flags; /* flags - see above */
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,8 @@ enum lc_reason
|
||||||
typedef unsigned int linenum_type;
|
typedef unsigned int linenum_type;
|
||||||
|
|
||||||
/* The typedef "source_location" is a key within the location database,
|
/* 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
|
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
|
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[0]->start_location) | first line in ordmap 0
|
||||||
-----------+-------------------------------+-------------------------------
|
-----------+-------------------------------+-------------------------------
|
||||||
| ordmap[1]->start_location | First line in ordmap 1
|
| ordmap[1]->start_location | First line in ordmap 1
|
||||||
| ordmap[1]->start_location+1 | First column in that line
|
| ordmap[1]->start_location+32 | First column in that line
|
||||||
| ordmap[1]->start_location+2 | 2nd column in that line
|
| (assuming range_bits == 5) |
|
||||||
| | Subsequent lines are offset by
|
| ordmap[1]->start_location+64 | 2nd column in that line
|
||||||
| | (1 << column_bits),
|
| ordmap[1]->start_location+4096| Second line in ordmap 1
|
||||||
| | e.g. 128 for 7 bits, with a
|
| (assuming column_bits == 12)
|
||||||
| | column value of 0 representing
|
|
|
||||||
| | "the whole line".
|
| 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-1 | Final location in ordmap 1
|
||||||
-----------+-------------------------------+-------------------------------
|
-----------+-------------------------------+-------------------------------
|
||||||
| ordmap[2]->start_location | First line in ordmap 2
|
| ordmap[2]->start_location | First line in ordmap 2
|
||||||
|
@ -127,8 +163,101 @@ typedef unsigned int linenum_type;
|
||||||
0xffffffff | UINT_MAX |
|
0xffffffff | UINT_MAX |
|
||||||
-----------+-------------------------------+-------------------------------
|
-----------+-------------------------------+-------------------------------
|
||||||
|
|
||||||
To see how this works in practice, see the worked example in
|
Examples of location encoding.
|
||||||
libcpp/location-example.txt. */
|
|
||||||
|
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;
|
typedef unsigned int source_location;
|
||||||
|
|
||||||
/* A range of source locations.
|
/* 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
|
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
|
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),
|
START_LOCATION+(L*(1<<m_column_and_range_bits))+(C*1<<m_range_bits), as
|
||||||
and the result_location is less than the next line_map's start_location.
|
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
|
(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".)
|
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. */
|
cpp_buffer. */
|
||||||
unsigned char sysp;
|
unsigned char sysp;
|
||||||
|
|
||||||
/* Number of the low-order source_location bits used for a column number. */
|
/* Number of the low-order source_location bits used for column numbers
|
||||||
unsigned int column_bits : 8;
|
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
|
/* 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;
|
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. */
|
/* Get the filename of ordinary map MAP. */
|
||||||
|
|
||||||
inline const char *
|
inline const char *
|
||||||
|
@ -524,9 +661,11 @@ struct GTY(()) maps_info_macro {
|
||||||
unsigned int cache;
|
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 {
|
struct GTY(()) location_adhoc_data {
|
||||||
source_location locus;
|
source_location locus;
|
||||||
|
source_range src_range;
|
||||||
void * GTY((skip)) data;
|
void * GTY((skip)) data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -588,6 +727,12 @@ struct GTY(()) line_maps {
|
||||||
|
|
||||||
/* True if we've seen a #line or # 44 "file" directive. */
|
/* True if we've seen a #line or # 44 "file" directive. */
|
||||||
bool seen_line_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
|
/* 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 void location_adhoc_data_fini (struct line_maps *);
|
||||||
extern source_location get_combined_adhoc_loc (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 void *get_data_from_adhoc_loc (struct line_maps *, source_location);
|
||||||
extern source_location get_location_from_adhoc_loc (struct line_maps *,
|
extern source_location get_location_from_adhoc_loc (struct line_maps *,
|
||||||
source_location);
|
source_location);
|
||||||
|
|
||||||
|
extern source_range get_range_from_loc (line_maps *set, source_location loc);
|
||||||
|
|
||||||
/* Get whether location LOC is an ad-hoc location. */
|
/* Get whether location LOC is an ad-hoc location. */
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
|
@ -838,14 +987,21 @@ IS_ADHOC_LOC (source_location loc)
|
||||||
return (loc & MAX_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. */
|
/* Combine LOC and BLOCK, giving a combined adhoc location. */
|
||||||
|
|
||||||
inline source_location
|
inline source_location
|
||||||
COMBINE_LOCATION_DATA (struct line_maps *set,
|
COMBINE_LOCATION_DATA (struct line_maps *set,
|
||||||
source_location loc,
|
source_location loc,
|
||||||
|
source_range src_range,
|
||||||
void *block)
|
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 *);
|
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)
|
SOURCE_LINE (const line_map_ordinary *ord_map, source_location loc)
|
||||||
{
|
{
|
||||||
return ((loc - ord_map->start_location)
|
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. */
|
/* 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)
|
SOURCE_COLUMN (const line_map_ordinary *ord_map, source_location loc)
|
||||||
{
|
{
|
||||||
return ((loc - ord_map->start_location)
|
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
|
/* 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
|
return (((map[1].start_location - 1
|
||||||
- map->start_location)
|
- map->start_location)
|
||||||
& ~((1 << map->column_bits) - 1))
|
& ~((1 << map->m_column_and_range_bits) - 1))
|
||||||
+ map->start_location);
|
+ 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
|
/* Encode and return a source location from a given line and
|
||||||
column. */
|
column. */
|
||||||
source_location
|
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);
|
linenum_type, unsigned int);
|
||||||
|
|
||||||
/* Encode and return a source_location starting from location LOC and
|
/* Encode and return a source_location starting from location LOC and
|
||||||
|
@ -1187,7 +1344,7 @@ class rich_location
|
||||||
/* Constructors. */
|
/* Constructors. */
|
||||||
|
|
||||||
/* Constructing from a location. */
|
/* Constructing from a location. */
|
||||||
rich_location (source_location loc);
|
rich_location (line_maps *set, source_location loc);
|
||||||
|
|
||||||
/* Constructing from a source_range. */
|
/* Constructing from a source_range. */
|
||||||
rich_location (source_range src_range);
|
rich_location (source_range src_range);
|
||||||
|
|
13
libcpp/lex.c
13
libcpp/lex.c
|
@ -2723,6 +2723,19 @@ _cpp_lex_direct (cpp_reader *pfile)
|
||||||
break;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,9 @@ along with this program; see the file COPYING3. If not see
|
||||||
#include "hashtab.h"
|
#include "hashtab.h"
|
||||||
|
|
||||||
/* Do not track column numbers higher than this one. As a result, the
|
/* 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). */
|
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. */
|
/* Do not track column numbers if locations get higher than this. */
|
||||||
const source_location LINE_MAP_MAX_LOCATION_WITH_COLS = 0x60000000;
|
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
|
static source_location linemap_macro_map_loc_to_def_point
|
||||||
(const line_map_macro *, source_location);
|
(const line_map_macro *, source_location);
|
||||||
static source_location linemap_macro_map_loc_unwind_toward_spelling
|
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
|
static source_location linemap_macro_map_loc_to_exp_point
|
||||||
(const line_map_macro *, source_location);
|
(const line_map_macro *, source_location);
|
||||||
static source_location linemap_macro_loc_to_spelling_point
|
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 *lb =
|
||||||
(const struct location_adhoc_data *) l;
|
(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. */
|
/* 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 *) l1;
|
||||||
const struct location_adhoc_data *lb2 =
|
const struct location_adhoc_data *lb2 =
|
||||||
(const struct location_adhoc_data *) l2;
|
(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. */
|
/* 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);
|
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. */
|
/* Combine LOCUS and DATA to a combined adhoc loc. */
|
||||||
|
|
||||||
source_location
|
source_location
|
||||||
get_combined_adhoc_loc (struct line_maps *set,
|
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 lb;
|
||||||
struct location_adhoc_data **slot;
|
struct location_adhoc_data **slot;
|
||||||
|
|
||||||
linemap_assert (data);
|
|
||||||
|
|
||||||
if (IS_ADHOC_LOC (locus))
|
if (IS_ADHOC_LOC (locus))
|
||||||
locus
|
locus
|
||||||
= set->location_adhoc_data_map.data[locus & MAX_SOURCE_LOCATION].locus;
|
= set->location_adhoc_data_map.data[locus & MAX_SOURCE_LOCATION].locus;
|
||||||
if (locus == 0 && data == NULL)
|
if (locus == 0 && data == NULL)
|
||||||
return 0;
|
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.locus = locus;
|
||||||
|
lb.src_range = src_range;
|
||||||
lb.data = data;
|
lb.data = data;
|
||||||
slot = (struct location_adhoc_data **)
|
slot = (struct location_adhoc_data **)
|
||||||
htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
|
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 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. */
|
/* Finalize the location_adhoc_data structure. */
|
||||||
void
|
void
|
||||||
location_adhoc_data_fini (struct line_maps *set)
|
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,
|
linemap_add (struct line_maps *set, enum lc_reason reason,
|
||||||
unsigned int sysp, const char *to_file, linenum_type to_line)
|
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)
|
linemap_assert (!(LINEMAPS_ORDINARY_USED (set)
|
||||||
&& (start_location
|
&& (start_location
|
||||||
|
@ -398,11 +550,18 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
|
||||||
map->to_file = to_file;
|
map->to_file = to_file;
|
||||||
map->to_line = to_line;
|
map->to_line = to_line;
|
||||||
LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1;
|
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_location = start_location;
|
||||||
set->highest_line = start_location;
|
set->highest_line = start_location;
|
||||||
set->max_column_hint = 0;
|
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)
|
if (reason == LC_ENTER)
|
||||||
{
|
{
|
||||||
map->included_from =
|
map->included_from =
|
||||||
|
@ -549,13 +708,14 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
|
||||||
SOURCE_LINE (map, set->highest_line);
|
SOURCE_LINE (map, set->highest_line);
|
||||||
int line_delta = to_line - last_line;
|
int line_delta = to_line - last_line;
|
||||||
bool add_map = false;
|
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
|
if (line_delta < 0
|
||||||
|| (line_delta > 10
|
|| (line_delta > 10
|
||||||
&& line_delta * ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) > 1000)
|
&& line_delta * map->m_column_and_range_bits > 1000)
|
||||||
|| (max_column_hint >= (1U << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map)))
|
|| (max_column_hint >= (1U << effective_column_bits))
|
||||||
|| (max_column_hint <= 80
|
|| (max_column_hint <= 80 && effective_column_bits >= 10)
|
||||||
&& ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) >= 10)
|
|
||||||
|| (highest > LINE_MAP_MAX_LOCATION_WITH_COLS
|
|| (highest > LINE_MAP_MAX_LOCATION_WITH_COLS
|
||||||
&& (set->max_column_hint || highest >= LINE_MAP_MAX_SOURCE_LOCATION)))
|
&& (set->max_column_hint || highest >= LINE_MAP_MAX_SOURCE_LOCATION)))
|
||||||
add_map = true;
|
add_map = true;
|
||||||
|
@ -564,22 +724,27 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
|
||||||
if (add_map)
|
if (add_map)
|
||||||
{
|
{
|
||||||
int column_bits;
|
int column_bits;
|
||||||
|
int range_bits;
|
||||||
if (max_column_hint > LINE_MAP_MAX_COLUMN_NUMBER
|
if (max_column_hint > LINE_MAP_MAX_COLUMN_NUMBER
|
||||||
|| highest > LINE_MAP_MAX_LOCATION_WITH_COLS)
|
|| highest > LINE_MAP_MAX_LOCATION_WITH_COLS)
|
||||||
{
|
{
|
||||||
/* If the column number is ridiculous or we've allocated a huge
|
/* 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;
|
max_column_hint = 0;
|
||||||
column_bits = 0;
|
column_bits = 0;
|
||||||
|
range_bits = 0;
|
||||||
if (highest > LINE_MAP_MAX_SOURCE_LOCATION)
|
if (highest > LINE_MAP_MAX_SOURCE_LOCATION)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
column_bits = 7;
|
column_bits = 7;
|
||||||
|
range_bits = set->default_range_bits;
|
||||||
while (max_column_hint >= (1U << column_bits))
|
while (max_column_hint >= (1U << column_bits))
|
||||||
column_bits++;
|
column_bits++;
|
||||||
max_column_hint = 1U << 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
|
/* Allocate the new line_map. However, if the current map only has a
|
||||||
single line we can sometimes just increase its column_bits instead. */
|
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_IN_SYSTEM_HEADER_P (map),
|
||||||
ORDINARY_MAP_FILE_NAME (map),
|
ORDINARY_MAP_FILE_NAME (map),
|
||||||
to_line)));
|
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)
|
r = (MAP_START_LOCATION (map)
|
||||||
+ ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
|
+ ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
|
||||||
<< column_bits));
|
<< column_bits));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
r = highest - SOURCE_COLUMN (map, highest)
|
r = set->highest_line + (line_delta << map->m_column_and_range_bits);
|
||||||
+ (line_delta << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map));
|
|
||||||
|
|
||||||
/* Locations of ordinary tokens are always lower than locations of
|
/* Locations of ordinary tokens are always lower than locations of
|
||||||
macro tokens. */
|
macro tokens. */
|
||||||
|
@ -610,6 +775,18 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
|
||||||
if (r > set->highest_location)
|
if (r > set->highest_location)
|
||||||
set->highest_location = r;
|
set->highest_location = r;
|
||||||
set->max_column_hint = max_column_hint;
|
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;
|
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 = 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)
|
if (r >= set->highest_location)
|
||||||
set->highest_location = r;
|
set->highest_location = r;
|
||||||
return r;
|
return r;
|
||||||
|
@ -650,16 +828,25 @@ linemap_position_for_column (struct line_maps *set, unsigned int to_column)
|
||||||
column. */
|
column. */
|
||||||
|
|
||||||
source_location
|
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,
|
linenum_type line,
|
||||||
unsigned column)
|
unsigned column)
|
||||||
{
|
{
|
||||||
linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
|
linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
|
||||||
|
|
||||||
return (MAP_START_LOCATION (ord_map)
|
source_location r = MAP_START_LOCATION (ord_map);
|
||||||
+ ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
|
r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
|
||||||
<< ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (ord_map))
|
<< ord_map->m_column_and_range_bits);
|
||||||
+ (column & ((1 << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (ord_map)) - 1)));
|
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
|
/* 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;
|
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. */
|
/* This function does not support virtual locations yet. */
|
||||||
if (linemap_assert_fails
|
if (linemap_assert_fails
|
||||||
(!linemap_location_from_macro_expansion_p (set, loc)))
|
(!linemap_location_from_macro_expansion_p (set, loc)))
|
||||||
|
@ -711,11 +901,11 @@ linemap_position_for_loc_and_offset (struct line_maps *set,
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += column;
|
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;
|
return loc;
|
||||||
|
|
||||||
source_location r =
|
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)
|
if (linemap_assert_fails (r <= set->highest_location)
|
||||||
|| linemap_assert_fails (map == linemap_lookup (set, r)))
|
|| linemap_assert_fails (map == linemap_lookup (set, r)))
|
||||||
return loc;
|
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
|
In other words, this returns the xI location presented in the
|
||||||
comments of line_map_macro above. */
|
comments of line_map_macro above. */
|
||||||
source_location
|
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)
|
source_location location)
|
||||||
{
|
{
|
||||||
unsigned token_no;
|
unsigned token_no;
|
||||||
|
|
||||||
|
if (IS_ADHOC_LOC (location))
|
||||||
|
location = get_location_from_adhoc_loc (set, location);
|
||||||
|
|
||||||
linemap_assert (linemap_macro_expansion_map_p (map)
|
linemap_assert (linemap_macro_expansion_map_p (map)
|
||||||
&& location >= MAP_START_LOCATION (map));
|
&& location >= MAP_START_LOCATION (map));
|
||||||
linemap_assert (location >= RESERVED_LOCATION_COUNT);
|
linemap_assert (location >= RESERVED_LOCATION_COUNT);
|
||||||
|
linemap_assert (!IS_ADHOC_LOC (location));
|
||||||
|
|
||||||
token_no = location - MAP_START_LOCATION (map);
|
token_no = location - MAP_START_LOCATION (map);
|
||||||
linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (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. */
|
/* It's a token resulting from a macro expansion. */
|
||||||
source_location loc =
|
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)
|
if (loc < RESERVED_LOCATION_COUNT)
|
||||||
/* This token might come from a built-in macro. Let's
|
/* This token might come from a built-in macro. Let's
|
||||||
look at where that macro got expanded. */
|
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)
|
const line_map_ordinary **original_map)
|
||||||
{
|
{
|
||||||
struct line_map *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);
|
linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -1198,7 +1388,7 @@ linemap_macro_loc_to_spelling_point (struct line_maps *set,
|
||||||
|
|
||||||
location
|
location
|
||||||
= linemap_macro_map_loc_unwind_toward_spelling
|
= linemap_macro_map_loc_unwind_toward_spelling
|
||||||
(linemap_check_macro (map),
|
(set, linemap_check_macro (map),
|
||||||
location);
|
location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1341,10 +1531,11 @@ linemap_resolve_location (struct line_maps *set,
|
||||||
enum location_resolution_kind lrk,
|
enum location_resolution_kind lrk,
|
||||||
const line_map_ordinary **map)
|
const line_map_ordinary **map)
|
||||||
{
|
{
|
||||||
|
source_location locus = loc;
|
||||||
if (IS_ADHOC_LOC (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
|
/* A reserved location wasn't encoded in a map. Let's return a
|
||||||
NULL map here, just like what linemap_ordinary_map_lookup
|
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;
|
loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
|
||||||
|
|
||||||
resolved_location =
|
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);
|
resolved_map = linemap_lookup (set, resolved_location);
|
||||||
|
|
||||||
if (!linemap_macro_expansion_map_p (resolved_map))
|
if (!linemap_macro_expansion_map_p (resolved_map))
|
||||||
|
@ -1478,9 +1669,9 @@ linemap_expand_location (struct line_maps *set,
|
||||||
memset (&xloc, 0, sizeof (xloc));
|
memset (&xloc, 0, sizeof (xloc));
|
||||||
if (IS_ADHOC_LOC (loc))
|
if (IS_ADHOC_LOC (loc))
|
||||||
{
|
{
|
||||||
loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
|
|
||||||
xloc.data
|
xloc.data
|
||||||
= set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].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)
|
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. */
|
/* 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_loc (loc),
|
||||||
m_num_ranges (0),
|
m_num_ranges (0),
|
||||||
m_have_expanded_location (false)
|
m_have_expanded_location (false)
|
||||||
{
|
{
|
||||||
/* Set up the 0th range: */
|
/* Set up the 0th range, extracting any range from LOC. */
|
||||||
add_range (loc, loc, true);
|
source_range src_range = get_range_from_loc (set, loc);
|
||||||
|
add_range (src_range, true);
|
||||||
m_ranges[0].m_caret = lazily_expand_location ();
|
m_ranges[0].m_caret = lazily_expand_location ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,142 +30,154 @@ RESERVED LOCATIONS
|
||||||
source_location interval: 0 <= loc < 2
|
source_location interval: 0 <= loc < 2
|
||||||
|
|
||||||
ORDINARY MAP: 0
|
ORDINARY MAP: 0
|
||||||
source_location interval: 2 <= loc < 3
|
source_location interval: 32 <= loc < 64
|
||||||
file: test.c
|
file: test.c
|
||||||
starting at line: 1
|
starting at line: 1
|
||||||
column bits: 7
|
column bits: 12
|
||||||
test.c: 1|loc: 2|#include "test.h"
|
range bits: 5
|
||||||
|00000001111111111
|
test.c: 1|loc: 32|#include "test.h"
|
||||||
|34567890123456789
|
|69269258258148147
|
||||||
|
|46802468024680246
|
||||||
|
|
||||||
ORDINARY MAP: 1
|
ORDINARY MAP: 1
|
||||||
source_location interval: 3 <= loc < 4
|
source_location interval: 64 <= loc < 96
|
||||||
file: <built-in>
|
file: <built-in>
|
||||||
starting at line: 0
|
starting at line: 0
|
||||||
column bits: 0
|
column bits: 0
|
||||||
|
range bits: 0
|
||||||
|
|
||||||
ORDINARY MAP: 2
|
ORDINARY MAP: 2
|
||||||
source_location interval: 4 <= loc < 5
|
source_location interval: 96 <= loc < 128
|
||||||
file: <command-line>
|
file: <command-line>
|
||||||
starting at line: 0
|
starting at line: 0
|
||||||
column bits: 0
|
column bits: 0
|
||||||
|
range bits: 0
|
||||||
|
|
||||||
ORDINARY MAP: 3
|
ORDINARY MAP: 3
|
||||||
source_location interval: 5 <= loc < 5005
|
source_location interval: 128 <= loc < 160128
|
||||||
file: /usr/include/stdc-predef.h
|
file: /usr/include/stdc-predef.h
|
||||||
starting at line: 1
|
starting at line: 1
|
||||||
column bits: 7
|
column bits: 12
|
||||||
|
range bits: 5
|
||||||
(contents of /usr/include/stdc-predef.h snipped for brevity)
|
(contents of /usr/include/stdc-predef.h snipped for brevity)
|
||||||
|
|
||||||
ORDINARY MAP: 4
|
ORDINARY MAP: 4
|
||||||
source_location interval: 5005 <= loc < 5006
|
source_location interval: 160128 <= loc < 160160
|
||||||
file: <command-line>
|
file: <command-line>
|
||||||
starting at line: 1
|
starting at line: 32
|
||||||
column bits: 7
|
column bits: 12
|
||||||
|
range bits: 5
|
||||||
|
|
||||||
ORDINARY MAP: 5
|
ORDINARY MAP: 5
|
||||||
source_location interval: 5006 <= loc < 5134
|
source_location interval: 160160 <= loc < 164256
|
||||||
file: test.c
|
file: test.c
|
||||||
starting at line: 1
|
starting at line: 1
|
||||||
column bits: 7
|
column bits: 12
|
||||||
test.c: 1|loc: 5006|#include "test.h"
|
range bits: 5
|
||||||
|55555555555555555
|
test.c: 1|loc:160160|#include "test.h"
|
||||||
|00000000000000000
|
|00000000000000000
|
||||||
|00011111111112222
|
|12223334445556667
|
||||||
|78901234567890123
|
|92582581481470470
|
||||||
|
|24680246802468024
|
||||||
|
|
||||||
ORDINARY MAP: 6
|
ORDINARY MAP: 6
|
||||||
source_location interval: 5134 <= loc < 5416
|
source_location interval: 164256 <= loc < 173280
|
||||||
file: test.h
|
file: test.h
|
||||||
starting at line: 1
|
starting at line: 1
|
||||||
column bits: 7
|
column bits: 12
|
||||||
test.h: 1|loc: 5134|extern int foo ();
|
range bits: 5
|
||||||
|555555555555555555
|
test.h: 1|loc:164256|extern int foo ();
|
||||||
|111111111111111111
|
|444444444444444444
|
||||||
|333334444444444555
|
|233344455566677788
|
||||||
|567890123456789012
|
|825814814704703603
|
||||||
test.h: 2|loc: 5262|
|
|802468024680246802
|
||||||
|
test.h: 2|loc:168352|
|
||||||
|
|
|
|
||||||
|
|
|
|
||||||
|
|
|
|
||||||
|
|
|
|
||||||
test.h: 3|loc: 5390|#define PLUS(A, B) A + B
|
test.h: 3|loc:172448|#define PLUS(A, B) A + B
|
||||||
|555555555555555555555555
|
|222222222222222223333333
|
||||||
|333333333444444444444444
|
|455566677788889990001112
|
||||||
|999999999000000000011111
|
|814704703603692692582581
|
||||||
|123456789012345678901234
|
|024680246802468024680246
|
||||||
|
|
||||||
ORDINARY MAP: 7
|
ORDINARY MAP: 7
|
||||||
source_location interval: 5416 <= loc < 6314
|
source_location interval: 173280 <= loc < 202016
|
||||||
file: test.c
|
file: test.c
|
||||||
starting at line: 2
|
starting at line: 2
|
||||||
column bits: 7
|
column bits: 12
|
||||||
test.c: 2|loc: 5416|
|
range bits: 5
|
||||||
|
test.c: 2|loc:173280|
|
||||||
|
|
|
|
||||||
|
|
|
|
||||||
|
|
|
|
||||||
|
|
|
|
||||||
test.c: 3|loc: 5544|int
|
test.c: 3|loc:177376|int
|
||||||
|555
|
|777
|
||||||
|555
|
|
||||||
|444
|
|444
|
||||||
|567
|
|047
|
||||||
test.c: 4|loc: 5672|main (int argc, char **argv)
|
|802
|
||||||
|5555555555555555555555555555
|
test.c: 4|loc:181472|main (int argc, char **argv)
|
||||||
|6666666666666666666666666667
|
|1111111111111111222222222222
|
||||||
|7777777888888888899999999990
|
|5556666777888999000111222333
|
||||||
|3456789012345678901234567890
|
|0360369269258258148147047036
|
||||||
test.c: 5|loc: 5800|{
|
|4680246802468024680246802468
|
||||||
|
test.c: 5|loc:185568|{
|
||||||
|5
|
|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
|
|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
|
|1
|
||||||
|3
|
|9
|
||||||
|
|8
|
||||||
|
|4
|
||||||
|
|
||||||
UNALLOCATED LOCATIONS
|
UNALLOCATED LOCATIONS
|
||||||
source_location interval: 6314 <= loc < 2147483633
|
source_location interval: 202016 <= loc < 2147483633
|
||||||
|
|
||||||
MACRO 1: PLUS (7 tokens)
|
MACRO 1: PLUS (7 tokens)
|
||||||
source_location interval: 2147483633 <= loc < 2147483640
|
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);
|
int b = PLUS (3,4);
|
||||||
^
|
^~~~
|
||||||
|
|
||||||
map->start_location: 2147483633
|
map->start_location: 2147483633
|
||||||
macro_locations:
|
macro_locations:
|
||||||
0: 6073, 5410
|
0: 194304, 173088
|
||||||
test.c:7:17: note: token 0 has x-location == 6073
|
test.c:7:17: note: token 0 has x-location == 194304
|
||||||
int b = PLUS (3,4);
|
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:
|
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
|
#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);
|
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
|
3: 0, 2947526575
|
||||||
cc1: note: token 3 has x-location == 0
|
cc1: note: token 3 has x-location == 0
|
||||||
cc1: note: token 3 has y-location == 2947526575
|
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)
|
MACRO 0: PLUS (7 tokens)
|
||||||
source_location interval: 2147483640 <= loc < 2147483647
|
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);
|
int a = PLUS (1,2);
|
||||||
^
|
^~~~
|
||||||
|
|
||||||
map->start_location: 2147483640
|
map->start_location: 2147483640
|
||||||
macro_locations:
|
macro_locations:
|
||||||
0: 5945, 5410
|
0: 190208, 173088
|
||||||
test.c:6:17: note: token 0 has x-location == 5945
|
test.c:6:17: note: token 0 has x-location == 190208
|
||||||
int a = PLUS (1,2);
|
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:
|
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
|
#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);
|
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
|
3: 0, 2947526575
|
||||||
cc1: note: token 3 has x-location == 0
|
cc1: note: token 3 has x-location == 0
|
||||||
cc1: note: token 3 has y-location == 2947526575
|
cc1: note: token 3 has y-location == 2947526575
|
||||||
|
|
Loading…
Reference in New Issue