c++: expose the type used to store line and column numbers

* data/skeletons/location.cc (position::counter_type)
(location::counter_type): New.
Use them.
* doc/bison.texi (C++ position, C++ location): Adjust.
This commit is contained in:
Akim Demaille
2019-11-06 08:33:44 +01:00
parent 583c193ffa
commit 7bdf7246fb
3 changed files with 68 additions and 51 deletions

3
NEWS
View File

@@ -14,7 +14,8 @@ GNU Bison NEWS
In C++, line numbers and columns are now represented as 'int' not In C++, line numbers and columns are now represented as 'int' not
'unsigned', so that integer overflow on positions is easily checkable via 'unsigned', so that integer overflow on positions is easily checkable via
'gcc -fsanitize=undefined' and the like. This affects the API for 'gcc -fsanitize=undefined' and the like. This affects the API for
positions. positions. The default position and location classes now expose
'counter_type' (int), used to define line and column numbers.
** Bug fixes ** Bug fixes

View File

@@ -62,11 +62,14 @@ m4_define([b4_location_define],
[[ /// A point in a source file. [[ /// A point in a source file.
class position class position
{ {
public:]m4_ifdef([b4_location_constructors], [[ public:
/// Type for line and column numbers.
typedef int counter_type;
]m4_ifdef([b4_location_constructors], [[
/// Construct a position. /// Construct a position.
explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR, explicit position (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
int l = ]b4_location_initial_line[, counter_type l = ]b4_location_initial_line[,
int c = ]b4_location_initial_column[) counter_type c = ]b4_location_initial_column[)
: filename (f) : filename (f)
, line (l) , line (l)
, column (c) , column (c)
@@ -75,8 +78,8 @@ m4_define([b4_location_define],
]])[ ]])[
/// Initialization. /// Initialization.
void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULLPTR, void initialize (]b4_percent_define_get([[filename_type]])[* fn = YY_NULLPTR,
int l = ]b4_location_initial_line[, counter_type l = ]b4_location_initial_line[,
int c = ]b4_location_initial_column[) counter_type c = ]b4_location_initial_column[)
{ {
filename = fn; filename = fn;
line = l; line = l;
@@ -86,7 +89,7 @@ m4_define([b4_location_define],
/** \name Line and Column related manipulators /** \name Line and Column related manipulators
** \{ */ ** \{ */
/// (line related) Advance to the COUNT next lines. /// (line related) Advance to the COUNT next lines.
void lines (int count = 1) void lines (counter_type count = 1)
{ {
if (count) if (count)
{ {
@@ -96,7 +99,7 @@ m4_define([b4_location_define],
} }
/// (column related) Advance to the COUNT next columns. /// (column related) Advance to the COUNT next columns.
void columns (int count = 1) void columns (counter_type count = 1)
{ {
column = add_ (column, count, ]b4_location_initial_column[); column = add_ (column, count, ]b4_location_initial_column[);
} }
@@ -105,13 +108,13 @@ m4_define([b4_location_define],
/// File name to which this position refers. /// File name to which this position refers.
]b4_percent_define_get([[filename_type]])[* filename; ]b4_percent_define_get([[filename_type]])[* filename;
/// Current line number. /// Current line number.
int line; counter_type line;
/// Current column number. /// Current column number.
int column; counter_type column;
private: private:
/// Compute max (min, lhs+rhs). /// Compute max (min, lhs+rhs).
static int add_ (int lhs, int rhs, int min) static counter_type add_ (counter_type lhs, counter_type rhs, counter_type min)
{ {
return lhs + rhs < min ? min : lhs + rhs; return lhs + rhs < min ? min : lhs + rhs;
} }
@@ -119,7 +122,7 @@ m4_define([b4_location_define],
/// Add \a width columns, in place. /// Add \a width columns, in place.
inline position& inline position&
operator+= (position& res, int width) operator+= (position& res, position::counter_type width)
{ {
res.columns (width); res.columns (width);
return res; return res;
@@ -127,21 +130,21 @@ m4_define([b4_location_define],
/// Add \a width columns. /// Add \a width columns.
inline position inline position
operator+ (position res, int width) operator+ (position res, position::counter_type width)
{ {
return res += width; return res += width;
} }
/// Subtract \a width columns, in place. /// Subtract \a width columns, in place.
inline position& inline position&
operator-= (position& res, int width) operator-= (position& res, position::counter_type width)
{ {
return res += -width; return res += -width;
} }
/// Subtract \a width columns. /// Subtract \a width columns.
inline position inline position
operator- (position res, int width) operator- (position res, position::counter_type width)
{ {
return res -= width; return res -= width;
} }
@@ -181,6 +184,8 @@ m4_define([b4_location_define],
class location class location
{ {
public: public:
/// Type for line and column numbers.
typedef position::counter_type counter_type;
]m4_ifdef([b4_location_constructors], [ ]m4_ifdef([b4_location_constructors], [
/// Construct a location from \a b to \a e. /// Construct a location from \a b to \a e.
location (const position& b, const position& e) location (const position& b, const position& e)
@@ -196,8 +201,8 @@ m4_define([b4_location_define],
/// Construct a 0-width location in \a f, \a l, \a c. /// Construct a 0-width location in \a f, \a l, \a c.
explicit location (]b4_percent_define_get([[filename_type]])[* f, explicit location (]b4_percent_define_get([[filename_type]])[* f,
int l = ]b4_location_initial_line[, counter_type l = ]b4_location_initial_line[,
int c = ]b4_location_initial_column[) counter_type c = ]b4_location_initial_column[)
: begin (f, l, c) : begin (f, l, c)
, end (f, l, c) , end (f, l, c)
{} {}
@@ -205,8 +210,8 @@ m4_define([b4_location_define],
])[ ])[
/// Initialization. /// Initialization.
void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR, void initialize (]b4_percent_define_get([[filename_type]])[* f = YY_NULLPTR,
int l = ]b4_location_initial_line[, counter_type l = ]b4_location_initial_line[,
int c = ]b4_location_initial_column[) counter_type c = ]b4_location_initial_column[)
{ {
begin.initialize (f, l, c); begin.initialize (f, l, c);
end = begin; end = begin;
@@ -222,13 +227,13 @@ m4_define([b4_location_define],
} }
/// Extend the current location to the COUNT next columns. /// Extend the current location to the COUNT next columns.
void columns (int count = 1) void columns (counter_type count = 1)
{ {
end += count; end += count;
} }
/// Extend the current location to the COUNT next lines. /// Extend the current location to the COUNT next lines.
void lines (int count = 1) void lines (counter_type count = 1)
{ {
end.lines (count); end.lines (count);
} }
@@ -243,39 +248,45 @@ m4_define([b4_location_define],
}; };
/// Join two locations, in place. /// Join two locations, in place.
inline location& operator+= (location& res, const location& end) inline location&
operator+= (location& res, const location& end)
{ {
res.end = end.end; res.end = end.end;
return res; return res;
} }
/// Join two locations. /// Join two locations.
inline location operator+ (location res, const location& end) inline location
operator+ (location res, const location& end)
{ {
return res += end; return res += end;
} }
/// Add \a width columns to the end position, in place. /// Add \a width columns to the end position, in place.
inline location& operator+= (location& res, int width) inline location&
operator+= (location& res, location::counter_type width)
{ {
res.columns (width); res.columns (width);
return res; return res;
} }
/// Add \a width columns to the end position. /// Add \a width columns to the end position.
inline location operator+ (location res, int width) inline location
operator+ (location res, location::counter_type width)
{ {
return res += width; return res += width;
} }
/// Subtract \a width columns to the end position, in place. /// Subtract \a width columns to the end position, in place.
inline location& operator-= (location& res, int width) inline location&
operator-= (location& res, location::counter_type width)
{ {
return res += -width; return res += -width;
} }
/// Subtract \a width columns to the end position. /// Subtract \a width columns to the end position.
inline location operator- (location res, int width) inline location
operator- (location res, location::counter_type width)
{ {
return res -= width; return res -= width;
} }
@@ -304,7 +315,8 @@ m4_define([b4_location_define],
std::basic_ostream<YYChar>& std::basic_ostream<YYChar>&
operator<< (std::basic_ostream<YYChar>& ostr, const location& loc) operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)
{ {
int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0; location::counter_type end_col
= 0 < loc.end.column ? loc.end.column - 1 : 0;
ostr << loc.begin; ostr << loc.begin;
if (loc.end.filename if (loc.end.filename
&& (!loc.begin.filename && (!loc.begin.filename

View File

@@ -11453,8 +11453,8 @@ is some time and/or some talented C++ hacker willing to contribute to Bison.
@node C++ Location Values @node C++ Location Values
@subsection C++ Location Values @subsection C++ Location Values
@c - %locations @c - %locations
@c - class Position @c - class position
@c - class Location @c - class location
@c - %define filename_type "const symbol::Symbol" @c - %define filename_type "const symbol::Symbol"
When the directive @code{%locations} is used, the C++ parser supports When the directive @code{%locations} is used, the C++ parser supports
@@ -11462,9 +11462,9 @@ location tracking, see @ref{Tracking Locations}.
By default, two auxiliary classes define a @code{position}, a single point By default, two auxiliary classes define a @code{position}, a single point
in a file, and a @code{location}, a range composed of a pair of in a file, and a @code{location}, a range composed of a pair of
@code{position}s (possibly spanning several files). But if the @code{position}s (possibly spanning several files). If the @code{%define}
@code{%define} variable @code{api.location.type} is defined, then these variable @code{api.location.type} is defined, then these classes will not be
classes will not be generated, and the user defined type will be used. generated, and the user defined type will be used.
@menu @menu
* C++ position:: One point in the source file * C++ position:: One point in the source file
@@ -11477,13 +11477,17 @@ classes will not be generated, and the user defined type will be used.
@node C++ position @node C++ position
@subsubsection C++ @code{position} @subsubsection C++ @code{position}
@deftypeop {Constructor} {position} {} position (std::string* @var{file} = nullptr, int @var{line} = 1, int @var{col} = 1) @defcv {Type} {position} {counter_type}
The type used to store line and column numbers. Defined as @code{int}.
@end defcv
@deftypeop {Constructor} {position} {} position (std::string* @var{file} = nullptr, counter_type @var{line} = 1, counter_type @var{col} = 1)
Create a @code{position} denoting a given point. Note that @code{file} is Create a @code{position} denoting a given point. Note that @code{file} is
not reclaimed when the @code{position} is destroyed: memory managed must be not reclaimed when the @code{position} is destroyed: memory managed must be
handled elsewhere. handled elsewhere.
@end deftypeop @end deftypeop
@deftypemethod {position} {void} initialize (std::string* @var{file} = nullptr, int @var{line} = 1, int @var{col} = 1) @deftypemethod {position} {void} initialize (std::string* @var{file} = nullptr, counter_type @var{line} = 1, counter_type @var{col} = 1)
Reset the position to the given values. Reset the position to the given values.
@end deftypemethod @end deftypemethod
@@ -11494,28 +11498,28 @@ change it to @samp{@var{type}*} using @samp{%define filename_type
"@var{type}"}. "@var{type}"}.
@end deftypeivar @end deftypeivar
@deftypeivar {position} {int} line @deftypeivar {position} {counter_type} line
The line, starting at 1. The line, starting at 1.
@end deftypeivar @end deftypeivar
@deftypemethod {position} {void} lines (int @var{height} = 1) @deftypemethod {position} {void} lines (counter_type @var{height} = 1)
If @var{height} is not null, advance by @var{height} lines, resetting the If @var{height} is not null, advance by @var{height} lines, resetting the
column number. The resulting line number cannot be less than 1. column number. The resulting line number cannot be less than 1.
@end deftypemethod @end deftypemethod
@deftypeivar {position} {int} column @deftypeivar {position} {counter_type} column
The column, starting at 1. The column, starting at 1.
@end deftypeivar @end deftypeivar
@deftypemethod {position} {void} columns (int @var{width} = 1) @deftypemethod {position} {void} columns (counter_type @var{width} = 1)
Advance by @var{width} columns, without changing the line number. The Advance by @var{width} columns, without changing the line number. The
resulting column number cannot be less than 1. resulting column number cannot be less than 1.
@end deftypemethod @end deftypemethod
@deftypemethod {position} {position&} operator+= (int @var{width}) @deftypemethod {position} {position&} operator+= (counter_type @var{width})
@deftypemethodx {position} {position} operator+ (int @var{width}) @deftypemethodx {position} {position} operator+ (counter_type @var{width})
@deftypemethodx {position} {position&} operator-= (int @var{width}) @deftypemethodx {position} {position&} operator-= (counter_type @var{width})
@deftypemethodx {position} {position} operator- (int @var{width}) @deftypemethodx {position} {position} operator- (counter_type @var{width})
Various forms of syntactic sugar for @code{columns}. Various forms of syntactic sugar for @code{columns}.
@end deftypemethod @end deftypemethod
@@ -11538,11 +11542,11 @@ Create a @code{Location} from the endpoints of the range.
@end deftypeop @end deftypeop
@deftypeop {Constructor} {location} {} location (const position& @var{pos} = position()) @deftypeop {Constructor} {location} {} location (const position& @var{pos} = position())
@deftypeopx {Constructor} {location} {} location (std::string* @var{file}, int @var{line}, int @var{col}) @deftypeopx {Constructor} {location} {} location (std::string* @var{file}, counter_type @var{line}, counter_type @var{col})
Create a @code{Location} denoting an empty range located at a given point. Create a @code{Location} denoting an empty range located at a given point.
@end deftypeop @end deftypeop
@deftypemethod {location} {void} initialize (std::string* @var{file} = nullptr, int @var{line} = 1, int @var{col} = 1) @deftypemethod {location} {void} initialize (std::string* @var{file} = nullptr, counter_type @var{line} = 1, counter_type @var{col} = 1)
Reset the location to an empty range at the given values. Reset the location to an empty range at the given values.
@end deftypemethod @end deftypemethod
@@ -11551,15 +11555,15 @@ Reset the location to an empty range at the given values.
The first, inclusive, position of the range, and the first beyond. The first, inclusive, position of the range, and the first beyond.
@end deftypeivar @end deftypeivar
@deftypemethod {location} {void} columns (int @var{width} = 1) @deftypemethod {location} {void} columns (counter_type @var{width} = 1)
@deftypemethodx {location} {void} lines (int @var{height} = 1) @deftypemethodx {location} {void} lines (counter_type @var{height} = 1)
Forwarded to the @code{end} position. Forwarded to the @code{end} position.
@end deftypemethod @end deftypemethod
@deftypemethod {location} {location} operator+ (int @var{width}) @deftypemethod {location} {location} operator+ (counter_type @var{width})
@deftypemethodx {location} {location} operator+= (int @var{width}) @deftypemethodx {location} {location} operator+= (counter_type @var{width})
@deftypemethodx {location} {location} operator- (int @var{width}) @deftypemethodx {location} {location} operator- (counter_type @var{width})
@deftypemethodx {location} {location} operator-= (int @var{width}) @deftypemethodx {location} {location} operator-= (counter_type @var{width})
Various forms of syntactic sugar for @code{columns}. Various forms of syntactic sugar for @code{columns}.
@end deftypemethod @end deftypemethod