X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgengtype-lex.l;h=51cd95a6310392966daadec2546525f26c2883f2;hb=839904a0e3a1859cdfeb5ff23e5263c332f347fa;hp=73167f5322b865a5aecc2fcd78a8f7b6bffa8faf;hpb=525ef9f93fe5003b747daddb0962d8847332123c;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/gengtype-lex.l b/gcc/gengtype-lex.l index 73167f5322b..51cd95a6310 100644 --- a/gcc/gengtype-lex.l +++ b/gcc/gengtype-lex.l @@ -1,6 +1,6 @@ /* -*- indented-text -*- */ /* Process source files and output type information. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GCC. @@ -16,30 +16,34 @@ 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, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +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 "hconfig.h" -#include "system.h" #include "gengtype.h" #include "gengtype-yacc.h" -#undef YY_USE_PROTOS -#define YY_DECL int yylex () +#define YY_INPUT(BUF,RESULT,SIZE) ((RESULT) = macro_input (BUF,SIZE)) -static void update_lineno PARAMS ((const char *l, size_t len)); +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 (l, len) - const char *l; - size_t len; +update_lineno (const char *l, size_t len) { while (len-- > 0) if (*l++ == '\n') @@ -48,9 +52,9 @@ update_lineno (l, len) %} -ID [[:alpha:]][[:alnum:]_]* +ID [[:alpha:]_][[:alnum:]_]* WS [[:space:]]+ -IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|bool|size_t +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 @@ -83,10 +87,17 @@ ITYPE {IWORD}({WS}{IWORD})* is_pointer = 1; for (namelen = 1; ISIDNUM (namestart[namelen]); namelen++) ; - t = find_structure (xmemdup (tagstart, taglen, taglen+1), union_p); + t = find_structure ((const char *) xmemdup (tagstart, taglen, taglen+1), + union_p); if (is_pointer) t = create_pointer (t); - do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line); + 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); } @@ -107,13 +118,14 @@ ITYPE {IWORD}({WS}{IWORD})* ISSPACE(*typestart); typestart++) ; - for (typelen = namestart - typestart; - ISSPACE(typestart[typelen-1]); + for (typelen = namestart - typestart; + ISSPACE (typestart[typelen-1]); typelen--) ; t = create_scalar_type (typestart, typelen); - do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line); + do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t, + &lexer_line); update_lineno (yytext, yyleng); } @@ -129,10 +141,29 @@ ITYPE {IWORD}({WS}{IWORD})* namestart -= namelen - 1; t = create_scalar_type ("function type", sizeof ("function type")-1); - do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line); + 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}?{ID}{WS}?")"{WS}?PARAMS { + +[^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS { char *namestart; size_t namelen; struct type *t; @@ -144,7 +175,25 @@ ITYPE {IWORD}({WS}{IWORD})* namestart -= namelen - 1; t = create_scalar_type ("function type", sizeof ("function type")-1); - do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line); + 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); } @@ -170,7 +219,9 @@ ITYPE {IWORD}({WS}{IWORD})* for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++) ; - yylval.t = find_structure (xmemdup (tagstart, taglen, taglen + 1), union_p); + 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; @@ -188,23 +239,62 @@ ITYPE {IWORD}({WS}{IWORD})* 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); + } +} + { "/*" { BEGIN(in_struct_comment); } -^"%{" { BEGIN(in_yacc_escape); } +^"%{" { 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; } -"param_is"/[^[:alnum:]_] { return PARAM_IS; } +"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}?")" { @@ -218,25 +308,46 @@ ITYPE {IWORD}({WS}{IWORD})* 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 = xmemdup (yytext, yyleng, yyleng+1); + yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1); return ID; } \"([^"\\]|\\.)*\" { - yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1); + yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1); return STRING; } "["[^\[\]]*"]" { - yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1); + yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1); return ARRAY; } ^"%"{ID} { - yylval.s = xmemdup (yytext+1, yyleng-1, yyleng); + yylval.s = (const char *) xmemdup (yytext+1, yyleng-1, yyleng); return PERCENT_ID; } "'"("\\".|[^\\])"'" { - yylval.s = xmemdup (yytext+1, yyleng-2, yyleng); + yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng); return CHAR; } @@ -256,6 +367,8 @@ ITYPE {IWORD}({WS}{IWORD})* return PERCENTPERCENT; } +"#define"[^\n]*\n {lexer_line.line++;} + . { error_at_line (&lexer_line, "unexpected character `%s'", yytext); } @@ -297,18 +410,191 @@ ITYPE {IWORD}({WS}{IWORD})* "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 (s) - const char *s; +yyerror (const char *s) { error_at_line (&lexer_line, s); } void -parse_file (fname) - const char *fname; +parse_file (const char *fname) { yyin = fopen (fname, "r"); lexer_line.file = fname;