diff options
Diffstat (limited to 'gcc/input.c')
-rw-r--r-- | gcc/input.c | 86 |
1 files changed, 66 insertions, 20 deletions
diff --git a/gcc/input.c b/gcc/input.c index 0c5f817e83a..10cab77359d 100644 --- a/gcc/input.c +++ b/gcc/input.c @@ -1402,10 +1402,17 @@ get_substring_ranges_for_loc (cpp_reader *pfile, return NULL; } -/* Attempt to populate *OUT_RANGE with source location information on the - range of given characters within the string literal found at STRLOC. - START_IDX and END_IDX refer to offsets within the execution character - set. +/* Attempt to populate *OUT_LOC with source location information on the + given characters within the string literal found at STRLOC. + CARET_IDX, START_IDX, and END_IDX refer to offsets within the execution + character set. + + For example, given CARET_IDX = 4, START_IDX = 3, END_IDX = 7 + and string literal "012345\n789" + *OUT_LOC is written to with: + "012345\n789" + ~^~~~~ + If CONCATS is non-NULL, then any string literals that the token at STRLOC was concatenated with are also considered. @@ -1416,16 +1423,17 @@ get_substring_ranges_for_loc (cpp_reader *pfile, than for end-users. */ const char * -get_source_range_for_substring (cpp_reader *pfile, - string_concat_db *concats, - location_t strloc, - enum cpp_ttype type, - int start_idx, int end_idx, - source_range *out_range) -{ +get_source_location_for_substring (cpp_reader *pfile, + string_concat_db *concats, + location_t strloc, + enum cpp_ttype type, + int caret_idx, int start_idx, int end_idx, + source_location *out_loc) +{ + gcc_checking_assert (caret_idx >= 0); gcc_checking_assert (start_idx >= 0); gcc_checking_assert (end_idx >= 0); - gcc_assert (out_range); + gcc_assert (out_loc); cpp_substring_ranges ranges; const char *err @@ -1433,17 +1441,56 @@ get_source_range_for_substring (cpp_reader *pfile, if (err) return err; + if (caret_idx >= ranges.get_num_ranges ()) + return "caret_idx out of range"; if (start_idx >= ranges.get_num_ranges ()) return "start_idx out of range"; if (end_idx >= ranges.get_num_ranges ()) return "end_idx out of range"; - out_range->m_start = ranges.get_range (start_idx).m_start; - out_range->m_finish = ranges.get_range (end_idx).m_finish; + *out_loc = make_location (ranges.get_range (caret_idx).m_start, + ranges.get_range (start_idx).m_start, + ranges.get_range (end_idx).m_finish); + return NULL; +} + +/* Attempt to populate *OUT_RANGE with source location information on the + given character within the string literal found at STRLOC. + CHAR_IDX refers to an offset within the execution character set. + If CONCATS is non-NULL, then any string literals that the token at + STRLOC was concatenated with are also considered. + + This is implemented by re-parsing the relevant source line(s). + + Return NULL if successful, or an error message if any errors occurred. + Error messages are intended for GCC developers (to help debugging) rather + than for end-users. */ + +static const char * +get_source_range_for_char (cpp_reader *pfile, + string_concat_db *concats, + location_t strloc, + enum cpp_ttype type, + int char_idx, + source_range *out_range) +{ + gcc_checking_assert (char_idx >= 0); + gcc_assert (out_range); + + cpp_substring_ranges ranges; + const char *err + = get_substring_ranges_for_loc (pfile, concats, strloc, type, ranges); + if (err) + return err; + + if (char_idx >= ranges.get_num_ranges ()) + return "char_idx out of range"; + + *out_range = ranges.get_range (char_idx); return NULL; } -/* As get_source_range_for_substring, but write to *OUT the number +/* As get_source_range_for_char, but write to *OUT the number of ranges that are available. */ const char * @@ -1939,8 +1986,8 @@ assert_char_at_range (const location &loc, source_range actual_range; const char *err - = get_source_range_for_substring (pfile, concats, strloc, type, - idx, idx, &actual_range); + = get_source_range_for_char (pfile, concats, strloc, type, idx, + &actual_range); if (should_have_column_data_p (strloc)) ASSERT_EQ_AT (loc, NULL, err); else @@ -2789,9 +2836,8 @@ test_lexer_string_locations_concatenation_2 (const line_table_case &case_) this case. */ source_range actual_range; const char *err - = get_source_range_for_substring (test.m_parser, &test.m_concats, - initial_loc, type, 0, 0, - &actual_range); + = get_source_range_for_char (test.m_parser, &test.m_concats, + initial_loc, type, 0, &actual_range); ASSERT_STREQ ("range starts after LINE_MAP_MAX_LOCATION_WITH_COLS", err); return; } |