diff options
Diffstat (limited to 'gcc-4.2.1-5666.3/gcc/gengtype-lex.l')
-rw-r--r-- | gcc-4.2.1-5666.3/gcc/gengtype-lex.l | 610 |
1 files changed, 610 insertions, 0 deletions
diff --git a/gcc-4.2.1-5666.3/gcc/gengtype-lex.l b/gcc-4.2.1-5666.3/gcc/gengtype-lex.l new file mode 100644 index 000000000..51cd95a63 --- /dev/null +++ b/gcc-4.2.1-5666.3/gcc/gengtype-lex.l @@ -0,0 +1,610 @@ +/* -*- indented-text -*- */ +/* Process source files and output type information. + Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to the Free +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ + +%{ +#include "bconfig.h" +#include "coretypes.h" +#include "system.h" + +#define malloc xmalloc +#define realloc xrealloc + +#include "gengtype.h" +#include "gengtype-yacc.h" + +#define YY_INPUT(BUF,RESULT,SIZE) ((RESULT) = macro_input (BUF,SIZE)) + +static unsigned macro_input (char *buffer, unsigned); +static const char *push_macro_expansion (const char *, unsigned, + const char *, unsigned); +static char *mangle_macro_name (const char *, unsigned, + const char *, unsigned); +static void update_lineno (const char *l, size_t len); + +struct fileloc lexer_line; +int lexer_toplevel_done; + +static void +update_lineno (const char *l, size_t len) +{ + while (len-- > 0) + if (*l++ == '\n') + lexer_line.line++; +} + +%} + +ID [[:alpha:]_][[:alnum:]_]* +WS [[:space:]]+ +IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD +ITYPE {IWORD}({WS}{IWORD})* + +%x in_struct in_struct_comment in_comment in_yacc_escape +%option warn noyywrap nounput nodefault perf-report +%option 8bit never-interactive +%% + +[^[:alnum:]_]typedef{WS}(struct|union){WS}{ID}{WS}?[*[:space:]]{WS}?{ID}{WS}?";" { + char *tagstart; + size_t taglen; + char *namestart; + size_t namelen; + int is_pointer = 0; + struct type *t; + int union_p; + + tagstart = yytext + strlen (" typedef "); + while (ISSPACE (*tagstart)) + tagstart++; + union_p = tagstart[0] == 'u'; + tagstart += strlen ("union "); + while (ISSPACE (*tagstart)) + tagstart++; + for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++) + ; + for (namestart = tagstart + taglen; + ! ISIDNUM (*namestart); + namestart++) + if (*namestart == '*') + is_pointer = 1; + for (namelen = 1; ISIDNUM (namestart[namelen]); namelen++) + ; + t = find_structure ((const char *) xmemdup (tagstart, taglen, taglen+1), + union_p); + if (is_pointer) + t = create_pointer (t); + namestart = (char *) xmemdup (namestart, namelen, namelen+1); +#ifdef USE_MAPPED_LOCATION + /* temporary kludge - gentype doesn't handle cpp conditionals */ + if (strcmp (namestart, "location_t") != 0 + && strcmp (namestart, "expanded_location") != 0) +#endif + do_typedef (namestart, t, &lexer_line); + update_lineno (yytext, yyleng); +} + +[^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" { + + char *namestart; + size_t namelen; + struct type *t; + char *typestart; + size_t typelen; + + for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--) + ; + for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++) + ; + namestart -= namelen - 1; + for (typestart = yytext + strlen (" typedef "); + ISSPACE(*typestart); + typestart++) + ; + for (typelen = namestart - typestart; + ISSPACE (typestart[typelen-1]); + typelen--) + ; + + t = create_scalar_type (typestart, typelen); + do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, + &lexer_line); + update_lineno (yytext, yyleng); +} + +[^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS { + char *namestart; + size_t namelen; + struct type *t; + + for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--) + ; + for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++) + ; + namestart -= namelen - 1; + + t = create_scalar_type ("function type", sizeof ("function type")-1); + do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, + &lexer_line); + update_lineno (yytext, yyleng); +} + +[^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" { + char *namestart; + size_t namelen; + struct type *t; + + for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--) + ; + for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++) + ; + namestart -= namelen - 1; + + t = create_scalar_type ("function type", sizeof ("function type")-1); + do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, + &lexer_line); + update_lineno (yytext, yyleng); +} + +[^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS { + char *namestart; + size_t namelen; + struct type *t; + + for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--) + ; + for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++) + ; + namestart -= namelen - 1; + + t = create_scalar_type ("function type", sizeof ("function type")-1); + do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, + &lexer_line); + update_lineno (yytext, yyleng); +} + +[^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" { + char *namestart; + size_t namelen; + struct type *t; + + for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--) + ; + for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++) + ; + namestart -= namelen - 1; + + t = create_scalar_type ("function type", sizeof ("function type")-1); + do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, + &lexer_line); + update_lineno (yytext, yyleng); +} + +[^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" { + char *tagstart; + size_t taglen; + int typedef_p; + int union_p; + + typedef_p = yytext[1] == 't'; + if (typedef_p) + for (tagstart = yytext + strlen (" typedef "); + ISSPACE(*tagstart); + tagstart++) + ; + else + tagstart = yytext + 1; + + union_p = tagstart[0] == 'u'; + tagstart += strlen ("union "); + while (ISSPACE (*tagstart)) + tagstart++; + for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++) + ; + + yylval.t = find_structure ((const char *) xmemdup (tagstart, taglen, + taglen + 1), + union_p); + BEGIN(in_struct); + update_lineno (yytext, yyleng); + return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT; +} + +[^[:alnum:]_](extern|static){WS}/"GTY" { + BEGIN(in_struct); + update_lineno (yytext, yyleng); + return ENT_EXTERNSTATIC; +} + +^"%union"{WS}"{"{WS}/"GTY" { + BEGIN(in_struct); + update_lineno (yytext, yyleng); + return ENT_YACCUNION; +} + +^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" { + char *macro, *arg; + unsigned macro_len, arg_len; + char *ptr = yytext; + const char *additional; + type_p t; + + /* Find the macro name. */ + for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++) + continue; + for (macro_len = ptr - macro; !(ISALNUM (*ptr) || *ptr == '_'); ptr++) + continue; + + /* Find the argument(s). */ + for (arg = ptr; *ptr != ')'; ptr++) + continue; + arg_len = ptr - arg; + + /* Create the struct and typedef. */ + ptr = mangle_macro_name ("VEC", 3, arg, arg_len); + + t = find_structure (ptr, 0); + do_typedef (ptr, t, &lexer_line); + + /* Push the macro for later expansion. */ + additional = push_macro_expansion (macro, macro_len, arg, arg_len); + + if (additional) + { + ptr = mangle_macro_name (ptr, strlen (ptr), + additional, strlen (additional)); + t = find_structure (ptr, 0); + do_typedef (ptr, t, &lexer_line); + } +} + +<in_struct>{ + +"/*" { BEGIN(in_struct_comment); } + +^"%{" { BEGIN(in_yacc_escape); } /* } */ + +{WS} { update_lineno (yytext, yyleng); } + +"const"/[^[:alnum:]_] /* don't care */ +"GTY"/[^[:alnum:]_] { return GTY_TOKEN; } +"union"/[^[:alnum:]_] { return UNION; } +"struct"/[^[:alnum:]_] { return STRUCT; } +"enum"/[^[:alnum:]_] { return ENUM; } +"ptr_alias"/[^[:alnum:]_] { return ALIAS; } +"nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; } +[0-9]+ { return NUM; } +"param"[0-9]*"_is"/[^[:alnum:]_] { + yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1); + return PARAM_IS; +} + +{IWORD}({WS}{IWORD})*/[^[:alnum:]_] | +"ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" { + size_t len; + + for (len = yyleng; ISSPACE (yytext[len-1]); len--) + ; + + yylval.t = create_scalar_type (yytext, len); + update_lineno (yytext, yyleng); + return SCALAR; +} + +"VEC"{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" { + char *macro, *arg; + unsigned macro_len, arg_len; + char *ptr = yytext; + + /* Find the macro name */ + for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++) + continue; + for (macro_len = ptr - macro; !(ISALNUM(*ptr) || *ptr == '_'); ptr++) + continue; + + /* Find the arguments. */ + for (arg = ptr; *ptr != ')'; ptr++) + continue; + arg_len = ptr - arg; + + ptr = mangle_macro_name (macro, macro_len, arg, arg_len); + yylval.s = ptr; + return ID; +} + +{ID}/[^[:alnum:]_] { + yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1); + return ID; +} + +\"([^"\\]|\\.)*\" { + yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1); + return STRING; +} +"["[^\[\]]*"]" { + yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1); + return ARRAY; +} +^"%"{ID} { + yylval.s = (const char *) xmemdup (yytext+1, yyleng-1, yyleng); + return PERCENT_ID; +} +"'"("\\".|[^\\])"'" { + yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng); + return CHAR; +} + +[(){},*:<>] { return yytext[0]; } + +[;=] { + if (lexer_toplevel_done) + { + BEGIN(INITIAL); + lexer_toplevel_done = 0; + } + return yytext[0]; +} + +^"%%" { + BEGIN(INITIAL); + return PERCENTPERCENT; +} + +"#define"[^\n]*\n {lexer_line.line++;} + +. { + error_at_line (&lexer_line, "unexpected character `%s'", yytext); +} +} + +"/*" { BEGIN(in_comment); } +\n { lexer_line.line++; } +{ID} | +"'"("\\".|[^\\])"'" | +[^"/\n] /* do nothing */ +\"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); } +"/"/[^*] /* do nothing */ + +<in_comment,in_struct_comment>{ +\n { lexer_line.line++; } +[^*\n]{16} | +[^*\n] /* do nothing */ +"*"/[^/] /* do nothing */ +} +<in_comment>"*/" { BEGIN(INITIAL); } +<in_struct_comment>"*/" { BEGIN(in_struct); } + +<in_yacc_escape>{ +\n { lexer_line.line++; } +[^%]{16} | +[^%] /* do nothing */ +"%"/[^}] /* do nothing */ +"%}" { BEGIN(in_struct); } +"%" { + error_at_line (&lexer_line, + "unterminated %%{; unexpected EOF"); +} +} + + +["/] | +<in_struct_comment,in_comment>"*" { + error_at_line (&lexer_line, + "unterminated comment or string; unexpected EOF"); +} + +^"#define"{WS}"GTY(" /* do nothing */ +{WS}"GTY"{WS}?"(" { + error_at_line (&lexer_line, "stray GTY marker"); +} + +%% + +/* Deal with the expansion caused by the DEF_VEC_x macros. */ + +/* Mangle a macro and argument list as done by cpp concatenation in + the compiler proper. */ +static char * +mangle_macro_name (const char *macro, unsigned macro_len, + const char *arg, unsigned arg_len) +{ + char *ptr = (char *) xmemdup (macro, macro_len, macro_len + arg_len + 2); + + /* Now copy and concatenate each argument */ + while (arg_len) + { + ptr[macro_len++] = '_'; + for (; arg_len && (ISALNUM(*arg) || *arg == '_'); arg_len--) + ptr[macro_len++] = *arg++; + for (; arg_len && !(ISALNUM(*arg) || *arg == '_'); arg_len--) + arg++; + } + ptr[macro_len] = 0; + + return ptr; +} + +typedef struct macro_def +{ + const char *name; + const char *expansion; + const char *additional; +} macro_def_t; + +typedef struct macro +{ + const macro_def_t *def; + struct macro *next; + const char *args[10]; +} macro_t; + +static const macro_def_t macro_defs[] = +{ +#define IN_GENGTYPE 1 +#include "vec.h" + {NULL, NULL, NULL} +}; + +/* Chain of macro expansions to do at end of scanning. */ +static macro_t *macro_expns; +static macro_t *macro_expns_end; + +/* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the + expansion queue. We ensure NAME is known at this point. */ + +static const char * +push_macro_expansion (const char *name, unsigned name_len, + const char *arg, unsigned arg_len) +{ + unsigned ix; + + for (ix = 0; macro_defs[ix].name; ix++) + if (strlen (macro_defs[ix].name) == name_len + && !memcmp (name, macro_defs[ix].name, name_len)) + { + macro_t *expansion = XNEW (macro_t); + char *args; + unsigned argno, last_arg; + + expansion->def = ¯o_defs[ix]; + expansion->next = NULL; + args = (char *) xmemdup (arg, arg_len, arg_len+1); + args[arg_len] = 0; + for (argno = 0; *args;) + { + expansion->args[argno++] = args; + while (*args && (ISALNUM (*args) || *args == '_')) + args++; + if (argno == 1) + expansion->args[argno++] = "base"; + if (!*args) + break; + *args++ = 0; + while (*args && !(ISALNUM (*args) || *args == '_')) + args++; + } + last_arg = argno; + for (; argno != 10; argno++) + expansion->args[argno] = NULL; + if (macro_expns_end) + macro_expns_end->next = expansion; + else + macro_expns = expansion; + macro_expns_end = expansion; + if (macro_defs[ix].additional) + { + macro_t *expn2 = XNEW (macro_t); + memcpy (expn2, expansion, sizeof (*expn2)); + expansion = expn2; + expansion->def += 1; + expansion->args[last_arg++] = macro_defs[ix].additional; + macro_expns_end->next = expansion; + macro_expns_end = expansion; + } + if (last_arg > 2 && strcmp (expansion->args[last_arg - 1], "heap")) + expansion->args[last_arg++] = "GTY (())"; + return macro_defs[ix].additional; + } + error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'", + name_len, name, arg_len, arg); + return NULL; +} + +/* Attempt to read some input. Use fread until we're at the end of + file. At end of file expand the next queued macro. We presume the + buffer is large enough for the entire expansion. */ + +static unsigned +macro_input (char *buffer, unsigned size) +{ + unsigned result; + + result = fread (buffer, 1, size, yyin); + if (result) + /*NOP*/; + else if (ferror (yyin)) + YY_FATAL_ERROR ("read of source file failed"); + else if (macro_expns) + { + const char *expn; + unsigned len; + + for (expn = macro_expns->def->expansion; *expn; expn++) + { + if (*expn == '#') + { + int argno; + + argno = expn[1] - '0'; + expn += 1; + + /* Remove inserted space? */ + if (buffer[result-1] == ' ' && buffer[result-2] == '_') + result--; + + /* Insert the argument value */ + if (macro_expns->args[argno]) + { + len = strlen (macro_expns->args[argno]); + memcpy (&buffer[result], macro_expns->args[argno], len); + result += len; + } + + /* Skip next space? */ + if (expn[1] == ' ' && expn[2] == '_') + expn++; + } + else + { + buffer[result++] = *expn; + if (*expn == ';' || *expn == '{') + buffer[result++] = '\n'; + } + } + if (result > size) + YY_FATAL_ERROR ("buffer too small to expand macro"); + macro_expns = macro_expns->next; + if (!macro_expns) + macro_expns_end = NULL; + } + return result; +} + +void +yyerror (const char *s) +{ + error_at_line (&lexer_line, s); +} + +void +parse_file (const char *fname) +{ + yyin = fopen (fname, "r"); + lexer_line.file = fname; + lexer_line.line = 1; + if (yyin == NULL) + { + perror (fname); + exit (1); + } + if (yyparse() != 0) + exit (1); + fclose (yyin); +} |