#include "config.h"
#include "system.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 "intl.h"
#include "genindex.h"
#ifdef CROSS_COMPILE
#undef MULTIBYTE_CHARS
#endif
#ifdef MULTIBYTE_CHARS
#include "mbchar.h"
#include <locale.h>
#endif
#if USE_CPPLIB
#include "cpplib.h"
extern cpp_reader parse_in;
extern cpp_options parse_options;
#else
FILE *finput;
#endif
extern void yyprint PROTO((FILE *, int, YYSTYPE));
tree ridpointers[(int) RID_MAX];
#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) == EOF ? 0 : yy_cur--)
#else
#define GETC() getc (finput)
#define UNGETC(c) ungetc (c, finput)
#endif
tree lastiddecl;
int doing_objc_thang;
int objc_need_raw_identifier;
extern int yydebug;
extern FILE *asm_out_file;
#ifndef WCHAR_TYPE_SIZE
#ifdef INT_TYPE_SIZE
#define WCHAR_TYPE_SIZE INT_TYPE_SIZE
#else
#define WCHAR_TYPE_SIZE BITS_PER_WORD
#endif
#endif
#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
static int maxtoken;
char *token_buffer;
static int indent_level = 0;
static int end_of_file;
#if !USE_CPPLIB
static int nextchar = -1;
#endif
#ifdef HANDLE_GENERIC_PRAGMAS
static int handle_generic_pragma PROTO((int));
#endif
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((const char *));
static int readescape PROTO((int *));
static void parse_float PROTO((PTR));
#include "c-gperf.h"
tree
make_pointer_declarator (type_quals, target)
tree type_quals, target;
{
return build1 (INDIRECT_REF, type_quals, target);
}
#ifndef OBJCPLUS
void
forget_protocol_qualifiers ()
{
int i, n = sizeof wordlist / sizeof (struct resword);
for (i = 0; i < n; i++)
if ((int) wordlist[i].rid >= (int) RID_IN
&& (int) wordlist[i].rid <= (int) RID_ONEWAY)
wordlist[i].name = "";
}
void
remember_protocol_qualifiers ()
{
int i, n = sizeof wordlist / sizeof (struct resword);
for (i = 0; i < n; i++)
if (wordlist[i].rid == RID_IN)
wordlist[i].name = "in";
else if (wordlist[i].rid == RID_OUT)
wordlist[i].name = "out";
else if (wordlist[i].rid == RID_INOUT)
wordlist[i].name = "inout";
else if (wordlist[i].rid == RID_BYCOPY)
wordlist[i].name = "bycopy";
else if (wordlist[i].rid == RID_BYREF)
wordlist[i].name = "byref";
else if (wordlist[i].rid == RID_ONEWAY)
wordlist[i].name = "oneway";
}
#endif
char *
init_parse (filename)
char *filename;
{
#if !USE_CPPLIB
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
#else
parse_in.show_column = 1;
if (! cpp_start_read (&parse_in, filename))
abort ();
if (filename == 0 || !strcmp (filename, "-"))
filename = "stdin";
yy_cur = parse_in.token_buffer;
yy_lim = CPP_PWRITTEN (&parse_in);
#endif
init_lex ();
return filename;
}
void
finish_parse ()
{
#if USE_CPPLIB
cpp_finish (&parse_in);
#else
fclose (finput);
#endif
}
void
init_lex ()
{
set_identifier_size (sizeof (struct lang_identifier));
lineno = 0;
#ifdef MULTIBYTE_CHARS
setlocale (LC_CTYPE, "");
literal_codeset = getenv ("LANG");
#endif
maxtoken = 40;
token_buffer = (char *) xmalloc (maxtoken + 2);
ridpointers[(int) RID_INT] = get_identifier ("int");
ridpointers[(int) RID_BOOL] = get_identifier ("bool");
ridpointers[(int) RID_CHAR] = get_identifier ("char");
ridpointers[(int) RID_VOID] = get_identifier ("void");
ridpointers[(int) RID_FLOAT] = get_identifier ("float");
ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
ridpointers[(int) RID_SHORT] = get_identifier ("short");
ridpointers[(int) RID_LONG] = get_identifier ("long");
ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
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");
ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
ridpointers[(int) RID_REGISTER] = get_identifier ("register");
ridpointers[(int) RID_ITERATOR] = get_identifier ("iterator");
ridpointers[(int) RID_COMPLEX] = get_identifier ("complex");
#if defined (_WIN32) && defined (NEXT_PDO)
ridpointers[(int) RID_STDCALL] = get_identifier ("stdcall");
ridpointers[(int) RID_DECLSPEC] = get_identifier ("declspec");
ridpointers[(int) RID_DLLIMPORT] = get_identifier ("dllimport");
ridpointers[(int) RID_DLLEXPORT] = get_identifier ("dllexport");
#if 0
ridpointers[(int) RID_THREAD] = get_identifier ("thread");
ridpointers[(int) RID_NAKED] = get_identifier ("naked");
#endif
#endif
ridpointers[(int) RID_PIXEL] = get_identifier ("__pixel");
ridpointers[(int) RID_VECTOR] = get_identifier ("__vector");
ridpointers[(int) RID_ID] = get_identifier ("id");
ridpointers[(int) RID_IN] = get_identifier ("in");
ridpointers[(int) RID_OUT] = get_identifier ("out");
ridpointers[(int) RID_INOUT] = get_identifier ("inout");
ridpointers[(int) RID_BYCOPY] = get_identifier ("bycopy");
ridpointers[(int) RID_BYREF] = get_identifier ("byref");
ridpointers[(int) RID_ONEWAY] = get_identifier ("oneway");
#ifdef NEXT_SEMANTICS
ridpointers[(int) RID_PRIVATE_EXTERN] = get_identifier ("private_extern");
ridpointers[(int) RID_RELATIVE] = get_identifier ("relative");
ridpointers[(int) RID_DIRECT] = get_identifier ("direct");
#endif
forget_protocol_qualifiers();
#define UNSET_RESERVED_WORD(STRING) \
do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \
if (s) s->name = ""; } while (0)
if (! doing_objc_thang)
UNSET_RESERVED_WORD ("id");
if (flag_traditional)
{
UNSET_RESERVED_WORD ("const");
UNSET_RESERVED_WORD ("restrict");
UNSET_RESERVED_WORD ("volatile");
UNSET_RESERVED_WORD ("typeof");
UNSET_RESERVED_WORD ("signed");
UNSET_RESERVED_WORD ("inline");
UNSET_RESERVED_WORD ("iterator");
UNSET_RESERVED_WORD ("complex");
}
else if (!flag_isoc9x)
UNSET_RESERVED_WORD ("restrict");
if (flag_no_asm)
{
UNSET_RESERVED_WORD ("asm");
UNSET_RESERVED_WORD ("typeof");
UNSET_RESERVED_WORD ("inline");
UNSET_RESERVED_WORD ("iterator");
UNSET_RESERVED_WORD ("complex");
}
if (!flag_altivec)
{
UNSET_RESERVED_WORD ("__vector");
UNSET_RESERVED_WORD ("__pixel");
UNSET_RESERVED_WORD ("bool");
UNSET_RESERVED_WORD ("vec_step");
UNSET_RESERVED_WORD ("vector");
UNSET_RESERVED_WORD ("pixel");
}
}
void
reinit_parse_for_function ()
{
}
void
yyprint (file, yychar, yylval)
FILE *file;
int yychar;
YYSTYPE yylval;
{
tree t;
switch (yychar)
{
case IDENTIFIER:
case TYPENAME:
case OBJECTNAME:
t = yylval.ttype;
if (IDENTIFIER_POINTER (t))
fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
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;
}
}
static int
whitespace_cr (c)
int c;
{
static int newline_warning = 0;
if (c == '\r')
{
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;
}
static int
skip_white_space (c)
register int c;
{
for (;;)
{
switch (c)
{
case '\n':
c = check_newline ();
break;
case ' ':
case '\t':
case '\f':
case '\v':
case '\b':
c = GETC();
break;
case '\r':
whitespace_cr (c);
c = GETC();
break;
case '\\':
c = GETC();
if (c == '\n')
lineno++;
else
error ("stray '\\' in program");
c = GETC();
break;
default:
return (c);
}
}
}
void
position_after_white_space ()
{
register int c;
#if !USE_CPPLIB
if (nextchar != -1)
c = nextchar, nextchar = -1;
else
#endif
c = GETC();
UNGETC (skip_white_space (c));
}
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;
}
static char *
extend_token_buffer (p)
const char *p;
{
int offset = p - token_buffer;
maxtoken = maxtoken * 2 + 10;
token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
return token_buffer + offset;
}
#if defined HANDLE_PRAGMA
static int
pragma_getc ()
{
return GETC();
}
static void
pragma_ungetc (arg)
int arg;
{
UNGETC (arg);
}
#endif
int
check_newline ()
{
register int c;
register int token;
lineno++;
c = GETC();
while (c == ' ' || c == '\t')
c = GETC();
if (c != '#')
{
return c;
}
c = GETC();
while (c == ' ' || c == '\t')
c = GETC();
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
{
if (c == 'p')
{
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;
#if defined HANDLE_PRAGMA || defined HANDLE_GENERIC_PRAGMAS
UNGETC (c);
token = yylex ();
if (token != IDENTIFIER)
goto skipline;
#endif
#ifdef HANDLE_PRAGMA
#if !USE_CPPLIB
if (nextchar >= 0)
{
c = nextchar, nextchar = -1;
UNGETC (c);
}
#endif
if (TREE_CODE (yylval.ttype) != IDENTIFIER_NODE)
goto skipline;
if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc,
IDENTIFIER_POINTER (yylval.ttype)))
return GETC ();
#endif
#ifdef HANDLE_GENERIC_PRAGMAS
if (handle_generic_pragma (token))
return GETC ();
#endif
if (warn_unknown_pragmas > 1
|| (warn_unknown_pragmas && ! in_system_header))
warning ("ignoring pragma: %s", token_buffer);
goto skipline;
}
}
else if (c == 'd')
{
if (GETC() == 'e'
&& GETC() == 'f'
&& GETC() == 'i'
&& GETC() == 'n'
&& GETC() == 'e'
&& ((c = GETC()) == ' ' || c == '\t' || c == '\n'))
{
if (c != '\n')
debug_define (lineno, GET_DIRECTIVE_LINE ());
goto skipline;
}
}
else if (c == 'u')
{
if (GETC() == 'n'
&& GETC() == 'd'
&& GETC() == 'e'
&& GETC() == 'f'
&& ((c = GETC()) == ' ' || c == '\t' || c == '\n'))
{
if (c != '\n')
debug_undef (lineno, GET_DIRECTIVE_LINE ());
goto skipline;
}
}
else if (c == 'l')
{
if (GETC() == 'i'
&& GETC() == 'n'
&& GETC() == 'e'
&& ((c = GETC()) == ' ' || c == '\t'))
goto linenum;
}
else if (c == 'i')
{
if (GETC() == 'd'
&& GETC() == 'e'
&& GETC() == 'n'
&& GETC() == 't'
&& ((c = GETC()) == ' ' || c == '\t'))
{
c = skip_white_space_on_line ();
if (c == '\n')
return c;
UNGETC (c);
token = yylex ();
if (token != STRING
|| TREE_CODE (yylval.ttype) != STRING_CST)
{
error ("invalid #ident");
goto skipline;
}
if (!flag_no_ident)
{
#ifdef ASM_OUTPUT_IDENT
ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));
#endif
}
goto skipline;
}
}
error ("undefined or invalid # directive");
goto skipline;
}
linenum:
UNGETC (c);
c = skip_white_space_on_line ();
if (c == '\n')
return c;
UNGETC (c);
token = yylex ();
if (token == CONSTANT
&& TREE_CODE (yylval.ttype) == INTEGER_CST)
{
int old_lineno = lineno;
int used_up = 0;
int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
c = skip_white_space_on_line ();
if (c == '\n')
{
lineno = l;
return c;
}
UNGETC (c);
token = yylex ();
if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
{
error ("invalid #line");
goto skipline;
}
input_filename
= (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
lineno = l;
in_system_header = 0;
if (main_input_filename == 0)
main_input_filename = input_filename;
c = skip_white_space_on_line ();
if (c == '\n')
{
if (input_file_stack)
input_file_stack->name = input_filename;
return c;
}
UNGETC (c);
token = yylex ();
used_up = 0;
if (token == CONSTANT
&& TREE_CODE (yylval.ttype) == INTEGER_CST)
{
if (TREE_INT_CST_LOW (yylval.ttype) == 1)
{
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;
p->indent_level = indent_level;
if (flag_gen_index_original)
process_header_indexing (p->name, PB_INDEX_BEGIN);
input_file_stack = p;
input_file_stack_tick++;
debug_start_source_file (input_filename);
used_up = 1;
}
else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
{
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;
input_file_stack_tick++;
debug_end_source_file (input_file_stack->line);
if (flag_gen_index_original)
process_header_indexing (p->name, PB_INDEX_END);
free (p);
}
else
error ("#-lines for entering and leaving files don't match");
used_up = 1;
}
}
if (input_file_stack)
input_file_stack->name = input_filename;
if (used_up)
{
c = skip_white_space_on_line ();
if (c == '\n')
return c;
UNGETC (c);
token = yylex ();
used_up = 0;
}
if (token == CONSTANT
&& TREE_CODE (yylval.ttype) == INTEGER_CST
&& TREE_INT_CST_LOW (yylval.ttype) == 3)
in_system_header = 1, used_up = 1;
if (used_up)
{
c = skip_white_space_on_line ();
if (c == '\n')
return c;
UNGETC (c);
}
warning ("unrecognized text at end of #line");
}
else
error ("invalid #-line");
skipline:
#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_GENERIC_PRAGMAS
static int
handle_generic_pragma (token)
register int token;
{
register int c;
for (;;)
{
switch (token)
{
case IDENTIFIER:
case TYPENAME:
case STRING:
case CONSTANT:
handle_pragma_token (token_buffer, yylval.ttype);
break;
default:
handle_pragma_token (token_buffer, NULL);
}
#if !USE_CPPLIB
if (nextchar >= 0)
c = nextchar, nextchar = -1;
else
#endif
c = GETC ();
while (c == ' ' || c == '\t')
c = GETC ();
UNGETC (c);
if (c == '\n' || c == EOF)
return handle_pragma_token (NULL, NULL);
token = yylex ();
}
}
#endif
#define ENDFILE -1
#ifdef PASCAL_STRINGS
#endif
static int
readescape (ignore_ptr)
int *ignore_ptr;
{
register int c = GETC();
register int code;
register unsigned count;
unsigned firstdig = 0;
int nonnull;
switch (c)
{
case 'x':
if (warn_traditional)
warning ("the meaning of `\\x' varies with -traditional");
if (flag_traditional)
return c;
code = 0;
count = 0;
nonnull = 0;
while (1)
{
c = GETC();
if (!(c >= 'a' && c <= 'f')
&& !(c >= 'A' && c <= 'F')
&& !(c >= '0' && c <= '9'))
{
UNGETC (c);
break;
}
code *= 16;
if (c >= 'a' && c <= 'f')
code += c - 'a' + 10;
if (c >= 'A' && c <= 'F')
code += c - 'A' + 10;
if (c >= '0' && c <= '9')
code += c - '0';
if (code != 0 || count != 0)
{
if (count == 0)
firstdig = code;
count++;
}
nonnull = 1;
}
if (! nonnull)
error ("\\x used with no following hex digits");
else if (count == 0)
;
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;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7':
code = 0;
count = 0;
while ((c <= '7') && (c >= '0') && (count++ < 3))
{
code = (code * 8) + (c - '0');
c = GETC();
}
UNGETC (c);
return code;
case '\\': case '\'': case '"':
return c;
case '\n':
lineno++;
*ignore_ptr = 1;
return 0;
case 'n':
return TARGET_NEWLINE;
case 't':
return TARGET_TAB;
case 'r':
return TARGET_CR;
case 'f':
return TARGET_FF;
case 'b':
return TARGET_BS;
case 'a':
if (warn_traditional)
warning ("the meaning of `\\a' varies with -traditional");
if (flag_traditional)
return c;
return TARGET_BELL;
case 'v':
#if 0
if (flag_traditional)
return c;
#endif
return TARGET_VT;
case 'e':
case 'E':
if (pedantic)
pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
return 033;
case '?':
return c;
case '(':
case '{':
case '[':
case '%':
if (pedantic)
pedwarn ("non-ANSI escape sequence `\\%c'", c);
return c;
#ifdef PASCAL_STRINGS
case 'p':
if (flag_pascal_strings)
return -1;
#endif
}
if (c >= 040 && c < 0177)
pedwarn ("unknown escape sequence `\\%c'", c);
else
pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
return c;
}
void
yyerror (msgid)
const char *msgid;
{
const char *string = _(msgid);
if (end_of_file)
error ("%s at end of input", string);
else if (token_buffer[0] == 0)
error ("%s at null character", string);
else if (token_buffer[0] == '"')
error ("%s before string constant", string);
else if (token_buffer[0] == '\'')
error ("%s before character constant", string);
else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177)
error ("%s before character 0%o", string, (unsigned char) token_buffer[0]);
else
error ("%s before `%s'", string, token_buffer);
}
#if 0
struct try_type
{
tree *node_var;
char unsigned_flag;
char long_flag;
char long_long_flag;
};
struct try_type type_sequence[] =
{
{ &integer_type_node, 0, 0, 0},
{ &unsigned_type_node, 1, 0, 0},
{ &long_integer_type_node, 0, 1, 0},
{ &long_unsigned_type_node, 1, 1, 0},
{ &long_long_integer_type_node, 0, 1, 1},
{ &long_long_unsigned_type_node, 1, 1, 1}
};
#endif
static unsigned long this_token_number, last_vector_token_number = -2;
static char peekahead_id_buf[9];
struct pf_args
{
int base;
char * p;
int c;
int imag;
tree type;
int conversion_errno;
REAL_VALUE_TYPE value;
};
static void
parse_float (data)
PTR data;
{
struct pf_args * args = (struct pf_args *) data;
int fflag = 0, lflag = 0;
char *copy = (char *) alloca (args->p - token_buffer + 1);
bcopy (token_buffer, copy, args->p - token_buffer + 1);
while (1)
{
int lose = 0;
switch (args->c)
{
case 'f': case 'F':
if (fflag)
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");
else if (pedantic)
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 = GETC();
}
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;
if (REAL_VALUE_ISINF (args->value) && pedantic)
warning ("floating point number exceeds range of `float'");
}
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
yylex ()
{
register int c;
register char *p;
register int value;
int wide_flag = 0;
int objc_flag = 0;
++this_token_number;
if (peekahead_id_buf[0] != 0)
goto letter;
#if !USE_CPPLIB
if (nextchar >= 0)
c = nextchar, nextchar = -1;
else
#endif
c = GETC();
while (1)
switch (c)
{
case ' ':
case '\t':
case '\f':
case '\v':
case '\b':
c = GETC();
break;
case '\r':
case '\n':
case '/':
case '\\':
c = skip_white_space (c);
default:
goto found_nonwhite;
}
found_nonwhite:
token_buffer[0] = c;
token_buffer[1] = 0;
switch (c)
{
case EOF:
end_of_file = 1;
token_buffer[0] = 0;
value = ENDFILE;
break;
case 'L':
{
register int c = GETC();
if (c == '\'')
{
wide_flag = 1;
goto char_constant;
}
if (c == '"')
{
wide_flag = 1;
goto string_constant;
}
UNGETC (c);
}
goto letter;
case '@':
#if defined (_WIN32) && defined (NEXT_PDO)
{
int theNextChar = getc(finput);
ungetc(theNextChar, finput);
if( (theNextChar >= '0') && (theNextChar <= '9') )
{
goto letter;
}
}
#endif
if (!doing_objc_thang)
{
value = c;
break;
}
else
{
register int c = GETC ();
if (c == '"')
{
objc_flag = 1;
goto string_constant;
}
UNGETC (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':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case '_':
case '$':
letter:
p = token_buffer;
if (peekahead_id_buf[0] != 0)
{
char *src = peekahead_id_buf;
while (*p++ = *src++)
;
peekahead_id_buf[0] = 0;
c = *(p -= 2);
}
while (ISALNUM (c) || c == '_' || c == '$' || c == '@')
{
if (c == '@')
{
#if defined (_WIN32) && defined (NEXT_PDO)
int nextchar = getc(finput);
ungetc(nextchar, finput);
if ((nextchar < '0') || (nextchar > '9'))
#endif
if (! doing_objc_thang)
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();
}
*p = 0;
#if USE_CPPLIB
UNGETC (c);
#else
nextchar = c;
#endif
value = IDENTIFIER;
yylval.itype = 0;
{
register struct resword *ptr;
if ((ptr = is_reserved_word (token_buffer, p - token_buffer)))
{
if (ptr->rid)
yylval.ttype = ridpointers[(int) ptr->rid];
value = (int) ptr->token;
if (doing_objc_thang && value == OBJECTNAME)
{
lastiddecl = lookup_name(yylval.ttype);
if (lastiddecl == NULL_TREE
|| TREE_CODE (lastiddecl) != TYPE_DECL)
value = IDENTIFIER;
}
else
if (flag_altivec && ptr->rid == RID_VECTOR)
{
int is_keyword = 0;
if (token_buffer[0] == '_')
is_keyword = 1;
else
{
nextchar = skip_white_space (nextchar);
if (nextchar == 'u' || nextchar == 's' || nextchar == 'b'
|| nextchar == 'f' || nextchar == 'p' || nextchar == 'c'
|| nextchar == 'i' || nextchar == 'l')
{
char *pb = peekahead_id_buf;
*pb++ = nextchar;
c = GETC ();
while (ISALPHA (c)
&& pb < &peekahead_id_buf[sizeof (peekahead_id_buf)-1])
{
*pb++ = c;
c = GETC ();
}
*pb = 0;
UNGETC (c);
nextchar = -1;
pb = peekahead_id_buf;
if (ISALNUM (c) || c == '_' || c == '$')
;
else
if (! strcmp (pb, "pixel") || ! strcmp (pb, "unsigned")
|| ! strcmp (pb, "signed") || ! strcmp (pb, "bool")
|| ! strcmp (pb, "float") || ! strcmp (pb, "char")
|| ! strcmp (pb, "int") || ! strcmp (pb, "short")
|| ! strcmp (pb, "long"))
{
is_keyword = 1;
}
}
}
if (is_keyword)
last_vector_token_number = this_token_number;
else
value = IDENTIFIER;
}
else
if (flag_altivec
&& (ptr->rid == RID_BOOL
|| (ptr->rid == RID_PIXEL && token_buffer[0] != '_')))
{
if (last_vector_token_number != this_token_number - 1)
value = IDENTIFIER;
}
if (pedantic
&& (value == ASM_KEYWORD || value == TYPEOF
|| ptr->rid == RID_INLINE)
&& token_buffer[0] != '_')
pedwarn ("ANSI does not permit the keyword `%s'",
token_buffer);
}
}
if (value == IDENTIFIER)
{
if (token_buffer[0] == '@')
error("invalid identifier `%s'", token_buffer);
yylval.ttype = get_identifier (token_buffer);
lastiddecl = lookup_name (yylval.ttype);
if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL)
value = TYPENAME;
else if (lastiddecl != 0 && TREE_CODE (lastiddecl) == VAR_DECL
&& DECL_IGNORED_P (lastiddecl)
&& TREE_READONLY (lastiddecl)
&& DECL_INITIAL (lastiddecl) != 0
&& TREE_CODE (DECL_INITIAL (lastiddecl)) == STRING_CST)
{
tree stringval = DECL_INITIAL (lastiddecl);
yylval.ttype = build_string (TREE_STRING_LENGTH (stringval),
TREE_STRING_POINTER (stringval));
value = STRING;
}
else if (doing_objc_thang)
{
tree objc_interface_decl = is_class_name (yylval.ttype);
if (objc_interface_decl
&& (global_bindings_p ()
|| (!objc_need_raw_identifier
&& !lastiddecl)))
{
value = CLASSNAME;
yylval.ttype = objc_interface_decl;
}
}
objc_need_raw_identifier = 0;
}
break;
case '0': case '1':
{
int next_c;
next_c = GETC ();
UNGETC (next_c);
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;
}
}
case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '.':
{
int base = 10;
int count = 0;
int largest_digit = 0;
int numdigits = 0;
#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
int parts[TOTAL_PARTS];
int overflow = 0;
enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS, AFTER_EXPON}
floatflag = NOT_FLOAT;
for (count = 0; count < TOTAL_PARTS; count++)
parts[count] = 0;
p = token_buffer;
*p++ = c;
if (c == '0')
{
*p++ = (c = GETC());
if ((c == 'x') || (c == 'X'))
{
base = 16;
*p++ = (c = GETC());
}
else if (c >= '0' && c <= '9')
{
base = 8;
numdigits++;
}
else
numdigits++;
}
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)
error ("floating constant may not be in radix 16");
if (floatflag == TOO_MANY_POINTS)
;
else if (floatflag == AFTER_POINT || floatflag == AFTER_EXPON)
{
error ("malformed floating constant");
floatflag = TOO_MANY_POINTS;
p[-1] = '\0';
}
else
floatflag = AFTER_POINT;
if (base == 8)
base = 10;
*p++ = c = GETC();
if (p == token_buffer + 2 && !ISDIGIT (c))
{
if (c == '.')
{
c = GETC();
if (c == '.')
{
*p++ = c;
*p = 0;
return ELLIPSIS;
}
error ("parse error at `..'");
}
UNGETC (c);
token_buffer[1] = 0;
value = '.';
goto done;
}
}
else
{
if (ISDIGIT (c))
{
c = c - '0';
}
else if (base <= 10)
{
if (c == 'e' || c == 'E')
{
base = 10;
floatflag = AFTER_EXPON;
break;
}
error ("nondigits in number and not hexadecimal");
c = 0;
}
else if (base == 16 && (c == 'p' || c == 'P'))
{
floatflag = AFTER_EXPON;
break;
}
else if (c >= 'a')
{
c = c - 'a' + 10;
}
else
{
c = c - 'A' + 10;
}
if (c >= largest_digit)
largest_digit = c;
numdigits++;
for (count = 0; count < TOTAL_PARTS; count++)
{
parts[count] *= base;
if (count)
{
parts[count]
+= (parts[count-1] >> HOST_BITS_PER_CHAR);
parts[count-1]
&= (1 << HOST_BITS_PER_CHAR) - 1;
}
else
parts[0] += c;
}
if (parts[TOTAL_PARTS - 1] != 0)
overflow = 1;
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = (c = GETC());
}
}
if (numdigits == 0)
error ("numeric constant with no digits");
if (largest_digit >= base)
error ("numeric constant contains digits beyond the radix");
*--p = 0;
if (floatflag != NOT_FLOAT)
{
tree type = double_type_node;
int imag = 0;
int conversion_errno = 0;
REAL_VALUE_TYPE value;
struct pf_args args;
if ((base == 10 && ((c == 'e') || (c == 'E')))
|| (base == 16 && (c == 'p' || c == 'P')))
{
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = c;
c = GETC();
if ((c == '+') || (c == '-'))
{
*p++ = c;
c = GETC();
}
if (! ISDIGIT (c))
error ("floating constant exponent has no digits");
while (ISDIGIT (c))
{
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = c;
c = GETC();
}
}
if (base == 16 && floatflag != AFTER_EXPON)
error ("hexadecimal floating constant has no exponent");
*p = 0;
args.base = base;
args.p = p;
args.c = c;
args.imag = imag;
args.type = type;
args.conversion_errno = conversion_errno;
if (do_float_handler (parse_float, (PTR) &args))
{
value = args.value;
}
else
{
error ("floating constant out of range");
value = dconst0;
}
c = args.c;
imag = args.imag;
type = args.type;
conversion_errno = args.conversion_errno;
#ifdef ERANGE
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
if (REAL_VALUE_ISNAN (value))
value = dconst0;
if (imag)
yylval.ttype = build_complex (NULL_TREE,
convert (type, integer_zero_node),
build_real (type, value));
else
yylval.ttype = build_real (type, value);
}
else
{
tree traditional_type, ansi_type, type;
HOST_WIDE_INT high, low;
int spec_unsigned = 0;
int spec_long = 0;
int spec_long_long = 0;
int spec_imag = 0;
int warn, i;
traditional_type = ansi_type = type = NULL_TREE;
while (1)
{
if (c == 'u' || c == 'U')
{
if (spec_unsigned)
error ("two `u's in integer constant");
spec_unsigned = 1;
}
else if (c == 'l' || c == 'L')
{
if (spec_long)
{
if (spec_long_long)
error ("three `l's in integer constant");
else if (pedantic && ! in_system_header && warn_long_long)
pedwarn ("ANSI C forbids long long integer constants");
spec_long_long = 1;
}
spec_long = 1;
}
else if (c == 'i' || c == 'j' || c == 'I' || c == 'J')
{
if (spec_imag)
error ("more than one `i' or `j' in numeric constant");
else if (pedantic)
pedwarn ("ANSI C forbids imaginary numeric constants");
spec_imag = 1;
}
else
break;
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = c;
c = GETC();
}
warn = overflow;
if (warn)
pedwarn ("integer constant out of range");
high = low = 0;
for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)
{
high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR)]
<< (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;
if (warn_traditional || flag_traditional)
{
if (! spec_long && base != 10
&& int_fits_type_p (yylval.ttype, unsigned_type_node))
traditional_type = (spec_unsigned ? unsigned_type_node
: integer_type_node);
else if (! spec_long && base == 10
&& int_fits_type_p (yylval.ttype, integer_type_node))
traditional_type = (spec_unsigned ? unsigned_type_node
: integer_type_node);
else if (! spec_long_long)
traditional_type = (spec_unsigned ? long_unsigned_type_node
: long_integer_type_node);
else
traditional_type = (spec_unsigned
? long_long_unsigned_type_node
: long_long_integer_type_node);
}
if (warn_traditional || ! flag_traditional)
{
if (! spec_long && ! spec_unsigned
&& int_fits_type_p (yylval.ttype, integer_type_node))
ansi_type = integer_type_node;
else if (! spec_long && (base != 10 || spec_unsigned)
&& int_fits_type_p (yylval.ttype, unsigned_type_node))
ansi_type = unsigned_type_node;
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
&& int_fits_type_p (yylval.ttype,
long_unsigned_type_node))
ansi_type = long_unsigned_type_node;
else if (! spec_unsigned
&& int_fits_type_p (yylval.ttype,
long_long_integer_type_node))
ansi_type = long_long_integer_type_node;
else
ansi_type = long_long_unsigned_type_node;
}
type = flag_traditional ? traditional_type : ansi_type;
if (warn_traditional && traditional_type != ansi_type)
{
if (TYPE_PRECISION (traditional_type)
!= TYPE_PRECISION (ansi_type))
warning ("width of integer constant changes with -traditional");
else if (TREE_UNSIGNED (traditional_type)
!= TREE_UNSIGNED (ansi_type))
warning ("integer constant is unsigned in ANSI C, signed with -traditional");
else
warning ("width of integer constant may change on other systems with -traditional");
}
if (pedantic && !flag_traditional && !spec_long_long && !warn
&& (TYPE_PRECISION (long_integer_type_node)
< TYPE_PRECISION (type)))
{
warn = 1;
pedwarn ("integer constant out of range");
}
if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
warning ("decimal constant is so large that it is unsigned");
if (spec_imag)
{
if (TYPE_PRECISION (type)
<= 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 if (flag_traditional && !int_fits_type_p (yylval.ttype, type))
{
TREE_TYPE (yylval.ttype) = unsigned_type (type);
yylval.ttype = convert (type, yylval.ttype);
TREE_OVERFLOW (yylval.ttype)
= TREE_CONSTANT_OVERFLOW (yylval.ttype) = 0;
}
else
TREE_TYPE (yylval.ttype) = type;
if (! warn
&& TREE_CODE (TREE_TYPE (yylval.ttype)) == INTEGER_TYPE
&& ! int_fits_type_p (yylval.ttype, TREE_TYPE (yylval.ttype)))
pedwarn ("integer constant out of range");
}
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;
}
case '\'':
char_constant:
{
register int result = 0;
register int num_chars = 0;
int chars_seen = 0;
unsigned width = TYPE_PRECISION (char_type_node);
int max_chars;
#ifdef MULTIBYTE_CHARS
int longest_char = local_mb_cur_max ();
(void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
#endif
max_chars = TYPE_PRECISION (integer_type_node) / width;
if (wide_flag)
width = WCHAR_TYPE_SIZE;
while (1)
{
tryagain:
c = GETC();
if (c == '\'' || c == EOF)
break;
++chars_seen;
if (c == '\\')
{
int ignore = 0;
c = readescape (&ignore);
if (ignore)
goto tryagain;
#ifdef PASCAL_STRINGS
if (flag_pascal_strings && c < 0)
{
pedwarn ("pascal string-length escape (\\p) not"
" allowed in character constant");
c = 'p';
}
#endif
if (width < HOST_BITS_PER_INT
&& (unsigned) c >= ((unsigned)1 << width))
pedwarn ("escape sequence out of range for character");
#ifdef MAP_CHARACTER
if (ISPRINT (c))
c = MAP_CHARACTER (c);
#endif
}
else if (c == '\n')
{
if (pedantic)
pedwarn ("ANSI C forbids newline in character constant");
lineno++;
}
else
{
#ifdef MULTIBYTE_CHARS
wchar_t wc;
int i;
int char_len = -1;
for (i = 1; i <= longest_char; ++i)
{
if (i > maxtoken - 4)
extend_token_buffer (token_buffer);
token_buffer[i] = c;
char_len = local_mbtowc (& wc,
token_buffer + 1,
i);
if (char_len != -1)
break;
c = GETC ();
}
if (char_len > 1)
{
if (char_len < i)
UNGETC (c);
if (! wide_flag)
{
for (i = 1; i <= char_len; ++i)
{
if (i > max_chars)
break;
if (width < HOST_BITS_PER_INT)
result = (result << width)
| (token_buffer[i]
& ((1 << width) - 1));
else
result = token_buffer[i];
}
num_chars += char_len;
goto tryagain;
}
c = wc;
}
else
{
if (char_len == -1)
warning ("Ignoring invalid multibyte character");
if (wide_flag)
c = wc;
#ifdef MAP_CHARACTER
else
c = MAP_CHARACTER (c);
#endif
}
#else
#ifdef MAP_CHARACTER
c = MAP_CHARACTER (c);
#endif
#endif
}
if (wide_flag)
{
if (chars_seen == 1)
result = c;
goto tryagain;
}
num_chars += (width / TYPE_PRECISION (char_type_node));
if (num_chars < max_chars + 1)
{
if (width < HOST_BITS_PER_INT)
result = (result << width) | (c & ((1 << width) - 1));
else
result = c;
}
}
if (c != '\'')
error ("malformatted character constant");
else if (chars_seen == 0)
error ("empty character constant");
else if (num_chars > max_chars)
{
num_chars = max_chars;
error ("character constant too long");
}
else if (chars_seen != 1 && ! flag_traditional)
#ifdef FOUR_CHAR_CONSTANTS
if ((chars_seen == 4 && warn_four_char_constants)
|| (chars_seen != 4 && warn_multichar))
#else
if (warn_multichar)
#endif
warning ("multi-character character constant");
if (! wide_flag)
{
int num_bits = num_chars * width;
if (num_bits == 0)
yylval.ttype = build_int_2 (0, 0);
else if (TREE_UNSIGNED (char_type_node)
|| ((result >> (num_bits - 1)) & 1) == 0)
yylval.ttype
= 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
>> (HOST_BITS_PER_WIDE_INT - num_bits)),
-1);
TREE_TYPE (yylval.ttype) = integer_type_node;
}
else
{
yylval.ttype = build_int_2 (result, 0);
TREE_TYPE (yylval.ttype) = wchar_type_node;
}
value = CONSTANT;
break;
}
case '"':
string_constant:
{
unsigned width = wide_flag ? WCHAR_TYPE_SIZE
: TYPE_PRECISION (char_type_node);
#ifdef PASCAL_STRINGS
int is_pascal_string = 0;
#endif
#ifdef MULTIBYTE_CHARS
int longest_char = local_mb_cur_max ();
(void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
#endif
c = GETC ();
p = token_buffer + 1;
while (c != '"' && c >= 0)
{
if (c == '\\')
{
int ignore = 0;
c = readescape (&ignore);
if (ignore)
goto skipnewline;
#ifdef PASCAL_STRINGS
if (flag_pascal_strings && c < 0)
{
if (wide_flag)
{
pedwarn ("pascal string-length escape (\\p) not"
" allowed in wide string");
c = 'p';
}
else if (objc_flag)
{
pedwarn ("pascal string-length escape (\\p) not"
" allowed in Objective-C string");
c = 'p';
}
else if (p == token_buffer + 1)
{
is_pascal_string = 1;
c = 0;
}
else
{
pedwarn ("pascal string-length escape (\\p) must"
" be at beginning of string");
c = 'p';
}
}
#endif
if (width < HOST_BITS_PER_INT
&& (unsigned) c >= ((unsigned)1 << width))
pedwarn ("escape sequence out of range for character");
}
else if (c == '\n')
{
if (pedantic)
pedwarn ("ANSI C forbids newline in string constant");
lineno++;
}
else
{
#ifdef MULTIBYTE_CHARS
wchar_t wc;
int i;
int char_len = -1;
for (i = 0; i < longest_char; ++i)
{
if (p + i >= token_buffer + maxtoken)
p = extend_token_buffer (p);
p[i] = c;
char_len = local_mbtowc (& wc, p, i + 1);
if (char_len != -1)
break;
c = GETC ();
}
if (char_len == -1)
warning ("Ignoring invalid multibyte character");
else
{
if (char_len <= i)
UNGETC (c);
if (! wide_flag)
{
p += (i + 1);
c = GETC ();
continue;
}
c = wc;
}
#endif
}
if (wide_flag)
{
unsigned width = TYPE_PRECISION (char_type_node);
unsigned bytemask = (1 << width) - 1;
int byte;
if (p + WCHAR_BYTES > token_buffer + maxtoken)
p = extend_token_buffer (p);
for (byte = 0; byte < WCHAR_BYTES; ++byte)
{
int value;
if (byte >= (int) sizeof (c))
value = 0;
else
value = (c >> (byte * width)) & bytemask;
if (BYTES_BIG_ENDIAN)
p[WCHAR_BYTES - byte - 1] = value;
else
p[byte] = value;
}
p += WCHAR_BYTES;
}
else
{
if (p >= token_buffer + maxtoken)
p = extend_token_buffer (p);
*p++ = c;
}
skipnewline:
c = GETC ();
}
if (wide_flag)
{
if (p + WCHAR_BYTES > token_buffer + maxtoken)
p = extend_token_buffer (p);
bzero (p, WCHAR_BYTES);
p += WCHAR_BYTES;
}
else
{
if (p >= token_buffer + maxtoken)
p = extend_token_buffer (p);
*p++ = 0;
}
if (c < 0)
error ("Unterminated string constant");
if (wide_flag)
{
yylval.ttype = build_string (p - (token_buffer + 1),
token_buffer + 1);
TREE_TYPE (yylval.ttype) = wchar_array_type_node;
value = STRING;
}
else if (objc_flag)
{
yylval.ttype = build_objc_string (p - (token_buffer + 1),
token_buffer + 1);
TREE_TYPE (yylval.ttype) = char_array_type_node;
value = OBJC_STRING;
}
else
{
#ifdef PASCAL_STRINGS
if (is_pascal_string)
{
int slen = p - token_buffer -3;
if (slen > 255)
{
error ("pascal string too long");
slen = 255;
}
token_buffer[1] = slen;
yylval.ttype = build_string (slen + 2, token_buffer + 1);
TREE_TYPE (yylval.ttype) = unsigned_char_array_type_node;
}
else {
#endif
yylval.ttype = build_string (p - (token_buffer + 1),
token_buffer + 1);
TREE_TYPE (yylval.ttype) = char_array_type_node;
#ifdef PASCAL_STRINGS
}
#endif
value = STRING;
}
break;
}
case '+':
case '-':
case '&':
case '|':
case ':':
case '<':
case '>':
case '*':
case '/':
case '%':
case '^':
case '!':
case '=':
{
register int c1;
combine:
switch (c)
{
case '+':
yylval.code = PLUS_EXPR; break;
case '-':
yylval.code = MINUS_EXPR; break;
case '&':
yylval.code = BIT_AND_EXPR; break;
case '|':
yylval.code = BIT_IOR_EXPR; break;
case '*':
yylval.code = MULT_EXPR; break;
case '/':
yylval.code = TRUNC_DIV_EXPR; break;
case '%':
yylval.code = TRUNC_MOD_EXPR; break;
case '^':
yylval.code = BIT_XOR_EXPR; break;
case LSHIFT:
yylval.code = LSHIFT_EXPR; break;
case RSHIFT:
yylval.code = RSHIFT_EXPR; break;
case '<':
yylval.code = LT_EXPR; break;
case '>':
yylval.code = GT_EXPR; break;
}
token_buffer[1] = c1 = GETC();
token_buffer[2] = 0;
if (c1 == '=')
{
switch (c)
{
case '<':
value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
case '>':
value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
case '!':
value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
case '=':
value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
}
value = ASSIGN; goto done;
}
else if (c == c1)
switch (c)
{
case '+':
value = PLUSPLUS; goto done;
case '-':
value = MINUSMINUS; goto done;
case '&':
value = ANDAND; goto done;
case '|':
value = OROR; goto done;
case '<':
c = LSHIFT;
goto combine;
case '>':
c = RSHIFT;
goto combine;
}
else
switch (c)
{
case '-':
if (c1 == '>')
{ value = POINTSAT; goto done; }
break;
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;
}
UNGETC (c1);
token_buffer[1] = 0;
if ((c == '<') || (c == '>'))
value = ARITHCOMPARE;
else value = c;
goto done;
}
case 0:
value = 1;
break;
case '{':
indent_level++;
value = c;
break;
case '}':
indent_level--;
value = c;
break;
case ';': case ')': case ',':
objc_need_raw_identifier = 0;
default:
value = c;
}
done:
return value;
}
void
set_yydebug (value)
int value;
{
#if YYDEBUG != 0
yydebug = value;
#else
warning ("YYDEBUG not defined.");
#endif
}