This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
(C++) sync lexer with C frontend
- To: gcc-patches at gcc dot gnu dot org
- Subject: (C++) sync lexer with C frontend
- From: Jason Merrill <jason at cygnus dot com>
- Date: Fri, 23 Jul 1999 17:45:25 -0700
There's really no reason for the lexers of the C and C++ frontends to be
out of sync; their requirements are very similar. This patch fixes a bunch
of inconsistencies.
1999-07-23 Jason Merrill <jason@yorick.cygnus.com>
* lex.c: Sync with C frontend.
(whitespace_cr): New fn.
(skip_white_space): Use it.
(init_parse): Reorder.
(yyprint): Support CONSTANT.
(pragma_getc, pragma_ungetc): Bring back.
(read_line_number): Change in_system_header directly.
(handle_generic_pragma, handle_cp_pragma, yyerror): Move up in file.
(parse_float): Update to C version.
(yylex): Handle '$' under the letter case.
Remove looking_for_typename handling.
Support hex floating point constants.
Follow C's lead for choosing type of integer constants.
Rearrange stuff to match C frontend.
(yyungetc, reinit_parse_for_block, yylex): Support indent_level.
* spew.c (yylex): Clear looking_for_typename if we see a TYPESPEC.
Index: lex.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/lex.c,v
retrieving revision 1.122
diff -c -p -r1.122 lex.c
*** lex.c 1999/07/21 12:48:12 1.122
--- lex.c 1999/07/24 00:44:14
*************** extern void yyprint PROTO((FILE *, int,
*** 57,62 ****
--- 57,63 ----
static tree get_time_identifier PROTO((const char *));
static int check_newline PROTO((void));
+ static int whitespace_cr PROTO((int));
static int skip_white_space PROTO((int));
static void finish_defarg PROTO((void));
static int my_get_run_time PROTO((void));
*************** static int maxtoken; /* Current nominal
*** 303,315 ****
char *token_buffer; /* Pointer to token buffer.
Actual allocated length is maxtoken + 2. */
! static int indent_level = 0; /* Number of { minus number of }. */
#include "hash.h"
/* Nonzero tells yylex to ignore \ in string constants. */
! static int ignore_escape_flag = 0;
static tree
get_time_identifier (name)
--- 304,316 ----
char *token_buffer; /* Pointer to token buffer.
Actual allocated length is maxtoken + 2. */
! static int indent_level; /* Number of { minus number of }. */
#include "hash.h"
/* Nonzero tells yylex to ignore \ in string constants. */
! static int ignore_escape_flag;
static tree
get_time_identifier (name)
*************** init_parse (filename)
*** 481,498 ****
literal_codeset = getenv ("LANG");
#endif
! #if USE_CPPLIB
! parse_in.show_column = 1;
! if (! cpp_start_read (&parse_in, filename))
! abort ();
!
! /* cpp_start_read always puts at least one line directive into the
! token buffer. We must arrange to read it out here. */
! yy_cur = parse_in.token_buffer;
! yy_lim = CPP_PWRITTEN (&parse_in);
! cpp_token = CPP_DIRECTIVE;
!
! #else
/* Open input file. */
if (filename == 0 || !strcmp (filename, "-"))
{
--- 482,488 ----
literal_codeset = getenv ("LANG");
#endif
! #if !USE_CPPLIB
/* Open input file. */
if (filename == 0 || !strcmp (filename, "-"))
{
*************** init_parse (filename)
*** 507,512 ****
--- 497,516 ----
#ifdef IO_BUFFER_SIZE
setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
#endif
+ #else /* !USE_CPPLIB */
+ parse_in.show_column = 1;
+ if (! cpp_start_read (&parse_in, filename))
+ abort ();
+
+ if (filename == 0 || !strcmp (filename, "-"))
+ filename = "stdin";
+
+ /* cpp_start_read always puts at least one line directive into the
+ token buffer. We must arrange to read it out here. */
+ yy_cur = parse_in.token_buffer;
+ yy_lim = CPP_PWRITTEN (&parse_in);
+ cpp_token = CPP_DIRECTIVE;
+
#endif /* !USE_CPPLIB */
/* Initialize the lookahead machinery. */
*************** init_parse (filename)
*** 686,693 ****
ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
ridpointers[(int) RID_INLINE] = get_identifier ("inline");
ridpointers[(int) RID_CONST] = get_identifier ("const");
- ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
ridpointers[(int) RID_RESTRICT] = get_identifier ("__restrict");
ridpointers[(int) RID_AUTO] = get_identifier ("auto");
ridpointers[(int) RID_STATIC] = get_identifier ("static");
ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
--- 690,697 ----
ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
ridpointers[(int) RID_INLINE] = get_identifier ("inline");
ridpointers[(int) RID_CONST] = get_identifier ("const");
ridpointers[(int) RID_RESTRICT] = get_identifier ("__restrict");
+ ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
ridpointers[(int) RID_AUTO] = get_identifier ("auto");
ridpointers[(int) RID_STATIC] = get_identifier ("static");
ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
*************** yyprint (file, yychar, yylval)
*** 921,926 ****
--- 925,931 ----
if (IDENTIFIER_POINTER (t))
fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
break;
+
case AGGR:
if (yylval.ttype == class_type_node)
fprintf (file, " `class'");
*************** yyprint (file, yychar, yylval)
*** 935,940 ****
--- 940,969 ----
else
my_friendly_abort (80);
break;
+
+ case CONSTANT:
+ t = yylval.ttype;
+ if (TREE_CODE (t) == INTEGER_CST)
+ fprintf (file,
+ #if HOST_BITS_PER_WIDE_INT == 64
+ #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+ " 0x%x%016x",
+ #else
+ #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
+ " 0x%lx%016lx",
+ #else
+ " 0x%llx%016llx",
+ #endif
+ #endif
+ #else
+ #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
+ " 0x%lx%08lx",
+ #else
+ " 0x%x%08x",
+ #endif
+ #endif
+ TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t));
+ break;
}
}
*************** yyungetc (ch, rescan)
*** 1435,1440 ****
--- 1464,1476 ----
/* Unget a character from the input stream. */
if (yychar == YYEMPTY || rescan == 0)
{
+ /* If we're putting back a brace, undo the change in indent_level
+ from the first time we saw it. */
+ if (ch == '{')
+ indent_level--;
+ else if (ch == '}')
+ indent_level++;
+
put_back (ch);
}
else
*************** reinit_parse_for_block (pyychar, obstack
*** 1530,1536 ****
int look_for_lbrac = 0;
if (pyychar == '{')
! obstack_1grow (obstackp, '{');
else if (pyychar == '=')
look_for_semicolon = 1;
else if (pyychar == ':')
--- 1566,1576 ----
int look_for_lbrac = 0;
if (pyychar == '{')
! {
! obstack_1grow (obstackp, '{');
! /* We incremented indent_level in yylex; undo that. */
! indent_level--;
! }
else if (pyychar == '=')
look_for_semicolon = 1;
else if (pyychar == ':')
*************** note_list_got_semicolon (declspecs)
*** 2117,2122 ****
--- 2157,2185 ----
clear_anon_tags ();
}
+ /* Iff C is a carriage return, warn about it - if appropriate -
+ and return nonzero. */
+ static int
+ whitespace_cr (c)
+ int c;
+ {
+ static int newline_warning = 0;
+
+ if (c == '\r')
+ {
+ /* ANSI C says the effects of a carriage return in a source file
+ are undefined. */
+ if (pedantic && !newline_warning)
+ {
+ warning ("carriage return in source file");
+ warning ("(we only warn about the first carriage return)");
+ newline_warning = 1;
+ }
+ return 1;
+ }
+ return 0;
+ }
+
/* If C is not whitespace, return C.
Otherwise skip whitespace and return first nonwhite char read. */
*************** skip_white_space (c)
*** 2128,2133 ****
--- 2191,2200 ----
{
switch (c)
{
+ /* We don't recognize comments here, because
+ cpp output can include / and * consecutively as operators.
+ Also, there's no need, since cpp removes all comments. */
+
case '\n':
if (linemode)
{
*************** skip_white_space (c)
*** 2140,2146 ****
case ' ':
case '\t':
case '\f':
- case '\r':
case '\v':
case '\b':
#if USE_CPPLIB
--- 2207,2212 ----
*************** skip_white_space (c)
*** 2153,2158 ****
--- 2219,2229 ----
c = getch ();
break;
+ case '\r':
+ whitespace_cr (c);
+ c = getch ();
+ break;
+
case '\\':
c = getch ();
if (c == '\n')
*************** extend_token_buffer (p)
*** 2192,2197 ****
--- 2263,2284 ----
return token_buffer + offset;
}
+ #if defined HANDLE_PRAGMA
+ /* Local versions of these macros, that can be passed as function pointers. */
+ static int
+ pragma_getc ()
+ {
+ return getch ();
+ }
+
+ static void
+ pragma_ungetc (arg)
+ int arg;
+ {
+ put_back (arg);
+ }
+ #endif
+
static int
read_line_number (num)
int *num;
*************** check_newline ()
*** 2228,2234 ****
int saw_line;
enum { act_none, act_push, act_pop } action;
int old_lineno, action_number, l;
- int entering_system_header;
int entering_c_header;
restart:
--- 2315,2320 ----
*************** check_newline ()
*** 2288,2303 ****
if (!strcmp (name, "pragma"))
{
token = real_yylex ();
! if (token == IDENTIFIER
! && TREE_CODE (yylval.ttype) == IDENTIFIER_NODE)
! {
! /* If this is 1, we handled it; if it's -1, it was one we
! wanted but had something wrong with it. Only if it's
! 0 was it not handled. */
! if (handle_cp_pragma (IDENTIFIER_POINTER (yylval.ttype)))
! goto skipline;
! }
! else if (token == END_OF_LINE)
goto skipline;
#ifdef HANDLE_PRAGMA
--- 2374,2387 ----
if (!strcmp (name, "pragma"))
{
token = real_yylex ();
! if (token != IDENTIFIER
! || TREE_CODE (yylval.ttype) != IDENTIFIER_NODE)
! goto skipline;
!
! /* If this is 1, we handled it; if it's -1, it was one we
! wanted but had something wrong with it. Only if it's
! 0 was it not handled. */
! if (handle_cp_pragma (IDENTIFIER_POINTER (yylval.ttype)))
goto skipline;
#ifdef HANDLE_PRAGMA
*************** check_newline ()
*** 2305,2311 ****
(if both are defined), in order to give the back
end a chance to override the interpretation of
SYSV style pragmas. */
! if (HANDLE_PRAGMA (getch, put_back,
IDENTIFIER_POINTER (yylval.ttype)))
goto skipline;
#endif /* HANDLE_PRAGMA */
--- 2389,2395 ----
(if both are defined), in order to give the back
end a chance to override the interpretation of
SYSV style pragmas. */
! if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc,
IDENTIFIER_POINTER (yylval.ttype)))
goto skipline;
#endif /* HANDLE_PRAGMA */
*************** linenum:
*** 2466,2477 ****
extract_interface_info ();
old_lineno = lineno;
- entering_system_header = 0;
- entering_c_header = 0;
action = act_none;
action_number = 0;
lineno = l;
if (!read_line_number (&action_number))
{
/* Update the name in the top element of input_file_stack. */
--- 2550,2564 ----
extract_interface_info ();
old_lineno = lineno;
action = act_none;
action_number = 0;
lineno = l;
+ /* Each change of file name
+ reinitializes whether we are now in a system header. */
+ in_system_header = 0;
+ entering_c_header = 0;
+
if (!read_line_number (&action_number))
{
/* Update the name in the top element of input_file_stack. */
*************** linenum:
*** 2495,2501 ****
if (action_number == 3)
{
/* `3' after file name means this is a system header file. */
! entering_system_header = 1;
read_line_number (&action_number);
}
if (action_number == 4)
--- 2582,2588 ----
if (action_number == 3)
{
/* `3' after file name means this is a system header file. */
! in_system_header = 1;
read_line_number (&action_number);
}
if (action_number == 4)
*************** linenum:
*** 2510,2518 ****
if (action == act_push)
{
/* Pushing to a new file. */
! struct file_stack *p;
!
! p = (struct file_stack *) xmalloc (sizeof (struct file_stack));
input_file_stack->line = old_lineno;
p->next = input_file_stack;
p->name = input_filename;
--- 2597,2604 ----
if (action == act_push)
{
/* Pushing to a new file. */
! struct file_stack *p
! = (struct file_stack *) xmalloc (sizeof (struct file_stack));
input_file_stack->line = old_lineno;
p->next = input_file_stack;
p->name = input_filename;
*************** linenum:
*** 2520,2526 ****
input_file_stack = p;
input_file_stack_tick++;
debug_start_source_file (input_filename);
- in_system_header = entering_system_header;
if (c_header_level)
++c_header_level;
else if (entering_c_header)
--- 2606,2611 ----
*************** linenum:
*** 2534,2540 ****
/* Popping out of a file. */
if (input_file_stack->next)
{
! struct file_stack *p;
if (c_header_level && --c_header_level == 0)
{
--- 2619,2625 ----
/* Popping out of a file. */
if (input_file_stack->next)
{
! struct file_stack *p = input_file_stack;
if (c_header_level && --c_header_level == 0)
{
*************** linenum:
*** 2542,2550 ****
warning ("badly nested C headers from preprocessor");
--pending_lang_change;
}
- in_system_header = entering_system_header;
- p = input_file_stack;
if (indent_level != p->indent_level)
{
warning_with_file_and_line
--- 2627,2633 ----
*************** linenum:
*** 2561,2578 ****
else
error ("#-lines for entering and leaving files don't match");
}
- else
- in_system_header = entering_system_header;
/* skip the rest of this line. */
skipline:
linemode = 0;
end_of_file = 0;
! while ((c = getch ()) != EOF && c != '\n');
return c;
}
void
do_pending_lang_change ()
{
--- 2644,2806 ----
else
error ("#-lines for entering and leaving files don't match");
}
+ /* Now that we've pushed or popped the input stack,
+ update the name in the top element. */
+ if (input_file_stack)
+ input_file_stack->name = input_filename;
+
/* skip the rest of this line. */
skipline:
linemode = 0;
end_of_file = 0;
! do
! c = getch ();
! while (c != '\n' && c != EOF);
return c;
}
+
+ #ifdef HANDLE_GENERIC_PRAGMAS
+
+ /* Handle a #pragma directive.
+ TOKEN is the token we read after `#pragma'. Processes the entire input
+ line and return non-zero iff the pragma has been successfully parsed. */
+
+ /* This function has to be in this file, in order to get at
+ the token types. */
+
+ static int
+ handle_generic_pragma (token)
+ register int token;
+ {
+ for (;;)
+ {
+ switch (token)
+ {
+ case IDENTIFIER:
+ case TYPENAME:
+ case STRING:
+ case CONSTANT:
+ handle_pragma_token (token_buffer, yylval.ttype);
+ break;
+
+ case LEFT_RIGHT:
+ handle_pragma_token ("(", NULL_TREE);
+ handle_pragma_token (")", NULL_TREE);
+ break;
+
+ case END_OF_LINE:
+ return handle_pragma_token (NULL_PTR, NULL_TREE);
+
+ default:
+ handle_pragma_token (token_buffer, NULL_TREE);
+ }
+
+ token = real_yylex ();
+ }
+ }
+ #endif /* HANDLE_GENERIC_PRAGMAS */
+
+ static int
+ handle_cp_pragma (pname)
+ const char *pname;
+ {
+ register int token;
+
+ if (! strcmp (pname, "vtable"))
+ {
+ extern tree pending_vtables;
+
+ /* More follows: it must be a string constant (class name). */
+ token = real_yylex ();
+ if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
+ {
+ error ("invalid #pragma vtable");
+ return -1;
+ }
+
+ pending_vtables
+ = perm_tree_cons (NULL_TREE,
+ get_identifier (TREE_STRING_POINTER (yylval.ttype)),
+ pending_vtables);
+ token = real_yylex ();
+ if (token != END_OF_LINE)
+ warning ("trailing characters ignored");
+ return 1;
+ }
+ else if (! strcmp (pname, "unit"))
+ {
+ /* More follows: it must be a string constant (unit name). */
+ token = real_yylex ();
+ if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
+ {
+ error ("invalid #pragma unit");
+ return -1;
+ }
+ token = real_yylex ();
+ if (token != END_OF_LINE)
+ warning ("trailing characters ignored");
+ return 1;
+ }
+ else if (! strcmp (pname, "interface"))
+ {
+ char *main_filename = input_filename;
+
+ main_filename = file_name_nondirectory (main_filename);
+
+ token = real_yylex ();
+
+ if (token != END_OF_LINE)
+ {
+ if (token != STRING
+ || TREE_CODE (yylval.ttype) != STRING_CST)
+ {
+ error ("invalid `#pragma interface'");
+ return -1;
+ }
+ main_filename = TREE_STRING_POINTER (yylval.ttype);
+ token = real_yylex ();
+ }
+
+ if (token != END_OF_LINE)
+ warning ("garbage after `#pragma interface' ignored");
+
+ cp_pragma_interface (main_filename);
+
+ return 1;
+ }
+ else if (! strcmp (pname, "implementation"))
+ {
+ char *main_filename = main_input_filename ? main_input_filename : input_filename;
+
+ main_filename = file_name_nondirectory (main_filename);
+
+ token = real_yylex ();
+
+ if (token != END_OF_LINE)
+ {
+ if (token != STRING
+ || TREE_CODE (yylval.ttype) != STRING_CST)
+ {
+ error ("invalid `#pragma implementation'");
+ return -1;
+ }
+ main_filename = TREE_STRING_POINTER (yylval.ttype);
+ token = real_yylex ();
+ }
+
+ if (token != END_OF_LINE)
+ warning ("garbage after `#pragma implementation' ignored");
+
+ cp_pragma_implementation (main_filename);
+ return 1;
+ }
+
+ return 0;
+ }
+
void
do_pending_lang_change ()
{
*************** readescape (ignore_ptr)
*** 2633,2640 ****
;
else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
|| (count > 1
! && (((unsigned)1 <<
! (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
<= firstdig)))
pedwarn ("hex escape out of range");
return code;
--- 2861,2869 ----
;
else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
|| (count > 1
! && (((unsigned)1
! << (TYPE_PRECISION (integer_type_node)
! - (count - 1) * 4))
<= firstdig)))
pedwarn ("hex escape out of range");
return code;
*************** readescape (ignore_ptr)
*** 2705,2711 ****
--- 2934,2970 ----
pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
return c;
}
+
+ void
+ yyerror (string)
+ const char *string;
+ {
+ extern int end_of_file;
+ char buf[200];
+
+ strcpy (buf, string);
+
+ /* We can't print string and character constants well
+ because the token_buffer contains the result of processing escapes. */
+ if (end_of_file)
+ strcat (buf, input_redirected ()
+ ? " at end of saved text"
+ : " at end of input");
+ else if (token_buffer[0] == 0)
+ strcat (buf, " at null character");
+ else if (token_buffer[0] == '"')
+ strcat (buf, " before string constant");
+ else if (token_buffer[0] == '\'')
+ strcat (buf, " before character constant");
+ else if (!ISGRAPH ((unsigned char)token_buffer[0]))
+ sprintf (buf + strlen (buf), " before character 0%o",
+ (unsigned char) token_buffer[0]);
+ else
+ strcat (buf, " before `%s'");
+ error (buf, token_buffer);
+ }
+
/* Value is 1 (or 2) if we should try to make the next identifier look like
a typename (when it may be a local variable or a class variable).
Value is 0 if we treat this name in a default fashion. */
*************** identifier_typedecl_value (node)
*** 3097,3111 ****
return NULL_TREE;
}
! struct pf_args
{
/* Input */
/* I/O */
- char *p;
int c;
int imag;
tree type;
! /* Output */
REAL_VALUE_TYPE value;
};
--- 3356,3372 ----
return NULL_TREE;
}
! struct pf_args
{
/* Input */
+ int base;
+ char * p;
/* I/O */
int c;
+ /* Output */
int imag;
tree type;
! int conversion_errno;
REAL_VALUE_TYPE value;
};
*************** parse_float (data)
*** 3120,3130 ****
REAL_VALUE_ATOF may not work any more. */
char *copy = (char *) alloca (args->p - token_buffer + 1);
bcopy (token_buffer, copy, args->p - token_buffer + 1);
!
while (1)
{
int lose = 0;
!
/* Read the suffixes to choose a data type. */
switch (args->c)
{
--- 3381,3394 ----
REAL_VALUE_ATOF may not work any more. */
char *copy = (char *) alloca (args->p - token_buffer + 1);
bcopy (token_buffer, copy, args->p - token_buffer + 1);
! args->imag = 0;
! args->conversion_errno = 0;
! args->type = double_type_node;
!
while (1)
{
int lose = 0;
!
/* Read the suffixes to choose a data type. */
switch (args->c)
{
*************** parse_float (data)
*** 3133,3145 ****
error ("more than one `f' in numeric constant");
fflag = 1;
break;
!
case 'l': case 'L':
if (lflag)
error ("more than one `l' in numeric constant");
lflag = 1;
break;
!
case 'i': case 'I':
if (args->imag)
error ("more than one `i' or `j' in numeric constant");
--- 3397,3409 ----
error ("more than one `f' in numeric constant");
fflag = 1;
break;
!
case 'l': case 'L':
if (lflag)
error ("more than one `l' in numeric constant");
lflag = 1;
break;
!
case 'i': case 'I':
if (args->imag)
error ("more than one `i' or `j' in numeric constant");
*************** parse_float (data)
*** 3147,3180 ****
pedwarn ("ANSI C++ forbids imaginary numeric constants");
args->imag = 1;
break;
!
default:
lose = 1;
}
!
if (lose)
break;
!
if (args->p >= token_buffer + maxtoken - 3)
args->p = extend_token_buffer (args->p);
*(args->p++) = args->c;
*(args->p) = 0;
args->c = getch ();
}
!
/* The second argument, machine_mode, of REAL_VALUE_ATOF
tells the desired precision of the binary result
of decimal-to-binary conversion. */
!
if (fflag)
{
if (lflag)
error ("both `f' and `l' in floating constant");
!
args->type = float_type_node;
! args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
/* A diagnostic is required here by some ANSI C testsuites.
! This is not pedwarn, become some people don't want
an error for this. */
if (REAL_VALUE_ISINF (args->value) && pedantic)
warning ("floating point number exceeds range of `float'");
--- 3411,3449 ----
pedwarn ("ANSI C++ forbids imaginary numeric constants");
args->imag = 1;
break;
!
default:
lose = 1;
}
!
if (lose)
break;
!
if (args->p >= token_buffer + maxtoken - 3)
args->p = extend_token_buffer (args->p);
*(args->p++) = args->c;
*(args->p) = 0;
args->c = getch ();
}
!
/* The second argument, machine_mode, of REAL_VALUE_ATOF
tells the desired precision of the binary result
of decimal-to-binary conversion. */
!
if (fflag)
{
if (lflag)
error ("both `f' and `l' in floating constant");
!
args->type = float_type_node;
! errno = 0;
! if (args->base == 16)
! args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type));
! else
! args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
! args->conversion_errno = errno;
/* A diagnostic is required here by some ANSI C testsuites.
! This is not pedwarn, because some people don't want
an error for this. */
if (REAL_VALUE_ISINF (args->value) && pedantic)
warning ("floating point number exceeds range of `float'");
*************** parse_float (data)
*** 3182,3194 ****
else if (lflag)
{
args->type = long_double_type_node;
! args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
if (REAL_VALUE_ISINF (args->value) && pedantic)
warning ("floating point number exceeds range of `long double'");
}
else
{
! args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
if (REAL_VALUE_ISINF (args->value) && pedantic)
warning ("floating point number exceeds range of `double'");
}
--- 3451,3473 ----
else if (lflag)
{
args->type = long_double_type_node;
! errno = 0;
! if (args->base == 16)
! args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type));
! else
! args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
! args->conversion_errno = errno;
if (REAL_VALUE_ISINF (args->value) && pedantic)
warning ("floating point number exceeds range of `long double'");
}
else
{
! errno = 0;
! if (args->base == 16)
! args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type));
! else
! args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
! args->conversion_errno = errno;
if (REAL_VALUE_ISINF (args->value) && pedantic)
warning ("floating point number exceeds range of `double'");
}
*************** int
*** 3232,3241 ****
real_yylex ()
{
register int c;
register int value;
int wide_flag = 0;
- int dollar_seen = 0;
- int i;
c = getch ();
--- 3511,3519 ----
real_yylex ()
{
register int c;
+ register char *p;
register int value;
int wide_flag = 0;
c = getch ();
*************** real_yylex ()
*** 3277,3284 ****
switch (c)
{
case EOF:
- token_buffer[0] = '\0';
end_of_file = 1;
if (input_redirected ())
value = END_OF_SAVED_INPUT;
else if (linemode)
--- 3555,3562 ----
switch (c)
{
case EOF:
end_of_file = 1;
+ token_buffer[0] = 0;
if (input_redirected ())
value = END_OF_SAVED_INPUT;
else if (linemode)
*************** real_yylex ()
*** 3287,3300 ****
value = ENDFILE;
break;
- case '$':
- if (! dollars_in_ident)
- error ("`$' in identifier");
- else if (pedantic)
- pedwarn ("`$' in identifier");
- dollar_seen = 1;
- goto letter;
-
case 'L':
#if USE_CPPLIB
if (cpp_token == CPP_NAME)
--- 3565,3570 ----
*************** real_yylex ()
*** 3315,3321 ****
}
token_put_back (c);
}
!
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'M': case 'N': case 'O':
--- 3585,3591 ----
}
token_put_back (c);
}
!
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'M': case 'N': case 'O':
*************** real_yylex ()
*** 3329,3509 ****
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case '_':
letter:
- {
- register char *p;
-
#if USE_CPPLIB
! if (cpp_token == CPP_NAME)
! {
! /* Note that one character has already been read from
! yy_cur into token_buffer. */
!
! int len = yy_lim - yy_cur + 1;
! if (len >= maxtoken)
! extend_token_buffer_to (len + 1);
! memcpy (token_buffer + 1, yy_cur, len);
! p = token_buffer + len;
! yy_cur = yy_lim;
! }
! else
#endif
! {
! /* We already installed C as the first char in token_buffer. */
! p = token_buffer+1;
! c = token_getch ();
!
! while (ISALNUM (c) || (c == '_') || c == '$')
! {
! if (c == '$')
! {
! if (! dollars_in_ident)
! error ("`$' in identifier");
! else if (pedantic)
! pedwarn ("`$' in identifier");
! }
!
! if (p >= token_buffer + maxtoken)
! p = extend_token_buffer (p);
!
! *p++ = c;
! c = token_getch ();
! }
! *p = 0;
! token_put_back (c);
! }
! value = IDENTIFIER;
! yylval.itype = 0;
! /* Try to recognize a keyword. Uses minimum-perfect hash function */
! {
! register struct resword *ptr;
! if ((ptr = is_reserved_word (token_buffer, p - token_buffer)))
! {
! if (ptr->rid)
! {
! tree old_ttype = ridpointers[(int) ptr->rid];
! /* If this provides a type for us, then revert lexical
! state to standard state. */
! if (TREE_CODE (old_ttype) == IDENTIFIER_NODE
! && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0
! && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL)
! looking_for_typename = 0;
! else if (ptr->token == AGGR || ptr->token == ENUM)
! looking_for_typename = 2;
! if (ptr->token == VISSPEC)
! {
! switch (ptr->rid)
! {
! case RID_PUBLIC:
! yylval.ttype = access_public_node;
! break;
! case RID_PRIVATE:
! yylval.ttype = access_private_node;
! break;
! case RID_PROTECTED:
! yylval.ttype = access_protected_node;
! break;
! default:
! my_friendly_abort (63);
! }
! }
! else
! yylval.ttype = old_ttype;
! }
! else switch (ptr->token)
! {
! case EQCOMPARE:
! yylval.code = NE_EXPR;
! token_buffer[0] = '!';
! token_buffer[1] = '=';
! token_buffer[2] = 0;
! break;
! case ASSIGN:
! if (strcmp ("and_eq", token_buffer) == 0)
! {
! yylval.code = BIT_AND_EXPR;
! token_buffer[0] = '&';
! }
! else if (strcmp ("or_eq", token_buffer) == 0)
! {
! yylval.code = BIT_IOR_EXPR;
! token_buffer[0] = '|';
! }
! else if (strcmp ("xor_eq", token_buffer) == 0)
! {
! yylval.code = BIT_XOR_EXPR;
! token_buffer[0] = '^';
! }
! token_buffer[1] = '=';
! token_buffer[2] = 0;
! break;
! case '&':
! yylval.code = BIT_AND_EXPR;
! token_buffer[0] = '&';
! token_buffer[1] = 0;
! break;
! case '|':
! yylval.code = BIT_IOR_EXPR;
! token_buffer[0] = '|';
! token_buffer[1] = 0;
! break;
! case '^':
! yylval.code = BIT_XOR_EXPR;
! token_buffer[0] = '^';
! token_buffer[1] = 0;
! break;
! }
! value = (int) ptr->token;
! }
! }
! /* If we did not find a keyword, look for an identifier
! (or a typename). */
! if (value == IDENTIFIER || value == TYPESPEC)
! GNU_xref_ref (current_function_decl, token_buffer);
! if (value == IDENTIFIER)
! {
! register tree tmp = get_identifier (token_buffer);
#if !defined(VMS) && defined(JOINER)
! /* Make sure that user does not collide with our internal
! naming scheme. */
! if (JOINER == '$'
! && dollar_seen
! && (THIS_NAME_P (tmp)
! || VPTR_NAME_P (tmp)
! || DESTRUCTOR_NAME_P (tmp)
! || VTABLE_NAME_P (tmp)
! || TEMP_NAME_P (tmp)
! || ANON_AGGRNAME_P (tmp)
! || ANON_PARMNAME_P (tmp)))
! warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
! token_buffer);
#endif
! yylval.ttype = tmp;
! }
! if (value == NEW && ! global_bindings_p ())
! {
! value = NEW;
! goto done;
! }
! }
!
break;
case '.':
--- 3599,3762 ----
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case '_':
+ case '$':
letter:
#if USE_CPPLIB
! if (cpp_token == CPP_NAME)
! {
! /* Note that one character has already been read from
! yy_cur into token_buffer. Also, cpplib complains about
! $ in identifiers, so we don't have to. */
!
! int len = yy_lim - yy_cur + 1;
! if (len >= maxtoken)
! extend_token_buffer_to (len + 1);
! memcpy (token_buffer + 1, yy_cur, len);
! p = token_buffer + len;
! yy_cur = yy_lim;
! }
! else
#endif
! {
! p = token_buffer;
! while (ISALNUM (c) || (c == '_') || c == '$')
! {
! /* Make sure this char really belongs in an identifier. */
! if (c == '$')
! {
! if (! dollars_in_ident)
! error ("`$' in identifier");
! else if (pedantic)
! pedwarn ("`$' in identifier");
! }
! if (p >= token_buffer + maxtoken)
! p = extend_token_buffer (p);
! *p++ = c;
! c = token_getch ();
! }
! *p = 0;
! token_put_back (c);
! }
! value = IDENTIFIER;
! yylval.itype = 0;
! /* Try to recognize a keyword. Uses minimum-perfect hash function */
! {
! register struct resword *ptr;
! if ((ptr = is_reserved_word (token_buffer, p - token_buffer)))
! {
! if (ptr->rid)
! {
! if (ptr->token == VISSPEC)
! {
! switch (ptr->rid)
! {
! case RID_PUBLIC:
! yylval.ttype = access_public_node;
! break;
! case RID_PRIVATE:
! yylval.ttype = access_private_node;
! break;
! case RID_PROTECTED:
! yylval.ttype = access_protected_node;
! break;
! default:
! my_friendly_abort (63);
! }
! }
! else
! yylval.ttype = ridpointers[(int) ptr->rid];
! }
! else switch (ptr->token)
! {
! case EQCOMPARE:
! yylval.code = NE_EXPR;
! token_buffer[0] = '!';
! token_buffer[1] = '=';
! token_buffer[2] = 0;
! break;
! case ASSIGN:
! if (strcmp ("and_eq", token_buffer) == 0)
! {
! yylval.code = BIT_AND_EXPR;
! token_buffer[0] = '&';
! }
! else if (strcmp ("or_eq", token_buffer) == 0)
! {
! yylval.code = BIT_IOR_EXPR;
! token_buffer[0] = '|';
! }
! else if (strcmp ("xor_eq", token_buffer) == 0)
! {
! yylval.code = BIT_XOR_EXPR;
! token_buffer[0] = '^';
! }
! token_buffer[1] = '=';
! token_buffer[2] = 0;
! break;
! case '&':
! yylval.code = BIT_AND_EXPR;
! token_buffer[0] = '&';
! token_buffer[1] = 0;
! break;
! case '|':
! yylval.code = BIT_IOR_EXPR;
! token_buffer[0] = '|';
! token_buffer[1] = 0;
! break;
! case '^':
! yylval.code = BIT_XOR_EXPR;
! token_buffer[0] = '^';
! token_buffer[1] = 0;
! break;
! }
! value = (int) ptr->token;
! }
! }
! /* If we did not find a keyword, look for an identifier
! (or a typename). */
! if (value == IDENTIFIER || value == TYPESPEC)
! GNU_xref_ref (current_function_decl, token_buffer);
! if (value == IDENTIFIER)
! {
! register tree tmp = get_identifier (token_buffer);
#if !defined(VMS) && defined(JOINER)
! /* Make sure that user does not collide with our internal
! naming scheme. */
! if (JOINER == '$'
! && (THIS_NAME_P (tmp)
! || VPTR_NAME_P (tmp)
! || DESTRUCTOR_NAME_P (tmp)
! || VTABLE_NAME_P (tmp)
! || TEMP_NAME_P (tmp)
! || ANON_AGGRNAME_P (tmp)
! || ANON_PARMNAME_P (tmp)))
! warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
! token_buffer);
#endif
! yylval.ttype = tmp;
! }
! if (value == NEW && ! global_bindings_p ())
! {
! value = NEW;
! goto done;
! }
break;
case '.':
*************** real_yylex ()
*** 3537,3549 ****
if (ISDIGIT (c1))
{
token_put_back (c1);
! goto resume_numerical_scan;
}
token_put_back (c1);
}
value = '.';
token_buffer[1] = 0;
! goto done;
case '0': case '1':
/* Optimize for most frequent case. */
--- 3790,3802 ----
if (ISDIGIT (c1))
{
token_put_back (c1);
! goto number;
}
token_put_back (c1);
}
value = '.';
token_buffer[1] = 0;
! break;
case '0': case '1':
/* Optimize for most frequent case. */
*************** real_yylex ()
*** 3559,3579 ****
#endif
if (cond)
{
! /* Terminate string. */
! if (c == '0')
! yylval.ttype = integer_zero_node;
! else
! yylval.ttype = integer_one_node;
value = CONSTANT;
! goto done;
}
}
! /* fall through... */
! case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
! resume_numerical_scan:
{
- register char *p;
int base = 10;
int count = 0;
int largest_digit = 0;
--- 3812,3827 ----
#endif
if (cond)
{
! yylval.ttype = (c == '0') ? integer_zero_node : integer_one_node;
value = CONSTANT;
! break;
}
+ /*FALLTHRU*/
}
! case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
! number:
{
int base = 10;
int count = 0;
int largest_digit = 0;
*************** real_yylex ()
*** 3591,3598 ****
#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2)
unsigned int parts[TOTAL_PARTS];
! enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
! = NOT_FLOAT;
for (count = 0; count < TOTAL_PARTS; count++)
parts[count] = 0;
--- 3839,3846 ----
#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2)
unsigned int parts[TOTAL_PARTS];
! enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS, AFTER_EXPON }
! floatflag = NOT_FLOAT;
for (count = 0; count < TOTAL_PARTS; count++)
parts[count] = 0;
*************** real_yylex ()
*** 3621,3639 ****
/* Read all the digits-and-decimal-points. */
while (c == '.'
! || (ISALNUM (c) && (c != 'l') && (c != 'L')
! && (c != 'u') && (c != 'U')
&& c != 'i' && c != 'I' && c != 'j' && c != 'J'
&& (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
{
if (c == '.')
{
! if (base == 16)
! error ("floating constant may not be in radix 16");
if (floatflag == TOO_MANY_POINTS)
/* We have already emitted an error. Don't need another. */
;
! else if (floatflag == AFTER_POINT)
{
error ("malformed floating constant");
floatflag = TOO_MANY_POINTS;
--- 3869,3887 ----
/* Read all the digits-and-decimal-points. */
while (c == '.'
! || (ISALNUM (c) && c != 'l' && c != 'L'
! && c != 'u' && c != 'U'
&& c != 'i' && c != 'I' && c != 'j' && c != 'J'
&& (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
{
if (c == '.')
{
! if (base == 16 && pedantic)
! pedwarn ("floating constant may not be in radix 16");
if (floatflag == TOO_MANY_POINTS)
/* We have already emitted an error. Don't need another. */
;
! else if (floatflag == AFTER_POINT || floatflag == AFTER_EXPON)
{
error ("malformed floating constant");
floatflag = TOO_MANY_POINTS;
*************** real_yylex ()
*** 3644,3650 ****
else
floatflag = AFTER_POINT;
! base = 10;
*p++ = c = token_getch ();
/* Accept '.' as the start of a floating-point number
only when it is followed by a digit. */
--- 3892,3899 ----
else
floatflag = AFTER_POINT;
! if (base == 8)
! base = 10;
*p++ = c = token_getch ();
/* Accept '.' as the start of a floating-point number
only when it is followed by a digit. */
*************** real_yylex ()
*** 3665,3676 ****
if (c == 'e' || c == 'E')
{
base = 10;
! floatflag = AFTER_POINT;
break; /* start of exponent */
}
error ("nondigits in number and not hexadecimal");
c = 0;
}
else if (c >= 'a')
{
c = c - 'a' + 10;
--- 3914,3930 ----
if (c == 'e' || c == 'E')
{
base = 10;
! floatflag = AFTER_EXPON;
break; /* start of exponent */
}
error ("nondigits in number and not hexadecimal");
c = 0;
}
+ else if (base == 16 && (c == 'p' || c == 'P'))
+ {
+ floatflag = AFTER_EXPON;
+ break; /* start of exponent */
+ }
else if (c >= 'a')
{
c = c - 'a' + 10;
*************** real_yylex ()
*** 3725,3739 ****
if (floatflag != NOT_FLOAT)
{
! tree type = double_type_node;
! int exceeds_double = 0;
! int imag = 0;
REAL_VALUE_TYPE value;
struct pf_args args;
/* Read explicit exponent if any, and put it in tokenbuf. */
! if ((c == 'e') || (c == 'E'))
{
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
--- 3979,3993 ----
if (floatflag != NOT_FLOAT)
{
! tree type;
! int imag, conversion_errno;
REAL_VALUE_TYPE value;
struct pf_args args;
/* Read explicit exponent if any, and put it in tokenbuf. */
! if ((base == 10 && ((c == 'e') || (c == 'E')))
! || (base == 16 && (c == 'p' || c == 'P')))
{
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*************** real_yylex ()
*** 3744,3752 ****
*p++ = c;
c = token_getch ();
}
if (! ISDIGIT (c))
error ("floating constant exponent has no digits");
! while (ISDIGIT (c))
{
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
--- 3998,4007 ----
*p++ = c;
c = token_getch ();
}
+ /* Exponent is decimal, even if string is a hex float. */
if (! ISDIGIT (c))
error ("floating constant exponent has no digits");
! while (ISDIGIT (c))
{
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*************** real_yylex ()
*** 3754,3769 ****
c = token_getch ();
}
}
*p = 0;
- errno = 0;
/* Setup input for parse_float() */
args.p = p;
args.c = c;
! args.imag = imag;
! args.type = type;
!
/* Convert string to a double, checking for overflow. */
if (do_float_handler (parse_float, (PTR) &args))
{
--- 4009,4024 ----
c = token_getch ();
}
}
+ if (base == 16 && floatflag != AFTER_EXPON)
+ error ("hexadecimal floating constant has no exponent");
*p = 0;
/* Setup input for parse_float() */
+ args.base = base;
args.p = p;
args.c = c;
!
/* Convert string to a double, checking for overflow. */
if (do_float_handler (parse_float, (PTR) &args))
{
*************** real_yylex ()
*** 3778,3801 ****
}
/* Receive output from parse_float() */
- p = args.p;
c = args.c;
imag = args.imag;
type = args.type;
#ifdef ERANGE
! if (errno == ERANGE && pedantic)
! {
! /* ERANGE is also reported for underflow,
! so test the value to distinguish overflow from that. */
! if (REAL_VALUES_LESS (dconst1, value)
! || REAL_VALUES_LESS (value, dconstm1))
! {
! pedwarn ("floating point number exceeds range of `%s'",
! IDENTIFIER_POINTER (TYPE_IDENTIFIER (type)));
! exceeds_double = 1;
! }
! }
#endif
/* If the result is not a number, assume it must have been
--- 4033,4050 ----
}
/* Receive output from parse_float() */
c = args.c;
imag = args.imag;
type = args.type;
+ conversion_errno = args.conversion_errno;
#ifdef ERANGE
! /* ERANGE is also reported for underflow,
! so test the value to distinguish overflow from that. */
! if (conversion_errno == ERANGE && pedantic
! && (REAL_VALUES_LESS (dconst1, value)
! || REAL_VALUES_LESS (value, dconstm1)))
! warning ("floating point number exceeds range of `double'");
#endif
/* If the result is not a number, assume it must have been
*************** real_yylex ()
*** 3807,3813 ****
/* Create a node with determined type and value. */
if (imag)
yylval.ttype = build_complex (NULL_TREE,
! cp_convert (type, integer_zero_node),
build_real (type, value));
else
yylval.ttype = build_real (type, value);
--- 4056,4062 ----
/* Create a node with determined type and value. */
if (imag)
yylval.ttype = build_complex (NULL_TREE,
! convert (type, integer_zero_node),
build_real (type, value));
else
yylval.ttype = build_real (type, value);
*************** real_yylex ()
*** 3820,3826 ****
int spec_long = 0;
int spec_long_long = 0;
int spec_imag = 0;
! int warn;
while (1)
{
--- 4069,4075 ----
int spec_long = 0;
int spec_long_long = 0;
int spec_imag = 0;
! int warn, i;
while (1)
{
*************** real_yylex ()
*** 3867,3872 ****
--- 4116,4122 ----
/* This is simplified by the fact that our constant
is always positive. */
+
high = low = 0;
for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)
*************** real_yylex ()
*** 3876,3902 ****
<< (i * HOST_BITS_PER_CHAR));
low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
}
!
!
yylval.ttype = build_int_2 (low, high);
TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
/* Calculate the ANSI type. */
! if (!spec_long && !spec_unsigned
&& int_fits_type_p (yylval.ttype, integer_type_node))
type = integer_type_node;
! else if (!spec_long && (base != 10 || spec_unsigned)
&& int_fits_type_p (yylval.ttype, unsigned_type_node))
- /* Nondecimal constants try unsigned even in traditional C. */
type = unsigned_type_node;
! else if (!spec_unsigned && !spec_long_long
&& int_fits_type_p (yylval.ttype, long_integer_type_node))
type = long_integer_type_node;
! else if (! spec_long_long)
type = long_unsigned_type_node;
else if (! spec_unsigned
- /* Verify value does not overflow into sign bit. */
- && TREE_INT_CST_HIGH (yylval.ttype) >= 0
&& int_fits_type_p (yylval.ttype,
long_long_integer_type_node))
type = long_long_integer_type_node;
--- 4126,4150 ----
<< (i * HOST_BITS_PER_CHAR));
low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
}
!
yylval.ttype = build_int_2 (low, high);
TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
/* Calculate the ANSI type. */
! if (! spec_long && ! spec_unsigned
&& int_fits_type_p (yylval.ttype, integer_type_node))
type = integer_type_node;
! else if (! spec_long && (base != 10 || spec_unsigned)
&& int_fits_type_p (yylval.ttype, unsigned_type_node))
type = unsigned_type_node;
! else if (! spec_unsigned && !spec_long_long
&& int_fits_type_p (yylval.ttype, long_integer_type_node))
type = long_integer_type_node;
! else if (! spec_long_long
! && int_fits_type_p (yylval.ttype,
! long_unsigned_type_node))
type = long_unsigned_type_node;
else if (! spec_unsigned
&& int_fits_type_p (yylval.ttype,
long_long_integer_type_node))
type = long_long_integer_type_node;
*************** real_yylex ()
*** 3910,3920 ****
else
type = widest_unsigned_literal_type_node;
! if (!int_fits_type_p (yylval.ttype, type) && !warn)
! pedwarn ("integer constant is larger than the maximum value for its type");
if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
! warning ("decimal integer constant is so large that it is unsigned");
if (spec_imag)
{
--- 4158,4173 ----
else
type = widest_unsigned_literal_type_node;
! if (pedantic && !spec_long_long && !warn
! && (TYPE_PRECISION (long_integer_type_node)
! < TYPE_PRECISION (type)))
! {
! warn = 1;
! pedwarn ("integer constant larger than the maximum value of an unsigned long int");
! }
if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
! warning ("decimal constant is so large that it is unsigned");
if (spec_imag)
{
*************** real_yylex ()
*** 3922,3939 ****
<= TYPE_PRECISION (integer_type_node))
yylval.ttype
= build_complex (NULL_TREE, integer_zero_node,
! cp_convert (integer_type_node,
! yylval.ttype));
else
error ("complex integer constant is too wide for `__complex int'");
}
else
TREE_TYPE (yylval.ttype) = type;
}
token_put_back (c);
*p = 0;
value = CONSTANT; break;
}
--- 4175,4206 ----
<= TYPE_PRECISION (integer_type_node))
yylval.ttype
= build_complex (NULL_TREE, integer_zero_node,
! convert (integer_type_node,
! yylval.ttype));
else
error ("complex integer constant is too wide for `__complex int'");
}
else
TREE_TYPE (yylval.ttype) = type;
+
+
+ /* If it's still an integer (not a complex), and it doesn't
+ fit in the type we choose for it, then pedwarn. */
+
+ if (! warn
+ && TREE_CODE (TREE_TYPE (yylval.ttype)) == INTEGER_TYPE
+ && ! int_fits_type_p (yylval.ttype, TREE_TYPE (yylval.ttype)))
+ pedwarn ("integer constant is larger than the maximum value for its type");
}
token_put_back (c);
*p = 0;
+ if (ISALNUM (c) || c == '.' || c == '_' || c == '$'
+ || ((c == '-' || c == '+')
+ && (p[-1] == 'e' || p[-1] == 'E')))
+ error ("missing white space after number `%s'", token_buffer);
+
value = CONSTANT; break;
}
*************** real_yylex ()
*** 4057,4063 ****
}
/* Merge character into result; ignore excess chars. */
! num_chars++;
if (num_chars < max_chars + 1)
{
if (width < HOST_BITS_PER_INT)
--- 4324,4330 ----
}
/* Merge character into result; ignore excess chars. */
! num_chars += (width / TYPE_PRECISION (char_type_node));
if (num_chars < max_chars + 1)
{
if (width < HOST_BITS_PER_INT)
*************** real_yylex ()
*** 4097,4102 ****
--- 4364,4370 ----
= build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0
>> (HOST_BITS_PER_WIDE_INT - num_bits)),
-1);
+ /* In C, a character constant has type 'int'; in C++, 'char'. */
if (chars_seen <= 1)
TREE_TYPE (yylval.ttype) = char_type_node;
else
*************** real_yylex ()
*** 4115,4121 ****
case '"':
string_constant:
{
- register char *p;
unsigned width = wide_flag ? WCHAR_TYPE_SIZE
: TYPE_PRECISION (char_type_node);
#ifdef MULTIBYTE_CHARS
--- 4383,4388 ----
*************** real_yylex ()
*** 4137,4143 ****
goto skipnewline;
if (width < HOST_BITS_PER_INT
&& (unsigned) c >= ((unsigned)1 << width))
! warning ("escape sequence out of range for character");
}
else if (c == '\n')
{
--- 4404,4410 ----
goto skipnewline;
if (width < HOST_BITS_PER_INT
&& (unsigned) c >= ((unsigned)1 << width))
! pedwarn ("escape sequence out of range for character");
}
else if (c == '\n')
{
*************** real_yylex ()
*** 4198,4204 ****
for (byte = 0; byte < WCHAR_BYTES; ++byte)
{
int value;
! if (byte >= (int) sizeof(c))
value = 0;
else
value = (c >> (byte * width)) & bytemask;
--- 4465,4471 ----
for (byte = 0; byte < WCHAR_BYTES; ++byte)
{
int value;
! if (byte >= (int) sizeof (c))
value = 0;
else
value = (c >> (byte * width)) & bytemask;
*************** real_yylex ()
*** 4218,4227 ****
skipnewline:
c = token_getch ();
- if (c == EOF) {
- error ("Unterminated string");
- break;
- }
}
/* Terminate the string value, either with a single byte zero
--- 4485,4490 ----
*************** real_yylex ()
*** 4240,4245 ****
--- 4503,4511 ----
*p++ = 0;
}
+ if (c == EOF)
+ error ("Unterminated string constant");
+
/* We have read the entire constant.
Construct a STRING_CST for the result. */
*************** real_yylex ()
*** 4261,4266 ****
--- 4527,4533 ----
case '-':
case '&':
case '|':
+ case ':':
case '<':
case '>':
case '*':
*************** real_yylex ()
*** 4337,4355 ****
case '>':
c = RSHIFT;
goto combine;
}
- else if ((c == '-') && (c1 == '>'))
- {
- c1 = token_getch ();
- if (c1 == '*')
- value = POINTSAT_STAR;
- else
- {
- token_put_back (c1);
- value = POINTSAT;
- }
- goto done;
- }
else if (c1 == '?' && (c == '<' || c == '>'))
{
token_buffer[3] = 0;
--- 4604,4614 ----
case '>':
c = RSHIFT;
goto combine;
+ case ':':
+ value = SCOPE;
+ yylval.itype = 1;
+ goto done;
}
else if (c1 == '?' && (c == '<' || c == '>'))
{
token_buffer[3] = 0;
*************** real_yylex ()
*** 4372,4420 ****
token_buffer);
goto done;
}
! /* digraphs */
! else if (c == '<' && c1 == '%')
! { value = '{'; goto done; }
! else if (c == '<' && c1 == ':')
! { value = '['; goto done; }
! else if (c == '%' && c1 == '>')
! { value = '}'; goto done; }
! else if (c == '%' && c1 == ':')
! { value = '#'; goto done; }
token_put_back (c1);
token_buffer[1] = 0;
value = c;
! goto done;
}
- case ':':
- c = token_getch ();
- if (c == ':')
- {
- token_buffer[1] = ':';
- token_buffer[2] = '\0';
- value = SCOPE;
- yylval.itype = 1;
- }
- else if (c == '>')
- {
- value = ']';
- goto done;
- }
- else
- {
- token_put_back (c);
- value = ':';
- }
- break;
-
case 0:
/* Don't make yyparse think this is eof. */
value = 1;
break;
default:
value = c;
}
--- 4631,4696 ----
token_buffer);
goto done;
}
! else
! switch (c)
! {
! case '-':
! if (c1 == '>')
! {
! c1 = token_getch ();
! if (c1 == '*')
! value = POINTSAT_STAR;
! else
! {
! token_put_back (c1);
! value = POINTSAT;
! }
! goto done;
! }
! break;
!
! /* digraphs */
! case ':':
! if (c1 == '>')
! { value = ']'; goto done; }
! break;
! case '<':
! if (c1 == '%')
! { value = '{'; indent_level++; goto done; }
! if (c1 == ':')
! { value = '['; goto done; }
! break;
! case '%':
! if (c1 == '>')
! { value = '}'; indent_level--; goto done; }
! break;
! }
token_put_back (c1);
token_buffer[1] = 0;
+ /* Here the C frontend changes < and > to ARITHCOMPARE. We don't
+ do that because of templates. */
+
value = c;
! break;
}
case 0:
/* Don't make yyparse think this is eof. */
value = 1;
break;
+ case '{':
+ indent_level++;
+ value = c;
+ break;
+
+ case '}':
+ indent_level--;
+ value = c;
+ break;
+
default:
value = c;
}
*************** compiler_error VPROTO ((const char *msg,
*** 4690,4824 ****
error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
}
- void
- yyerror (string)
- const char *string;
- {
- extern int end_of_file;
- char buf[200];
-
- strcpy (buf, string);
-
- /* We can't print string and character constants well
- because the token_buffer contains the result of processing escapes. */
- if (end_of_file)
- strcat (buf, input_redirected ()
- ? " at end of saved text"
- : " at end of input");
- else if (token_buffer[0] == 0)
- strcat (buf, " at null character");
- else if (token_buffer[0] == '"')
- strcat (buf, " before string constant");
- else if (token_buffer[0] == '\'')
- strcat (buf, " before character constant");
- else if (!ISGRAPH ((unsigned char)token_buffer[0]))
- sprintf (buf + strlen (buf), " before character 0%o",
- (unsigned char) token_buffer[0]);
- else
- strcat (buf, " before `%s'");
-
- error (buf, token_buffer);
- }
-
- static int
- handle_cp_pragma (pname)
- const char *pname;
- {
- register int token;
-
- if (! strcmp (pname, "vtable"))
- {
- extern tree pending_vtables;
-
- /* More follows: it must be a string constant (class name). */
- token = real_yylex ();
- if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
- {
- error ("invalid #pragma vtable");
- return -1;
- }
-
- pending_vtables
- = perm_tree_cons (NULL_TREE,
- get_identifier (TREE_STRING_POINTER (yylval.ttype)),
- pending_vtables);
- token = real_yylex ();
- if (token != END_OF_LINE)
- warning ("trailing characters ignored");
- return 1;
- }
- else if (! strcmp (pname, "unit"))
- {
- /* More follows: it must be a string constant (unit name). */
- token = real_yylex ();
- if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
- {
- error ("invalid #pragma unit");
- return -1;
- }
- token = real_yylex ();
- if (token != END_OF_LINE)
- warning ("trailing characters ignored");
- return 1;
- }
- else if (! strcmp (pname, "interface"))
- {
- char *main_filename = input_filename;
-
- main_filename = file_name_nondirectory (main_filename);
-
- token = real_yylex ();
-
- if (token != END_OF_LINE)
- {
- if (token != STRING
- || TREE_CODE (yylval.ttype) != STRING_CST)
- {
- error ("invalid `#pragma interface'");
- return -1;
- }
- main_filename = TREE_STRING_POINTER (yylval.ttype);
- token = real_yylex ();
- }
-
- if (token != END_OF_LINE)
- warning ("garbage after `#pragma interface' ignored");
-
- cp_pragma_interface (main_filename);
-
- return 1;
- }
- else if (! strcmp (pname, "implementation"))
- {
- char *main_filename = main_input_filename ? main_input_filename : input_filename;
-
- main_filename = file_name_nondirectory (main_filename);
-
- token = real_yylex ();
-
- if (token != END_OF_LINE)
- {
- if (token != STRING
- || TREE_CODE (yylval.ttype) != STRING_CST)
- {
- error ("invalid `#pragma implementation'");
- return -1;
- }
- main_filename = TREE_STRING_POINTER (yylval.ttype);
- token = real_yylex ();
- }
-
- if (token != END_OF_LINE)
- warning ("garbage after `#pragma implementation' ignored");
-
- cp_pragma_implementation (main_filename);
-
- return 1;
- }
-
- return 0;
- }
-
/* Return the type-qualifier corresponding to the identifier given by
RID. */
--- 4966,4971 ----
*************** cp_type_qual_from_rid (rid)
*** 4836,4880 ****
my_friendly_abort (0);
return TYPE_UNQUALIFIED;
}
-
-
- #ifdef HANDLE_GENERIC_PRAGMAS
-
- /* Handle a #pragma directive. TOKEN is the type of the word following
- the #pragma directive on the line. Process the entire input line and
- return non-zero iff the directive successfully parsed. */
-
- /* This function has to be in this file, in order to get at
- the token types. */
-
- static int
- handle_generic_pragma (token)
- register int token;
- {
- for (;;)
- {
- switch (token)
- {
- case IDENTIFIER:
- case TYPENAME:
- case STRING:
- case CONSTANT:
- handle_pragma_token (token_buffer, yylval.ttype);
- break;
-
- case LEFT_RIGHT:
- handle_pragma_token ("(", NULL_TREE);
- handle_pragma_token (")", NULL_TREE);
- break;
-
- case END_OF_LINE:
- return handle_pragma_token (NULL_PTR, NULL_TREE);
-
- default:
- handle_pragma_token (token_buffer, NULL_TREE);
- }
-
- token = real_yylex ();
- }
- }
- #endif /* HANDLE_GENERIC_PRAGMAS */
--- 4983,4985 ----
Index: spew.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/spew.c,v
retrieving revision 1.21
diff -c -p -r1.21 spew.c
*** spew.c 1999/07/20 19:53:38 1.21
--- spew.c 1999/07/24 00:44:14
*************** yylex ()
*** 401,406 ****
--- 401,409 ----
break;
case TYPESPEC:
+ /* If this provides a type for us, then revert lexical
+ state to standard state. */
+ looking_for_typename = 0;
consume_token ();
break;