Mercurial > hg > CbC > CbC_gcc
diff gcc/input.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/input.c Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/input.c Thu Oct 25 07:37:49 2018 +0900 @@ -1,5 +1,5 @@ /* Data and functions related to line maps and input files. - Copyright (C) 2004-2017 Free Software Foundation, Inc. + Copyright (C) 2004-2018 Free Software Foundation, Inc. This file is part of GCC. @@ -741,29 +741,27 @@ The line is not nul-terminated. The returned pointer is only valid until the next call of location_get_source_line. Note that the line can contain several null characters, - so LINE_LEN, if non-null, points to the actual length of the line. - If the function fails, NULL is returned. */ - -const char * -location_get_source_line (const char *file_path, int line, - int *line_len) + so the returned value's length has the actual length of the line. + If the function fails, a NULL char_span is returned. */ + +char_span +location_get_source_line (const char *file_path, int line) { char *buffer = NULL; ssize_t len; if (line == 0) - return NULL; + return char_span (NULL, 0); fcache *c = lookup_or_add_file_to_cache_tab (file_path); if (c == NULL) - return NULL; + return char_span (NULL, 0); bool read = read_line_num (c, line, &buffer, &len); - - if (read && line_len) - *line_len = len; - - return read ? buffer : NULL; + if (!read) + return char_span (NULL, 0); + + return char_span (buffer, len); } /* Determine if FILE_PATH missing a trailing newline on its final line. @@ -815,10 +813,10 @@ "<built-in>". */ expanded_location -expand_location_to_spelling_point (source_location loc) +expand_location_to_spelling_point (source_location loc, + enum location_aspect aspect) { - return expand_location_1 (loc, /*expansion_point_p=*/false, - LOCATION_ASPECT_CARET); + return expand_location_1 (loc, /*expansion_point_p=*/false, aspect); } /* The rich_location class within libcpp requires a way to expand @@ -1117,29 +1115,27 @@ expanded_location exploc = linemap_expand_location (line_table, map, loc); - if (0 == exploc.column) + if (exploc.column == 0) { /* Beginning of a new source line: draw the line. */ - int line_size; - const char *line_text = location_get_source_line (exploc.file, - exploc.line, - &line_size); + char_span line_text = location_get_source_line (exploc.file, + exploc.line); if (!line_text) break; fprintf (stream, "%s:%3i|loc:%5i|%.*s\n", exploc.file, exploc.line, loc, - line_size, line_text); + (int)line_text.length (), line_text.get_buffer ()); /* "loc" is at column 0, which means "the whole line". Render the locations *within* the line, by underlining it, showing the source_location numeric values at each column. */ - int max_col = (1 << map->m_column_and_range_bits) - 1; - if (max_col > line_size) - max_col = line_size + 1; + size_t max_col = (1 << map->m_column_and_range_bits) - 1; + if (max_col > line_text.length ()) + max_col = line_text.length () + 1; int indent = 14 + strlen (exploc.file); @@ -1401,24 +1397,32 @@ source_range src_range = get_range_from_loc (line_table, strlocs[i]); if (src_range.m_start >= LINEMAPS_MACRO_LOWEST_LOCATION (line_table)) - /* If the string is within a macro expansion, we can't get at the - end location. */ - return "macro expansion"; - - if (src_range.m_start >= LINE_MAP_MAX_LOCATION_WITH_COLS) - /* If so, we can't reliably determine where the token started within - its line. */ - return "range starts after LINE_MAP_MAX_LOCATION_WITH_COLS"; - - if (src_range.m_finish >= LINE_MAP_MAX_LOCATION_WITH_COLS) - /* If so, we can't reliably determine where the token finished within - its line. */ - return "range ends after LINE_MAP_MAX_LOCATION_WITH_COLS"; + { + /* If the string token was within a macro expansion, then we can + cope with it for the simple case where we have a single token. + Otherwise, bail out. */ + if (src_range.m_start != src_range.m_finish) + return "macro expansion"; + } + else + { + if (src_range.m_start >= LINE_MAP_MAX_LOCATION_WITH_COLS) + /* If so, we can't reliably determine where the token started within + its line. */ + return "range starts after LINE_MAP_MAX_LOCATION_WITH_COLS"; + + if (src_range.m_finish >= LINE_MAP_MAX_LOCATION_WITH_COLS) + /* If so, we can't reliably determine where the token finished + within its line. */ + return "range ends after LINE_MAP_MAX_LOCATION_WITH_COLS"; + } expanded_location start - = expand_location_to_spelling_point (src_range.m_start); + = expand_location_to_spelling_point (src_range.m_start, + LOCATION_ASPECT_START); expanded_location finish - = expand_location_to_spelling_point (src_range.m_finish); + = expand_location_to_spelling_point (src_range.m_finish, + LOCATION_ASPECT_FINISH); if (start.file != finish.file) return "range endpoints are in different files"; if (start.line != finish.line) @@ -1426,37 +1430,44 @@ if (start.column > finish.column) return "range endpoints are reversed"; - int line_width; - const char *line = location_get_source_line (start.file, start.line, - &line_width); - if (line == NULL) + char_span line = location_get_source_line (start.file, start.line); + if (!line) return "unable to read source line"; /* Determine the location of the literal (including quotes and leading prefix chars, such as the 'u' in a u"" token). */ - const char *literal = line + start.column - 1; - int literal_length = finish.column - start.column + 1; + size_t literal_length = finish.column - start.column + 1; /* Ensure that we don't crash if we got the wrong location. */ - if (line_width < (start.column - 1 + literal_length)) + if (line.length () < (start.column - 1 + literal_length)) return "line is not wide enough"; + char_span literal = line.subspan (start.column - 1, literal_length); + cpp_string from; from.len = literal_length; /* Make a copy of the literal, to avoid having to rely on the lifetime of the copy of the line within the cache. This will be released by the auto_cpp_string_vec dtor. */ - from.text = XDUPVEC (unsigned char, literal, literal_length); + from.text = (unsigned char *)literal.xstrdup (); strs.safe_push (from); /* For very long lines, a new linemap could have started halfway through the token. Ensure that the loc_reader uses the linemap of the *end* of the token for its start location. */ + const line_map_ordinary *start_ord_map; + linemap_resolve_location (line_table, src_range.m_start, + LRK_SPELLING_LOCATION, &start_ord_map); const line_map_ordinary *final_ord_map; linemap_resolve_location (line_table, src_range.m_finish, - LRK_MACRO_EXPANSION_POINT, &final_ord_map); + LRK_SPELLING_LOCATION, &final_ord_map); + /* Bulletproofing. We ought to only have different ordinary maps + for start vs finish due to line-length jumps. */ + if (start_ord_map != final_ord_map + && start_ord_map->to_file != final_ord_map->to_file) + return "start and finish are spelled in different ordinary maps"; location_t start_loc = linemap_position_for_line_and_column (line_table, final_ord_map, start.line, start.column); @@ -1595,6 +1606,21 @@ /* Selftests of location handling. */ +/* Verify that compare() on linenum_type handles comparisons over the full + range of the type. */ + +static void +test_linenum_comparisons () +{ + linenum_type min_line (0); + linenum_type max_line (0xffffffff); + ASSERT_EQ (0, compare (min_line, min_line)); + ASSERT_EQ (0, compare (max_line, max_line)); + + ASSERT_GT (compare (max_line, min_line), 0); + ASSERT_LT (compare (min_line, max_line), 0); +} + /* Helper function for verifying location data: when location_t values are > LINE_MAP_MAX_LOCATION_WITH_COLS, they are treated as having column 0. */ @@ -1893,24 +1919,23 @@ "This is the 3rd line"); /* Read back a specific line from the tempfile. */ - int line_size; - const char *source_line = location_get_source_line (tmp.get_filename (), - 3, &line_size); - ASSERT_TRUE (source_line != NULL); - ASSERT_EQ (20, line_size); + char_span source_line = location_get_source_line (tmp.get_filename (), 3); + ASSERT_TRUE (source_line); + ASSERT_TRUE (source_line.get_buffer () != NULL); + ASSERT_EQ (20, source_line.length ()); ASSERT_TRUE (!strncmp ("This is the 3rd line", - source_line, line_size)); - - source_line = location_get_source_line (tmp.get_filename (), - 2, &line_size); - ASSERT_TRUE (source_line != NULL); - ASSERT_EQ (21, line_size); + source_line.get_buffer (), source_line.length ())); + + source_line = location_get_source_line (tmp.get_filename (), 2); + ASSERT_TRUE (source_line); + ASSERT_TRUE (source_line.get_buffer () != NULL); + ASSERT_EQ (21, source_line.length ()); ASSERT_TRUE (!strncmp ("This is the test text", - source_line, line_size)); - - source_line = location_get_source_line (tmp.get_filename (), - 4, &line_size); - ASSERT_TRUE (source_line == NULL); + source_line.get_buffer (), source_line.length ())); + + source_line = location_get_source_line (tmp.get_filename (), 4); + ASSERT_FALSE (source_line); + ASSERT_TRUE (source_line.get_buffer () == NULL); } /* Tests of lexing. */ @@ -2099,14 +2124,14 @@ cpp_opts->narrow_charset = "IBM1047"; cpp_callbacks *callbacks = cpp_get_callbacks (test.m_parser); - callbacks->error = on_error; + callbacks->diagnostic = on_diagnostic; } - static bool on_error (cpp_reader *pfile ATTRIBUTE_UNUSED, - int level ATTRIBUTE_UNUSED, - int reason ATTRIBUTE_UNUSED, - rich_location *richloc ATTRIBUTE_UNUSED, - const char *msgid, va_list *ap ATTRIBUTE_UNUSED) + static bool on_diagnostic (cpp_reader *pfile ATTRIBUTE_UNUSED, + enum cpp_diagnostic_level level ATTRIBUTE_UNUSED, + enum cpp_warning_reason reason ATTRIBUTE_UNUSED, + rich_location *richloc ATTRIBUTE_UNUSED, + const char *msgid, va_list *ap ATTRIBUTE_UNUSED) ATTRIBUTE_FPTR_PRINTF(5,0) { gcc_assert (s_singleton); @@ -2136,53 +2161,53 @@ ebcdic_execution_charset *ebcdic_execution_charset::s_singleton; -/* A lexer_test_options subclass that records a list of error +/* A lexer_test_options subclass that records a list of diagnostic messages emitted by the lexer. */ -class lexer_error_sink : public lexer_test_options +class lexer_diagnostic_sink : public lexer_test_options { public: - lexer_error_sink () + lexer_diagnostic_sink () { gcc_assert (s_singleton == NULL); s_singleton = this; } - ~lexer_error_sink () + ~lexer_diagnostic_sink () { gcc_assert (s_singleton == this); s_singleton = NULL; int i; char *str; - FOR_EACH_VEC_ELT (m_errors, i, str) + FOR_EACH_VEC_ELT (m_diagnostics, i, str) free (str); } void apply (lexer_test &test) FINAL OVERRIDE { cpp_callbacks *callbacks = cpp_get_callbacks (test.m_parser); - callbacks->error = on_error; + callbacks->diagnostic = on_diagnostic; } - static bool on_error (cpp_reader *pfile ATTRIBUTE_UNUSED, - int level ATTRIBUTE_UNUSED, - int reason ATTRIBUTE_UNUSED, - rich_location *richloc ATTRIBUTE_UNUSED, - const char *msgid, va_list *ap) + static bool on_diagnostic (cpp_reader *pfile ATTRIBUTE_UNUSED, + enum cpp_diagnostic_level level ATTRIBUTE_UNUSED, + enum cpp_warning_reason reason ATTRIBUTE_UNUSED, + rich_location *richloc ATTRIBUTE_UNUSED, + const char *msgid, va_list *ap) ATTRIBUTE_FPTR_PRINTF(5,0) { char *msg = xvasprintf (msgid, *ap); - s_singleton->m_errors.safe_push (msg); + s_singleton->m_diagnostics.safe_push (msg); return true; } - auto_vec<char *> m_errors; + auto_vec<char *> m_diagnostics; private: - static lexer_error_sink *s_singleton; + static lexer_diagnostic_sink *s_singleton; }; -lexer_error_sink *lexer_error_sink::s_singleton; +lexer_diagnostic_sink *lexer_diagnostic_sink::s_singleton; /* Constructor. Override line_table with a new instance based on CASE_, and write CONTENT to a tempfile. Create a cpp_reader, and use it to @@ -3396,21 +3421,21 @@ { const char *content = "R\"ouch()ouCh\" /* etc */"; - lexer_error_sink errors; - lexer_test test (case_, content, &errors); + lexer_diagnostic_sink diagnostics; + lexer_test test (case_, content, &diagnostics); test.m_implicitly_expect_EOF = false; /* Attempt to parse the raw string. */ const cpp_token *tok = test.get_token (); ASSERT_EQ (tok->type, CPP_EOF); - ASSERT_EQ (1, errors.m_errors.length ()); + ASSERT_EQ (1, diagnostics.m_diagnostics.length ()); /* We expect the message "unterminated raw string" in the "cpplib" translation domain. It's not clear that dgettext is available on all supported hosts, so this assertion is commented-out for now. ASSERT_STREQ (dgettext ("cpplib", "unterminated raw string"), - errors.m_errors[0]); + diagnostics.m_diagnostics[0]); */ } @@ -3528,6 +3553,7 @@ void input_c_tests () { + test_linenum_comparisons (); test_should_have_column_data_p (); test_unknown_location (); test_builtins ();