52 template<
class CharSeq>
58 unsigned long long val = numeric_limits<unsigned long long>::max();
60 unsigned byte1 = *chew & 0xff;
61 unsigned byte2, byte3, byte4;
62 if (byte1 ==
unsigned(EOF)) {
64 }
else if (byte1 >> 7 == 0) {
67 }
else if (byte1 >> 5 == 0x6) {
70 }
else if (byte1 >> 4 == 0xe) {
73 }
else if (byte1 >> 3 == 0x1e) {
86 if (byte2 ==
unsigned(EOF) || byte2 >> 6 != 2) {
92 val = ((byte1 << 6) | byte2);
99 if (byte2 ==
unsigned(EOF) || byte2 >> 6 != 2) {
104 byte3 = 0xff & *chew;
105 if (byte3 ==
unsigned(EOF) || byte3 >> 6 != 2) {
109 val = (byte1 << 12) | (byte2 << 6) | byte3;
115 byte2 = 0xff & *chew;
116 if (byte2 ==
unsigned(EOF) || byte2 >> 6 != 2) {
121 byte3 = 0xff & *chew;
122 if (byte3 ==
unsigned(EOF) || byte3 >> 6 != 2) {
127 byte4 = 0xff & *chew;
128 if (byte4 ==
unsigned(EOF) || byte4 >> 6 != 2) {
132 val = (byte1 << 18) | (byte2 << 12) | (byte3 << 6) | byte4;
141 template<
class CharSeq>
142 pair<unsigned long long,bool>
148 unsigned long long val = 0;
149 unsigned long long tmp;
150 bool overflow =
false;
210 if (
unsigned(dval) < base) {
213 if (val / base != tmp) {
226 return pair<unsigned long long, bool>(val,overflow);
229 template<
class CharSeq>
272 template<
class CharSeq>
278 unsigned long long const bad_val =
279 numeric_limits<unsigned long long>::max();
280 unsigned long long val = bad_val;
281 assert(base == 8 || base == 16);
282 size_t mark = size_t(chew);
287 if ( (base == 8 && *chew ==
'0') ||
288 (base == 16 && (*chew ==
'x' || *chew ==
'u' ||
291 std::pair<unsigned long long,bool> verdict =
294 bool overflow = verdict.second;
296 val > (
unsigned long long)numeric_limits<int>::max()
303 if (val == bad_val) {
309 template<
class CharSeq>
319 unsigned long long const bad_val =
320 numeric_limits<unsigned long long>::max();
323 unsigned long long max_val = bad_val;
324 bool overflow =
false;
326 size_t mark = size_t(chew);
327 char const *type_desc =
nullptr;
328 bool has_suffix =
false;
334 if (*chew ==
'x' || *chew ==
'X') {
341 pair<unsigned long long, bool> verdict =
343 result._val = verdict.first;
344 overflow = verdict.second;
347 type_desc =
"unsigned long long";
350 num_len = size_t(chew) - mark;
351 if (num_len == 1 && base == 16) {
353 }
else if (num_len > 0) {
354 if (*chew ==
'u' || *chew ==
'U') {
359 if (*chew ==
'l' || *chew ==
'L') {
364 if (*chew ==
'l' || *chew ==
'L') {
369 if (result.is_signed() && (*chew ==
'u' || *chew ==
'U')) {
374 result.make_unsigned();
382 if (result.is_signed() &&
383 result._val > (
unsigned long long)numeric_limits<long long>::max() &&
390 "Integer constant \"" <<
391 chew.
buf().substr(mark,
size_t(chew) - mark)
392 <<
"\" is so large it is treated as unsigned" <<
defer();
397 result._val > numeric_limits<unsigned long>::max()) {
399 type_desc =
"unsigned long";
400 max_val = numeric_limits<unsigned long>::max();
401 }
else if (result.type() ==
INT_LONG &&
402 result._val > (
unsigned long long)numeric_limits<long>::max()) {
405 max_val = numeric_limits<long>::max();
408 (
unsigned long long)numeric_limits<long long>::max()) {
410 type_desc =
"long long";
411 max_val = numeric_limits<long long>::max();
417 chew.
buf().substr(mark,
size_t(chew) - mark)
418 <<
"\" is too large for type " <<
419 type_desc <<
"(max " << max_val <<
420 "): expression will not be resolved" <<
emit();
427 if (result.is_signed()) {
429 (
unsigned long long)numeric_limits<int>::max()) {
432 }
else if (result._val <=
433 (
unsigned long long)numeric_limits<unsigned>::max()) {
448 template<
class CharSeq>
453 char const *type_desc =
"int";
454 unsigned long long const bad_val =
455 numeric_limits<unsigned long long>::max();
456 unsigned long long val = bad_val;
457 unsigned long max_val = numeric_limits<int>::max();
458 size_t mark = size_t(chew);
461 max_val = numeric_limits<wchar_t>::max();
462 type_desc =
"wchar_t";
464 }
else if (*chew ==
'u') {
465 max_val = numeric_limits<char16_t>::max();
466 type_desc =
"char16_t";
468 }
else if (*chew ==
'U') {
469 max_val = numeric_limits<char32_t>::max();
470 type_desc =
"char32_t";
478 if (val == bad_val) {
481 if (val == bad_val) {
484 size_t restart = size_t(chew);
495 for ( ; chew && *chew !=
'\'' && *chew !=
'\n'; ++nbytes) {
501 val = (val << 8 | chval);
506 "Multi-byte character constant "
507 << chew.
buf().substr(
508 mark,
size_t(chew) - mark + 1)
514 <<
"Missing \"'\" terminator after \""
515 << chew.
buf().substr(mark) <<
'\"' <<
emit();
519 chew += (*chew ==
'\'');
520 if (val != bad_val && val > max_val) {
522 << chew.
buf().substr(mark,
size_t(chew) - mark)
523 <<
" overflows type " <<
524 type_desc <<
"(max " << max_val
525 <<
"). Will not be resolved" <<
emit();
528 if (val != bad_val) {
warning_msg< 18 > warning_int_overflow
Report that an integer constant evaluates > INT_MAX.
template struct traits::is_random_access_char_sequence<T> exports a static const boolean member value...
static integer read_numeral(chewer< CharSeq > &chew)
Read a numeral from a chewer<CharSeq>
static std::pair< unsigned long long, bool > read_based_numeral(unsigned base, chewer< CharSeq > &chew)
Read a numeral of known base from a text pointer, returning a value and overflow indicator.
warning_msg< 19 > warning_missing_terminator
Report missing terminator quotation.
static size_t flush()
Emit all deferred diagnostics of this type.
static int read_char_escaping(chewer< CharSeq > &chew)
Read a possibly escaped ASCII character from a text offset, returning its escaped value...
Undetermined type or invalid.
warning_msg< 21 > warning_forced_unsigned
Report a huge integer constant forced to be unsigned.
Class integer encapsulates an integer of some type.
warning_msg< 25 > warning_mulitbyte_char_constant
Report that character constant goes multi-byte.
sequence_type & buf()
Get a [const] reference to the associated sequence_type
static unsigned long long read_encoded_char(int base, chewer< CharSeq > &chew)
Read a numerically encoded character constant from a text offset, returning its value as an integer...
static unsigned long long decode_utf8(chewer< CharSeq > &chew)
Decode an UTF-8 encoded character from a text offset.
warning_msg< 24 > warning_char_constant_too_long
Report a character constant too long for current locale.
chew_mode::continuation const continuation
An exemplar chew_mode::continuation
static size_t discard()
Forget all queued diagnostics of this type.
The tag class is inserted in a diagnostic_base to tell it to emit itself.
The tag class is inserted in a diagnostic_base to tell it to defer itself.
`template struct chewer<CharSeq> is a cursor-like type that is associated with a character-sequence t...
static integer read_char(chewer< CharSeq > &chew)
Read a character constant from a text offset, returning its value as an integer.