+2018-03-14 David Malcolm <dmalcolm@redhat.com>
+
+ PR c/84852
+ * diagnostic-show-locus.c (class layout_point): Convert m_line
+ from int to linenum_type.
+ (line_span::comparator): Use linenum "compare" function when
+ comparing line numbers.
+ (test_line_span): New function.
+ (layout_range::contains_point): Convert param "row" from int to
+ linenum_type.
+ (layout_range::intersects_line_p): Likewise.
+ (layout::will_show_line_p): Likewise.
+ (layout::print_source_line): Likewise.
+ (layout::should_print_annotation_line_p): Likewise.
+ (layout::print_annotation_line): Likewise.
+ (layout::print_leading_fixits): Likewise.
+ (layout::annotation_line_showed_range_p): Likewise.
+ (struct line_corrections): Likewise for field m_row.
+ (line_corrections::line_corrections): Likewise for param "row".
+ (layout::print_trailing_fixits): Likewise.
+ (layout::get_state_at_point): Likewise.
+ (layout::get_x_bound_for_row): Likewise.
+ (layout::print_line): Likewise.
+ (diagnostic_show_locus): Likewise for locals "last_line" and
+ "row".
+ (selftest::diagnostic_show_locus_c_tests): Call test_line_span.
+ * input.c (selftest::test_linenum_comparisons): New function.
+ (selftest::input_c_tests): Call it.
+ * selftest.c (selftest::test_assertions): Test ASSERT_GT,
+ ASSERT_GT_AT, ASSERT_LT, and ASSERT_LT_AT.
+ * selftest.h (ASSERT_GT): New macro.
+ (ASSERT_GT_AT): New macro.
+ (ASSERT_LT): New macro.
+ (ASSERT_LT_AT): New macro.
+
2018-03-14 Segher Boessenkool <segher@kernel.crashing.org>
PR rtl-optimization/84780
: m_line (exploc.line),
m_column (exploc.column) {}
- int m_line;
+ linenum_type m_line;
int m_column;
};
bool show_caret_p,
const expanded_location *caret_exploc);
- bool contains_point (int row, int column) const;
- bool intersects_line_p (int row) const;
+ bool contains_point (linenum_type row, int column) const;
+ bool intersects_line_p (linenum_type row) const;
layout_point m_start;
layout_point m_finish;
{
const line_span *ls1 = (const line_span *)p1;
const line_span *ls2 = (const line_span *)p2;
- int first_line_diff = (int)ls1->m_first_line - (int)ls2->m_first_line;
- if (first_line_diff)
- return first_line_diff;
- return (int)ls1->m_last_line - (int)ls2->m_last_line;
+ int first_line_cmp = compare (ls1->m_first_line, ls2->m_first_line);
+ if (first_line_cmp)
+ return first_line_cmp;
+ return compare (ls1->m_last_line, ls2->m_last_line);
}
linenum_type m_first_line;
linenum_type m_last_line;
};
+#if CHECKING_P
+
+/* Selftests for line_span. */
+
+static void
+test_line_span ()
+{
+ line_span line_one (1, 1);
+ ASSERT_EQ (1, line_one.get_first_line ());
+ ASSERT_EQ (1, line_one.get_last_line ());
+ ASSERT_FALSE (line_one.contains_line_p (0));
+ ASSERT_TRUE (line_one.contains_line_p (1));
+ ASSERT_FALSE (line_one.contains_line_p (2));
+
+ line_span lines_1_to_3 (1, 3);
+ ASSERT_EQ (1, lines_1_to_3.get_first_line ());
+ ASSERT_EQ (3, lines_1_to_3.get_last_line ());
+ ASSERT_TRUE (lines_1_to_3.contains_line_p (1));
+ ASSERT_TRUE (lines_1_to_3.contains_line_p (3));
+
+ ASSERT_EQ (0, line_span::comparator (&line_one, &line_one));
+ ASSERT_GT (line_span::comparator (&lines_1_to_3, &line_one), 0);
+ ASSERT_LT (line_span::comparator (&line_one, &lines_1_to_3), 0);
+
+ /* A linenum > 2^31. */
+ const linenum_type LARGEST_LINE = 0xffffffff;
+ line_span largest_line (LARGEST_LINE, LARGEST_LINE);
+ ASSERT_EQ (LARGEST_LINE, largest_line.get_first_line ());
+ ASSERT_EQ (LARGEST_LINE, largest_line.get_last_line ());
+
+ ASSERT_GT (line_span::comparator (&largest_line, &line_one), 0);
+ ASSERT_LT (line_span::comparator (&line_one, &largest_line), 0);
+}
+
+#endif /* #if CHECKING_P */
+
/* A class to control the overall layout when printing a diagnostic.
The layout is determined within the constructor.
expanded_location get_expanded_location (const line_span *) const;
- void print_line (int row);
+ void print_line (linenum_type row);
private:
- bool will_show_line_p (int row) const;
- void print_leading_fixits (int row);
- void print_source_line (int row, const char *line, int line_width,
+ bool will_show_line_p (linenum_type row) const;
+ void print_leading_fixits (linenum_type row);
+ void print_source_line (linenum_type row, const char *line, int line_width,
line_bounds *lbounds_out);
- bool should_print_annotation_line_p (int row) const;
- void print_annotation_line (int row, const line_bounds lbounds);
- void print_trailing_fixits (int row);
+ bool should_print_annotation_line_p (linenum_type row) const;
+ void print_annotation_line (linenum_type row, const line_bounds lbounds);
+ void print_trailing_fixits (linenum_type row);
- bool annotation_line_showed_range_p (int line, int start_column,
+ bool annotation_line_showed_range_p (linenum_type line, int start_column,
int finish_column) const;
void show_ruler (int max_column) const;
bool
get_state_at_point (/* Inputs. */
- int row, int column,
+ linenum_type row, int column,
int first_non_ws, int last_non_ws,
/* Outputs. */
point_state *out_state);
int
- get_x_bound_for_row (int row, int caret_column,
+ get_x_bound_for_row (linenum_type row, int caret_column,
int last_non_ws);
void
- 'a' indicates a subsequent point *after* the range. */
bool
-layout_range::contains_point (int row, int column) const
+layout_range::contains_point (linenum_type row, int column) const
{
gcc_assert (m_start.m_line <= m_finish.m_line);
/* ...but the equivalent isn't true for the columns;
/* Does this layout_range contain any part of line ROW? */
bool
-layout_range::intersects_line_p (int row) const
+layout_range::intersects_line_p (linenum_type row) const
{
gcc_assert (m_start.m_line <= m_finish.m_line);
if (row < m_start.m_line)
/* Return true iff ROW is within one of the line spans for this layout. */
bool
-layout::will_show_line_p (int row) const
+layout::will_show_line_p (linenum_type row) const
{
for (int line_span_idx = 0; line_span_idx < get_num_line_spans ();
line_span_idx++)
is its width. */
void
-layout::print_source_line (int row, const char *line, int line_width,
+layout::print_source_line (linenum_type row, const char *line, int line_width,
line_bounds *lbounds_out)
{
m_colorizer.set_normal_text ();
i.e. if any of m_layout_ranges contains ROW. */
bool
-layout::should_print_annotation_line_p (int row) const
+layout::should_print_annotation_line_p (linenum_type row) const
{
layout_range *range;
int i;
source line. */
void
-layout::print_annotation_line (int row, const line_bounds lbounds)
+layout::print_annotation_line (linenum_type row, const line_bounds lbounds)
{
int x_bound = get_x_bound_for_row (row, m_exploc.column,
lbounds.m_last_non_ws);
itself, with a leading '+'. */
void
-layout::print_leading_fixits (int row)
+layout::print_leading_fixits (linenum_type row)
{
for (unsigned int i = 0; i < m_fixit_hints.length (); i++)
{
the exact range from START_COLUMN to FINISH_COLUMN. */
bool
-layout::annotation_line_showed_range_p (int line, int start_column,
+layout::annotation_line_showed_range_p (linenum_type line, int start_column,
int finish_column) const
{
layout_range *range;
struct line_corrections
{
- line_corrections (const char *filename, int row)
+ line_corrections (const char *filename, linenum_type row)
: m_filename (filename), m_row (row)
{}
~line_corrections ();
void add_hint (const fixit_hint *hint);
const char *m_filename;
- int m_row;
+ linenum_type m_row;
auto_vec <correction *> m_corrections;
};
in layout::print_leading_fixits. */
void
-layout::print_trailing_fixits (int row)
+layout::print_trailing_fixits (linenum_type row)
{
/* Build a list of correction instances for the line,
potentially consolidating hints (for the sake of readability). */
bool
layout::get_state_at_point (/* Inputs. */
- int row, int column,
+ linenum_type row, int column,
int first_non_ws, int last_non_ws,
/* Outputs. */
point_state *out_state)
character of source (as determined when printing the source line). */
int
-layout::get_x_bound_for_row (int row, int caret_column,
+layout::get_x_bound_for_row (linenum_type row, int caret_column,
int last_non_ws_column)
{
int result = caret_column + 1;
consisting of any caret/underlines, then any fixits.
If the source line can't be read, print nothing. */
void
-layout::print_line (int row)
+layout::print_line (linenum_type row)
{
int line_width;
const char *line = location_get_source_line (m_exploc.file, row,
expanded_location exploc = layout.get_expanded_location (line_span);
context->start_span (context, exploc);
}
- int last_line = line_span->get_last_line ();
- for (int row = line_span->get_first_line (); row <= last_line; row++)
+ linenum_type last_line = line_span->get_last_line ();
+ for (linenum_type row = line_span->get_first_line ();
+ row <= last_line; row++)
layout.print_line (row);
}
void
diagnostic_show_locus_c_tests ()
{
+ test_line_span ();
+
test_layout_range_for_single_point ();
test_layout_range_for_single_line ();
test_layout_range_for_multiple_lines ();
::selftest::fail ((LOC), desc); \
SELFTEST_END_STMT
+/* Evaluate LHS and RHS and compare them with >, calling
+ ::selftest::pass if LHS > RHS,
+ ::selftest::fail otherwise. */
+
+#define ASSERT_GT(LHS, RHS) \
+ ASSERT_GT_AT ((SELFTEST_LOCATION), (LHS), (RHS))
+
+/* Like ASSERT_GT, but treat LOC as the effective location of the
+ selftest. */
+
+#define ASSERT_GT_AT(LOC, LHS, RHS) \
+ SELFTEST_BEGIN_STMT \
+ const char *desc_ = "ASSERT_GT (" #LHS ", " #RHS ")"; \
+ if ((LHS) > (RHS)) \
+ ::selftest::pass ((LOC), desc_); \
+ else \
+ ::selftest::fail ((LOC), desc_); \
+ SELFTEST_END_STMT
+
+/* Evaluate LHS and RHS and compare them with <, calling
+ ::selftest::pass if LHS < RHS,
+ ::selftest::fail otherwise. */
+
+#define ASSERT_LT(LHS, RHS) \
+ ASSERT_LT_AT ((SELFTEST_LOCATION), (LHS), (RHS))
+
+/* Like ASSERT_LT, but treat LOC as the effective location of the
+ selftest. */
+
+#define ASSERT_LT_AT(LOC, LHS, RHS) \
+ SELFTEST_BEGIN_STMT \
+ const char *desc_ = "ASSERT_LT (" #LHS ", " #RHS ")"; \
+ if ((LHS) < (RHS)) \
+ ::selftest::pass ((LOC), desc_); \
+ else \
+ ::selftest::fail ((LOC), desc_); \
+ SELFTEST_END_STMT
+
/* Evaluate EXPECTED and ACTUAL and compare them with strcmp, calling
::selftest::pass if they are equal,
::selftest::fail if they are non-equal. */