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
46 changed files with 2107 additions and 242 deletions
|
@ -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>
|
||||
|
||||
PR tree-optimization/67682
|
||||
|
|
|
@ -1263,6 +1263,7 @@ OBJS = \
|
|||
fold-const-call.o \
|
||||
function.o \
|
||||
fwprop.o \
|
||||
gcc-rich-location.o \
|
||||
gcse.o \
|
||||
gcse-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>
|
||||
|
||||
* exp_attr.adb: Minor reformatting.
|
||||
|
|
|
@ -9650,7 +9650,8 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus, bool clear_column)
|
|||
line = 1;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
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 nowarning = TREE_NO_WARNING (expr);
|
||||
bool unused_p;
|
||||
source_range old_range;
|
||||
|
||||
/* This function is not relevant to C++ because C++ folds while
|
||||
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)
|
||||
return expr;
|
||||
|
||||
if (IS_EXPR_CODE_CLASS (kind))
|
||||
old_range = EXPR_LOCATION_RANGE (expr);
|
||||
|
||||
/* Operands of variable-length expressions (function calls) have
|
||||
already been folded, as have __builtin_* function calls, and such
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -245,6 +245,8 @@ c_common_init_options (unsigned int decoded_options_count,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
global_dc->colorize_source_p = true;
|
||||
}
|
||||
|
||||
/* 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>
|
||||
|
||||
PR c/68320
|
||||
|
|
|
@ -5278,7 +5278,7 @@ warn_defaults_to (location_t location, int opt, const char *gmsgid, ...)
|
|||
{
|
||||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
rich_location richloc (location);
|
||||
rich_location richloc (line_table, location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
|
||||
|
|
|
@ -37,7 +37,7 @@ pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...)
|
|||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
bool warned = false;
|
||||
rich_location richloc (location);
|
||||
rich_location richloc (line_table, location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
/* 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;
|
||||
va_list ap;
|
||||
rich_location richloc (location);
|
||||
rich_location richloc (line_table, location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
/* 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 "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. */
|
||||
|
||||
|
@ -164,6 +181,16 @@ struct GTY (()) c_token {
|
|||
location_t location;
|
||||
/* The value associated with this token, if any. */
|
||||
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
|
||||
|
@ -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,
|
||||
code, exp_location, rhs.value,
|
||||
rhs.original_type);
|
||||
set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
|
||||
if (code == NOP_EXPR)
|
||||
ret.original_code = MODIFY_EXPR;
|
||||
else
|
||||
|
@ -6147,7 +6175,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
|
|||
tree omp_atomic_lhs)
|
||||
{
|
||||
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 ());
|
||||
|
||||
|
@ -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))
|
||||
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 = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
|
||||
c_parser_consume_token (parser);
|
||||
|
@ -6230,6 +6262,7 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
|
|||
? t1
|
||||
: NULL);
|
||||
}
|
||||
set_c_expr_source_range (&ret, start, exp2.get_finish ());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -6382,6 +6415,7 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after,
|
|||
{
|
||||
enum c_parser_prec oprec;
|
||||
enum tree_code ocode;
|
||||
source_range src_range;
|
||||
if (parser->error)
|
||||
goto out;
|
||||
switch (c_parser_peek_token (parser)->type)
|
||||
|
@ -6470,6 +6504,7 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after,
|
|||
switch (ocode)
|
||||
{
|
||||
case TRUTH_ANDIF_EXPR:
|
||||
src_range = stack[sp].expr.src_range;
|
||||
stack[sp].expr
|
||||
= convert_lvalue_to_rvalue (stack[sp].loc,
|
||||
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));
|
||||
c_inhibit_evaluation_warnings += (stack[sp].expr.value
|
||||
== truthvalue_false_node);
|
||||
set_c_expr_source_range (&stack[sp].expr, src_range);
|
||||
break;
|
||||
case TRUTH_ORIF_EXPR:
|
||||
src_range = stack[sp].expr.src_range;
|
||||
stack[sp].expr
|
||||
= convert_lvalue_to_rvalue (stack[sp].loc,
|
||||
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));
|
||||
c_inhibit_evaluation_warnings += (stack[sp].expr.value
|
||||
== truthvalue_true_node);
|
||||
set_c_expr_source_range (&stack[sp].expr, src_range);
|
||||
break;
|
||||
default:
|
||||
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);
|
||||
}
|
||||
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_type = NULL;
|
||||
return ret;
|
||||
|
@ -6603,6 +6643,7 @@ c_parser_unary_expression (c_parser *parser)
|
|||
struct c_expr ret, op;
|
||||
location_t op_loc = c_parser_peek_token (parser)->location;
|
||||
location_t exp_loc;
|
||||
location_t finish;
|
||||
ret.original_code = ERROR_MARK;
|
||||
ret.original_type = NULL;
|
||||
switch (c_parser_peek_token (parser)->type)
|
||||
|
@ -6642,8 +6683,10 @@ c_parser_unary_expression (c_parser *parser)
|
|||
c_parser_consume_token (parser);
|
||||
exp_loc = c_parser_peek_token (parser)->location;
|
||||
op = c_parser_cast_expression (parser, NULL);
|
||||
finish = op.get_finish ();
|
||||
op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
|
||||
ret.value = build_indirect_ref (op_loc, op.value, RO_UNARY_STAR);
|
||||
set_c_expr_source_range (&ret, op_loc, finish);
|
||||
return ret;
|
||||
case CPP_PLUS:
|
||||
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)
|
||||
{
|
||||
struct c_expr expr;
|
||||
struct c_expr result;
|
||||
location_t expr_loc;
|
||||
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_inhibit_evaluation_warnings++;
|
||||
in_sizeof++;
|
||||
|
@ -6746,6 +6796,7 @@ c_parser_sizeof_expression (c_parser *parser)
|
|||
expr_loc = c_parser_peek_token (parser)->location;
|
||||
type_name = c_parser_type_name (parser);
|
||||
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
|
||||
finish = parser->tokens_buf[0].location;
|
||||
if (type_name == NULL)
|
||||
{
|
||||
struct c_expr ret;
|
||||
|
@ -6761,17 +6812,19 @@ c_parser_sizeof_expression (c_parser *parser)
|
|||
expr = c_parser_postfix_expression_after_paren_type (parser,
|
||||
type_name,
|
||||
expr_loc);
|
||||
finish = expr.get_finish ();
|
||||
goto sizeof_expr;
|
||||
}
|
||||
/* sizeof ( type-name ). */
|
||||
c_inhibit_evaluation_warnings--;
|
||||
in_sizeof--;
|
||||
return c_expr_sizeof_type (expr_loc, type_name);
|
||||
result = c_expr_sizeof_type (expr_loc, type_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
expr_loc = c_parser_peek_token (parser)->location;
|
||||
expr = c_parser_unary_expression (parser);
|
||||
finish = expr.get_finish ();
|
||||
sizeof_expr:
|
||||
c_inhibit_evaluation_warnings--;
|
||||
in_sizeof--;
|
||||
|
@ -6779,8 +6832,11 @@ c_parser_sizeof_expression (c_parser *parser)
|
|||
if (TREE_CODE (expr.value) == COMPONENT_REF
|
||||
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
|
||||
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. */
|
||||
|
@ -7200,12 +7256,14 @@ c_parser_postfix_expression (c_parser *parser)
|
|||
struct c_expr expr, e1;
|
||||
struct c_type_name *t1, *t2;
|
||||
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_type = NULL;
|
||||
switch (c_parser_peek_token (parser)->type)
|
||||
{
|
||||
case CPP_NUMBER:
|
||||
expr.value = c_parser_peek_token (parser)->value;
|
||||
set_c_expr_source_range (&expr, tok_range);
|
||||
loc = c_parser_peek_token (parser)->location;
|
||||
c_parser_consume_token (parser);
|
||||
if (TREE_CODE (expr.value) == FIXED_CST
|
||||
|
@ -7220,6 +7278,7 @@ c_parser_postfix_expression (c_parser *parser)
|
|||
case CPP_CHAR32:
|
||||
case CPP_WCHAR:
|
||||
expr.value = c_parser_peek_token (parser)->value;
|
||||
set_c_expr_source_range (&expr, tok_range);
|
||||
c_parser_consume_token (parser);
|
||||
break;
|
||||
case CPP_STRING:
|
||||
|
@ -7228,6 +7287,7 @@ c_parser_postfix_expression (c_parser *parser)
|
|||
case CPP_WSTRING:
|
||||
case CPP_UTF8STRING:
|
||||
expr.value = c_parser_peek_token (parser)->value;
|
||||
set_c_expr_source_range (&expr, tok_range);
|
||||
expr.original_code = STRING_CST;
|
||||
c_parser_consume_token (parser);
|
||||
break;
|
||||
|
@ -7235,6 +7295,7 @@ c_parser_postfix_expression (c_parser *parser)
|
|||
gcc_assert (c_dialect_objc ());
|
||||
expr.value
|
||||
= objc_build_string_object (c_parser_peek_token (parser)->value);
|
||||
set_c_expr_source_range (&expr, tok_range);
|
||||
c_parser_consume_token (parser);
|
||||
break;
|
||||
case CPP_NAME:
|
||||
|
@ -7248,6 +7309,7 @@ c_parser_postfix_expression (c_parser *parser)
|
|||
(c_parser_peek_token (parser)->type
|
||||
== CPP_OPEN_PAREN),
|
||||
&expr.original_type);
|
||||
set_c_expr_source_range (&expr, tok_range);
|
||||
break;
|
||||
}
|
||||
case C_ID_CLASSNAME:
|
||||
|
@ -7336,6 +7398,7 @@ c_parser_postfix_expression (c_parser *parser)
|
|||
else
|
||||
{
|
||||
/* A parenthesized expression. */
|
||||
location_t loc_open_paren = c_parser_peek_token (parser)->location;
|
||||
c_parser_consume_token (parser);
|
||||
expr = c_parser_expression (parser);
|
||||
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)
|
||||
expr.original_code = ERROR_MARK;
|
||||
/* 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,
|
||||
"expected %<)%>");
|
||||
}
|
||||
|
@ -7933,6 +7998,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
|||
vec<tree, va_gc> *exprlist;
|
||||
vec<tree, va_gc> *origtypes = NULL;
|
||||
vec<location_t> arg_loc = vNULL;
|
||||
location_t start;
|
||||
location_t finish;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
@ -7969,7 +8036,10 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
|||
{
|
||||
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
|
||||
"expected %<]%>");
|
||||
start = expr.get_start ();
|
||||
finish = parser->tokens_buf[0].location;
|
||||
expr.value = build_array_ref (op_loc, expr.value, idx);
|
||||
set_c_expr_source_range (&expr, start, finish);
|
||||
}
|
||||
}
|
||||
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; "
|
||||
"this could be due to transposed parameters");
|
||||
|
||||
start = expr.get_start ();
|
||||
finish = parser->tokens_buf[0].get_finish ();
|
||||
expr.value
|
||||
= c_build_function_call_vec (expr_loc, arg_loc, expr.value,
|
||||
exprlist, origtypes);
|
||||
set_c_expr_source_range (&expr, start, finish);
|
||||
|
||||
expr.original_code = ERROR_MARK;
|
||||
if (TREE_CODE (expr.value) == INTEGER_CST
|
||||
&& TREE_CODE (orig_expr.value) == FUNCTION_DECL
|
||||
|
@ -8043,8 +8117,11 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
|||
expr.original_type = NULL;
|
||||
return expr;
|
||||
}
|
||||
start = expr.get_start ();
|
||||
finish = c_parser_peek_token (parser)->get_finish ();
|
||||
c_parser_consume_token (parser);
|
||||
expr.value = build_component_ref (op_loc, expr.value, ident);
|
||||
set_c_expr_source_range (&expr, start, finish);
|
||||
expr.original_code = ERROR_MARK;
|
||||
if (TREE_CODE (expr.value) != COMPONENT_REF)
|
||||
expr.original_type = NULL;
|
||||
|
@ -8072,12 +8149,15 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
|||
expr.original_type = NULL;
|
||||
return expr;
|
||||
}
|
||||
start = expr.get_start ();
|
||||
finish = c_parser_peek_token (parser)->get_finish ();
|
||||
c_parser_consume_token (parser);
|
||||
expr.value = build_component_ref (op_loc,
|
||||
build_indirect_ref (op_loc,
|
||||
expr.value,
|
||||
RO_ARROW),
|
||||
ident);
|
||||
set_c_expr_source_range (&expr, start, finish);
|
||||
expr.original_code = ERROR_MARK;
|
||||
if (TREE_CODE (expr.value) != COMPONENT_REF)
|
||||
expr.original_type = NULL;
|
||||
|
@ -8093,6 +8173,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
|||
break;
|
||||
case CPP_PLUS_PLUS:
|
||||
/* Postincrement. */
|
||||
start = expr.get_start ();
|
||||
finish = c_parser_peek_token (parser)->get_finish ();
|
||||
c_parser_consume_token (parser);
|
||||
/* If the expressions have array notations, we expand them. */
|
||||
if (flag_cilkplus
|
||||
|
@ -8104,11 +8186,14 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
|||
expr.value = build_unary_op (op_loc,
|
||||
POSTINCREMENT_EXPR, expr.value, 0);
|
||||
}
|
||||
set_c_expr_source_range (&expr, start, finish);
|
||||
expr.original_code = ERROR_MARK;
|
||||
expr.original_type = NULL;
|
||||
break;
|
||||
case CPP_MINUS_MINUS:
|
||||
/* Postdecrement. */
|
||||
start = expr.get_start ();
|
||||
finish = c_parser_peek_token (parser)->get_finish ();
|
||||
c_parser_consume_token (parser);
|
||||
/* If the expressions have array notations, we expand them. */
|
||||
if (flag_cilkplus
|
||||
|
@ -8120,6 +8205,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
|||
expr.value = build_unary_op (op_loc,
|
||||
POSTDECREMENT_EXPR, expr.value, 0);
|
||||
}
|
||||
set_c_expr_source_range (&expr, start, finish);
|
||||
expr.original_code = ERROR_MARK;
|
||||
expr.original_type = NULL;
|
||||
break;
|
||||
|
|
|
@ -132,6 +132,17 @@ struct c_expr
|
|||
The type of an enum constant is a plain integer type, but this
|
||||
field will be the enum 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
|
||||
|
@ -708,4 +719,12 @@ extern void pedwarn_c90 (location_t, int opt, const char *, ...)
|
|||
extern bool pedwarn_c99 (location_t, int opt, const char *, ...)
|
||||
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 */
|
||||
|
|
|
@ -3460,6 +3460,12 @@ parser_build_unary_op (location_t loc, enum tree_code code, struct c_expr arg)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -3497,6 +3503,10 @@ parser_build_binary_op (location_t location, enum tree_code code,
|
|||
if (location != UNKNOWN_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
|
||||
to misinterpret. */
|
||||
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>
|
||||
|
||||
* 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;
|
||||
va_list ap;
|
||||
bool ret;
|
||||
rich_location richloc (location);
|
||||
rich_location richloc (line_table, location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
|
||||
|
|
|
@ -867,7 +867,7 @@ diagnostic_append_note (diagnostic_context *context,
|
|||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
const char *saved_prefix;
|
||||
rich_location richloc (location);
|
||||
rich_location richloc (line_table, location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
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;
|
||||
va_list ap;
|
||||
bool ret;
|
||||
rich_location richloc (location);
|
||||
rich_location richloc (line_table, location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
if (kind == DK_PERMERROR)
|
||||
|
@ -952,7 +952,7 @@ inform (location_t location, const char *gmsgid, ...)
|
|||
{
|
||||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
rich_location richloc (location);
|
||||
rich_location richloc (line_table, location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
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;
|
||||
va_list ap;
|
||||
rich_location richloc (location);
|
||||
rich_location richloc (line_table, location);
|
||||
|
||||
va_start (ap, plural_gmsgid);
|
||||
diagnostic_set_info_translated (&diagnostic,
|
||||
|
@ -1000,7 +1000,7 @@ warning (int opt, const char *gmsgid, ...)
|
|||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
bool ret;
|
||||
rich_location richloc (input_location);
|
||||
rich_location richloc (line_table, input_location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
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;
|
||||
va_list ap;
|
||||
bool ret;
|
||||
rich_location richloc (location);
|
||||
rich_location richloc (line_table, location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
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;
|
||||
va_list ap;
|
||||
bool ret;
|
||||
rich_location richloc (location);
|
||||
rich_location richloc (line_table, location);
|
||||
|
||||
va_start (ap, plural_gmsgid);
|
||||
diagnostic_set_info_translated (&diagnostic,
|
||||
|
@ -1091,7 +1091,7 @@ pedwarn (location_t location, int opt, const char *gmsgid, ...)
|
|||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
bool ret;
|
||||
rich_location richloc (location);
|
||||
rich_location richloc (line_table, location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN);
|
||||
|
@ -1114,7 +1114,7 @@ permerror (location_t location, const char *gmsgid, ...)
|
|||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
bool ret;
|
||||
rich_location richloc (location);
|
||||
rich_location richloc (line_table, location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
|
||||
|
@ -1150,7 +1150,7 @@ error (const char *gmsgid, ...)
|
|||
{
|
||||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
rich_location richloc (input_location);
|
||||
rich_location richloc (line_table, input_location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
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;
|
||||
va_list ap;
|
||||
rich_location richloc (location);
|
||||
rich_location richloc (line_table, location);
|
||||
|
||||
va_start (ap, plural_gmsgid);
|
||||
diagnostic_set_info_translated (&diagnostic,
|
||||
|
@ -1182,7 +1182,7 @@ error_at (location_t loc, const char *gmsgid, ...)
|
|||
{
|
||||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
rich_location richloc (loc);
|
||||
rich_location richloc (line_table, loc);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ERROR);
|
||||
|
@ -1213,7 +1213,7 @@ sorry (const char *gmsgid, ...)
|
|||
{
|
||||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
rich_location richloc (input_location);
|
||||
rich_location richloc (line_table, input_location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_SORRY);
|
||||
|
@ -1237,7 +1237,7 @@ fatal_error (location_t loc, const char *gmsgid, ...)
|
|||
{
|
||||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
rich_location richloc (loc);
|
||||
rich_location richloc (line_table, loc);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_FATAL);
|
||||
|
@ -1256,7 +1256,7 @@ internal_error (const char *gmsgid, ...)
|
|||
{
|
||||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
rich_location richloc (input_location);
|
||||
rich_location richloc (line_table, input_location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ICE);
|
||||
|
@ -1274,7 +1274,7 @@ internal_error_no_backtrace (const char *gmsgid, ...)
|
|||
{
|
||||
diagnostic_info diagnostic;
|
||||
va_list ap;
|
||||
rich_location richloc (input_location);
|
||||
rich_location richloc (line_table, input_location);
|
||||
|
||||
va_start (ap, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ICE_NOBT);
|
||||
|
@ -1351,7 +1351,7 @@ real_abort (void)
|
|||
DEBUG_FUNCTION void
|
||||
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);
|
||||
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>
|
||||
|
||||
PR fortran/68318
|
||||
|
|
|
@ -773,7 +773,7 @@ gfc_warning (int opt, const char *gmsgid, va_list ap)
|
|||
va_copy (argp, ap);
|
||||
|
||||
diagnostic_info diagnostic;
|
||||
rich_location rich_loc (UNKNOWN_LOCATION);
|
||||
rich_location rich_loc (line_table, UNKNOWN_LOCATION);
|
||||
bool fatal_errors = global_dc->fatal_errors;
|
||||
pretty_printer *pp = global_dc->printer;
|
||||
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;
|
||||
diagnostic_info diagnostic;
|
||||
rich_location rich_loc (loc);
|
||||
rich_location rich_loc (line_table, loc);
|
||||
bool ret;
|
||||
|
||||
va_start (argp, gmsgid);
|
||||
|
@ -1138,7 +1138,7 @@ gfc_warning_now (int opt, const char *gmsgid, ...)
|
|||
{
|
||||
va_list argp;
|
||||
diagnostic_info diagnostic;
|
||||
rich_location rich_loc (UNKNOWN_LOCATION);
|
||||
rich_location rich_loc (line_table, UNKNOWN_LOCATION);
|
||||
bool ret;
|
||||
|
||||
va_start (argp, gmsgid);
|
||||
|
@ -1158,7 +1158,7 @@ gfc_error_now (const char *gmsgid, ...)
|
|||
{
|
||||
va_list argp;
|
||||
diagnostic_info diagnostic;
|
||||
rich_location rich_loc (UNKNOWN_LOCATION);
|
||||
rich_location rich_loc (line_table, UNKNOWN_LOCATION);
|
||||
|
||||
error_buffer.flag = true;
|
||||
|
||||
|
@ -1176,7 +1176,7 @@ gfc_fatal_error (const char *gmsgid, ...)
|
|||
{
|
||||
va_list argp;
|
||||
diagnostic_info diagnostic;
|
||||
rich_location rich_loc (UNKNOWN_LOCATION);
|
||||
rich_location rich_loc (line_table, UNKNOWN_LOCATION);
|
||||
|
||||
va_start (argp, gmsgid);
|
||||
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;
|
||||
rich_location richloc (UNKNOWN_LOCATION);
|
||||
rich_location richloc (line_table, UNKNOWN_LOCATION);
|
||||
bool fatal_errors = global_dc->fatal_errors;
|
||||
pretty_printer *pp = global_dc->printer;
|
||||
output_buffer *tmp_buffer = pp->buffer;
|
||||
|
@ -1288,7 +1288,7 @@ gfc_internal_error (const char *gmsgid, ...)
|
|||
{
|
||||
va_list argp;
|
||||
diagnostic_info diagnostic;
|
||||
rich_location rich_loc (UNKNOWN_LOCATION);
|
||||
rich_location rich_loc (line_table, UNKNOWN_LOCATION);
|
||||
|
||||
va_start (argp, gmsgid);
|
||||
diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ICE);
|
||||
|
|
86
gcc/gcc-rich-location.c
Normal file
86
gcc/gcc-rich-location.c
Normal file
|
@ -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);
|
||||
}
|
47
gcc/gcc-rich-location.h
Normal file
47
gcc/gcc-rich-location.h
Normal file
|
@ -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
|
||||
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_start (ap, msg);
|
||||
error_cb (NULL, CPP_DL_FATAL, 0, &richloc, msg, &ap);
|
||||
|
@ -132,7 +132,7 @@ __attribute__((format (printf, 2, 3)))
|
|||
#endif
|
||||
fatal_at (source_location loc, const char *msg, ...)
|
||||
{
|
||||
rich_location richloc (loc);
|
||||
rich_location richloc (line_table, loc);
|
||||
va_list ap;
|
||||
va_start (ap, msg);
|
||||
error_cb (NULL, CPP_DL_FATAL, 0, &richloc, msg, &ap);
|
||||
|
@ -145,7 +145,7 @@ __attribute__((format (printf, 2, 3)))
|
|||
#endif
|
||||
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_start (ap, msg);
|
||||
error_cb (NULL, CPP_DL_WARNING, 0, &richloc, msg, &ap);
|
||||
|
@ -158,7 +158,7 @@ __attribute__((format (printf, 2, 3)))
|
|||
#endif
|
||||
warning_at (source_location loc, const char *msg, ...)
|
||||
{
|
||||
rich_location richloc (loc);
|
||||
rich_location richloc (line_table, loc);
|
||||
va_list ap;
|
||||
va_start (ap, msg);
|
||||
error_cb (NULL, CPP_DL_WARNING, 0, &richloc, msg, &ap);
|
||||
|
|
|
@ -1740,11 +1740,7 @@ gimple_block (const gimple *g)
|
|||
static inline void
|
||||
gimple_set_block (gimple *g, tree block)
|
||||
{
|
||||
if (block)
|
||||
g->location =
|
||||
COMBINE_LOCATION_DATA (line_table, g->location, block);
|
||||
else
|
||||
g->location = LOCATION_LOCUS (g->location);
|
||||
g->location = set_block (g->location, block);
|
||||
}
|
||||
|
||||
|
||||
|
|
28
gcc/input.c
28
gcc/input.c
|
@ -887,6 +887,10 @@ dump_line_table_statistics (void)
|
|||
STAT_LABEL (s.adhoc_table_size));
|
||||
fprintf (stderr, "Ad-hoc table entries used: %5ld\n",
|
||||
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");
|
||||
}
|
||||
|
@ -917,13 +921,14 @@ write_digit (FILE *stream, int digit)
|
|||
|
||||
static void
|
||||
write_digit_row (FILE *stream, int indent,
|
||||
const line_map_ordinary *map,
|
||||
source_location loc, int max_col, int divisor)
|
||||
{
|
||||
fprintf (stream, "%*c", indent, ' ');
|
||||
fprintf (stream, "|");
|
||||
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);
|
||||
}
|
||||
fprintf (stream, "\n");
|
||||
|
@ -977,14 +982,20 @@ dump_location_info (FILE *stream)
|
|||
fprintf (stream, " file: %s\n", ORDINARY_MAP_FILE_NAME (map));
|
||||
fprintf (stream, " starting at line: %i\n",
|
||||
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",
|
||||
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. */
|
||||
for (source_location loc = MAP_START_LOCATION (map);
|
||||
loc < end_location;
|
||||
loc++)
|
||||
loc += (1 << map->m_range_bits) )
|
||||
{
|
||||
gcc_assert (pure_location_p (line_table, loc) );
|
||||
|
||||
expanded_location exploc
|
||||
= linemap_expand_location (line_table, map, loc);
|
||||
|
||||
|
@ -1008,8 +1019,7 @@ dump_location_info (FILE *stream)
|
|||
Render the locations *within* the line, by underlining
|
||||
it, showing the source_location numeric values
|
||||
at each column. */
|
||||
int max_col
|
||||
= (1 << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map)) - 1;
|
||||
int max_col = (1 << map->m_column_and_range_bits) - 1;
|
||||
if (max_col > line_size)
|
||||
max_col = line_size + 1;
|
||||
|
||||
|
@ -1017,17 +1027,17 @@ dump_location_info (FILE *stream)
|
|||
|
||||
/* Thousands. */
|
||||
if (end_location > 999)
|
||||
write_digit_row (stream, indent, loc, max_col, 1000);
|
||||
write_digit_row (stream, indent, map, loc, max_col, 1000);
|
||||
|
||||
/* Hundreds. */
|
||||
if (end_location > 99)
|
||||
write_digit_row (stream, indent, loc, max_col, 100);
|
||||
write_digit_row (stream, indent, map, loc, max_col, 100);
|
||||
|
||||
/* Tens. */
|
||||
write_digit_row (stream, indent, loc, max_col, 10);
|
||||
write_digit_row (stream, indent, map, loc, max_col, 10);
|
||||
|
||||
/* Units. */
|
||||
write_digit_row (stream, indent, loc, max_col, 1);
|
||||
write_digit_row (stream, indent, map, loc, max_col, 1);
|
||||
}
|
||||
}
|
||||
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));
|
||||
indent_to (file, indent+4);
|
||||
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, ">");
|
||||
|
|
|
@ -67,7 +67,7 @@ diagnostic_for_asm (const rtx_insn *insn, const char *msg, va_list *args_ptr,
|
|||
diagnostic_t kind)
|
||||
{
|
||||
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,
|
||||
&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>
|
||||
|
||||
PR tree-optimization/67682
|
||||
|
|
120
gcc/testsuite/gcc.dg/diagnostic-token-ranges.c
Normal file
120
gcc/testsuite/gcc.dg/diagnostic-token-ranges.c
Normal file
|
@ -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 "" } */
|
23
gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c
Normal file
23
gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c
Normal file
|
@ -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;
|
||||
}
|
422
gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c
Normal file
422
gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c
Normal file
|
@ -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 "" } */
|
||||
|
||||
}
|
65
gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-trees-1.c
Normal file
65
gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-trees-1.c
Normal file
|
@ -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 "" } */
|
||||
}
|
174
gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c
Normal file
174
gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c
Normal file
|
@ -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. */
|
||||
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);
|
||||
|
||||
return loc;
|
||||
|
@ -163,7 +164,7 @@ test_show_locus (function *fun)
|
|||
if (0 == strcmp (fnname, "test_simple"))
|
||||
{
|
||||
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, 16), get_loc (line, 16), false);
|
||||
warning_at_rich_loc (&richloc, 0, "test");
|
||||
|
@ -172,7 +173,7 @@ test_show_locus (function *fun)
|
|||
if (0 == strcmp (fnname, "test_simple_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),
|
||||
get_loc (line, 22), false);
|
||||
richloc.add_range (get_loc (line, 26),
|
||||
|
@ -183,7 +184,7 @@ test_show_locus (function *fun)
|
|||
if (0 == strcmp (fnname, "test_multiline"))
|
||||
{
|
||||
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),
|
||||
get_loc (line, 23), false);
|
||||
richloc.add_range (get_loc (line + 1, 9),
|
||||
|
@ -194,7 +195,7 @@ test_show_locus (function *fun)
|
|||
if (0 == strcmp (fnname, "test_many_lines"))
|
||||
{
|
||||
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),
|
||||
get_loc (line + 4, 65), false);
|
||||
richloc.add_range (get_loc (line + 5, 9),
|
||||
|
@ -223,7 +224,7 @@ test_show_locus (function *fun)
|
|||
source_range src_range;
|
||||
src_range.m_start = get_loc (line, 12);
|
||||
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);
|
||||
warning_at_rich_loc (&richloc, 0, "test");
|
||||
}
|
||||
|
@ -237,7 +238,7 @@ test_show_locus (function *fun)
|
|||
source_range src_range;
|
||||
src_range.m_start = get_loc (line, 90);
|
||||
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);
|
||||
warning_at_rich_loc (&richloc, 0, "test");
|
||||
}
|
||||
|
@ -248,7 +249,7 @@ test_show_locus (function *fun)
|
|||
const int line = fnstart_line + 2;
|
||||
location_t caret_a = get_loc (line, 7);
|
||||
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);
|
||||
global_dc->caret_chars[0] = 'A';
|
||||
global_dc->caret_chars[1] = 'B';
|
||||
|
@ -269,7 +270,7 @@ test_show_locus (function *fun)
|
|||
const int line = fnstart_line + 3;
|
||||
location_t caret_a = get_loc (line, 5);
|
||||
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);
|
||||
global_dc->caret_chars[0] = '1';
|
||||
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))
|
||||
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++)
|
||||
{
|
||||
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-test-show-locus-bw.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 } \
|
||||
]
|
||||
|
||||
|
|
|
@ -1130,6 +1130,7 @@ general_init (const char *argv0, bool init_signals)
|
|||
linemap_init (line_table, BUILTINS_LOCATION);
|
||||
line_table->reallocator = realloc_for_line_map;
|
||||
line_table->round_alloc_size = ggc_round_alloc_size;
|
||||
line_table->default_range_bits = 5;
|
||||
init_ttree ();
|
||||
|
||||
/* Initialize register usage now so switches may override. */
|
||||
|
|
|
@ -6719,10 +6719,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
|
|||
continue;
|
||||
if (d->orig_block == NULL_TREE || block == d->orig_block)
|
||||
{
|
||||
if (d->new_block == NULL_TREE)
|
||||
locus = LOCATION_LOCUS (locus);
|
||||
else
|
||||
locus = COMBINE_LOCATION_DATA (line_table, locus, d->new_block);
|
||||
locus = set_block (locus, d->new_block);
|
||||
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);
|
||||
if (d->orig_block == NULL_TREE
|
||||
|| block == d->orig_block)
|
||||
e->goto_locus = d->new_block ?
|
||||
COMBINE_LOCATION_DATA (line_table, e->goto_locus, d->new_block) :
|
||||
LOCATION_LOCUS (e->goto_locus);
|
||||
e->goto_locus = set_block (e->goto_locus, d->new_block);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2348,10 +2348,7 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
|
|||
tree *n;
|
||||
n = id->decl_map->get (LOCATION_BLOCK (locus));
|
||||
gcc_assert (n);
|
||||
if (*n)
|
||||
locus = COMBINE_LOCATION_DATA (line_table, locus, *n);
|
||||
else
|
||||
locus = LOCATION_LOCUS (locus);
|
||||
locus = set_block (locus, *n);
|
||||
}
|
||||
else
|
||||
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 (b)
|
||||
t->exp.locus = COMBINE_LOCATION_DATA (line_table, t->exp.locus, b);
|
||||
else
|
||||
t->exp.locus = LOCATION_LOCUS (t->exp.locus);
|
||||
t->exp.locus = set_block (t->exp.locus, b);
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
@ -13813,5 +13810,60 @@ nonnull_arg_p (const_tree arg)
|
|||
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"
|
||||
|
|
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_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
|
||||
location. */
|
||||
#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);
|
||||
|
||||
/* In a TARGET_EXPR node. */
|
||||
|
@ -2172,6 +2187,9 @@ extern machine_mode element_mode (const_tree t);
|
|||
#define DECL_IS_BUILTIN(DECL) \
|
||||
(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
|
||||
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
|
||||
|
@ -5277,10 +5295,25 @@ type_with_alias_set_p (const_tree t)
|
|||
return false;
|
||||
}
|
||||
|
||||
extern location_t set_block (location_t loc, tree block);
|
||||
|
||||
extern void gt_ggc_mx (tree &);
|
||||
extern void gt_pch_nx (tree &);
|
||||
extern void gt_pch_nx (tree &, gt_pointer_operator, void *);
|
||||
|
||||
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 */
|
||||
|
|
|
@ -1,3 +1,85 @@
|
|||
2015-11-13 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* errors.c (cpp_diagnostic): Pass pfile->line_table to
|
||||
rich_location ctor.
|
||||
(cpp_diagnostic_with_line): Likewise.
|
||||
* include/cpplib.h (struct cpp_token): Update comment for src_loc
|
||||
to indicate that the range of the token is "baked into" the
|
||||
source_location.
|
||||
* include/line-map.h (source_location): Update the descriptive
|
||||
comment to reflect the packing scheme for short ranges, adding
|
||||
worked examples of location encoding.
|
||||
(struct line_map_ordinary): Drop field "column_bits" in favor
|
||||
of field "m_column_and_range_bits"; add field "m_range_bits".
|
||||
(ORDINARY_MAP_NUMBER_OF_COLUMN_BITS): Delete.
|
||||
(location_adhoc_data): Add source_range field.
|
||||
(struct line_maps): Add fields "default_range_bits",
|
||||
"num_optimized_ranges" and "num_unoptimized_ranges".
|
||||
(get_combined_adhoc_loc): Add source_range param.
|
||||
(get_range_from_loc): New declaration.
|
||||
(pure_location_p): New prototype.
|
||||
(COMBINE_LOCATION_DATA): Add source_range param.
|
||||
(SOURCE_LINE): Update for renaming of column_bits.
|
||||
(SOURCE_COLUMN): Likewise. Shift the column right by the map's
|
||||
range_bits.
|
||||
(LAST_SOURCE_LINE_LOCATION): Update for renaming of column_bits.
|
||||
(linemap_position_for_line_and_column): Add line_maps * params.
|
||||
(rich_location::rich_location): Likewise.
|
||||
* lex.c (_cpp_lex_direct): Capture the range of the token, baking
|
||||
it into token->src_loc via a call to COMBINE_LOCATION_DATA.
|
||||
* line-map.c (LINE_MAP_MAX_COLUMN_NUMBER): Reduce from 1U << 17 to
|
||||
1U << 12.
|
||||
(location_adhoc_data_hash): Add the src_range into
|
||||
the hash value.
|
||||
(location_adhoc_data_eq): Require equality of the src_range
|
||||
values.
|
||||
(can_be_stored_compactly_p): New function.
|
||||
(get_combined_adhoc_loc): Add src_range param, and store it,
|
||||
via a bit-packing scheme for short ranges, otherwise within the
|
||||
lookaside table. Remove the requirement that data is non-NULL.
|
||||
(get_range_from_adhoc_loc): New function.
|
||||
(get_range_from_loc): New function.
|
||||
(pure_location_p): New function.
|
||||
(linemap_add): Ensure that start_location has zero for the
|
||||
range_bits, unless we're past LINE_MAP_MAX_LOCATION_WITH_COLS.
|
||||
Initialize range_bits to zero. Assert that the start_location
|
||||
is "pure".
|
||||
(linemap_line_start): Assert that the
|
||||
column_and_range_bits >= range_bits.
|
||||
Update determinination of whether we need to start a new map
|
||||
using the effective column bits, without the range bits.
|
||||
Use the set's default_range_bits in new maps, apart from
|
||||
those with column_bits == 0, which should also have 0 range_bits.
|
||||
Increase the column bits for new maps by the range bits.
|
||||
When adding lines to an existing map, use set->highest_line
|
||||
directly rather than offsetting highest by SOURCE_COLUMN.
|
||||
Add assertions to sanity-check the return value.
|
||||
(linemap_position_for_column): Offset to_column by range_bits.
|
||||
Update set->highest_location if necessary.
|
||||
(linemap_position_for_line_and_column): Add line_maps * param.
|
||||
Update the calculation to offset the column by range_bits, and
|
||||
conditionalize it on being <= LINE_MAP_MAX_LOCATION_WITH_COLS.
|
||||
Bound it by LINEMAPS_MACRO_LOWEST_LOCATION. Update
|
||||
set->highest_location if necessary.
|
||||
(linemap_position_for_loc_and_offset): Handle ad-hoc locations;
|
||||
pass "set" to linemap_position_for_line_and_column.
|
||||
(linemap_macro_map_loc_unwind_toward_spelling): Add line_maps
|
||||
param. Handle ad-hoc locations.
|
||||
(linemap_location_in_system_header_p): Pass on "set" to call to
|
||||
linemap_macro_map_loc_unwind_toward_spelling.
|
||||
(linemap_macro_loc_to_spelling_point): Retain ad-hoc locations.
|
||||
Pass on "set" to call to
|
||||
linemap_macro_map_loc_unwind_toward_spelling.
|
||||
(linemap_resolve_location): Retain ad-hoc locations. Pass on
|
||||
"set" to call to linemap_macro_map_loc_unwind_toward_spelling.
|
||||
(linemap_unwind_toward_expansion): Pass on "set" to call to
|
||||
linemap_macro_map_loc_unwind_toward_spelling.
|
||||
(linemap_expand_location): Extract the data pointer before
|
||||
extracting the location.
|
||||
(rich_location::rich_location): Add line_maps param; use it to
|
||||
extract the range from the source_location.
|
||||
* location-example.txt: Regenerate, showing new representation.
|
||||
|
||||
2015-11-06 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* errors.c (cpp_diagnostic): Update for change in signature
|
||||
|
|
|
@ -57,7 +57,7 @@ cpp_diagnostic (cpp_reader * pfile, int level, int reason,
|
|||
|
||||
if (!pfile->cb.error)
|
||||
abort ();
|
||||
rich_location richloc (src_loc);
|
||||
rich_location richloc (pfile->line_table, src_loc);
|
||||
ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap);
|
||||
|
||||
return ret;
|
||||
|
@ -140,7 +140,7 @@ cpp_diagnostic_with_line (cpp_reader * pfile, int level, int reason,
|
|||
|
||||
if (!pfile->cb.error)
|
||||
abort ();
|
||||
rich_location richloc (src_loc);
|
||||
rich_location richloc (pfile->line_table, src_loc);
|
||||
richloc.override_column (column);
|
||||
ret = pfile->cb.error (pfile, level, reason, &richloc, _(msgid), ap);
|
||||
|
||||
|
|
|
@ -237,7 +237,8 @@ struct GTY(()) cpp_identifier {
|
|||
/* A preprocessing token. This has been carefully packed and should
|
||||
occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */
|
||||
struct GTY(()) cpp_token {
|
||||
source_location src_loc; /* Location of first char of token. */
|
||||
source_location src_loc; /* Location of first char of token,
|
||||
together with range of full token. */
|
||||
ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */
|
||||
unsigned short flags; /* flags - see above */
|
||||
|
||||
|
|
|
@ -47,7 +47,8 @@ enum lc_reason
|
|||
typedef unsigned int linenum_type;
|
||||
|
||||
/* The typedef "source_location" is a key within the location database,
|
||||
identifying a source location or macro expansion.
|
||||
identifying a source location or macro expansion, along with range
|
||||
information, and (optionally) a pointer for use by gcc.
|
||||
|
||||
This key only has meaning in relation to a line_maps instance. Within
|
||||
gcc there is a single line_maps instance: "line_table", declared in
|
||||
|
@ -69,13 +70,48 @@ typedef unsigned int linenum_type;
|
|||
| ordmap[0]->start_location) | first line in ordmap 0
|
||||
-----------+-------------------------------+-------------------------------
|
||||
| ordmap[1]->start_location | First line in ordmap 1
|
||||
| ordmap[1]->start_location+1 | First column in that line
|
||||
| ordmap[1]->start_location+2 | 2nd column in that line
|
||||
| | Subsequent lines are offset by
|
||||
| | (1 << column_bits),
|
||||
| | e.g. 128 for 7 bits, with a
|
||||
| | column value of 0 representing
|
||||
| | "the whole line".
|
||||
| ordmap[1]->start_location+32 | First column in that line
|
||||
| (assuming range_bits == 5) |
|
||||
| ordmap[1]->start_location+64 | 2nd column in that line
|
||||
| ordmap[1]->start_location+4096| Second line in ordmap 1
|
||||
| (assuming column_bits == 12)
|
||||
|
|
||||
| Subsequent lines are offset by (1 << column_bits),
|
||||
| e.g. 4096 for 12 bits, with a column value of 0 representing
|
||||
| "the whole line".
|
||||
|
|
||||
| Within a line, the low "range_bits" (typically 5) are used for
|
||||
| storing short ranges, so that there's an offset of
|
||||
| (1 << range_bits) between individual columns within a line,
|
||||
| typically 32.
|
||||
| The low range_bits store the offset of the end point from the
|
||||
| start point, and the start point is found by masking away
|
||||
| the range bits.
|
||||
|
|
||||
| For example:
|
||||
| ordmap[1]->start_location+64 "2nd column in that line"
|
||||
| above means a caret at that location, with a range
|
||||
| starting and finishing at the same place (the range bits
|
||||
| are 0), a range of length 1.
|
||||
|
|
||||
| By contrast:
|
||||
| ordmap[1]->start_location+68
|
||||
| has range bits 0x4, meaning a caret with a range starting at
|
||||
| that location, but with endpoint 4 columns further on: a range
|
||||
| of length 5.
|
||||
|
|
||||
| Ranges that have caret != start, or have an endpoint too
|
||||
| far away to fit in range_bits are instead stored as ad-hoc
|
||||
| locations. Hence for range_bits == 5 we can compactly store
|
||||
| tokens of length <= 32 without needing to use the ad-hoc
|
||||
| table.
|
||||
|
|
||||
| This packing scheme means we effectively have
|
||||
| (column_bits - range_bits)
|
||||
| of bits for the columns, typically (12 - 5) = 7, for 128
|
||||
| columns; longer line widths are accomodated by starting a
|
||||
| new ordmap with a higher column_bits.
|
||||
|
|
||||
| ordmap[2]->start_location-1 | Final location in ordmap 1
|
||||
-----------+-------------------------------+-------------------------------
|
||||
| ordmap[2]->start_location | First line in ordmap 2
|
||||
|
@ -127,8 +163,101 @@ typedef unsigned int linenum_type;
|
|||
0xffffffff | UINT_MAX |
|
||||
-----------+-------------------------------+-------------------------------
|
||||
|
||||
To see how this works in practice, see the worked example in
|
||||
libcpp/location-example.txt. */
|
||||
Examples of location encoding.
|
||||
|
||||
Packed ranges
|
||||
=============
|
||||
|
||||
Consider encoding the location of a token "foo", seen underlined here
|
||||
on line 523, within an ordinary line_map that starts at line 500:
|
||||
|
||||
11111111112
|
||||
12345678901234567890
|
||||
522
|
||||
523 return foo + bar;
|
||||
^~~
|
||||
524
|
||||
|
||||
The location's caret and start are both at line 523, column 11; the
|
||||
location's finish is on the same line, at column 13 (an offset of 2
|
||||
columns, for length 3).
|
||||
|
||||
Line 523 is offset 23 from the starting line of the ordinary line_map.
|
||||
|
||||
caret == start, and the offset of the finish fits within 5 bits, so
|
||||
this can be stored as a packed range.
|
||||
|
||||
This is encoded as:
|
||||
ordmap->start
|
||||
+ (line_offset << ordmap->m_column_and_range_bits)
|
||||
+ (column << ordmap->m_range_bits)
|
||||
+ (range_offset);
|
||||
i.e. (for line offset 23, column 11, range offset 2):
|
||||
ordmap->start
|
||||
+ (23 << 12)
|
||||
+ (11 << 5)
|
||||
+ 2;
|
||||
i.e.:
|
||||
ordmap->start + 0x17162
|
||||
assuming that the line_map uses the default of 7 bits for columns and
|
||||
5 bits for packed range (giving 12 bits for m_column_and_range_bits).
|
||||
|
||||
|
||||
"Pure" locations
|
||||
================
|
||||
|
||||
These are a special case of the above, where
|
||||
caret == start == finish
|
||||
They are stored as packed ranges with offset == 0.
|
||||
For example, the location of the "f" of "foo" could be stored
|
||||
as above, but with range offset 0, giving:
|
||||
ordmap->start
|
||||
+ (23 << 12)
|
||||
+ (11 << 5)
|
||||
+ 0;
|
||||
i.e.:
|
||||
ordmap->start + 0x17160
|
||||
|
||||
|
||||
Unoptimized ranges
|
||||
==================
|
||||
|
||||
Consider encoding the location of the binary expression
|
||||
below:
|
||||
|
||||
11111111112
|
||||
12345678901234567890
|
||||
521
|
||||
523 return foo + bar;
|
||||
~~~~^~~~~
|
||||
523
|
||||
|
||||
The location's caret is at the "+", line 523 column 15, but starts
|
||||
earlier, at the "f" of "foo" at column 11. The finish is at the "r"
|
||||
of "bar" at column 19.
|
||||
|
||||
This can't be stored as a packed range since start != caret.
|
||||
Hence it is stored as an ad-hoc location e.g. 0x80000003.
|
||||
|
||||
Stripping off the top bit gives us an index into the ad-hoc
|
||||
lookaside table:
|
||||
|
||||
line_table->location_adhoc_data_map.data[0x3]
|
||||
|
||||
from which the caret, start and finish can be looked up,
|
||||
encoded as "pure" locations:
|
||||
|
||||
start == ordmap->start + (23 << 12) + (11 << 5)
|
||||
== ordmap->start + 0x17160 (as above; the "f" of "foo")
|
||||
|
||||
caret == ordmap->start + (23 << 12) + (15 << 5)
|
||||
== ordmap->start + 0x171e0
|
||||
|
||||
finish == ordmap->start + (23 << 12) + (19 << 5)
|
||||
== ordmap->start + 0x17260
|
||||
|
||||
To further see how source_location works in practice, see the
|
||||
worked example in libcpp/location-example.txt. */
|
||||
typedef unsigned int source_location;
|
||||
|
||||
/* A range of source locations.
|
||||
|
@ -217,8 +346,9 @@ struct GTY((tag ("0"), desc ("%h.reason == LC_ENTER_MACRO ? 2 : 1"))) line_map {
|
|||
|
||||
Physical source file TO_FILE at line TO_LINE at column 0 is represented
|
||||
by the logical START_LOCATION. TO_LINE+L at column C is represented by
|
||||
START_LOCATION+(L*(1<<column_bits))+C, as long as C<(1<<column_bits),
|
||||
and the result_location is less than the next line_map's start_location.
|
||||
START_LOCATION+(L*(1<<m_column_and_range_bits))+(C*1<<m_range_bits), as
|
||||
long as C<(1<<effective range bits), and the result_location is less than
|
||||
the next line_map's start_location.
|
||||
(The top line is line 1 and the leftmost column is column 1; line/column 0
|
||||
means "entire file/line" or "unknown line/column" or "not applicable".)
|
||||
|
||||
|
@ -238,8 +368,24 @@ struct GTY((tag ("1"))) line_map_ordinary : public line_map {
|
|||
cpp_buffer. */
|
||||
unsigned char sysp;
|
||||
|
||||
/* Number of the low-order source_location bits used for a column number. */
|
||||
unsigned int column_bits : 8;
|
||||
/* Number of the low-order source_location bits used for column numbers
|
||||
and ranges. */
|
||||
unsigned int m_column_and_range_bits : 8;
|
||||
|
||||
/* Number of the low-order "column" bits used for storing short ranges
|
||||
inline, rather than in the ad-hoc table.
|
||||
MSB LSB
|
||||
31 0
|
||||
+-------------------------+-------------------------------------------+
|
||||
| |<---map->column_and_range_bits (e.g. 12)-->|
|
||||
+-------------------------+-----------------------+-------------------+
|
||||
| | column_and_range_bits | map->range_bits |
|
||||
| | - range_bits | |
|
||||
+-------------------------+-----------------------+-------------------+
|
||||
| row bits | effective column bits | short range bits |
|
||||
| | (e.g. 7) | (e.g. 5) |
|
||||
+-------------------------+-----------------------+-------------------+ */
|
||||
unsigned int m_range_bits : 8;
|
||||
};
|
||||
|
||||
/* This is the highest possible source location encoded within an
|
||||
|
@ -435,15 +581,6 @@ ORDINARY_MAP_IN_SYSTEM_HEADER_P (const line_map_ordinary *ord_map)
|
|||
return ord_map->sysp;
|
||||
}
|
||||
|
||||
/* Get the number of the low-order source_location bits used for a
|
||||
column number within ordinary map MAP. */
|
||||
|
||||
inline unsigned char
|
||||
ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (const line_map_ordinary *ord_map)
|
||||
{
|
||||
return ord_map->column_bits;
|
||||
}
|
||||
|
||||
/* Get the filename of ordinary map MAP. */
|
||||
|
||||
inline const char *
|
||||
|
@ -524,9 +661,11 @@ struct GTY(()) maps_info_macro {
|
|||
unsigned int cache;
|
||||
};
|
||||
|
||||
/* Data structure to associate an arbitrary data to a source location. */
|
||||
/* Data structure to associate a source_range together with an arbitrary
|
||||
data pointer with a source location. */
|
||||
struct GTY(()) location_adhoc_data {
|
||||
source_location locus;
|
||||
source_range src_range;
|
||||
void * GTY((skip)) data;
|
||||
};
|
||||
|
||||
|
@ -588,6 +727,12 @@ struct GTY(()) line_maps {
|
|||
|
||||
/* True if we've seen a #line or # 44 "file" directive. */
|
||||
bool seen_line_directive;
|
||||
|
||||
/* The default value of range_bits in ordinary line maps. */
|
||||
unsigned int default_range_bits;
|
||||
|
||||
unsigned int num_optimized_ranges;
|
||||
unsigned int num_unoptimized_ranges;
|
||||
};
|
||||
|
||||
/* Returns the number of allocated maps so far. MAP_KIND shall be TRUE
|
||||
|
@ -825,11 +970,15 @@ LINEMAPS_LAST_ALLOCATED_MACRO_MAP (const line_maps *set)
|
|||
|
||||
extern void location_adhoc_data_fini (struct line_maps *);
|
||||
extern source_location get_combined_adhoc_loc (struct line_maps *,
|
||||
source_location, void *);
|
||||
source_location,
|
||||
source_range,
|
||||
void *);
|
||||
extern void *get_data_from_adhoc_loc (struct line_maps *, source_location);
|
||||
extern source_location get_location_from_adhoc_loc (struct line_maps *,
|
||||
source_location);
|
||||
|
||||
extern source_range get_range_from_loc (line_maps *set, source_location loc);
|
||||
|
||||
/* Get whether location LOC is an ad-hoc location. */
|
||||
|
||||
inline bool
|
||||
|
@ -838,14 +987,21 @@ IS_ADHOC_LOC (source_location loc)
|
|||
return (loc & MAX_SOURCE_LOCATION) != loc;
|
||||
}
|
||||
|
||||
/* Get whether location LOC is a "pure" location, or
|
||||
whether it is an ad-hoc location, or embeds range information. */
|
||||
|
||||
bool
|
||||
pure_location_p (line_maps *set, source_location loc);
|
||||
|
||||
/* Combine LOC and BLOCK, giving a combined adhoc location. */
|
||||
|
||||
inline source_location
|
||||
COMBINE_LOCATION_DATA (struct line_maps *set,
|
||||
source_location loc,
|
||||
source_range src_range,
|
||||
void *block)
|
||||
{
|
||||
return get_combined_adhoc_loc (set, loc, block);
|
||||
return get_combined_adhoc_loc (set, loc, src_range, block);
|
||||
}
|
||||
|
||||
extern void rebuild_location_adhoc_htab (struct line_maps *);
|
||||
|
@ -931,7 +1087,7 @@ inline linenum_type
|
|||
SOURCE_LINE (const line_map_ordinary *ord_map, source_location loc)
|
||||
{
|
||||
return ((loc - ord_map->start_location)
|
||||
>> ord_map->column_bits) + ord_map->to_line;
|
||||
>> ord_map->m_column_and_range_bits) + ord_map->to_line;
|
||||
}
|
||||
|
||||
/* Convert a map and source_location to source column number. */
|
||||
|
@ -939,7 +1095,7 @@ inline linenum_type
|
|||
SOURCE_COLUMN (const line_map_ordinary *ord_map, source_location loc)
|
||||
{
|
||||
return ((loc - ord_map->start_location)
|
||||
& ((1 << ord_map->column_bits) - 1));
|
||||
& ((1 << ord_map->m_column_and_range_bits) - 1)) >> ord_map->m_range_bits;
|
||||
}
|
||||
|
||||
/* Return the location of the last source line within an ordinary
|
||||
|
@ -949,7 +1105,7 @@ LAST_SOURCE_LINE_LOCATION (const line_map_ordinary *map)
|
|||
{
|
||||
return (((map[1].start_location - 1
|
||||
- map->start_location)
|
||||
& ~((1 << map->column_bits) - 1))
|
||||
& ~((1 << map->m_column_and_range_bits) - 1))
|
||||
+ map->start_location);
|
||||
}
|
||||
|
||||
|
@ -999,7 +1155,8 @@ linemap_position_for_column (struct line_maps *, unsigned int);
|
|||
/* Encode and return a source location from a given line and
|
||||
column. */
|
||||
source_location
|
||||
linemap_position_for_line_and_column (const line_map_ordinary *,
|
||||
linemap_position_for_line_and_column (line_maps *set,
|
||||
const line_map_ordinary *,
|
||||
linenum_type, unsigned int);
|
||||
|
||||
/* Encode and return a source_location starting from location LOC and
|
||||
|
@ -1187,7 +1344,7 @@ class rich_location
|
|||
/* Constructors. */
|
||||
|
||||
/* Constructing from a location. */
|
||||
rich_location (source_location loc);
|
||||
rich_location (line_maps *set, source_location loc);
|
||||
|
||||
/* Constructing from a source_range. */
|
||||
rich_location (source_range src_range);
|
||||
|
|
13
libcpp/lex.c
13
libcpp/lex.c
|
@ -2723,6 +2723,19 @@ _cpp_lex_direct (cpp_reader *pfile)
|
|||
break;
|
||||
}
|
||||
|
||||
source_range tok_range;
|
||||
tok_range.m_start = result->src_loc;
|
||||
if (result->src_loc >= RESERVED_LOCATION_COUNT)
|
||||
tok_range.m_finish
|
||||
= linemap_position_for_column (pfile->line_table,
|
||||
CPP_BUF_COLUMN (buffer, buffer->cur));
|
||||
else
|
||||
tok_range.m_finish = tok_range.m_start;
|
||||
|
||||
result->src_loc = COMBINE_LOCATION_DATA (pfile->line_table,
|
||||
result->src_loc,
|
||||
tok_range, NULL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,9 +27,9 @@ along with this program; see the file COPYING3. If not see
|
|||
#include "hashtab.h"
|
||||
|
||||
/* Do not track column numbers higher than this one. As a result, the
|
||||
range of column_bits is [7, 18] (or 0 if column numbers are
|
||||
range of column_bits is [12, 18] (or 0 if column numbers are
|
||||
disabled). */
|
||||
const unsigned int LINE_MAP_MAX_COLUMN_NUMBER = (1U << 17);
|
||||
const unsigned int LINE_MAP_MAX_COLUMN_NUMBER = (1U << 12);
|
||||
|
||||
/* Do not track column numbers if locations get higher than this. */
|
||||
const source_location LINE_MAP_MAX_LOCATION_WITH_COLS = 0x60000000;
|
||||
|
@ -46,7 +46,7 @@ static const line_map_macro* linemap_macro_map_lookup (struct line_maps *,
|
|||
static source_location linemap_macro_map_loc_to_def_point
|
||||
(const line_map_macro *, source_location);
|
||||
static source_location linemap_macro_map_loc_unwind_toward_spelling
|
||||
(const line_map_macro *, source_location);
|
||||
(line_maps *set, const line_map_macro *, source_location);
|
||||
static source_location linemap_macro_map_loc_to_exp_point
|
||||
(const line_map_macro *, source_location);
|
||||
static source_location linemap_macro_loc_to_spelling_point
|
||||
|
@ -69,7 +69,10 @@ location_adhoc_data_hash (const void *l)
|
|||
{
|
||||
const struct location_adhoc_data *lb =
|
||||
(const struct location_adhoc_data *) l;
|
||||
return (hashval_t) lb->locus + (size_t) lb->data;
|
||||
return ((hashval_t) lb->locus
|
||||
+ (hashval_t) lb->src_range.m_start
|
||||
+ (hashval_t) lb->src_range.m_finish
|
||||
+ (size_t) lb->data);
|
||||
}
|
||||
|
||||
/* Compare function for location_adhoc_data hashtable. */
|
||||
|
@ -81,7 +84,10 @@ location_adhoc_data_eq (const void *l1, const void *l2)
|
|||
(const struct location_adhoc_data *) l1;
|
||||
const struct location_adhoc_data *lb2 =
|
||||
(const struct location_adhoc_data *) l2;
|
||||
return lb1->locus == lb2->locus && lb1->data == lb2->data;
|
||||
return (lb1->locus == lb2->locus
|
||||
&& lb1->src_range.m_start == lb2->src_range.m_start
|
||||
&& lb1->src_range.m_finish == lb2->src_range.m_finish
|
||||
&& lb1->data == lb2->data);
|
||||
}
|
||||
|
||||
/* Update the hashtable when location_adhoc_data is reallocated. */
|
||||
|
@ -106,23 +112,103 @@ rebuild_location_adhoc_htab (struct line_maps *set)
|
|||
set->location_adhoc_data_map.data + i, INSERT);
|
||||
}
|
||||
|
||||
/* Helper function for get_combined_adhoc_loc.
|
||||
Can the given LOCUS + SRC_RANGE and DATA pointer be stored compactly
|
||||
within a source_location, without needing to use an ad-hoc location. */
|
||||
|
||||
static bool
|
||||
can_be_stored_compactly_p (struct line_maps *set,
|
||||
source_location locus,
|
||||
source_range src_range,
|
||||
void *data)
|
||||
{
|
||||
/* If there's an ad-hoc pointer, we can't store it directly in the
|
||||
source_location, we need the lookaside. */
|
||||
if (data)
|
||||
return false;
|
||||
|
||||
/* We only store ranges that begin at the locus and that are sufficiently
|
||||
"sane". */
|
||||
if (src_range.m_start != locus)
|
||||
return false;
|
||||
|
||||
if (src_range.m_finish < src_range.m_start)
|
||||
return false;
|
||||
|
||||
if (src_range.m_start < RESERVED_LOCATION_COUNT)
|
||||
return false;
|
||||
|
||||
if (locus >= LINE_MAP_MAX_LOCATION_WITH_COLS)
|
||||
return false;
|
||||
|
||||
/* All 3 locations must be within ordinary maps, typically, the same
|
||||
ordinary map. */
|
||||
source_location lowest_macro_loc = LINEMAPS_MACRO_LOWEST_LOCATION (set);
|
||||
if (locus >= lowest_macro_loc)
|
||||
return false;
|
||||
if (src_range.m_start >= lowest_macro_loc)
|
||||
return false;
|
||||
if (src_range.m_finish >= lowest_macro_loc)
|
||||
return false;
|
||||
|
||||
/* Passed all tests. */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Combine LOCUS and DATA to a combined adhoc loc. */
|
||||
|
||||
source_location
|
||||
get_combined_adhoc_loc (struct line_maps *set,
|
||||
source_location locus, void *data)
|
||||
source_location locus,
|
||||
source_range src_range,
|
||||
void *data)
|
||||
{
|
||||
struct location_adhoc_data lb;
|
||||
struct location_adhoc_data **slot;
|
||||
|
||||
linemap_assert (data);
|
||||
|
||||
if (IS_ADHOC_LOC (locus))
|
||||
locus
|
||||
= set->location_adhoc_data_map.data[locus & MAX_SOURCE_LOCATION].locus;
|
||||
if (locus == 0 && data == NULL)
|
||||
return 0;
|
||||
|
||||
/* Any ordinary locations ought to be "pure" at this point: no
|
||||
compressed ranges. */
|
||||
linemap_assert (locus < RESERVED_LOCATION_COUNT
|
||||
|| locus >= LINE_MAP_MAX_LOCATION_WITH_COLS
|
||||
|| locus >= LINEMAPS_MACRO_LOWEST_LOCATION (set)
|
||||
|| pure_location_p (set, locus));
|
||||
|
||||
/* Consider short-range optimization. */
|
||||
if (can_be_stored_compactly_p (set, locus, src_range, data))
|
||||
{
|
||||
/* The low bits ought to be clear. */
|
||||
linemap_assert (pure_location_p (set, locus));
|
||||
const line_map *map = linemap_lookup (set, locus);
|
||||
const line_map_ordinary *ordmap = linemap_check_ordinary (map);
|
||||
unsigned int int_diff = src_range.m_finish - src_range.m_start;
|
||||
unsigned int col_diff = (int_diff >> ordmap->m_range_bits);
|
||||
if (col_diff < (1U << ordmap->m_range_bits))
|
||||
{
|
||||
source_location packed = locus | col_diff;
|
||||
set->num_optimized_ranges++;
|
||||
return packed;
|
||||
}
|
||||
}
|
||||
|
||||
/* We can also compactly store the reserved locations
|
||||
when locus == start == finish (and data is NULL). */
|
||||
if (locus < RESERVED_LOCATION_COUNT
|
||||
&& locus == src_range.m_start
|
||||
&& locus == src_range.m_finish
|
||||
&& !data)
|
||||
return locus;
|
||||
|
||||
if (!data)
|
||||
set->num_unoptimized_ranges++;
|
||||
|
||||
lb.locus = locus;
|
||||
lb.src_range = src_range;
|
||||
lb.data = data;
|
||||
slot = (struct location_adhoc_data **)
|
||||
htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
|
||||
|
@ -177,6 +263,60 @@ get_location_from_adhoc_loc (struct line_maps *set, source_location loc)
|
|||
return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
|
||||
}
|
||||
|
||||
/* Return the source_range for adhoc location LOC. */
|
||||
|
||||
static source_range
|
||||
get_range_from_adhoc_loc (struct line_maps *set, source_location loc)
|
||||
{
|
||||
linemap_assert (IS_ADHOC_LOC (loc));
|
||||
return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].src_range;
|
||||
}
|
||||
|
||||
/* Get the source_range of location LOC, either from the ad-hoc
|
||||
lookaside table, or embedded inside LOC itself. */
|
||||
|
||||
source_range
|
||||
get_range_from_loc (struct line_maps *set,
|
||||
source_location loc)
|
||||
{
|
||||
if (IS_ADHOC_LOC (loc))
|
||||
return get_range_from_adhoc_loc (set, loc);
|
||||
|
||||
/* For ordinary maps, extract packed range. */
|
||||
if (loc >= RESERVED_LOCATION_COUNT
|
||||
&& loc < LINEMAPS_MACRO_LOWEST_LOCATION (set)
|
||||
&& loc <= LINE_MAP_MAX_LOCATION_WITH_COLS)
|
||||
{
|
||||
const line_map *map = linemap_lookup (set, loc);
|
||||
const line_map_ordinary *ordmap = linemap_check_ordinary (map);
|
||||
source_range result;
|
||||
int offset = loc & ((1 << ordmap->m_range_bits) - 1);
|
||||
result.m_start = loc - offset;
|
||||
result.m_finish = result.m_start + (offset << ordmap->m_range_bits);
|
||||
return result;
|
||||
}
|
||||
|
||||
return source_range::from_location (loc);
|
||||
}
|
||||
|
||||
/* Get whether location LOC is a "pure" location, or
|
||||
whether it is an ad-hoc location, or embeds range information. */
|
||||
|
||||
bool
|
||||
pure_location_p (line_maps *set, source_location loc)
|
||||
{
|
||||
if (IS_ADHOC_LOC (loc))
|
||||
return false;
|
||||
|
||||
const line_map *map = linemap_lookup (set, loc);
|
||||
const line_map_ordinary *ordmap = linemap_check_ordinary (map);
|
||||
|
||||
if (loc & ((1U << ordmap->m_range_bits) - 1))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Finalize the location_adhoc_data structure. */
|
||||
void
|
||||
location_adhoc_data_fini (struct line_maps *set)
|
||||
|
@ -319,7 +459,19 @@ const struct line_map *
|
|||
linemap_add (struct line_maps *set, enum lc_reason reason,
|
||||
unsigned int sysp, const char *to_file, linenum_type to_line)
|
||||
{
|
||||
source_location start_location = set->highest_location + 1;
|
||||
/* Generate a start_location above the current highest_location.
|
||||
If possible, make the low range bits be zero. */
|
||||
source_location start_location;
|
||||
if (set->highest_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
|
||||
{
|
||||
start_location = set->highest_location + (1 << set->default_range_bits);
|
||||
if (set->default_range_bits)
|
||||
start_location &= ~((1 << set->default_range_bits) - 1);
|
||||
linemap_assert (0 == (start_location
|
||||
& ((1 << set->default_range_bits) - 1)));
|
||||
}
|
||||
else
|
||||
start_location = set->highest_location + 1;
|
||||
|
||||
linemap_assert (!(LINEMAPS_ORDINARY_USED (set)
|
||||
&& (start_location
|
||||
|
@ -398,11 +550,18 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
|
|||
map->to_file = to_file;
|
||||
map->to_line = to_line;
|
||||
LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1;
|
||||
map->column_bits = 0;
|
||||
map->m_column_and_range_bits = 0;
|
||||
map->m_range_bits = 0;
|
||||
set->highest_location = start_location;
|
||||
set->highest_line = start_location;
|
||||
set->max_column_hint = 0;
|
||||
|
||||
/* This assertion is placed after set->highest_location has
|
||||
been updated, since the latter affects
|
||||
linemap_location_from_macro_expansion_p, which ultimately affects
|
||||
pure_location_p. */
|
||||
linemap_assert (pure_location_p (set, start_location));
|
||||
|
||||
if (reason == LC_ENTER)
|
||||
{
|
||||
map->included_from =
|
||||
|
@ -549,13 +708,14 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
|
|||
SOURCE_LINE (map, set->highest_line);
|
||||
int line_delta = to_line - last_line;
|
||||
bool add_map = false;
|
||||
linemap_assert (map->m_column_and_range_bits >= map->m_range_bits);
|
||||
int effective_column_bits = map->m_column_and_range_bits - map->m_range_bits;
|
||||
|
||||
if (line_delta < 0
|
||||
|| (line_delta > 10
|
||||
&& line_delta * ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) > 1000)
|
||||
|| (max_column_hint >= (1U << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map)))
|
||||
|| (max_column_hint <= 80
|
||||
&& ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) >= 10)
|
||||
&& line_delta * map->m_column_and_range_bits > 1000)
|
||||
|| (max_column_hint >= (1U << effective_column_bits))
|
||||
|| (max_column_hint <= 80 && effective_column_bits >= 10)
|
||||
|| (highest > LINE_MAP_MAX_LOCATION_WITH_COLS
|
||||
&& (set->max_column_hint || highest >= LINE_MAP_MAX_SOURCE_LOCATION)))
|
||||
add_map = true;
|
||||
|
@ -564,22 +724,27 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
|
|||
if (add_map)
|
||||
{
|
||||
int column_bits;
|
||||
int range_bits;
|
||||
if (max_column_hint > LINE_MAP_MAX_COLUMN_NUMBER
|
||||
|| highest > LINE_MAP_MAX_LOCATION_WITH_COLS)
|
||||
{
|
||||
/* If the column number is ridiculous or we've allocated a huge
|
||||
number of source_locations, give up on column numbers. */
|
||||
number of source_locations, give up on column numbers
|
||||
(and on packed ranges). */
|
||||
max_column_hint = 0;
|
||||
column_bits = 0;
|
||||
range_bits = 0;
|
||||
if (highest > LINE_MAP_MAX_SOURCE_LOCATION)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
column_bits = 7;
|
||||
range_bits = set->default_range_bits;
|
||||
while (max_column_hint >= (1U << column_bits))
|
||||
column_bits++;
|
||||
max_column_hint = 1U << column_bits;
|
||||
column_bits += range_bits;
|
||||
}
|
||||
/* Allocate the new line_map. However, if the current map only has a
|
||||
single line we can sometimes just increase its column_bits instead. */
|
||||
|
@ -592,14 +757,14 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
|
|||
ORDINARY_MAP_IN_SYSTEM_HEADER_P (map),
|
||||
ORDINARY_MAP_FILE_NAME (map),
|
||||
to_line)));
|
||||
map->column_bits = column_bits;
|
||||
map->m_column_and_range_bits = column_bits;
|
||||
map->m_range_bits = range_bits;
|
||||
r = (MAP_START_LOCATION (map)
|
||||
+ ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
|
||||
<< column_bits));
|
||||
}
|
||||
else
|
||||
r = highest - SOURCE_COLUMN (map, highest)
|
||||
+ (line_delta << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map));
|
||||
r = set->highest_line + (line_delta << map->m_column_and_range_bits);
|
||||
|
||||
/* Locations of ordinary tokens are always lower than locations of
|
||||
macro tokens. */
|
||||
|
@ -610,6 +775,18 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
|
|||
if (r > set->highest_location)
|
||||
set->highest_location = r;
|
||||
set->max_column_hint = max_column_hint;
|
||||
|
||||
/* At this point, we expect one of:
|
||||
(a) the normal case: a "pure" location with 0 range bits, or
|
||||
(b) we've gone past LINE_MAP_MAX_LOCATION_WITH_COLS so can't track
|
||||
columns anymore (or ranges), or
|
||||
(c) we're in a region with a column hint exceeding
|
||||
LINE_MAP_MAX_COLUMN_NUMBER, so column-tracking is off,
|
||||
with column_bits == 0. */
|
||||
linemap_assert (pure_location_p (set, r)
|
||||
|| r >= LINE_MAP_MAX_LOCATION_WITH_COLS
|
||||
|| map->m_column_and_range_bits == 0);
|
||||
linemap_assert (SOURCE_LINE (map, r) == to_line);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -640,7 +817,8 @@ linemap_position_for_column (struct line_maps *set, unsigned int to_column)
|
|||
r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
|
||||
}
|
||||
}
|
||||
r = r + to_column;
|
||||
line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
|
||||
r = r + (to_column << map->m_range_bits);
|
||||
if (r >= set->highest_location)
|
||||
set->highest_location = r;
|
||||
return r;
|
||||
|
@ -650,16 +828,25 @@ linemap_position_for_column (struct line_maps *set, unsigned int to_column)
|
|||
column. */
|
||||
|
||||
source_location
|
||||
linemap_position_for_line_and_column (const line_map_ordinary *ord_map,
|
||||
linemap_position_for_line_and_column (line_maps *set,
|
||||
const line_map_ordinary *ord_map,
|
||||
linenum_type line,
|
||||
unsigned column)
|
||||
{
|
||||
linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
|
||||
|
||||
return (MAP_START_LOCATION (ord_map)
|
||||
+ ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
|
||||
<< ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (ord_map))
|
||||
+ (column & ((1 << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (ord_map)) - 1)));
|
||||
source_location r = MAP_START_LOCATION (ord_map);
|
||||
r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
|
||||
<< ord_map->m_column_and_range_bits);
|
||||
if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS)
|
||||
r += ((column & ((1 << ord_map->m_column_and_range_bits) - 1))
|
||||
<< ord_map->m_range_bits);
|
||||
source_location upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set);
|
||||
if (r >= upper_limit)
|
||||
r = upper_limit - 1;
|
||||
if (r > set->highest_location)
|
||||
set->highest_location = r;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Encode and return a source_location starting from location LOC and
|
||||
|
@ -673,6 +860,9 @@ linemap_position_for_loc_and_offset (struct line_maps *set,
|
|||
{
|
||||
const line_map_ordinary * map = NULL;
|
||||
|
||||
if (IS_ADHOC_LOC (loc))
|
||||
loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
|
||||
|
||||
/* This function does not support virtual locations yet. */
|
||||
if (linemap_assert_fails
|
||||
(!linemap_location_from_macro_expansion_p (set, loc)))
|
||||
|
@ -711,11 +901,11 @@ linemap_position_for_loc_and_offset (struct line_maps *set,
|
|||
}
|
||||
|
||||
offset += column;
|
||||
if (linemap_assert_fails (offset < (1u << map->column_bits)))
|
||||
if (linemap_assert_fails (offset < (1u << map->m_column_and_range_bits)))
|
||||
return loc;
|
||||
|
||||
source_location r =
|
||||
linemap_position_for_line_and_column (map, line, offset);
|
||||
linemap_position_for_line_and_column (set, map, line, offset);
|
||||
if (linemap_assert_fails (r <= set->highest_location)
|
||||
|| linemap_assert_fails (map == linemap_lookup (set, r)))
|
||||
return loc;
|
||||
|
@ -893,14 +1083,19 @@ linemap_macro_map_loc_to_def_point (const line_map_macro *map,
|
|||
In other words, this returns the xI location presented in the
|
||||
comments of line_map_macro above. */
|
||||
source_location
|
||||
linemap_macro_map_loc_unwind_toward_spelling (const line_map_macro* map,
|
||||
linemap_macro_map_loc_unwind_toward_spelling (line_maps *set,
|
||||
const line_map_macro* map,
|
||||
source_location location)
|
||||
{
|
||||
unsigned token_no;
|
||||
|
||||
if (IS_ADHOC_LOC (location))
|
||||
location = get_location_from_adhoc_loc (set, location);
|
||||
|
||||
linemap_assert (linemap_macro_expansion_map_p (map)
|
||||
&& location >= MAP_START_LOCATION (map));
|
||||
linemap_assert (location >= RESERVED_LOCATION_COUNT);
|
||||
linemap_assert (!IS_ADHOC_LOC (location));
|
||||
|
||||
token_no = location - MAP_START_LOCATION (map);
|
||||
linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
|
||||
|
@ -1010,7 +1205,7 @@ linemap_location_in_system_header_p (struct line_maps *set,
|
|||
|
||||
/* It's a token resulting from a macro expansion. */
|
||||
source_location loc =
|
||||
linemap_macro_map_loc_unwind_toward_spelling (macro_map, location);
|
||||
linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, location);
|
||||
if (loc < RESERVED_LOCATION_COUNT)
|
||||
/* This token might come from a built-in macro. Let's
|
||||
look at where that macro got expanded. */
|
||||
|
@ -1183,11 +1378,6 @@ linemap_macro_loc_to_spelling_point (struct line_maps *set,
|
|||
const line_map_ordinary **original_map)
|
||||
{
|
||||
struct line_map *map;
|
||||
|
||||
if (IS_ADHOC_LOC (location))
|
||||
location = set->location_adhoc_data_map.data[location
|
||||
& MAX_SOURCE_LOCATION].locus;
|
||||
|
||||
linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
|
||||
|
||||
while (true)
|
||||
|
@ -1198,7 +1388,7 @@ linemap_macro_loc_to_spelling_point (struct line_maps *set,
|
|||
|
||||
location
|
||||
= linemap_macro_map_loc_unwind_toward_spelling
|
||||
(linemap_check_macro (map),
|
||||
(set, linemap_check_macro (map),
|
||||
location);
|
||||
}
|
||||
|
||||
|
@ -1341,10 +1531,11 @@ linemap_resolve_location (struct line_maps *set,
|
|||
enum location_resolution_kind lrk,
|
||||
const line_map_ordinary **map)
|
||||
{
|
||||
source_location locus = loc;
|
||||
if (IS_ADHOC_LOC (loc))
|
||||
loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
|
||||
locus = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
|
||||
|
||||
if (loc < RESERVED_LOCATION_COUNT)
|
||||
if (locus < RESERVED_LOCATION_COUNT)
|
||||
{
|
||||
/* A reserved location wasn't encoded in a map. Let's return a
|
||||
NULL map here, just like what linemap_ordinary_map_lookup
|
||||
|
@ -1396,7 +1587,7 @@ linemap_unwind_toward_expansion (struct line_maps *set,
|
|||
loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
|
||||
|
||||
resolved_location =
|
||||
linemap_macro_map_loc_unwind_toward_spelling (macro_map, loc);
|
||||
linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, loc);
|
||||
resolved_map = linemap_lookup (set, resolved_location);
|
||||
|
||||
if (!linemap_macro_expansion_map_p (resolved_map))
|
||||
|
@ -1478,9 +1669,9 @@ linemap_expand_location (struct line_maps *set,
|
|||
memset (&xloc, 0, sizeof (xloc));
|
||||
if (IS_ADHOC_LOC (loc))
|
||||
{
|
||||
loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
|
||||
xloc.data
|
||||
= set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
|
||||
loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
|
||||
}
|
||||
|
||||
if (loc < RESERVED_LOCATION_COUNT)
|
||||
|
@ -1760,13 +1951,14 @@ line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary,
|
|||
|
||||
/* Construct a rich_location with location LOC as its initial range. */
|
||||
|
||||
rich_location::rich_location (source_location loc) :
|
||||
rich_location::rich_location (line_maps *set, source_location loc) :
|
||||
m_loc (loc),
|
||||
m_num_ranges (0),
|
||||
m_have_expanded_location (false)
|
||||
{
|
||||
/* Set up the 0th range: */
|
||||
add_range (loc, loc, true);
|
||||
/* Set up the 0th range, extracting any range from LOC. */
|
||||
source_range src_range = get_range_from_loc (set, loc);
|
||||
add_range (src_range, true);
|
||||
m_ranges[0].m_caret = lazily_expand_location ();
|
||||
}
|
||||
|
||||
|
|
|
@ -30,142 +30,154 @@ RESERVED LOCATIONS
|
|||
source_location interval: 0 <= loc < 2
|
||||
|
||||
ORDINARY MAP: 0
|
||||
source_location interval: 2 <= loc < 3
|
||||
source_location interval: 32 <= loc < 64
|
||||
file: test.c
|
||||
starting at line: 1
|
||||
column bits: 7
|
||||
test.c: 1|loc: 2|#include "test.h"
|
||||
|00000001111111111
|
||||
|34567890123456789
|
||||
column bits: 12
|
||||
range bits: 5
|
||||
test.c: 1|loc: 32|#include "test.h"
|
||||
|69269258258148147
|
||||
|46802468024680246
|
||||
|
||||
ORDINARY MAP: 1
|
||||
source_location interval: 3 <= loc < 4
|
||||
source_location interval: 64 <= loc < 96
|
||||
file: <built-in>
|
||||
starting at line: 0
|
||||
column bits: 0
|
||||
range bits: 0
|
||||
|
||||
ORDINARY MAP: 2
|
||||
source_location interval: 4 <= loc < 5
|
||||
source_location interval: 96 <= loc < 128
|
||||
file: <command-line>
|
||||
starting at line: 0
|
||||
column bits: 0
|
||||
range bits: 0
|
||||
|
||||
ORDINARY MAP: 3
|
||||
source_location interval: 5 <= loc < 5005
|
||||
source_location interval: 128 <= loc < 160128
|
||||
file: /usr/include/stdc-predef.h
|
||||
starting at line: 1
|
||||
column bits: 7
|
||||
column bits: 12
|
||||
range bits: 5
|
||||
(contents of /usr/include/stdc-predef.h snipped for brevity)
|
||||
|
||||
ORDINARY MAP: 4
|
||||
source_location interval: 5005 <= loc < 5006
|
||||
source_location interval: 160128 <= loc < 160160
|
||||
file: <command-line>
|
||||
starting at line: 1
|
||||
column bits: 7
|
||||
starting at line: 32
|
||||
column bits: 12
|
||||
range bits: 5
|
||||
|
||||
ORDINARY MAP: 5
|
||||
source_location interval: 5006 <= loc < 5134
|
||||
source_location interval: 160160 <= loc < 164256
|
||||
file: test.c
|
||||
starting at line: 1
|
||||
column bits: 7
|
||||
test.c: 1|loc: 5006|#include "test.h"
|
||||
|55555555555555555
|
||||
column bits: 12
|
||||
range bits: 5
|
||||
test.c: 1|loc:160160|#include "test.h"
|
||||
|00000000000000000
|
||||
|00011111111112222
|
||||
|78901234567890123
|
||||
|12223334445556667
|
||||
|92582581481470470
|
||||
|24680246802468024
|
||||
|
||||
ORDINARY MAP: 6
|
||||
source_location interval: 5134 <= loc < 5416
|
||||
source_location interval: 164256 <= loc < 173280
|
||||
file: test.h
|
||||
starting at line: 1
|
||||
column bits: 7
|
||||
test.h: 1|loc: 5134|extern int foo ();
|
||||
|555555555555555555
|
||||
|111111111111111111
|
||||
|333334444444444555
|
||||
|567890123456789012
|
||||
test.h: 2|loc: 5262|
|
||||
column bits: 12
|
||||
range bits: 5
|
||||
test.h: 1|loc:164256|extern int foo ();
|
||||
|444444444444444444
|
||||
|233344455566677788
|
||||
|825814814704703603
|
||||
|802468024680246802
|
||||
test.h: 2|loc:168352|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
test.h: 3|loc: 5390|#define PLUS(A, B) A + B
|
||||
|555555555555555555555555
|
||||
|333333333444444444444444
|
||||
|999999999000000000011111
|
||||
|123456789012345678901234
|
||||
test.h: 3|loc:172448|#define PLUS(A, B) A + B
|
||||
|222222222222222223333333
|
||||
|455566677788889990001112
|
||||
|814704703603692692582581
|
||||
|024680246802468024680246
|
||||
|
||||
ORDINARY MAP: 7
|
||||
source_location interval: 5416 <= loc < 6314
|
||||
source_location interval: 173280 <= loc < 202016
|
||||
file: test.c
|
||||
starting at line: 2
|
||||
column bits: 7
|
||||
test.c: 2|loc: 5416|
|
||||
column bits: 12
|
||||
range bits: 5
|
||||
test.c: 2|loc:173280|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
test.c: 3|loc: 5544|int
|
||||
|555
|
||||
|555
|
||||
test.c: 3|loc:177376|int
|
||||
|777
|
||||
|444
|
||||
|567
|
||||
test.c: 4|loc: 5672|main (int argc, char **argv)
|
||||
|5555555555555555555555555555
|
||||
|6666666666666666666666666667
|
||||
|7777777888888888899999999990
|
||||
|3456789012345678901234567890
|
||||
test.c: 5|loc: 5800|{
|
||||
|047
|
||||
|802
|
||||
test.c: 4|loc:181472|main (int argc, char **argv)
|
||||
|1111111111111111222222222222
|
||||
|5556666777888999000111222333
|
||||
|0360369269258258148147047036
|
||||
|4680246802468024680246802468
|
||||
test.c: 5|loc:185568|{
|
||||
|5
|
||||
|8
|
||||
|0
|
||||
|1
|
||||
test.c: 6|loc: 5928| int a = PLUS (1,2);
|
||||
|555555555555555555555
|
||||
|999999999999999999999
|
||||
|233333333334444444444
|
||||
|901234567890123456789
|
||||
test.c: 7|loc: 6056| int b = PLUS (3,4);
|
||||
|666666666666666666666
|
||||
|000000000000000000000
|
||||
|555666666666677777777
|
||||
|789012345678901234567
|
||||
test.c: 8|loc: 6184| return 0;
|
||||
|66666666666
|
||||
|11111111111
|
||||
|88888999999
|
||||
|56789012345
|
||||
test.c: 9|loc: 6312|}
|
||||
|6
|
||||
|3
|
||||
|0
|
||||
|0
|
||||
test.c: 6|loc:189664| int a = PLUS (1,2);
|
||||
|999999999900000000000
|
||||
|677788899900011122233
|
||||
|926925825814814704703
|
||||
|680246802468024680246
|
||||
test.c: 7|loc:193760| int b = PLUS (3,4);
|
||||
|333333344444444444444
|
||||
|788899900011122233344
|
||||
|925825814814704703603
|
||||
|246802468024680246802
|
||||
test.c: 8|loc:197856| return 0;
|
||||
|77778888888
|
||||
|89990001112
|
||||
|82581481470
|
||||
|80246802468
|
||||
test.c: 9|loc:201952|}
|
||||
|1
|
||||
|3
|
||||
|9
|
||||
|8
|
||||
|4
|
||||
|
||||
UNALLOCATED LOCATIONS
|
||||
source_location interval: 6314 <= loc < 2147483633
|
||||
source_location interval: 202016 <= loc < 2147483633
|
||||
|
||||
MACRO 1: PLUS (7 tokens)
|
||||
source_location interval: 2147483633 <= loc < 2147483640
|
||||
test.c:7:11: note: expansion point is location 6067
|
||||
test.c:7:11: note: expansion point is location 194115
|
||||
int b = PLUS (3,4);
|
||||
^
|
||||
^~~~
|
||||
|
||||
map->start_location: 2147483633
|
||||
macro_locations:
|
||||
0: 6073, 5410
|
||||
test.c:7:17: note: token 0 has x-location == 6073
|
||||
0: 194304, 173088
|
||||
test.c:7:17: note: token 0 has x-location == 194304
|
||||
int b = PLUS (3,4);
|
||||
^
|
||||
test.c:7:17: note: token 0 has y-location == 5410
|
||||
1: 5412, 5412
|
||||
|
||||
test.c:7:17: note: token 0 has y-location == 173088
|
||||
1: 173152, 173152
|
||||
In file included from test.c:1:0:
|
||||
test.h:3:22: note: token 1 has x-location == y-location == 5412
|
||||
test.h:3:22: note: token 1 has x-location == y-location == 173152
|
||||
#define PLUS(A, B) A + B
|
||||
^
|
||||
2: 6075, 5414
|
||||
test.c:7:19: note: token 2 has x-location == 6075
|
||||
|
||||
2: 194368, 173216
|
||||
test.c:7:19: note: token 2 has x-location == 194368
|
||||
int b = PLUS (3,4);
|
||||
^
|
||||
test.c:7:19: note: token 2 has y-location == 5414
|
||||
|
||||
test.c:7:19: note: token 2 has y-location == 173216
|
||||
3: 0, 2947526575
|
||||
cc1: note: token 3 has x-location == 0
|
||||
cc1: note: token 3 has y-location == 2947526575
|
||||
|
@ -178,26 +190,30 @@ x-location == y-location == 2947526575 encodes token # 800042942
|
|||
|
||||
MACRO 0: PLUS (7 tokens)
|
||||
source_location interval: 2147483640 <= loc < 2147483647
|
||||
test.c:6:11: note: expansion point is location 5939
|
||||
test.c:6:11: note: expansion point is location 190019
|
||||
int a = PLUS (1,2);
|
||||
^
|
||||
^~~~
|
||||
|
||||
map->start_location: 2147483640
|
||||
macro_locations:
|
||||
0: 5945, 5410
|
||||
test.c:6:17: note: token 0 has x-location == 5945
|
||||
0: 190208, 173088
|
||||
test.c:6:17: note: token 0 has x-location == 190208
|
||||
int a = PLUS (1,2);
|
||||
^
|
||||
test.c:6:17: note: token 0 has y-location == 5410
|
||||
1: 5412, 5412
|
||||
|
||||
test.c:6:17: note: token 0 has y-location == 173088
|
||||
1: 173152, 173152
|
||||
In file included from test.c:1:0:
|
||||
test.h:3:22: note: token 1 has x-location == y-location == 5412
|
||||
test.h:3:22: note: token 1 has x-location == y-location == 173152
|
||||
#define PLUS(A, B) A + B
|
||||
^
|
||||
2: 5947, 5414
|
||||
test.c:6:19: note: token 2 has x-location == 5947
|
||||
|
||||
2: 190272, 173216
|
||||
test.c:6:19: note: token 2 has x-location == 190272
|
||||
int a = PLUS (1,2);
|
||||
^
|
||||
test.c:6:19: note: token 2 has y-location == 5414
|
||||
|
||||
test.c:6:19: note: token 2 has y-location == 173216
|
||||
3: 0, 2947526575
|
||||
cc1: note: token 3 has x-location == 0
|
||||
cc1: note: token 3 has y-location == 2947526575
|
||||
|
|
Loading…
Add table
Reference in a new issue