diff options
author | Edward Smith-Rowland <3dw4rd@verizon.net> | 2013-10-31 14:01:23 +0000 |
---|---|---|
committer | Edward Smith-Rowland <emsr@gcc.gnu.org> | 2013-10-31 14:01:23 +0000 |
commit | 7057e6452ba6b205085eede49eddf37c2feab29a (patch) | |
tree | 28dc58242b9d84a0f1723c9f24e40c623e194ef1 /libcpp/expr.c | |
parent | b63cb15373bf384f1d644c4cfae0c60422cc3909 (diff) | |
download | gcc-7057e6452ba6b205085eede49eddf37c2feab29a.zip gcc-7057e6452ba6b205085eede49eddf37c2feab29a.tar.gz gcc-7057e6452ba6b205085eede49eddf37c2feab29a.tar.bz2 |
Implement C++14 digit separators.
libcpp:
2013-10-31 Edward Smith-Rowland <3dw4rd@verizon.net>
Implement C++14 digit separators.
* include/cpplib.h (cpp_options): Add digit_separators flag.
* internal.h (DIGIT_SEP(c)): New macro.
* expr.c (cpp_classify_number): Check improper placement of digit sep;
(cpp_interpret_integer): Skip over digit separators.
* init.c (lang_flags): Add digit_separators flag; (lang_defaults): Add
digit separator flags per language; (cpp_set_lang): Set
digit_separators
* lex.c (lex_number): Add digits separator to allowable characters for
C++14.
gcc/c-family:
2013-10-31 Edward Smith-Rowland <3dw4rd@verizon.net>
Implement C++14 digit separators.
* c-lex.c (interpret_float): Remove digit separators from scratch string
before building real literal.
gcc/testsuite:
2013-10-31 Edward Smith-Rowland <3dw4rd@verizon.net>
Implement C++14 digit separators.
* g++.dg/cpp1y/digit-sep.C: New.
* g++.dg/cpp1y/digit-sep-neg.C: New.
* g++.dg/cpp1y/digit-sep-cxx11-neg.C: New.
libstdc++-v3:
2013-10-31 Edward Smith-Rowland <3dw4rd@verizon.net>
Implement C++14 digit separators.
* include/include/bits/parse_numbers.h: Change struct _Digit<_Base, '`'>
to struct _Digit<_Base, '\''>.
From-SVN: r204260
Diffstat (limited to 'libcpp/expr.c')
-rw-r--r-- | libcpp/expr.c | 67 |
1 files changed, 56 insertions, 11 deletions
diff --git a/libcpp/expr.c b/libcpp/expr.c index 0eb6c13..c009807 100644 --- a/libcpp/expr.c +++ b/libcpp/expr.c @@ -394,6 +394,7 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token, unsigned int max_digit, result, radix; enum {NOT_FLOAT = 0, AFTER_POINT, AFTER_EXPON} float_flag; bool seen_digit; + bool seen_digit_sep; if (ud_suffix) *ud_suffix = NULL; @@ -408,6 +409,7 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token, max_digit = 0; radix = 10; seen_digit = false; + seen_digit_sep = false; /* First, interpret the radix. */ if (*str == '0') @@ -416,16 +418,27 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token, str++; /* Require at least one hex digit to classify it as hex. */ - if ((*str == 'x' || *str == 'X') - && (str[1] == '.' || ISXDIGIT (str[1]))) + if (*str == 'x' || *str == 'X') { - radix = 16; - str++; + if (str[1] == '.' || ISXDIGIT (str[1])) + { + radix = 16; + str++; + } + else if (DIGIT_SEP (str[1])) + SYNTAX_ERROR_AT (virtual_location, + "digit separator after base indicator"); } - else if ((*str == 'b' || *str == 'B') && (str[1] == '0' || str[1] == '1')) + else if (*str == 'b' || *str == 'B') { - radix = 2; - str++; + if (str[1] == '0' || str[1] == '1') + { + radix = 2; + str++; + } + else if (DIGIT_SEP (str[1])) + SYNTAX_ERROR_AT (virtual_location, + "digit separator after base indicator"); } } @@ -436,13 +449,24 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token, if (ISDIGIT (c) || (ISXDIGIT (c) && radix == 16)) { + seen_digit_sep = false; seen_digit = true; c = hex_value (c); if (c > max_digit) max_digit = c; } + else if (DIGIT_SEP (c)) + { + if (seen_digit_sep) + SYNTAX_ERROR_AT (virtual_location, "adjacent digit separators"); + seen_digit_sep = true; + } else if (c == '.') { + if (seen_digit_sep || DIGIT_SEP (*str)) + SYNTAX_ERROR_AT (virtual_location, + "digit separator adjacent to decimal point"); + seen_digit_sep = false; if (float_flag == NOT_FLOAT) float_flag = AFTER_POINT; else @@ -452,6 +476,9 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token, else if ((radix <= 10 && (c == 'e' || c == 'E')) || (radix == 16 && (c == 'p' || c == 'P'))) { + if (seen_digit_sep || DIGIT_SEP (*str)) + SYNTAX_ERROR_AT (virtual_location, + "digit separator adjacent to exponent"); float_flag = AFTER_EXPON; break; } @@ -463,6 +490,10 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token, } } + if (seen_digit_sep && float_flag != AFTER_EXPON) + SYNTAX_ERROR_AT (virtual_location, + "digit separator outside digit sequence"); + /* The suffix may be for decimal fixed-point constants without exponent. */ if (radix != 16 && float_flag == NOT_FLOAT) { @@ -520,16 +551,28 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token, /* Exponent is decimal, even if string is a hex float. */ if (!ISDIGIT (*str)) - SYNTAX_ERROR_AT (virtual_location, "exponent has no digits"); - + { + if (DIGIT_SEP (*str)) + SYNTAX_ERROR_AT (virtual_location, + "digit separator adjacent to exponent"); + else + SYNTAX_ERROR_AT (virtual_location, "exponent has no digits"); + } do - str++; - while (ISDIGIT (*str)); + { + seen_digit_sep = DIGIT_SEP (*str); + str++; + } + while (ISDIGIT (*str) || DIGIT_SEP (*str)); } else if (radix == 16) SYNTAX_ERROR_AT (virtual_location, "hexadecimal floating constants require an exponent"); + if (seen_digit_sep) + SYNTAX_ERROR_AT (virtual_location, + "digit separator outside digit sequence"); + result = interpret_float_suffix (pfile, str, limit - str); if (result == 0) { @@ -723,6 +766,8 @@ cpp_interpret_integer (cpp_reader *pfile, const cpp_token *token, if (ISDIGIT (c) || (base == 16 && ISXDIGIT (c))) c = hex_value (c); + else if (DIGIT_SEP (c)) + continue; else break; |