diff options
author | emsr <emsr@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-10 00:08:49 +0000 |
---|---|---|
committer | emsr <emsr@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-10 00:08:49 +0000 |
commit | 2dd006369c22f7affef6c7082e3671cba988468d (patch) | |
tree | 6f4eb9fb1a2dfd8c43e78bcc98930f16138e78c4 /libcpp | |
parent | ec745a53793f0eec84eabfc3b93cb12ba1e4916f (diff) | |
download | gcc-2dd006369c22f7affef6c7082e3671cba988468d.tar.gz |
Implement a flag -fext-numeric-literals that allows control of whether GNU
numeric suffix extensions are parsed or passed to C++ as user-defined literals.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193382 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libcpp')
-rw-r--r-- | libcpp/ChangeLog | 12 | ||||
-rw-r--r-- | libcpp/expr.c | 118 | ||||
-rw-r--r-- | libcpp/include/cpplib.h | 10 | ||||
-rw-r--r-- | libcpp/init.c | 1 |
4 files changed, 86 insertions, 55 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 4bd0b26aa5e..4f78ecf761c 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,15 @@ +2012-11-09 Ed Smith-Rowland <3dw4rd@verizon.net> + + PR c++/54413 + * include/cpplib.h (cpp_interpret_float_suffix): Add cpp_reader* arg. + (cpp_interpret_int_suffix): Add cpp_reader* arg. + * init.c (cpp_create_reader): Iitialize new flags. + * expr.c (interpret_float_suffix): Use new flags. + (cpp_interpret_float_suffix): Add cpp_reader* arg. + (interpret_int_suffix): Use new flags. + (cpp_interpret_int_suffix): Add cpp_reader* arg. + (cpp_classify_number): Adjust calls to interpret_x_suffix. + 2012-10-23 Ian Bolton <ian.bolton@arm.com> Jim MacArthur <jim.macarthur@arm.com> Marcus Shawcroft <marcus.shawcroft@arm.com> diff --git a/libcpp/expr.c b/libcpp/expr.c index cd6e7d4eca6..df8d96553fd 100644 --- a/libcpp/expr.c +++ b/libcpp/expr.c @@ -61,8 +61,8 @@ static cpp_num append_digit (cpp_num, int, int, size_t); static cpp_num parse_defined (cpp_reader *); static cpp_num eval_token (cpp_reader *, const cpp_token *, source_location); static struct op *reduce (cpp_reader *, struct op *, enum cpp_ttype); -static unsigned int interpret_float_suffix (const uchar *, size_t); -static unsigned int interpret_int_suffix (const uchar *, size_t); +static unsigned int interpret_float_suffix (cpp_reader *, const uchar *, size_t); +static unsigned int interpret_int_suffix (cpp_reader *, const uchar *, size_t); static void check_promotion (cpp_reader *, const struct op *); /* Token type abuse to create unary plus and minus operators. */ @@ -87,7 +87,7 @@ static void check_promotion (cpp_reader *, const struct op *); length LEN, possibly zero. Returns 0 for an invalid suffix, or a flag vector describing the suffix. */ static unsigned int -interpret_float_suffix (const uchar *s, size_t len) +interpret_float_suffix (cpp_reader *pfile, const uchar *s, size_t len) { size_t flags; size_t f, d, l, w, q, i; @@ -115,55 +115,58 @@ interpret_float_suffix (const uchar *s, size_t len) } } - /* Recognize a fixed-point suffix. */ - if (len != 0) - switch (s[len-1]) - { - case 'k': case 'K': flags = CPP_N_ACCUM; break; - case 'r': case 'R': flags = CPP_N_FRACT; break; - default: break; - } - - /* Continue processing a fixed-point suffix. The suffix is case - insensitive except for ll or LL. Order is significant. */ - if (flags) + if (CPP_OPTION (pfile, ext_numeric_literals)) { - if (len == 1) - return flags; - len--; + /* Recognize a fixed-point suffix. */ + if (len != 0) + switch (s[len-1]) + { + case 'k': case 'K': flags = CPP_N_ACCUM; break; + case 'r': case 'R': flags = CPP_N_FRACT; break; + default: break; + } - if (*s == 'u' || *s == 'U') + /* Continue processing a fixed-point suffix. The suffix is case + insensitive except for ll or LL. Order is significant. */ + if (flags) { - flags |= CPP_N_UNSIGNED; if (len == 1) return flags; len--; - s++; - } - switch (*s) - { - case 'h': case 'H': - if (len == 1) - return flags |= CPP_N_SMALL; - break; - case 'l': - if (len == 1) - return flags |= CPP_N_MEDIUM; - if (len == 2 && s[1] == 'l') - return flags |= CPP_N_LARGE; - break; - case 'L': - if (len == 1) - return flags |= CPP_N_MEDIUM; - if (len == 2 && s[1] == 'L') - return flags |= CPP_N_LARGE; - break; - default: - break; - } - /* Anything left at this point is invalid. */ - return 0; + if (*s == 'u' || *s == 'U') + { + flags |= CPP_N_UNSIGNED; + if (len == 1) + return flags; + len--; + s++; + } + + switch (*s) + { + case 'h': case 'H': + if (len == 1) + return flags |= CPP_N_SMALL; + break; + case 'l': + if (len == 1) + return flags |= CPP_N_MEDIUM; + if (len == 2 && s[1] == 'l') + return flags |= CPP_N_LARGE; + break; + case 'L': + if (len == 1) + return flags |= CPP_N_MEDIUM; + if (len == 2 && s[1] == 'L') + return flags |= CPP_N_LARGE; + break; + default: + break; + } + /* Anything left at this point is invalid. */ + return 0; + } } /* In any remaining valid suffix, the case and order don't matter. */ @@ -184,6 +187,12 @@ interpret_float_suffix (const uchar *s, size_t len) if (f + d + l + w + q > 1 || i > 1) return 0; + if (i && !CPP_OPTION (pfile, ext_numeric_literals)) + return 0; + + if ((w || q) && !CPP_OPTION (pfile, ext_numeric_literals)) + return 0; + return ((i ? CPP_N_IMAGINARY : 0) | (f ? CPP_N_SMALL : d ? CPP_N_MEDIUM : @@ -194,16 +203,16 @@ interpret_float_suffix (const uchar *s, size_t len) /* Return the classification flags for a float suffix. */ unsigned int -cpp_interpret_float_suffix (const char *s, size_t len) +cpp_interpret_float_suffix (cpp_reader *pfile, const char *s, size_t len) { - return interpret_float_suffix ((const unsigned char *)s, len); + return interpret_float_suffix (pfile, (const unsigned char *)s, len); } /* Subroutine of cpp_classify_number. S points to an integer suffix of length LEN, possibly zero. Returns 0 for an invalid suffix, or a flag vector describing the suffix. */ static unsigned int -interpret_int_suffix (const uchar *s, size_t len) +interpret_int_suffix (cpp_reader *pfile, const uchar *s, size_t len) { size_t u, l, i; @@ -227,6 +236,9 @@ interpret_int_suffix (const uchar *s, size_t len) if (l > 2 || u > 1 || i > 1) return 0; + if (i && !CPP_OPTION (pfile, ext_numeric_literals)) + return 0; + return ((i ? CPP_N_IMAGINARY : 0) | (u ? CPP_N_UNSIGNED : 0) | ((l == 0) ? CPP_N_SMALL @@ -235,9 +247,9 @@ interpret_int_suffix (const uchar *s, size_t len) /* Return the classification flags for an int suffix. */ unsigned int -cpp_interpret_int_suffix (const char *s, size_t len) +cpp_interpret_int_suffix (cpp_reader *pfile, const char *s, size_t len) { - return interpret_int_suffix ((const unsigned char *)s, len); + return interpret_int_suffix (pfile, (const unsigned char *)s, len); } /* Return the string type corresponding to the the input user-defined string @@ -455,7 +467,7 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token, /* The suffix may be for decimal fixed-point constants without exponent. */ if (radix != 16 && float_flag == NOT_FLOAT) { - result = interpret_float_suffix (str, limit - str); + result = interpret_float_suffix (pfile, str, limit - str); if ((result & CPP_N_FRACT) || (result & CPP_N_ACCUM)) { result |= CPP_N_FLOATING; @@ -519,7 +531,7 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token, SYNTAX_ERROR_AT (virtual_location, "hexadecimal floating constants require an exponent"); - result = interpret_float_suffix (str, limit - str); + result = interpret_float_suffix (pfile, str, limit - str); if (result == 0) { if (CPP_OPTION (pfile, user_literals)) @@ -573,7 +585,7 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token, } else { - result = interpret_int_suffix (str, limit - str); + result = interpret_int_suffix (pfile, str, limit - str); if (result == 0) { if (CPP_OPTION (pfile, user_literals)) diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index a58454e9839..72415f0348a 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -431,6 +431,10 @@ struct cpp_options ud-suffix which does not beging with an underscore. */ unsigned char warn_literal_suffix; + /* Nonzero means interpret imaginary, fixed-point, or other gnu extension + literal number suffixes as user-defined literal number suffixes. */ + unsigned char ext_numeric_literals; + /* Holds the name of the target (execution) character set. */ const char *narrow_charset; @@ -854,10 +858,12 @@ extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *, const char **, source_location); /* Return the classification flags for a float suffix. */ -extern unsigned int cpp_interpret_float_suffix (const char *, size_t); +extern unsigned int cpp_interpret_float_suffix (cpp_reader *, const char *, + size_t); /* Return the classification flags for an int suffix. */ -extern unsigned int cpp_interpret_int_suffix (const char *, size_t); +extern unsigned int cpp_interpret_int_suffix (cpp_reader *, const char *, + size_t); /* Evaluate a token classified as category CPP_N_INTEGER. */ extern cpp_num cpp_interpret_integer (cpp_reader *, const cpp_token *, diff --git a/libcpp/init.c b/libcpp/init.c index 81b66df57e5..ebe51c76c86 100644 --- a/libcpp/init.c +++ b/libcpp/init.c @@ -182,6 +182,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table, CPP_OPTION (pfile, track_macro_expansion) = 2; CPP_OPTION (pfile, warn_normalize) = normalized_C; CPP_OPTION (pfile, warn_literal_suffix) = 1; + CPP_OPTION (pfile, ext_numeric_literals) = 1; /* Default CPP arithmetic to something sensible for the host for the benefit of dumb users like fix-header. */ |