if (tok_type == CPP_OTHER)
return "unrecognized string type";
- return get_location_within_string (parse_in, g_string_concat_db,
+ return get_location_within_string (parse_in,
+ global_dc->get_file_cache (),
+ g_string_concat_db,
substr_loc.get_fmt_string_loc (),
tok_type,
substr_loc.get_caret_idx (),
if (caret.column > finish.column)
return NULL;
- char_span line = location_get_source_line (start.file, start.line);
+ char_span line
+ = global_dc->get_file_cache ().get_source_line (start.file, start.line);
if (!line)
return NULL;
on the line (up to or before EXPLOC). */
static bool
-get_visual_column (expanded_location exploc,
+get_visual_column (file_cache &fc,
+ expanded_location exploc,
unsigned int *out,
unsigned int *first_nws,
unsigned int tab_width)
{
- char_span line = location_get_source_line (exploc.file, exploc.line);
+ char_span line = fc.get_source_line (exploc.file, exploc.line);
if (!line)
return false;
if ((size_t)exploc.column > line.length ())
Otherwise, return false, leaving *FIRST_NWS untouched. */
static bool
-get_first_nws_vis_column (const char *file, int line_num,
+get_first_nws_vis_column (file_cache &fc,
+ const char *file, int line_num,
unsigned int *first_nws,
unsigned int tab_width)
{
gcc_assert (first_nws);
- char_span line = location_get_source_line (file, line_num);
+ char_span line = fc.get_source_line (file, line_num);
if (!line)
return false;
unsigned int vis_column = 0;
Return true if such an unindent/outdent is detected. */
static bool
-detect_intervening_unindent (const char *file,
+detect_intervening_unindent (file_cache &fc,
+ const char *file,
int body_line,
int next_stmt_line,
unsigned int vis_column,
for (int line = body_line + 1; line < next_stmt_line; line++)
{
unsigned int line_vis_column;
- if (get_first_nws_vis_column (file, line, &line_vis_column, tab_width))
+ if (get_first_nws_vis_column (fc, file, line, &line_vis_column, tab_width))
if (line_vis_column < vis_column)
return true;
}
if (next_stmt_exploc.file != body_exploc.file)
return false;
+ file_cache &fc = global_dc->get_file_cache ();
+
/* If NEXT_STMT_LOC and BODY_LOC are on the same line, consider
the location of the guard.
gcc_assert (guard_exploc.line == next_stmt_exploc.line);
unsigned int guard_vis_column;
unsigned int guard_line_first_nws;
- if (!get_visual_column (guard_exploc,
+ if (!get_visual_column (fc,
+ guard_exploc,
&guard_vis_column,
&guard_line_first_nws, tab_width))
return false;
the case for input files containing #line directives, and these
are often for autogenerated sources (e.g. from .md files), where
it's not clear that it's meaningful to look at indentation. */
- if (!get_visual_column (next_stmt_exploc,
+ if (!get_visual_column (fc,
+ next_stmt_exploc,
&next_stmt_vis_column,
&next_stmt_line_first_nws, tab_width))
return false;
- if (!get_visual_column (body_exploc,
+ if (!get_visual_column (fc,
+ body_exploc,
&body_vis_column,
&body_line_first_nws, tab_width))
return false;
- if (!get_visual_column (guard_exploc,
+ if (!get_visual_column (fc,
+ guard_exploc,
&guard_vis_column,
&guard_line_first_nws, tab_width))
return false;
/* Don't warn if there is an unindent between the two statements. */
int vis_column = MIN (next_stmt_vis_column, body_vis_column);
- if (detect_intervening_unindent (body_exploc.file, body_exploc.line,
+ if (detect_intervening_unindent (fc,
+ body_exploc.file, body_exploc.line,
next_stmt_exploc.line,
vis_column, tab_width))
return false;
static void
assert_get_visual_column_succeeds (const location &loc,
+ file_cache &fc,
const char *file, int line, int column,
const unsigned int tab_width,
unsigned int expected_visual_column,
exploc.sysp = false;
unsigned int actual_visual_column;
unsigned int actual_first_nws;
- bool result = get_visual_column (exploc,
+ bool result = get_visual_column (fc,
+ exploc,
&actual_visual_column,
&actual_first_nws, tab_width);
ASSERT_TRUE_AT (loc, result);
/* Verify that the given call to get_visual_column succeeds, with
the given results. */
-#define ASSERT_GET_VISUAL_COLUMN_SUCCEEDS(FILENAME, LINE, COLUMN, \
+#define ASSERT_GET_VISUAL_COLUMN_SUCCEEDS(FILE_CACHE, \
+ FILENAME, LINE, COLUMN, \
TAB_WIDTH, \
EXPECTED_VISUAL_COLUMN, \
EXPECTED_FIRST_NWS) \
SELFTEST_BEGIN_STMT \
assert_get_visual_column_succeeds (SELFTEST_LOCATION, \
+ FILE_CACHE, \
FILENAME, LINE, COLUMN, \
TAB_WIDTH, \
EXPECTED_VISUAL_COLUMN, \
static void
assert_get_visual_column_fails (const location &loc,
+ file_cache &fc,
const char *file, int line, int column,
const unsigned int tab_width)
{
exploc.sysp = false;
unsigned int actual_visual_column;
unsigned int actual_first_nws;
- bool result = get_visual_column (exploc,
+ bool result = get_visual_column (fc,
+ exploc,
&actual_visual_column,
&actual_first_nws, tab_width);
ASSERT_FALSE_AT (loc, result);
/* Verify that the given call to get_visual_column fails gracefully. */
-#define ASSERT_GET_VISUAL_COLUMN_FAILS(FILENAME, LINE, COLUMN, \
+#define ASSERT_GET_VISUAL_COLUMN_FAILS(FILE_CACHE, \
+ FILENAME, LINE, COLUMN, \
TAB_WIDTH) \
SELFTEST_BEGIN_STMT \
assert_get_visual_column_fails (SELFTEST_LOCATION, \
+ FILE_CACHE, \
FILENAME, LINE, COLUMN, \
TAB_WIDTH); \
SELFTEST_END_STMT
"\t line 2\n");
line_table_test ltt;
temp_source_file tmp (SELFTEST_LOCATION, ".txt", content);
+ file_cache fc;
const unsigned int tab_width = 8;
const char *file = tmp.get_filename ();
/* Line 1 (space-based indentation). */
{
const int line = 1;
- ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 1, tab_width, 0, 0);
- ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 2, tab_width, 1, 1);
- ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 3, tab_width, 2, 2);
+ ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc, file, line, 1, tab_width, 0, 0);
+ ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc, file, line, 2, tab_width, 1, 1);
+ ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc, file, line, 3, tab_width, 2, 2);
/* first_nws should have stopped increasing. */
- ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 4, tab_width, 3, 2);
+ ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc, file, line, 4, tab_width, 3, 2);
/* Verify the end-of-line boundary. */
- ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 8, tab_width, 7, 2);
- ASSERT_GET_VISUAL_COLUMN_FAILS (file, line, 9, tab_width);
+ ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc, file, line, 8, tab_width, 7, 2);
+ ASSERT_GET_VISUAL_COLUMN_FAILS (fc, file, line, 9, tab_width);
}
/* Line 2 (tab-based indentation). */
{
const int line = 2;
- ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 1, tab_width, 0, 0);
- ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 2, tab_width, 8, 8);
- ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 3, tab_width, 9, 9);
+ ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc, file, line, 1, tab_width, 0, 0);
+ ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc, file, line, 2, tab_width, 8, 8);
+ ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc, file, line, 3, tab_width, 9, 9);
/* first_nws should have stopped increasing. */
- ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 4, tab_width, 10, 9);
+ ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc, file, line, 4, tab_width, 10, 9);
/* Verify the end-of-line boundary. */
- ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (file, line, 8, tab_width, 14, 9);
- ASSERT_GET_VISUAL_COLUMN_FAILS (file, line, 9, tab_width);
+ ASSERT_GET_VISUAL_COLUMN_SUCCEEDS (fc, file, line, 8, tab_width, 14, 9);
+ ASSERT_GET_VISUAL_COLUMN_FAILS (fc, file, line, 9, tab_width);
}
}
{
/* Try to get the actual source text for the condition; if that fails pretty
print the resulting tree. */
- char *str = get_source_text_between (condition.get_start (),
+ char *str = get_source_text_between (global_dc->get_file_cache (),
+ condition.get_start (),
condition.get_finish ());
if (!str)
{
sarif_builder::get_sarif_column (expanded_location exploc) const
{
cpp_char_column_policy policy (m_tabstop, cpp_wcwidth);
- return location_compute_display_column (exploc, policy);
+ return location_compute_display_column (m_context->get_file_cache (),
+ exploc, policy);
}
/* Make a region object (SARIF v2.1.0 section 3.30) for LOC,
{
/* Let input.cc handle any charset conversion. */
char_span utf8_content
- = m_context->get_file_cache ()->get_source_file_content (filename);
+ = m_context->get_file_cache ().get_source_file_content (filename);
if (!utf8_content)
return NULL;
for (int line = start_line; line <= end_line; line++)
{
char_span line_content
- = m_context->get_file_cache ()->get_source_line (filename, line);
+ = m_context->get_file_cache ().get_source_line (filename, line);
if (!line_content.get_buffer ())
return NULL;
result.reserve (line_content.length () + 1);
class exploc_with_display_col : public expanded_location
{
public:
- exploc_with_display_col (const expanded_location &exploc,
+ exploc_with_display_col (file_cache &fc,
+ const expanded_location &exploc,
const cpp_char_column_policy &policy,
enum location_aspect aspect)
: expanded_location (exploc),
- m_display_col (location_compute_display_column (exploc, policy))
+ m_display_col (location_compute_display_column (fc, exploc, policy))
{
if (exploc.column > 0)
{
expanded_location prev_exploc (exploc);
prev_exploc.column--;
int prev_display_col
- = (location_compute_display_column (prev_exploc, policy));
+ = (location_compute_display_column (fc, prev_exploc, policy));
m_display_col = prev_display_col + 1;
}
}
const diagnostic_source_printing_options &m_options;
const line_maps *m_line_table;
+ file_cache &m_file_cache;
pretty_printer *m_pp;
char_display_policy m_policy;
location_t m_primary_loc;
e.g. in test_diagnostic_show_locus_one_liner_utf8(). */
static layout_range
-make_range (int start_line, int start_col, int end_line, int end_col)
+make_range (file_cache &fc,
+ int start_line, int start_col, int end_line, int end_col)
{
const expanded_location start_exploc
= {"", start_line, start_col, NULL, false};
const expanded_location finish_exploc
= {"", end_line, end_col, NULL, false};
- return layout_range (exploc_with_display_col (start_exploc, def_policy (),
+ return layout_range (exploc_with_display_col (fc,
+ start_exploc, def_policy (),
LOCATION_ASPECT_START),
- exploc_with_display_col (finish_exploc, def_policy (),
+ exploc_with_display_col (fc,
+ finish_exploc, def_policy (),
LOCATION_ASPECT_FINISH),
SHOW_RANGE_WITHOUT_CARET,
- exploc_with_display_col (start_exploc, def_policy (),
+ exploc_with_display_col (fc,
+ start_exploc, def_policy (),
LOCATION_ASPECT_CARET),
0, NULL);
}
static void
test_layout_range_for_single_point ()
{
- layout_range point = make_range (7, 10, 7, 10);
+ file_cache fc;
+ layout_range point = make_range (fc, 7, 10, 7, 10);
/* Tests for layout_range::contains_point. */
static void
test_layout_range_for_single_line ()
{
- layout_range example_a = make_range (2, 22, 2, 38);
+ file_cache fc;
+ layout_range example_a = make_range (fc, 2, 22, 2, 38);
/* Tests for layout_range::contains_point. */
static void
test_layout_range_for_multiple_lines ()
{
- layout_range example_b = make_range (3, 14, 5, 8);
+ file_cache fc;
+ layout_range example_b = make_range (fc, 3, 14, 5, 8);
/* Tests for layout_range::contains_point. */
pretty_printer *pp)
: m_options (context.m_source_printing),
m_line_table (richloc.get_line_table ()),
+ m_file_cache (context.get_file_cache ()),
m_pp (pp ? pp : context.printer),
m_policy (make_policy (context, richloc)),
m_primary_loc (richloc.get_range (0)->m_loc),
- m_exploc (richloc.get_expanded_location (0), m_policy,
+ m_exploc (m_file_cache,
+ richloc.get_expanded_location (0), m_policy,
LOCATION_ASPECT_CARET),
m_colorizer (m_pp, diagnostic_kind),
m_diagnostic_path_p (diagnostic_kind == DK_DIAGNOSTIC_PATH),
/* Everything is now known to be in the correct source file,
but it may require further sanitization. */
- layout_range ri (exploc_with_display_col (start, m_policy,
+ layout_range ri (exploc_with_display_col (m_file_cache,
+ start, m_policy,
LOCATION_ASPECT_START),
- exploc_with_display_col (finish, m_policy,
+ exploc_with_display_col (m_file_cache,
+ finish, m_policy,
LOCATION_ASPECT_FINISH),
loc_range->m_range_display_kind,
- exploc_with_display_col (caret, m_policy,
+ exploc_with_display_col (m_file_cache,
+ caret, m_policy,
LOCATION_ASPECT_CARET),
original_idx, loc_range->m_label);
return;
}
- const char_span line = location_get_source_line (m_exploc.file,
- m_exploc.line);
+ const char_span line = m_file_cache.get_source_line (m_exploc.file,
+ m_exploc.line);
if (!line)
{
/* Nothing to do, we couldn't find the source line. */
/* Get the range of bytes or display columns that HINT would affect. */
static column_range
-get_affected_range (const cpp_char_column_policy &policy,
+get_affected_range (file_cache &fc,
+ const cpp_char_column_policy &policy,
const fixit_hint *hint, enum column_unit col_unit)
{
expanded_location exploc_start = expand_location (hint->get_start_loc ());
int finish_column;
if (col_unit == CU_DISPLAY_COLS)
{
- start_column = location_compute_display_column (exploc_start, policy);
+ start_column = location_compute_display_column (fc, exploc_start, policy);
if (hint->insertion_p ())
finish_column = start_column - 1;
else
- finish_column = location_compute_display_column (exploc_finish, policy);
+ finish_column
+ = location_compute_display_column (fc, exploc_finish, policy);
}
else
{
/* Get the range of display columns that would be printed for HINT. */
static column_range
-get_printed_columns (const cpp_char_column_policy &policy,
+get_printed_columns (file_cache &fc,
+ const cpp_char_column_policy &policy,
const fixit_hint *hint)
{
expanded_location exploc = expand_location (hint->get_start_loc ());
- int start_column = location_compute_display_column (exploc, policy);
+ int start_column = location_compute_display_column (fc, exploc, policy);
int hint_width = cpp_display_width (hint->get_string (), hint->get_length (),
policy);
int final_hint_column = start_column + hint_width - 1;
{
exploc = expand_location (hint->get_next_loc ());
--exploc.column;
- int finish_column = location_compute_display_column (exploc, policy);
+ int finish_column = location_compute_display_column (fc, exploc, policy);
return column_range (start_column,
MAX (finish_column, final_hint_column));
}
class line_corrections
{
public:
- line_corrections (const char_display_policy &policy,
+ line_corrections (file_cache &fc,
+ const char_display_policy &policy,
const char *filename,
linenum_type row)
- : m_policy (policy), m_filename (filename), m_row (row)
+ : m_file_cache (fc),
+ m_policy (policy), m_filename (filename), m_row (row)
{}
~line_corrections ();
void add_hint (const fixit_hint *hint);
+ file_cache &m_file_cache;
const char_display_policy &m_policy;
const char *m_filename;
linenum_type m_row;
class source_line
{
public:
- source_line (const char *filename, int line);
+ source_line (file_cache &fc, const char *filename, int line);
char_span as_span () { return char_span (chars, width); }
/* source_line's ctor. */
-source_line::source_line (const char *filename, int line)
+source_line::source_line (file_cache &fc, const char *filename, int line)
{
- char_span span = location_get_source_line (filename, line);
+ char_span span = fc.get_source_line (filename, line);
chars = span.get_buffer ();
width = span.length ();
}
void
line_corrections::add_hint (const fixit_hint *hint)
{
- column_range affected_bytes = get_affected_range (m_policy, hint, CU_BYTES);
- column_range affected_columns = get_affected_range (m_policy, hint,
- CU_DISPLAY_COLS);
- column_range printed_columns = get_printed_columns (m_policy, hint);
+ column_range affected_bytes
+ = get_affected_range (m_file_cache, m_policy, hint, CU_BYTES);
+ column_range affected_columns
+ = get_affected_range (m_file_cache, m_policy, hint, CU_DISPLAY_COLS);
+ column_range printed_columns
+ = get_printed_columns (m_file_cache, m_policy, hint);
/* Potentially consolidate. */
if (!m_corrections.is_empty ())
affected_bytes.start - 1);
/* Try to read the source. */
- source_line line (m_filename, m_row);
+ source_line line (m_file_cache, m_filename, m_row);
if (line.chars && between.finish < line.width)
{
/* Consolidate into the last correction:
{
/* Build a list of correction instances for the line,
potentially consolidating hints (for the sake of readability). */
- line_corrections corrections (m_policy, m_exploc.file, row);
+ line_corrections corrections (m_file_cache, m_policy, m_exploc.file, row);
for (unsigned int i = 0; i < m_fixit_hints.length (); i++)
{
const fixit_hint *hint = m_fixit_hints[i];
void
layout::print_line (linenum_type row)
{
- char_span line = location_get_source_line (m_exploc.file, row);
+ char_span line = m_file_cache.get_source_line (m_exploc.file, row);
if (!line)
return;
const int emoji_col = 102;
temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
+ file_cache fc;
line_table_test ltt (case_);
linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1);
ASSERT_EQ (1, LOCATION_LINE (line_end));
ASSERT_EQ (line_bytes, LOCATION_COLUMN (line_end));
- char_span lspan = location_get_source_line (tmp.get_filename (), 1);
+ char_span lspan = fc.get_source_line (tmp.get_filename (), 1);
ASSERT_EQ (line_display_cols,
cpp_display_width (lspan.get_buffer (), lspan.length (),
def_policy ()));
ASSERT_EQ (line_display_cols,
- location_compute_display_column (expand_location (line_end),
+ location_compute_display_column (fc,
+ expand_location (line_end),
def_policy ()));
ASSERT_EQ (0, memcmp (lspan.get_buffer () + (emoji_col - 1),
"\xf0\x9f\x98\x82\xf0\x9f\x98\x82", 8));
ASSERT_EQ (7, extra_width[10]);
temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
+ file_cache fc;
line_table_test ltt (case_);
linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1);
return;
/* Check that cpp_display_width handles the tabs as expected. */
- char_span lspan = location_get_source_line (tmp.get_filename (), 1);
+ char_span lspan = fc.get_source_line (tmp.get_filename (), 1);
ASSERT_EQ ('\t', *(lspan.get_buffer () + (tab_col - 1)));
for (int tabstop = 1; tabstop != num_tabstops; ++tabstop)
{
cpp_display_width (lspan.get_buffer (), lspan.length (),
policy));
ASSERT_EQ (line_bytes + extra_width[tabstop],
- location_compute_display_column (expand_location (line_end),
+ location_compute_display_column (fc,
+ expand_location (line_end),
policy));
}
1111222233334444567890122223333456789999000011112222345678999900001
Byte columns. */
temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
+ file_cache fc;
line_table_test ltt (case_);
linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1);
ASSERT_EQ (1, LOCATION_LINE (line_end));
ASSERT_EQ (31, LOCATION_COLUMN (line_end));
- char_span lspan = location_get_source_line (tmp.get_filename (), 1);
+ char_span lspan = fc.get_source_line (tmp.get_filename (), 1);
ASSERT_EQ (25, cpp_display_width (lspan.get_buffer (), lspan.length (),
def_policy ()));
- ASSERT_EQ (25, location_compute_display_column (expand_location (line_end),
+ ASSERT_EQ (25, location_compute_display_column (fc,
+ expand_location (line_end),
def_policy ()));
test_one_liner_simple_caret_utf8 ();
" double x;\n" /* line 4. */
" double y;\n" /* line 5. */
";\n"); /* line 6. */
- temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
+ temp_source_file tmp (SELFTEST_LOCATION, ".c", content,
+
+ /* gcc_rich_location::add_location_if_nearby implicitly
+ uses global_dc's file_cache, so we need to evict
+ tmp when we're done. */
+ &global_dc->get_file_cache ());
line_table_test ltt (case_);
const line_map_ordinary *ord_map
const char *content
= (" foo *f = (foo *)ptr->field;\n");
temp_source_file tmp (SELFTEST_LOCATION, ".C", content);
+ file_cache fc;
line_table_test ltt (case_);
const line_map_ordinary *ord_map
ASSERT_EQ (3, richloc.get_num_fixit_hints ());
const fixit_hint *hint_0 = richloc.get_fixit_hint (0);
ASSERT_EQ (column_range (12, 12),
- get_affected_range (policy, hint_0, CU_BYTES));
+ get_affected_range (fc, policy, hint_0, CU_BYTES));
ASSERT_EQ (column_range (12, 12),
- get_affected_range (policy, hint_0, CU_DISPLAY_COLS));
- ASSERT_EQ (column_range (12, 22), get_printed_columns (policy, hint_0));
+ get_affected_range (fc, policy, hint_0, CU_DISPLAY_COLS));
+ ASSERT_EQ (column_range (12, 22), get_printed_columns (fc, policy, hint_0));
const fixit_hint *hint_1 = richloc.get_fixit_hint (1);
ASSERT_EQ (column_range (18, 18),
- get_affected_range (policy, hint_1, CU_BYTES));
+ get_affected_range (fc, policy, hint_1, CU_BYTES));
ASSERT_EQ (column_range (18, 18),
- get_affected_range (policy, hint_1, CU_DISPLAY_COLS));
- ASSERT_EQ (column_range (18, 20), get_printed_columns (policy, hint_1));
+ get_affected_range (fc, policy, hint_1, CU_DISPLAY_COLS));
+ ASSERT_EQ (column_range (18, 20), get_printed_columns (fc, policy, hint_1));
const fixit_hint *hint_2 = richloc.get_fixit_hint (2);
ASSERT_EQ (column_range (29, 28),
- get_affected_range (policy, hint_2, CU_BYTES));
+ get_affected_range (fc, policy, hint_2, CU_BYTES));
ASSERT_EQ (column_range (29, 28),
- get_affected_range (policy, hint_2, CU_DISPLAY_COLS));
- ASSERT_EQ (column_range (29, 29), get_printed_columns (policy, hint_2));
+ get_affected_range (fc, policy, hint_2, CU_DISPLAY_COLS));
+ ASSERT_EQ (column_range (29, 29), get_printed_columns (fc, policy, hint_2));
/* Add each hint in turn to a line_corrections instance,
and verify that they are consolidated into one correction instance
as expected. */
- line_corrections lc (policy, tmp.get_filename (), 1);
+ line_corrections lc (fc, policy, tmp.get_filename (), 1);
/* The first replace hint by itself. */
lc.add_hint (hint_0);
/* Example where 3 fix-it hints are printed as one. */
{
test_diagnostic_context dc;
+ file_cache &fc = dc.get_file_cache ();
rich_location richloc (line_table, expr);
richloc.add_fixit_replace (open_paren, "const_cast<");
richloc.add_fixit_replace (close_paren, "> (");
ASSERT_EQ (3, richloc.get_num_fixit_hints ());
const fixit_hint *hint_0 = richloc.get_fixit_hint (0);
ASSERT_EQ (column_range (14, 14),
- get_affected_range (policy, hint_0, CU_BYTES));
+ get_affected_range (fc, policy, hint_0, CU_BYTES));
ASSERT_EQ (column_range (12, 12),
- get_affected_range (policy, hint_0, CU_DISPLAY_COLS));
- ASSERT_EQ (column_range (12, 22), get_printed_columns (policy, hint_0));
+ get_affected_range (fc, policy, hint_0, CU_DISPLAY_COLS));
+ ASSERT_EQ (column_range (12, 22), get_printed_columns (fc, policy, hint_0));
const fixit_hint *hint_1 = richloc.get_fixit_hint (1);
ASSERT_EQ (column_range (22, 22),
- get_affected_range (policy, hint_1, CU_BYTES));
+ get_affected_range (fc, policy, hint_1, CU_BYTES));
ASSERT_EQ (column_range (18, 18),
- get_affected_range (policy, hint_1, CU_DISPLAY_COLS));
- ASSERT_EQ (column_range (18, 20), get_printed_columns (policy, hint_1));
+ get_affected_range (fc, policy, hint_1, CU_DISPLAY_COLS));
+ ASSERT_EQ (column_range (18, 20), get_printed_columns (fc, policy, hint_1));
const fixit_hint *hint_2 = richloc.get_fixit_hint (2);
ASSERT_EQ (column_range (35, 34),
- get_affected_range (policy, hint_2, CU_BYTES));
+ get_affected_range (fc, policy, hint_2, CU_BYTES));
ASSERT_EQ (column_range (30, 29),
- get_affected_range (policy, hint_2, CU_DISPLAY_COLS));
- ASSERT_EQ (column_range (30, 30), get_printed_columns (policy, hint_2));
+ get_affected_range (fc, policy, hint_2, CU_DISPLAY_COLS));
+ ASSERT_EQ (column_range (30, 30), get_printed_columns (fc, policy, hint_2));
/* Add each hint in turn to a line_corrections instance,
and verify that they are consolidated into one correction instance
as expected. */
- line_corrections lc (policy, tmp.get_filename (), 1);
+ line_corrections lc (fc, policy, tmp.get_filename (), 1);
/* The first replace hint by itself. */
lc.add_hint (hint_0);
/* Two insertions, in the wrong order. */
{
test_diagnostic_context dc;
+ file_cache &fc = dc.get_file_cache ();
rich_location richloc (line_table, col_20);
richloc.add_fixit_insert_before (col_23, "{");
ASSERT_EQ (2, richloc.get_num_fixit_hints ());
const fixit_hint *hint_0 = richloc.get_fixit_hint (0);
ASSERT_EQ (column_range (23, 22),
- get_affected_range (policy, hint_0, CU_BYTES));
- ASSERT_EQ (column_range (23, 23), get_printed_columns (policy, hint_0));
+ get_affected_range (fc, policy, hint_0, CU_BYTES));
+ ASSERT_EQ (column_range (23, 23), get_printed_columns (fc, policy, hint_0));
const fixit_hint *hint_1 = richloc.get_fixit_hint (1);
ASSERT_EQ (column_range (21, 20),
- get_affected_range (policy, hint_1, CU_BYTES));
- ASSERT_EQ (column_range (21, 21), get_printed_columns (policy, hint_1));
+ get_affected_range (fc, policy, hint_1, CU_BYTES));
+ ASSERT_EQ (column_range (21, 21), get_printed_columns (fc, policy, hint_1));
/* Verify that they're printed correctly. */
diagnostic_show_locus (&dc, &richloc, DK_ERROR);
this->printer = XNEW (pretty_printer);
new (this->printer) pretty_printer ();
- m_file_cache = nullptr;
+ m_file_cache = new file_cache ();
memset (m_diagnostic_count, 0, sizeof m_diagnostic_count);
m_warning_as_error_requested = false;
m_n_opts = n_opts;
initialize_input_context (diagnostic_input_charset_callback ccb,
bool should_skip_bom)
{
- if (!m_file_cache)
- m_file_cache = new file_cache;
m_file_cache->initialize_input_context (ccb, should_skip_bom);
}
diagnostic_context::create_edit_context ()
{
delete m_edit_context_ptr;
- m_edit_context_ptr = new edit_context ();
+ gcc_assert (m_file_cache);
+ m_edit_context_ptr = new edit_context (*m_file_cache);
}
/* Initialize DIAGNOSTIC, where the message MSG has already been
Return -1 if the column is invalid (<= 0). */
static int
-convert_column_unit (enum diagnostics_column_unit column_unit,
+convert_column_unit (file_cache &fc,
+ enum diagnostics_column_unit column_unit,
int tabstop,
expanded_location s)
{
case DIAGNOSTICS_COLUMN_UNIT_DISPLAY:
{
cpp_char_column_policy policy (tabstop, cpp_wcwidth);
- return location_compute_display_column (s, policy);
+ return location_compute_display_column (fc, s, policy);
}
case DIAGNOSTICS_COLUMN_UNIT_BYTE:
int
diagnostic_context::converted_column (expanded_location s) const
{
- int one_based_col = convert_column_unit (m_column_unit, m_tabstop, s);
+ int one_based_col = convert_column_unit (get_file_cache (),
+ m_column_unit, m_tabstop, s);
if (one_based_col <= 0)
return -1;
return one_based_col + (m_column_origin - 1);
Use TABSTOP when handling DIAGNOSTICS_COLUMN_UNIT_DISPLAY. */
static void
-print_parseable_fixits (pretty_printer *pp, rich_location *richloc,
+print_parseable_fixits (file_cache &fc,
+ pretty_printer *pp, rich_location *richloc,
enum diagnostics_column_unit column_unit,
int tabstop)
{
location_t next_loc = hint->get_next_loc ();
expanded_location next_exploc = expand_location (next_loc);
int start_col
- = convert_column_unit (column_unit, tabstop, start_exploc);
+ = convert_column_unit (fc, column_unit, tabstop, start_exploc);
int next_col
- = convert_column_unit (column_unit, tabstop, next_exploc);
+ = convert_column_unit (fc, column_unit, tabstop, next_exploc);
pp_printf (pp, ":{%i:%i-%i:%i}:",
start_exploc.line, start_col,
next_exploc.line, next_col);
default:
break;
case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1:
- print_parseable_fixits (this->printer, diagnostic->richloc,
+ print_parseable_fixits (get_file_cache (),
+ this->printer, diagnostic->richloc,
DIAGNOSTICS_COLUMN_UNIT_BYTE,
m_tabstop);
pp_flush (this->printer);
break;
case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2:
- print_parseable_fixits (this->printer, diagnostic->richloc,
+ print_parseable_fixits (get_file_cache (),
+ this->printer, diagnostic->richloc,
DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
m_tabstop);
pp_flush (this->printer);
test_print_parseable_fixits_none ()
{
pretty_printer pp;
+ file_cache fc;
rich_location richloc (line_table, UNKNOWN_LOCATION);
- print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
+ print_parseable_fixits (fc, &pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
ASSERT_STREQ ("", pp_formatted_text (&pp));
}
test_print_parseable_fixits_insert ()
{
pretty_printer pp;
+ file_cache fc;
rich_location richloc (line_table, UNKNOWN_LOCATION);
linemap_add (line_table, LC_ENTER, false, "test.c", 0);
location_t where = linemap_position_for_column (line_table, 10);
richloc.add_fixit_insert_before (where, "added content");
- print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
+ print_parseable_fixits (fc, &pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n",
pp_formatted_text (&pp));
}
test_print_parseable_fixits_remove ()
{
pretty_printer pp;
+ file_cache fc;
rich_location richloc (line_table, UNKNOWN_LOCATION);
linemap_add (line_table, LC_ENTER, false, "test.c", 0);
where.m_finish = linemap_position_for_column (line_table, 20);
richloc.add_fixit_remove (where);
- print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
+ print_parseable_fixits (fc, &pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n",
pp_formatted_text (&pp));
}
test_print_parseable_fixits_replace ()
{
pretty_printer pp;
+ file_cache fc;
rich_location richloc (line_table, UNKNOWN_LOCATION);
linemap_add (line_table, LC_ENTER, false, "test.c", 0);
where.m_finish = linemap_position_for_column (line_table, 20);
richloc.add_fixit_replace (where, "replacement");
- print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
+ print_parseable_fixits (fc, &pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n",
pp_formatted_text (&pp));
}
const int tabstop = 8;
temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
+ file_cache fc;
const char *const fname = tmp.get_filename ();
linemap_add (line_table, LC_ENTER, false, fname, 0);
{
pretty_printer pp;
- print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE,
+ print_parseable_fixits (fc, &pp, &richloc,
+ DIAGNOSTICS_COLUMN_UNIT_BYTE,
tabstop);
snprintf (expected, buf_len,
"fix-it:%s:{1:12-1:18}:\"color\"\n", escaped_fname);
}
{
pretty_printer pp;
- print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
+ print_parseable_fixits (fc, &pp, &richloc,
+ DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
tabstop);
snprintf (expected, buf_len,
"fix-it:%s:{1:10-1:16}:\"color\"\n", escaped_fname);
void color_init (int value);
void urls_init (int value);
- void file_cache_init ();
-
void finish ();
void set_set_locations_callback (set_locations_callback_t cb)
return m_escape_format;
}
- file_cache *
+ file_cache &
get_file_cache () const
{
- return m_file_cache;
+ gcc_assert (m_file_cache);
+ return *m_file_cache;
}
edit_context *get_edit_context () const
class edited_file
{
public:
- edited_file (const char *filename);
+ edited_file (edit_context &ec, const char *filename);
static void delete_cb (edited_file *file);
const char *get_filename () const { return m_filename; }
return 0;
}
+ file_cache &get_file_cache () const
+ {
+ return m_edit_context.get_file_cache ();
+ }
+
private:
bool print_content (pretty_printer *pp);
void print_diff (pretty_printer *pp, bool show_filenames);
int start_of_run,
int end_of_run);
+ edit_context &m_edit_context;
const char *m_filename;
typed_splay_tree<int, edited_line *> m_edited_lines;
int m_num_lines;
class edited_line
{
public:
- edited_line (const char *filename, int line_num);
+ edited_line (file_cache &fc, const char *filename, int line_num);
~edited_line ();
static void delete_cb (edited_line *el);
/* edit_context's ctor. */
-edit_context::edit_context ()
-: m_valid (true),
+edit_context::edit_context (file_cache &fc)
+: m_file_cache (fc),
+ m_valid (true),
m_files (strcmp, NULL, edited_file::delete_cb)
{}
return *file;
/* Not found. */
- file = new edited_file (filename);
+ file = new edited_file (*this, filename);
m_files.insert (filename, file);
return *file;
}
/* edited_file's constructor. */
-edited_file::edited_file (const char *filename)
-: m_filename (filename),
+edited_file::edited_file (edit_context &ec, const char *filename)
+: m_edit_context (ec),
+ m_filename (filename),
m_edited_lines (line_comparator, NULL, edited_line::delete_cb),
m_num_lines (-1)
{
el->print_content (pp);
else
{
- char_span line = location_get_source_line (m_filename, line_num);
+ char_span line
+ = get_file_cache ().get_source_line (m_filename, line_num);
if (!line)
return false;
for (size_t i = 0; i < line.length (); i++)
else
{
/* Unchanged line. */
- char_span old_line = location_get_source_line (m_filename, line_num);
+ char_span old_line
+ = get_file_cache ().get_source_line (m_filename, line_num);
print_diff_line (pp, ' ', old_line.get_buffer (), old_line.length ());
line_num++;
}
gcc_assert (el_in_run);
if (el_in_run->actually_edited_p ())
{
- char_span old_line = location_get_source_line (m_filename, line_num);
+ char_span old_line
+ = get_file_cache ().get_source_line (m_filename, line_num);
print_diff_line (pp, '-', old_line.get_buffer (),
old_line.length ());
}
edited_line *el = get_line (line);
if (el)
return el;
- el = new edited_line (m_filename, line);
+ el = new edited_line (get_file_cache (), m_filename, line);
if (el->get_content () == NULL)
{
delete el;
while (true)
{
char_span line
- = location_get_source_line (m_filename, m_num_lines + 1);
+ = get_file_cache ().get_source_line (m_filename, m_num_lines + 1);
if (line)
m_num_lines++;
else
break;
}
}
- *missing_trailing_newline = location_missing_trailing_newline (m_filename);
+ *missing_trailing_newline
+ = get_file_cache ().missing_trailing_newline_p (m_filename);
return m_num_lines;
}
/* edited_line's ctor. */
-edited_line::edited_line (const char *filename, int line_num)
+edited_line::edited_line (file_cache &fc, const char *filename, int line_num)
: m_line_num (line_num),
m_content (NULL), m_len (0), m_alloc_sz (0),
m_line_events (),
m_predecessors ()
{
- char_span line = location_get_source_line (filename, line_num);
+ char_span line = fc.get_source_line (filename, line_num);
if (!line)
return;
m_len = line.length ();
{
const char *content = ("");
temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
auto_free <char *> result = edit.get_content (tmp.get_filename ());
ASSERT_STREQ ("", result);
}
"foo = bar.field;\n"
"/* after */\n");
temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
auto_free <char *> result = edit.get_content (tmp.get_filename ());
ASSERT_STREQ ("/* before */\n"
"foo = bar.field;\n"
"foo = bar.field;\n"
"/* after */");
temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
auto_free <char *> result = edit.get_content (tmp.get_filename ());
/* We should respect the omitted trailing newline. */
ASSERT_STREQ ("/* before */\n"
if (start > LINE_MAP_MAX_LOCATION_WITH_COLS)
return;
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&richloc);
auto_free <char *> new_content = edit.get_content (filename);
if (start <= LINE_MAP_MAX_LOCATION_WITH_COLS)
return;
/* Verify that the text was inserted after the end of "field". */
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&richloc);
auto_free <char *> new_content = edit.get_content (filename);
ASSERT_STREQ ("/* before */\n"
if (loc > LINE_MAP_MAX_LOCATION_WITH_COLS)
return;
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&richloc);
auto_free <char *> new_content = edit.get_content (filename);
ASSERT_STREQ ("/* before */\n"
richloc.add_fixit_insert_after ("/* inserted */");
ASSERT_TRUE (richloc.seen_impossible_fixit_p ());
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&richloc);
ASSERT_FALSE (edit.valid_p ());
ASSERT_EQ (NULL, edit.get_content (filename));
if (case_finish > LINE_MAP_MAX_LOCATION_WITH_COLS)
return;
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&richloc);
auto_free <char *> new_content = edit.get_content (filename);
ASSERT_STREQ ((" case 'a':\n"
rich_location richloc (line_table, field);
richloc.add_fixit_replace ("m_field");
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&richloc);
auto_free <char *> new_content = edit.get_content (filename);
if (finish <= LINE_MAP_MAX_LOCATION_WITH_COLS)
rich_location richloc (line_table, m_field);
richloc.add_fixit_replace ("field");
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&richloc);
auto_free <char *> new_content = edit.get_content (filename);
if (finish <= LINE_MAP_MAX_LOCATION_WITH_COLS)
if (finish > LINE_MAP_MAX_LOCATION_WITH_COLS)
return;
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&richloc);
auto_free <char *> new_content = edit.get_content (filename);
//ASSERT_STREQ ("foo\n = bar ();\n", new_content);
range.m_finish = finish;
richloc.add_fixit_remove (range);
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&richloc);
auto_free <char *> new_content = edit.get_content (filename);
if (finish <= LINE_MAP_MAX_LOCATION_WITH_COLS)
replace_b.add_fixit_replace (source_range::from_locations (c11, c15),
"meadow");
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&insert_a);
ASSERT_EQ (100, edit.get_effective_column (filename, 1, 100));
ASSERT_EQ (1, edit.get_effective_column (filename, 2, 1));
linemap_add (line_table, LC_ENTER, false, filename, 1);
linemap_position_for_column (line_table, 127);
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
/* A run of consecutive lines. */
change_line (edit, 2);
/* The order should not matter. Do r1 then r2. */
{
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&r1);
/* Verify state after first replacement. */
/* Try again, doing r2 then r1; the new_content should be the same. */
{
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&r2);
edit.add_fixits (&r1);
auto_free <char *> new_content = edit.get_content (tmp.get_filename ());
insert.add_fixit_insert_before ("change 1");
insert.add_fixit_insert_before ("change 2");
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
/* Attempting to add the fixits affecting the unreadable file
should transition the edit from valid to invalid. */
ASSERT_TRUE (edit.valid_p ());
/* Verify that attempting the insertion puts an edit_context
into an invalid state. */
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
ASSERT_TRUE (edit.valid_p ());
edit.add_fixits (&insert);
ASSERT_FALSE (edit.valid_p ());
/* Col 15 is at the end of the line, so the insertion
should succeed. */
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&richloc);
auto_free <char *> new_content = edit.get_content (tmp.get_filename ());
if (c15 <= LINE_MAP_MAX_LOCATION_WITH_COLS)
/* Col 16 is beyond the end of the line, so the insertion
should fail gracefully. */
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
ASSERT_TRUE (edit.valid_p ());
edit.add_fixits (&richloc);
ASSERT_FALSE (edit.valid_p ());
/* Col 14 is at the end of the line, so the replacement
should succeed. */
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
edit.add_fixits (&richloc);
auto_free <char *> new_content = edit.get_content (tmp.get_filename ());
if (c14 <= LINE_MAP_MAX_LOCATION_WITH_COLS)
/* Col 15 is after the end of the line, so the replacement
should fail; verify that the attempt fails gracefully. */
- edit_context edit;
+ file_cache fc;
+ edit_context edit (fc);
ASSERT_TRUE (edit.valid_p ());
edit.add_fixits (&richloc);
ASSERT_FALSE (edit.valid_p ());
class edit_context
{
public:
- edit_context ();
+ edit_context (file_cache &);
bool valid_p () const { return m_valid; }
char *generate_diff (bool show_filenames);
void print_diff (pretty_printer *pp, bool show_filenames);
+ file_cache &get_file_cache () const { return m_file_cache; }
+
private:
bool apply_fixit (const fixit_hint *hint);
edited_file *get_file (const char *filename);
edited_file &get_or_insert_file (const char *filename);
+ file_cache &m_file_cache;
bool m_valid;
typed_splay_tree<const char *, edited_file *> m_files;
};
#include "print-rtl.h"
#include "function-abi.h"
#include "common/common-target.h"
+#include "diagnostic.h"
#include "dwarf2out.h"
if (!filename)
return;
- char_span line = location_get_source_line (filename, linenum);
+ char_span line
+ = global_dc->get_file_cache ().get_source_line (filename, linenum);
if (!line)
return;
/* Return true if there is nothing on LOC's line before LOC. */
static bool
-blank_line_before_p (location_t loc)
+blank_line_before_p (file_cache &fc,
+ location_t loc)
{
expanded_location exploc = expand_location (loc);
- char_span line = location_get_source_line (exploc.file, exploc.line);
+ char_span line = fc.get_source_line (exploc.file, exploc.line);
if (!line)
return false;
if (line.length () < (size_t)exploc.column)
If true is returned then *OUT_START_OF_LINE is written to. */
static bool
-use_new_line (location_t insertion_point, location_t indent,
+use_new_line (file_cache &fc,
+ location_t insertion_point, location_t indent,
location_t *out_start_of_line)
{
if (indent == UNKNOWN_LOCATION)
if (linemap_macro_expansion_map_p (indent_map))
return false;
- if (!blank_line_before_p (insertion_point))
+ if (!blank_line_before_p (fc, insertion_point))
return false;
/* Locate the start of the line containing INSERTION_POINT. */
location_t indent)
{
location_t start_of_line;
- if (use_new_line (insertion_point, indent, &start_of_line))
+ if (use_new_line (global_dc->get_file_cache (),
+ insertion_point, indent, &start_of_line))
{
/* Add CONTENT on its own line, using the indentation of INDENT. */
return xloc;
}
-/* Initialize the set of cache used for files accessed by caret
- diagnostic. */
-
-static void
-diagnostic_file_cache_init (void)
-{
- gcc_assert (global_dc);
- global_dc->file_cache_init ();
-}
-
-void
-diagnostic_context::file_cache_init ()
-{
- if (m_file_cache == nullptr)
- m_file_cache = new file_cache ();
-}
-
/* Return the total lines number that have been read so far by the
line map (in the preprocessor) so far. For languages like C++ that
entirely preprocess the input file before starting to parse, this
printing source code. For use in selftests when working
with tempfiles. */
-void
-diagnostics_file_cache_forcibly_evict_file (const char *file_path)
-{
- gcc_assert (file_path);
-
- auto file_cache = global_dc->get_file_cache ();
- if (!file_cache)
- return;
- file_cache->forcibly_evict_file (file_path);
-}
-
void
file_cache::forcibly_evict_file (const char *file_path)
{
r->evict ();
}
+/* Determine if FILE_PATH missing a trailing newline on its final line.
+ Only valid to call once all of the file has been loaded, by
+ requesting a line number beyond the end of the file. */
+
+bool
+file_cache::missing_trailing_newline_p (const char *file_path)
+{
+ gcc_assert (file_path);
+
+ file_cache_slot *r = lookup_or_add_file (file_path);
+ return r->missing_trailing_newline_p ();
+}
+
void
file_cache_slot::evict ()
{
file_cache_slot*
file_cache::evicted_cache_tab_entry (unsigned *highest_use_count)
{
- diagnostic_file_cache_init ();
-
file_cache_slot *to_evict = &m_file_slots[0];
unsigned huc = to_evict->get_use_count ();
for (unsigned i = 1; i < num_file_slots; ++i)
return char_span (buffer, len);
}
-char_span
-location_get_source_line (const char *file_path, int line)
-{
- diagnostic_file_cache_init ();
- return global_dc->get_file_cache ()->get_source_line (file_path, line);
-}
-
/* Return a NUL-terminated copy of the source text between two locations, or
NULL if the arguments are invalid. The caller is responsible for freeing
the return value. */
char *
-get_source_text_between (location_t start, location_t end)
+get_source_text_between (file_cache &fc, location_t start, location_t end)
{
expanded_location expstart =
expand_location_to_spelling_point (start, LOCATION_ASPECT_START);
/* For a single line we need to trim both edges. */
if (expstart.line == expend.line)
{
- char_span line = location_get_source_line (expstart.file, expstart.line);
+ char_span line = fc.get_source_line (expstart.file, expstart.line);
if (line.length () < 1)
return NULL;
int s = expstart.column - 1;
parts of the start and end lines off depending on column values. */
for (int lnum = expstart.line; lnum <= expend.line; ++lnum)
{
- char_span line = location_get_source_line (expstart.file, lnum);
+ char_span line = fc.get_source_line (expstart.file, lnum);
if (line.length () < 1 && (lnum != expstart.line && lnum != expend.line))
continue;
return c->get_full_file_content ();
}
-
-/* Get a borrowed char_span to the full content of FILE_PATH
- as decoded according to the input charset, encoded as UTF-8. */
-
-char_span
-get_source_file_content (const char *file_path)
-{
- diagnostic_file_cache_init ();
- return global_dc->get_file_cache ()->get_source_file_content (file_path);
-}
-
-/* Determine if FILE_PATH missing a trailing newline on its final line.
- Only valid to call once all of the file has been loaded, by
- requesting a line number beyond the end of the file. */
-
-bool
-location_missing_trailing_newline (const char *file_path)
-{
- diagnostic_file_cache_init ();
-
- file_cache_slot *c = global_dc->get_file_cache ()->lookup_or_add_file (file_path);
- if (c == NULL)
- return false;
-
- return c->missing_trailing_newline_p ();
-}
-
/* Test if the location originates from the spelling location of a
builtin-tokens. That is, return TRUE if LOC is a (possibly
virtual) location of a built-in token that appears in the expansion
source line in order to calculate the display width. If that cannot be done
for any reason, then returns the byte column as a fallback. */
int
-location_compute_display_column (expanded_location exploc,
+location_compute_display_column (file_cache &fc,
+ expanded_location exploc,
const cpp_char_column_policy &policy)
{
if (!(exploc.file && *exploc.file && exploc.line && exploc.column))
return exploc.column;
- char_span line = location_get_source_line (exploc.file, exploc.line);
+ char_span line = fc.get_source_line (exploc.file, exploc.line);
/* If line is NULL, this function returns exploc.column which is the
desired fallback. */
return cpp_byte_column_to_display_column (line.get_buffer (), line.length (),
void
dump_location_info (FILE *stream)
{
+ file_cache fc;
+
/* Visualize the reserved locations. */
dump_labelled_location_range (stream, "RESERVED LOCATIONS",
0, RESERVED_LOCATION_COUNT);
{
/* Beginning of a new source line: draw the line. */
- char_span line_text = location_get_source_line (exploc.file,
- exploc.line);
+ char_span line_text = fc.get_source_line (exploc.file,
+ exploc.line);
if (!line_text)
break;
fprintf (stream,
static const char *
get_substring_ranges_for_loc (cpp_reader *pfile,
+ file_cache &fc,
string_concat_db *concats,
location_t strloc,
enum cpp_ttype type,
if (start.column > finish.column)
return "range endpoints are reversed";
- char_span line = location_get_source_line (start.file, start.line);
+ char_span line = fc.get_source_line (start.file, start.line);
if (!line)
return "unable to read source line";
const char *
get_location_within_string (cpp_reader *pfile,
+ file_cache &fc,
string_concat_db *concats,
location_t strloc,
enum cpp_ttype type,
cpp_substring_ranges ranges;
const char *err
- = get_substring_ranges_for_loc (pfile, concats, strloc, type, ranges);
+ = get_substring_ranges_for_loc (pfile, fc, concats, strloc, type, ranges);
if (err)
return err;
static const char *
get_source_range_for_char (cpp_reader *pfile,
+ file_cache &fc,
string_concat_db *concats,
location_t strloc,
enum cpp_ttype type,
cpp_substring_ranges ranges;
const char *err
- = get_substring_ranges_for_loc (pfile, concats, strloc, type, ranges);
+ = get_substring_ranges_for_loc (pfile, fc, concats, strloc, type, ranges);
if (err)
return err;
static const char *
get_num_source_ranges_for_substring (cpp_reader *pfile,
+ file_cache &fc,
string_concat_db *concats,
location_t strloc,
enum cpp_ttype type,
cpp_substring_ranges ranges;
const char *err
- = get_substring_ranges_for_loc (pfile, concats, strloc, type, ranges);
+ = get_substring_ranges_for_loc (pfile, fc, concats, strloc, type, ranges);
if (err)
return err;
"01234567890123456789\n"
"This is the test text\n"
"This is the 3rd line");
+ file_cache fc;
/* Read back a specific line from the tempfile. */
- char_span source_line = location_get_source_line (tmp.get_filename (), 3);
+ char_span source_line = fc.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.get_buffer (), source_line.length ()));
- source_line = location_get_source_line (tmp.get_filename (), 2);
+ source_line = fc.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.get_buffer (), source_line.length ()));
- source_line = location_get_source_line (tmp.get_filename (), 4);
+ source_line = fc.get_source_line (tmp.get_filename (), 4);
ASSERT_FALSE (source_line);
ASSERT_TRUE (source_line.get_buffer () == NULL);
}
line_table_test m_ltt;
cpp_reader_ptr m_parser;
temp_source_file m_tempfile;
+ file_cache m_file_cache;
string_concat_db m_concats;
bool m_implicitly_expect_EOF;
};
source_range actual_range = source_range();
const char *err
- = get_source_range_for_char (pfile, concats, strloc, type, idx,
+ = get_source_range_for_char (pfile, test.m_file_cache,
+ concats, strloc, type, idx,
&actual_range);
if (should_have_column_data_p (strloc))
ASSERT_EQ_AT (loc, NULL, err);
int actual_num_ranges = -1;
const char *err
- = get_num_source_ranges_for_substring (pfile, concats, strloc, type,
+ = get_num_source_ranges_for_substring (pfile, test.m_file_cache,
+ concats, strloc, type,
&actual_num_ranges);
if (should_have_column_data_p (strloc))
ASSERT_EQ_AT (loc, NULL, err);
string_concat_db *concats = &test.m_concats;
cpp_substring_ranges ranges;
const char *actual_err
- = get_substring_ranges_for_loc (pfile, concats, strloc,
+ = get_substring_ranges_for_loc (pfile, test.m_file_cache, concats, strloc,
type, ranges);
if (should_have_column_data_p (strloc))
ASSERT_STREQ_AT (loc, expected_err, actual_err);
this case. */
source_range actual_range;
const char *err
- = get_source_range_for_char (test.m_parser, &test.m_concats,
+ = get_source_range_for_char (test.m_parser, test.m_file_cache,
+ &test.m_concats,
initial_loc, type, 0, &actual_range);
ASSERT_STREQ ("range starts after LINE_MAP_MAX_LOCATION_WITH_COLS", err);
return;
#include "line-map.h"
+class file_cache;
+
extern GTY(()) class line_maps *line_table;
extern GTY(()) class line_maps *saved_line_table;
class cpp_char_column_policy;
extern int
-location_compute_display_column (expanded_location exploc,
+location_compute_display_column (file_cache &fc,
+ expanded_location exploc,
const cpp_char_column_policy &policy);
/* A class capturing the bounds of a buffer, to allow for run-time
size_t m_n_elts;
};
-extern char_span location_get_source_line (const char *file_path, int line);
-extern char *get_source_text_between (location_t, location_t);
-extern char_span get_source_file_content (const char *file_path);
-
-extern bool location_missing_trailing_newline (const char *file_path);
+extern char *
+get_source_text_between (file_cache &, location_t, location_t);
/* Forward decl of slot within file_cache, so that the definition doesn't
need to be in this header. */
char_span get_source_file_content (const char *file_path);
char_span get_source_line (const char *file_path, int line);
+ bool missing_trailing_newline_p (const char *file_path);
private:
file_cache_slot *evicted_cache_tab_entry (unsigned *highest_use_count);
void dump_location_info (FILE *stream);
-void diagnostics_file_cache_forcibly_evict_file (const char *file_path);
-
class GTY(()) string_concat
{
public:
/* Constructor. Generate a name for the file. */
-named_temp_file::named_temp_file (const char *suffix)
+named_temp_file::named_temp_file (const char *suffix,
+ file_cache *fc)
{
m_filename = make_temp_file (suffix);
ASSERT_NE (m_filename, NULL);
+ m_file_cache = fc;
}
/* Destructor. Delete the tempfile. */
named_temp_file::~named_temp_file ()
{
unlink (m_filename);
- diagnostics_file_cache_forcibly_evict_file (m_filename);
+ if (m_file_cache)
+ m_file_cache->forcibly_evict_file (m_filename);
free (m_filename);
}
temp_source_file::temp_source_file (const location &loc,
const char *suffix,
- const char *content)
-: named_temp_file (suffix)
+ const char *content,
+ file_cache *fc)
+: named_temp_file (suffix, fc)
{
FILE *out = fopen (get_filename (), "w");
if (!out)
#if CHECKING_P
+class file_cache;
+
namespace selftest {
/* A struct describing the source-location of a selftest, to make it
/* A named temporary file for use in selftests.
Usable for writing out files, and as the base class for
temp_source_file.
- The file is unlinked in the destructor. */
+ The file is unlinked in the destructor.
+ If the file_cache is non-null, the filename is evicted from
+ the file_cache when the named_temp_file is destroyed. */
class named_temp_file
{
public:
- named_temp_file (const char *suffix);
+ named_temp_file (const char *suffix, file_cache *fc = nullptr);
~named_temp_file ();
const char *get_filename () const { return m_filename; }
private:
char *m_filename;
+ file_cache *m_file_cache;
};
/* A class for writing out a temporary sourcefile for use in selftests
{
public:
temp_source_file (const location &loc, const char *suffix,
- const char *content);
+ const char *content, file_cache *fc = nullptr);
temp_source_file (const location &loc, const char *suffix,
const char *content, size_t sz);
};
LANG_HOOKS_GET_SUBSTRING_LOCATION. */
extern const char *get_location_within_string (cpp_reader *pfile,
+ file_cache &fc,
string_concat_db *concats,
location_t strloc,
enum cpp_ttype type,
rich_location richloc (line_table, loc);
for (int line = start_line; line <= finish_line; line++)
{
- char_span content = location_get_source_line (file, line);
+ file_cache &fc = global_dc->get_file_cache ();
+ char_span content = fc.get_source_line (file, line);
gcc_assert (content);
/* Split line up into words. */
for (int idx = 0; idx < content.length (); idx++)
diagnostic_show_locus (&dc, richloc, DK_ERROR);
/* Generate a diff. */
- edit_context ec;
+ edit_context ec (global_dc->get_file_cache ());
ec.add_fixits (richloc);
char *diff = ec.generate_diff (true);
free (diff);