summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/c-lex.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>1999-08-26 09:30:50 +0000
committerobrien <obrien@FreeBSD.org>1999-08-26 09:30:50 +0000
commit0bedf4fb30066e5e1d4342a1d3914dae7d37cba7 (patch)
tree68d8110b41afd0ebbf39167b1a4918eea667a7c5 /contrib/gcc/c-lex.c
parentd4db5fb866b7ad5216abd5047774a3973b9901a9 (diff)
downloadFreeBSD-src-0bedf4fb30066e5e1d4342a1d3914dae7d37cba7.zip
FreeBSD-src-0bedf4fb30066e5e1d4342a1d3914dae7d37cba7.tar.gz
Virgin import of gcc from EGCS 1.1.2
Diffstat (limited to 'contrib/gcc/c-lex.c')
-rw-r--r--contrib/gcc/c-lex.c648
1 files changed, 397 insertions, 251 deletions
diff --git a/contrib/gcc/c-lex.c b/contrib/gcc/c-lex.c
index 007b363..f82ad76 100644
--- a/contrib/gcc/c-lex.c
+++ b/contrib/gcc/c-lex.c
@@ -1,5 +1,5 @@
/* Lexical analyzer for C and Objective C.
- Copyright (C) 1987, 88, 89, 92, 94, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 89, 92, 94-97, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -18,32 +18,43 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-
-#include <stdio.h>
-#include <errno.h>
+#include "config.h"
+#include "system.h"
#include <setjmp.h>
-#include "config.h"
#include "rtl.h"
#include "tree.h"
#include "input.h"
+#include "output.h"
#include "c-lex.h"
#include "c-tree.h"
#include "flags.h"
#include "c-parse.h"
#include "c-pragma.h"
+#include "toplev.h"
-#include <ctype.h>
+/* MULTIBYTE_CHARS support only works for native compilers.
+ ??? Ideally what we want is to model widechar support after
+ the current floating point support. */
+#ifdef CROSS_COMPILE
+#undef MULTIBYTE_CHARS
+#endif
#ifdef MULTIBYTE_CHARS
-#include <stdlib.h>
#include <locale.h>
#endif
-#ifndef errno
-extern int errno;
+#if USE_CPPLIB
+#include "cpplib.h"
+extern cpp_reader parse_in;
+extern cpp_options parse_options;
+#else
+/* Stream for reading from the input file. */
+FILE *finput;
#endif
+extern void yyprint PROTO((FILE *, int, YYSTYPE));
+
/* The elements of `ridpointers' are identifier nodes
for the reserved type names and storage classes.
It is indexed by a RID_... value. */
@@ -52,6 +63,18 @@ tree ridpointers[(int) RID_MAX];
/* Cause the `yydebug' variable to be defined. */
#define YYDEBUG 1
+#if USE_CPPLIB
+extern unsigned char *yy_cur, *yy_lim;
+
+extern int yy_get_token ();
+
+#define GETC() (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ())
+#define UNGETC(c) ((c), yy_cur--)
+#else
+#define GETC() getc (finput)
+#define UNGETC(c) ungetc (c, finput)
+#endif
+
/* the declaration found for the last IDENTIFIER token read in.
yylex must look this up to detect typedefs, which get token type TYPENAME,
so it is left around in case the identifier is not a typedef but is
@@ -62,8 +85,6 @@ tree lastiddecl;
int doing_objc_thang;
-extern tree is_class_name ();
-
extern int yydebug;
/* File used for outputting assembler code. */
@@ -85,13 +106,24 @@ char *token_buffer; /* Pointer to token buffer.
Actual allocated length is maxtoken + 2.
This is not static because objc-parse.y uses it. */
+static int indent_level = 0; /* Number of { minus number of }. */
+
/* Nonzero if end-of-file has been seen on input. */
static int end_of_file;
+#if !USE_CPPLIB
/* Buffered-back input character; faster than using ungetc. */
static int nextchar = -1;
+#endif
-int check_newline ();
+#ifdef HANDLE_SYSV_PRAGMA
+static int handle_sysv_pragma PROTO((int));
+#endif /* HANDLE_SYSV_PRAGMA */
+static int whitespace_cr PROTO((int));
+static int skip_white_space PROTO((int));
+static int skip_white_space_on_line PROTO((void));
+static char *extend_token_buffer PROTO((char *));
+static int readescape PROTO((int *));
/* Do not insert generated code into the source, instead, include it.
This allows us to build gcc automatically even for targets that
@@ -142,6 +174,51 @@ remember_protocol_qualifiers ()
wordlist[i].name = "oneway";
}
+char *
+init_parse (filename)
+ char *filename;
+{
+#if !USE_CPPLIB
+ /* Open input file. */
+ if (filename == 0 || !strcmp (filename, "-"))
+ {
+ finput = stdin;
+ filename = "stdin";
+ }
+ else
+ finput = fopen (filename, "r");
+ if (finput == 0)
+ pfatal_with_name (filename);
+
+#ifdef IO_BUFFER_SIZE
+ setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
+#endif
+#endif /* !USE_CPPLIB */
+
+ init_lex ();
+
+#if USE_CPPLIB
+ yy_cur = "\n";
+ yy_lim = yy_cur+1;
+
+ parse_in.show_column = 1;
+ if (! cpp_start_read (&parse_in, filename))
+ abort ();
+#endif
+
+ return filename;
+}
+
+void
+finish_parse ()
+{
+#if USE_CPPLIB
+ cpp_finish (&parse_in);
+#else
+ fclose (finput);
+#endif
+}
+
void
init_lex ()
{
@@ -245,10 +322,14 @@ yyprint (file, yychar, yylval)
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
+#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%x%016x",
+ " 0x%llx%016llx",
+#endif
#endif
#else
#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
@@ -261,8 +342,30 @@ yyprint (file, yychar, yylval)
break;
}
}
-
+/* 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. */
@@ -270,8 +373,6 @@ static int
skip_white_space (c)
register int c;
{
- static int newline_warning = 0;
-
for (;;)
{
switch (c)
@@ -289,28 +390,21 @@ skip_white_space (c)
case '\f':
case '\v':
case '\b':
- c = getc (finput);
+ c = GETC();
break;
case '\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;
- }
- c = getc (finput);
+ whitespace_cr (c);
+ c = GETC();
break;
case '\\':
- c = getc (finput);
+ c = GETC();
if (c == '\n')
lineno++;
else
error ("stray '\\' in program");
- c = getc (finput);
+ c = GETC();
break;
default:
@@ -327,12 +421,46 @@ position_after_white_space ()
{
register int c;
+#if !USE_CPPLIB
if (nextchar != -1)
c = nextchar, nextchar = -1;
else
- c = getc (finput);
+#endif
+ c = GETC();
- ungetc (skip_white_space (c), finput);
+ UNGETC (skip_white_space (c));
+}
+
+/* Like skip_white_space, but don't advance beyond the end of line.
+ Moreover, we don't get passed a character to start with. */
+static int
+skip_white_space_on_line ()
+{
+ register int c;
+
+ while (1)
+ {
+ c = GETC();
+ switch (c)
+ {
+ case '\n':
+ default:
+ break;
+
+ case ' ':
+ case '\t':
+ case '\f':
+ case '\v':
+ case '\b':
+ continue;
+
+ case '\r':
+ whitespace_cr (c);
+ continue;
+ }
+ break;
+ }
+ return c;
}
/* Make the token buffer longer, preserving the data in it.
@@ -367,9 +495,9 @@ check_newline ()
/* Read first nonwhite char on the line. */
- c = getc (finput);
+ c = GETC();
while (c == ' ' || c == '\t')
- c = getc (finput);
+ c = GETC();
if (c != '#')
{
@@ -379,9 +507,9 @@ check_newline ()
/* Read first nonwhite char after the `#'. */
- c = getc (finput);
+ c = GETC();
while (c == ' ' || c == '\t')
- c = getc (finput);
+ c = GETC();
/* If a letter follows, then if the word here is `line', skip
it and ignore it; otherwise, ignore the line, with an error
@@ -391,86 +519,105 @@ check_newline ()
{
if (c == 'p')
{
- if (getc (finput) == 'r'
- && getc (finput) == 'a'
- && getc (finput) == 'g'
- && getc (finput) == 'm'
- && getc (finput) == 'a'
- && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))
+ if (GETC() == 'r'
+ && GETC() == 'a'
+ && GETC() == 'g'
+ && GETC() == 'm'
+ && GETC() == 'a'
+ && ((c = GETC()) == ' ' || c == '\t' || c == '\n'
+ || whitespace_cr (c) ))
{
+ while (c == ' ' || c == '\t' || whitespace_cr (c))
+ c = GETC ();
+ if (c == '\n')
+ return c;
#ifdef HANDLE_SYSV_PRAGMA
- return handle_sysv_pragma (finput, c);
+ UNGETC (c);
+ token = yylex ();
+ if (token != IDENTIFIER)
+ goto skipline;
+ return handle_sysv_pragma (token);
#else /* !HANDLE_SYSV_PRAGMA */
#ifdef HANDLE_PRAGMA
- HANDLE_PRAGMA (finput);
+#if !USE_CPPLIB
+ UNGETC (c);
+ token = yylex ();
+ if (token != IDENTIFIER)
+ goto skipline;
+ if (nextchar >= 0)
+ c = nextchar, nextchar = -1;
+ else
+ c = GETC ();
+ ungetc (c, finput);
+ if (HANDLE_PRAGMA (finput, yylval.ttype))
+ {
+ c = GETC ();
+ return c;
+ }
+#else
+ ??? do not know what to do ???;
+#endif /* !USE_CPPLIB */
#endif /* HANDLE_PRAGMA */
- goto skipline;
#endif /* !HANDLE_SYSV_PRAGMA */
+ goto skipline;
}
}
else if (c == 'd')
{
- if (getc (finput) == 'e'
- && getc (finput) == 'f'
- && getc (finput) == 'i'
- && getc (finput) == 'n'
- && getc (finput) == 'e'
- && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))
+ if (GETC() == 'e'
+ && GETC() == 'f'
+ && GETC() == 'i'
+ && GETC() == 'n'
+ && GETC() == 'e'
+ && ((c = GETC()) == ' ' || c == '\t' || c == '\n'))
{
-#ifdef DWARF_DEBUGGING_INFO
- if ((debug_info_level == DINFO_LEVEL_VERBOSE)
- && (write_symbols == DWARF_DEBUG))
- dwarfout_define (lineno, get_directive_line (finput));
-#endif /* DWARF_DEBUGGING_INFO */
+ if (c != '\n')
+ debug_define (lineno, GET_DIRECTIVE_LINE ());
goto skipline;
}
}
else if (c == 'u')
{
- if (getc (finput) == 'n'
- && getc (finput) == 'd'
- && getc (finput) == 'e'
- && getc (finput) == 'f'
- && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))
+ if (GETC() == 'n'
+ && GETC() == 'd'
+ && GETC() == 'e'
+ && GETC() == 'f'
+ && ((c = GETC()) == ' ' || c == '\t' || c == '\n'))
{
-#ifdef DWARF_DEBUGGING_INFO
- if ((debug_info_level == DINFO_LEVEL_VERBOSE)
- && (write_symbols == DWARF_DEBUG))
- dwarfout_undef (lineno, get_directive_line (finput));
-#endif /* DWARF_DEBUGGING_INFO */
+ if (c != '\n')
+ debug_undef (lineno, GET_DIRECTIVE_LINE ());
goto skipline;
}
}
else if (c == 'l')
{
- if (getc (finput) == 'i'
- && getc (finput) == 'n'
- && getc (finput) == 'e'
- && ((c = getc (finput)) == ' ' || c == '\t'))
+ if (GETC() == 'i'
+ && GETC() == 'n'
+ && GETC() == 'e'
+ && ((c = GETC()) == ' ' || c == '\t'))
goto linenum;
}
else if (c == 'i')
{
- if (getc (finput) == 'd'
- && getc (finput) == 'e'
- && getc (finput) == 'n'
- && getc (finput) == 't'
- && ((c = getc (finput)) == ' ' || c == '\t'))
+ if (GETC() == 'd'
+ && GETC() == 'e'
+ && GETC() == 'n'
+ && GETC() == 't'
+ && ((c = GETC()) == ' ' || c == '\t'))
{
/* #ident. The pedantic warning is now in cccp.c. */
/* Here we have just seen `#ident '.
A string constant should follow. */
- while (c == ' ' || c == '\t')
- c = getc (finput);
+ c = skip_white_space_on_line ();
/* If no argument, ignore the line. */
if (c == '\n')
return c;
- ungetc (c, finput);
+ UNGETC (c);
token = yylex ();
if (token != STRING
|| TREE_CODE (yylval.ttype) != STRING_CST)
@@ -499,8 +646,11 @@ linenum:
/* Here we have either `#line' or `# <nonletter>'.
In either case, it should be a line number; a digit should follow. */
- while (c == ' ' || c == '\t')
- c = getc (finput);
+ /* Can't use skip_white_space here, but must handle all whitespace
+ that is not '\n', lest we get a recursion for '\r' '\n' when
+ calling yylex. */
+ UNGETC (c);
+ c = skip_white_space_on_line ();
/* If the # is the only nonwhite char on the line,
just ignore it. Check the new newline. */
@@ -509,7 +659,7 @@ linenum:
/* Something follows the #; read a token. */
- ungetc (c, finput);
+ UNGETC (c);
token = yylex ();
if (token == CONSTANT
@@ -523,16 +673,14 @@ linenum:
int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
/* Is this the last nonwhite stuff on the line? */
- c = getc (finput);
- while (c == ' ' || c == '\t')
- c = getc (finput);
+ c = skip_white_space_on_line ();
if (c == '\n')
{
/* No more: store the line number and check following line. */
lineno = l;
return c;
}
- ungetc (c, finput);
+ UNGETC (c);
/* More follows: it must be a string constant (filename). */
@@ -558,9 +706,7 @@ linenum:
main_input_filename = input_filename;
/* Is this the last nonwhite stuff on the line? */
- c = getc (finput);
- while (c == ' ' || c == '\t')
- c = getc (finput);
+ c = skip_white_space_on_line ();
if (c == '\n')
{
/* Update the name in the top element of input_file_stack. */
@@ -569,7 +715,7 @@ linenum:
return c;
}
- ungetc (c, finput);
+ UNGETC (c);
token = yylex ();
used_up = 0;
@@ -588,14 +734,10 @@ linenum:
input_file_stack->line = old_lineno;
p->next = input_file_stack;
p->name = input_filename;
+ p->indent_level = indent_level;
input_file_stack = p;
input_file_stack_tick++;
-#ifdef DWARF_DEBUGGING_INFO
- if (debug_info_level == DINFO_LEVEL_VERBOSE
- && write_symbols == DWARF_DEBUG)
- dwarfout_start_new_source_file (input_filename);
-#endif /* DWARF_DEBUGGING_INFO */
-
+ debug_start_source_file (input_filename);
used_up = 1;
}
else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
@@ -604,14 +746,18 @@ linenum:
if (input_file_stack->next)
{
struct file_stack *p = input_file_stack;
+ if (indent_level != p->indent_level)
+ {
+ warning_with_file_and_line
+ (p->name, old_lineno,
+ "This file contains more `%c's than `%c's.",
+ indent_level > p->indent_level ? '{' : '}',
+ indent_level > p->indent_level ? '}' : '{');
+ }
input_file_stack = p->next;
free (p);
input_file_stack_tick++;
-#ifdef DWARF_DEBUGGING_INFO
- if (debug_info_level == DINFO_LEVEL_VERBOSE
- && write_symbols == DWARF_DEBUG)
- dwarfout_resume_previous_source_file (input_file_stack->line);
-#endif /* DWARF_DEBUGGING_INFO */
+ debug_end_source_file (input_file_stack->line);
}
else
error ("#-lines for entering and leaving files don't match");
@@ -630,12 +776,10 @@ linenum:
if (used_up)
{
/* Is this the last nonwhite stuff on the line? */
- c = getc (finput);
- while (c == ' ' || c == '\t')
- c = getc (finput);
+ c = skip_white_space_on_line ();
if (c == '\n')
return c;
- ungetc (c, finput);
+ UNGETC (c);
token = yylex ();
used_up = 0;
@@ -651,12 +795,10 @@ linenum:
if (used_up)
{
/* Is this the last nonwhite stuff on the line? */
- c = getc (finput);
- while (c == ' ' || c == '\t')
- c = getc (finput);
+ c = skip_white_space_on_line ();
if (c == '\n')
return c;
- ungetc (c, finput);
+ UNGETC (c);
}
warning ("unrecognized text at end of #line");
@@ -666,37 +808,33 @@ linenum:
/* skip the rest of this line. */
skipline:
- if (c == '\n')
- return c;
- while ((c = getc (finput)) != EOF && c != '\n');
+#if !USE_CPPLIB
+ if (c != '\n' && c != EOF && nextchar >= 0)
+ c = nextchar, nextchar = -1;
+#endif
+ while (c != '\n' && c != EOF)
+ c = GETC();
return c;
}
#ifdef HANDLE_SYSV_PRAGMA
-/* Handle a #pragma directive. INPUT is the current input stream,
- and C is a character to reread. Processes the entire input line
- and returns a character for the caller to reread: either \n or EOF. */
+/* Handle a #pragma directive.
+ TOKEN is the token we read after `#pragma'. Processes the entire input
+ line and returns a character for the caller to reread: either \n or EOF. */
/* This function has to be in this file, in order to get at
the token types. */
-int
-handle_sysv_pragma (input, c)
- FILE *input;
- int c;
+static int
+handle_sysv_pragma (token)
+ register int token;
{
+ register int c;
+
for (;;)
{
- while (c == ' ' || c == '\t')
- c = getc (input);
- if (c == '\n' || c == EOF)
- {
- handle_pragma_token (0, 0);
- return c;
- }
- ungetc (c, input);
- switch (yylex ())
+ switch (token)
{
case IDENTIFIER:
case TYPENAME:
@@ -707,10 +845,22 @@ handle_sysv_pragma (input, c)
default:
handle_pragma_token (token_buffer, 0);
}
+#if !USE_CPPLIB
if (nextchar >= 0)
c = nextchar, nextchar = -1;
else
- c = getc (input);
+#endif
+ c = GETC ();
+
+ while (c == ' ' || c == '\t')
+ c = GETC ();
+ if (c == '\n' || c == EOF)
+ {
+ handle_pragma_token (0, 0);
+ return c;
+ }
+ UNGETC (c);
+ token = yylex ();
}
}
@@ -725,7 +875,7 @@ static int
readescape (ignore_ptr)
int *ignore_ptr;
{
- register int c = getc (finput);
+ register int c = GETC();
register int code;
register unsigned count;
unsigned firstdig = 0;
@@ -745,12 +895,12 @@ readescape (ignore_ptr)
nonnull = 0;
while (1)
{
- c = getc (finput);
+ c = GETC();
if (!(c >= 'a' && c <= 'f')
&& !(c >= 'A' && c <= 'F')
&& !(c >= '0' && c <= '9'))
{
- ungetc (c, finput);
+ UNGETC (c);
break;
}
code *= 16;
@@ -787,9 +937,9 @@ readescape (ignore_ptr)
while ((c <= '7') && (c >= '0') && (count++ < 3))
{
code = (code * 8) + (c - '0');
- c = getc (finput);
+ c = GETC();
}
- ungetc (c, finput);
+ UNGETC (c);
return code;
case '\\': case '\'': case '"':
@@ -913,10 +1063,12 @@ yylex ()
int wide_flag = 0;
int objc_flag = 0;
+#if !USE_CPPLIB
if (nextchar >= 0)
c = nextchar, nextchar = -1;
else
- c = getc (finput);
+#endif
+ c = GETC();
/* Effectively do c = skip_white_space (c)
but do it faster in the usual cases. */
@@ -928,7 +1080,7 @@ yylex ()
case '\f':
case '\v':
case '\b':
- c = getc (finput);
+ c = GETC();
break;
case '\r':
@@ -956,15 +1108,10 @@ yylex ()
value = ENDFILE;
break;
- case '$':
- if (dollars_in_ident)
- goto letter;
- return '$';
-
case 'L':
/* Capital L may start a wide-string or wide-character constant. */
{
- register int c = getc (finput);
+ register int c = GETC();
if (c == '\'')
{
wide_flag = 1;
@@ -975,7 +1122,7 @@ yylex ()
wide_flag = 1;
goto string_constant;
}
- ungetc (c, finput);
+ UNGETC (c);
}
goto letter;
@@ -988,13 +1135,13 @@ yylex ()
else
{
/* '@' may start a constant string object. */
- register int c = getc(finput);
+ register int c = GETC ();
if (c == '"')
{
objc_flag = 1;
goto string_constant;
}
- ungetc(c, finput);
+ UNGETC (c);
/* Fall through to treat '@' as the start of an identifier. */
}
@@ -1011,25 +1158,35 @@ yylex ()
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case '_':
+ case '$':
letter:
p = token_buffer;
- while (isalnum (c) || c == '_' || c == '$' || c == '@')
+ while (ISALNUM (c) || c == '_' || c == '$' || c == '@')
{
/* Make sure this char really belongs in an identifier. */
if (c == '@' && ! doing_objc_thang)
break;
- if (c == '$' && ! dollars_in_ident)
- break;
+ 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 = getc (finput);
+ c = GETC();
}
*p = 0;
+#if USE_CPPLIB
+ UNGETC (c);
+#else
nextchar = c;
+#endif
value = IDENTIFIER;
yylval.itype = 0;
@@ -1039,7 +1196,7 @@ yylex ()
{
register struct resword *ptr;
- if (ptr = is_reserved_word (token_buffer, p - token_buffer))
+ if ((ptr = is_reserved_word (token_buffer, p - token_buffer)))
{
if (ptr->rid)
yylval.ttype = ridpointers[(int) ptr->rid];
@@ -1109,7 +1266,23 @@ yylex ()
break;
- case '0': case '1': case '2': case '3': case '4':
+ case '0': case '1':
+ {
+ int next_c;
+ /* Check first for common special case: single-digit 0 or 1. */
+
+ next_c = GETC ();
+ UNGETC (next_c); /* Always undo this lookahead. */
+ if (!ISALNUM (next_c) && next_c != '.')
+ {
+ token_buffer[0] = (char)c, token_buffer[1] = '\0';
+ 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':
case '.':
{
@@ -1138,11 +1311,11 @@ yylex ()
if (c == '0')
{
- *p++ = (c = getc (finput));
+ *p++ = (c = GETC());
if ((c == 'x') || (c == 'X'))
{
base = 16;
- *p++ = (c = getc (finput));
+ *p++ = (c = GETC());
}
/* Leading 0 forces octal unless the 0 is the only digit. */
else if (c >= '0' && c <= '9')
@@ -1157,7 +1330,7 @@ yylex ()
/* Read all the digits-and-decimal-points. */
while (c == '.'
- || (isalnum (c) && c != 'l' && c != 'L'
+ || (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')))))
@@ -1181,16 +1354,16 @@ yylex ()
floatflag = AFTER_POINT;
base = 10;
- *p++ = c = getc (finput);
+ *p++ = c = GETC();
/* Accept '.' as the start of a floating-point number
only when it is followed by a digit.
Otherwise, unread the following non-digit
and use the '.' as a structural token. */
- if (p == token_buffer + 2 && !isdigit (c))
+ if (p == token_buffer + 2 && !ISDIGIT (c))
{
if (c == '.')
{
- c = getc (finput);
+ c = GETC();
if (c == '.')
{
*p++ = c;
@@ -1199,7 +1372,7 @@ yylex ()
}
error ("parse error at `..'");
}
- ungetc (c, finput);
+ UNGETC (c);
token_buffer[1] = 0;
value = '.';
goto done;
@@ -1210,7 +1383,7 @@ yylex ()
/* It is not a decimal point.
It should be a digit (perhaps a hex digit). */
- if (isdigit (c))
+ if (ISDIGIT (c))
{
c = c - '0';
}
@@ -1258,7 +1431,7 @@ yylex ()
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
- *p++ = (c = getc (finput));
+ *p++ = (c = GETC());
}
}
@@ -1274,8 +1447,8 @@ yylex ()
if (floatflag != NOT_FLOAT)
{
tree type = double_type_node;
- int garbage_chars = 0, exceeds_double = 0;
int imag = 0;
+ int conversion_errno = 0;
REAL_VALUE_TYPE value;
jmp_buf handler;
@@ -1286,25 +1459,24 @@ yylex ()
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = c;
- c = getc (finput);
+ c = GETC();
if ((c == '+') || (c == '-'))
{
*p++ = c;
- c = getc (finput);
+ c = GETC();
}
- if (! isdigit (c))
+ if (! ISDIGIT (c))
error ("floating constant exponent has no digits");
- while (isdigit (c))
+ while (ISDIGIT (c))
{
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = c;
- c = getc (finput);
+ c = GETC();
}
}
*p = 0;
- errno = 0;
/* Convert string to a double, checking for overflow. */
if (setjmp (handler))
@@ -1361,7 +1533,7 @@ yylex ()
p = extend_token_buffer (p);
*p++ = c;
*p = 0;
- c = getc (finput);
+ c = GETC();
}
/* The second argument, machine_mode, of REAL_VALUE_ATOF
@@ -1374,7 +1546,9 @@ yylex ()
error ("both `f' and `l' in floating constant");
type = float_type_node;
+ errno = 0;
value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
+ conversion_errno = errno;
/* A diagnostic is required here by some ANSI C testsuites.
This is not pedwarn, become some people don't want
an error for this. */
@@ -1384,13 +1558,17 @@ yylex ()
else if (lflag)
{
type = long_double_type_node;
+ errno = 0;
value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
+ conversion_errno = errno;
if (REAL_VALUE_ISINF (value) && pedantic)
warning ("floating point number exceeds range of `long double'");
}
else
{
+ errno = 0;
value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
+ conversion_errno = errno;
if (REAL_VALUE_ISINF (value) && pedantic)
warning ("floating point number exceeds range of `double'");
}
@@ -1398,31 +1576,13 @@ yylex ()
set_float_handler (NULL_PTR);
}
#ifdef ERANGE
- if (errno == ERANGE && !flag_traditional && 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))
- {
- warning ("floating point number exceeds range of `double'");
- exceeds_double = 1;
- }
- }
+ /* ERANGE is also reported for underflow,
+ so test the value to distinguish overflow from that. */
+ if (conversion_errno == ERANGE && !flag_traditional && pedantic
+ && (REAL_VALUES_LESS (dconst1, value)
+ || REAL_VALUES_LESS (value, dconstm1)))
+ warning ("floating point number exceeds range of `double'");
#endif
- garbage_chars = 0;
- while (isalnum (c) || c == '.' || c == '_'
- || (!flag_traditional && (c == '+' || c == '-')
- && (p[-1] == 'e' || p[-1] == 'E')))
- {
- if (p >= token_buffer + maxtoken - 3)
- p = extend_token_buffer (p);
- *p++ = c;
- c = getc (finput);
- garbage_chars++;
- }
- if (garbage_chars > 0)
- error ("garbage at end of number");
/* If the result is not a number, assume it must have been
due to some error message above, so silently convert
@@ -1432,13 +1592,11 @@ yylex ()
/* Create a node with determined type and value. */
if (imag)
- yylval.ttype = build_complex (convert (type, integer_zero_node),
+ yylval.ttype = build_complex (NULL_TREE,
+ convert (type, integer_zero_node),
build_real (type, value));
else
yylval.ttype = build_real (type, value);
-
- ungetc (c, finput);
- *p = 0;
}
else
{
@@ -1450,6 +1608,7 @@ yylex ()
int spec_imag = 0;
int bytes, warn, i;
+ traditional_type = ansi_type = type = NULL_TREE;
while (1)
{
if (c == 'u' || c == 'U')
@@ -1479,46 +1638,22 @@ yylex ()
spec_imag = 1;
}
else
- {
- if (isalnum (c) || c == '.' || c == '_'
- || (!flag_traditional && (c == '+' || c == '-')
- && (p[-1] == 'e' || p[-1] == 'E')))
- {
- error ("garbage at end of number");
- while (isalnum (c) || c == '.' || c == '_'
- || (!flag_traditional && (c == '+' || c == '-')
- && (p[-1] == 'e' || p[-1] == 'E')))
- {
- if (p >= token_buffer + maxtoken - 3)
- p = extend_token_buffer (p);
- *p++ = c;
- c = getc (finput);
- }
- }
- break;
- }
+ break;
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = c;
- c = getc (finput);
+ c = GETC();
}
- ungetc (c, finput);
-
- /* If the constant is not long long and it won't fit in an
- unsigned long, or if the constant is long long and won't fit
- in an unsigned long long, then warn that the constant is out
- of range. */
+ /* If the constant won't fit in an unsigned long long,
+ then warn that the constant is out of range. */
/* ??? This assumes that long long and long integer types are
a multiple of 8 bits. This better than the original code
though which assumed that long was exactly 32 bits and long
long was exactly 64 bits. */
- if (spec_long_long)
- bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;
- else
- bytes = TYPE_PRECISION (long_integer_type_node) / 8;
+ bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;
warn = overflow;
for (i = bytes; i < TOTAL_PARTS; i++)
@@ -1585,11 +1720,11 @@ yylex ()
else if (! spec_unsigned && !spec_long_long
&& int_fits_type_p (yylval.ttype, long_integer_type_node))
ansi_type = long_integer_type_node;
- else if (! spec_long_long)
+ else if (! spec_long_long
+ && int_fits_type_p (yylval.ttype,
+ long_unsigned_type_node))
ansi_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))
ansi_type = long_long_integer_type_node;
@@ -1611,8 +1746,9 @@ yylex ()
warning ("width of integer constant may change on other systems with -traditional");
}
- if (!flag_traditional && !int_fits_type_p (yylval.ttype, type)
- && !warn)
+ if (pedantic && !flag_traditional && !spec_long_long && !warn
+ && (TYPE_PRECISION (long_integer_type_node)
+ < TYPE_PRECISION (type)))
pedwarn ("integer constant out of range");
if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
@@ -1623,8 +1759,9 @@ yylex ()
if (TYPE_PRECISION (type)
<= TYPE_PRECISION (integer_type_node))
yylval.ttype
- = build_complex (integer_zero_node,
- convert (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'");
}
@@ -1640,10 +1777,16 @@ yylex ()
}
else
TREE_TYPE (yylval.ttype) = type;
-
- *p = 0;
}
+ UNGETC (c);
+ *p = 0;
+
+ if (ISALNUM (c) || c == '.' || c == '_' || c == '$'
+ || (!flag_traditional && (c == '-' || c == '+')
+ && (p[-1] == 'e' || p[-1] == 'E')))
+ error ("missing white space after number `%s'", token_buffer);
+
value = CONSTANT; break;
}
@@ -1671,7 +1814,7 @@ yylex ()
{
tryagain:
- c = getc (finput);
+ c = GETC();
if (c == '\'' || c == EOF)
break;
@@ -1686,7 +1829,7 @@ yylex ()
&& (unsigned) c >= (1 << width))
pedwarn ("escape sequence out of range for character");
#ifdef MAP_CHARACTER
- if (isprint (c))
+ if (ISPRINT (c))
c = MAP_CHARACTER (c);
#endif
}
@@ -1729,7 +1872,7 @@ yylex ()
num_chars = max_chars;
error ("character constant too long");
}
- else if (num_chars != 1 && ! flag_traditional)
+ else if (num_chars != 1 && ! flag_traditional && warn_multichar)
warning ("multi-character character constant");
/* If char type is signed, sign-extend the constant. */
@@ -1742,12 +1885,12 @@ yylex ()
else if (TREE_UNSIGNED (char_type_node)
|| ((result >> (num_bits - 1)) & 1) == 0)
yylval.ttype
- = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0
+ = build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0
>> (HOST_BITS_PER_WIDE_INT - num_bits)),
0);
else
yylval.ttype
- = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0
+ = build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0
>> (HOST_BITS_PER_WIDE_INT - num_bits)),
-1);
TREE_TYPE (yylval.ttype) = integer_type_node;
@@ -1781,7 +1924,7 @@ yylex ()
case '"':
string_constant:
{
- c = getc (finput);
+ c = GETC();
p = token_buffer + 1;
while (c != '"' && c >= 0)
@@ -1809,7 +1952,7 @@ yylex ()
*p++ = c;
skipnewline:
- c = getc (finput);
+ c = GETC();
}
*p = 0;
@@ -1836,15 +1979,9 @@ yylex ()
bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES);
#else
{
- union { long l; char c[sizeof (long)]; } u;
- int big_endian;
char *wp, *cp;
- /* Determine whether host is little or big endian. */
- u.l = 1;
- big_endian = u.c[sizeof (long) - 1];
- wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0);
-
+ wp = widep + (BYTES_BIG_ENDIAN ? WCHAR_BYTES - 1 : 0);
bzero (widep, (p - token_buffer) * WCHAR_BYTES);
for (cp = token_buffer + 1; cp < p; cp++)
*wp = *cp, wp += WCHAR_BYTES;
@@ -1857,7 +1994,6 @@ yylex ()
}
else if (objc_flag)
{
- extern tree build_objc_string();
/* Return an Objective-C @"..." constant string object. */
yylval.ttype = build_objc_string (p - token_buffer,
token_buffer + 1);
@@ -1923,7 +2059,7 @@ yylex ()
yylval.code = GT_EXPR; break;
}
- token_buffer[1] = c1 = getc (finput);
+ token_buffer[1] = c1 = GETC();
token_buffer[2] = 0;
if (c1 == '=')
@@ -1972,16 +2108,16 @@ yylex ()
break;
case '<':
if (c1 == '%')
- { value = '{'; goto done; }
+ { value = '{'; indent_level++; goto done; }
if (c1 == ':')
{ value = '['; goto done; }
break;
case '%':
if (c1 == '>')
- { value = '}'; goto done; }
+ { value = '}'; indent_level--; goto done; }
break;
}
- ungetc (c1, finput);
+ UNGETC (c1);
token_buffer[1] = 0;
if ((c == '<') || (c == '>'))
@@ -1995,6 +2131,16 @@ yylex ()
value = 1;
break;
+ case '{':
+ indent_level++;
+ value = c;
+ break;
+
+ case '}':
+ indent_level--;
+ value = c;
+ break;
+
default:
value = c;
}
OpenPOWER on IntegriCloud