/* -*- indented-text -*- */ /* Process source files and output type information. Copyright (C) 2002, 2004 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ %{ #include "bconfig.h" #include "system.h" #include "coretypes.h" #include "tm.h" #include "gengtype.h" #define YYERROR_VERBOSE %} %union { type_p t; pair_p p; options_p o; const char *s; } %token ENT_TYPEDEF_STRUCT %token ENT_STRUCT %token ENT_EXTERNSTATIC %token ENT_YACCUNION %token GTY_TOKEN %token UNION %token STRUCT %token ENUM %token ALIAS %token NESTED_PTR %token PARAM_IS %token NUM %token PERCENTPERCENT "%%" %token SCALAR %token ID %token STRING %token ARRAY %token PERCENT_ID %token CHAR %type

struct_fields yacc_ids yacc_typematch %type type lasttype %type optionsopt options option optionseq optionseqopt %type type_option stringseq %% start: /* empty */ | typedef_struct start | externstatic start | yacc_union start ; typedef_struct: ENT_TYPEDEF_STRUCT options '{' struct_fields '}' ID { new_structure ($1->u.s.tag, UNION_P ($1), &lexer_line, $4, $2); do_typedef ($6, $1, &lexer_line); lexer_toplevel_done = 1; } ';' {} | ENT_STRUCT options '{' struct_fields '}' { new_structure ($1->u.s.tag, UNION_P ($1), &lexer_line, $4, $2); lexer_toplevel_done = 1; } ';' {} ; externstatic: ENT_EXTERNSTATIC options lasttype ID semiequal { note_variable ($4, adjust_field_type ($3, $2), $2, &lexer_line); } | ENT_EXTERNSTATIC options lasttype ID ARRAY semiequal { note_variable ($4, create_array ($3, $5), $2, &lexer_line); } | ENT_EXTERNSTATIC options lasttype ID ARRAY ARRAY semiequal { note_variable ($4, create_array (create_array ($3, $6), $5), $2, &lexer_line); } ; lasttype: type { lexer_toplevel_done = 1; $$ = $1; } ; semiequal: ';' | '=' ; yacc_union: ENT_YACCUNION options struct_fields '}' yacc_typematch PERCENTPERCENT { note_yacc_type ($2, $3, $5, &lexer_line); } ; yacc_typematch: /* empty */ { $$ = NULL; } | yacc_typematch PERCENT_ID yacc_ids { pair_p p; for (p = $3; p->next != NULL; p = p->next) { p->name = NULL; p->type = NULL; } p->name = NULL; p->type = NULL; p->next = $1; $$ = $3; } | yacc_typematch PERCENT_ID '<' ID '>' yacc_ids { pair_p p; type_p newtype = NULL; if (strcmp ($2, "type") == 0) newtype = (type_p) 1; for (p = $6; p->next != NULL; p = p->next) { p->name = $4; p->type = newtype; } p->name = $4; p->next = $1; p->type = newtype; $$ = $6; } ; yacc_ids: /* empty */ { $$ = NULL; } | yacc_ids ID { pair_p p = XCNEW (struct pair); p->next = $1; p->line = lexer_line; p->opt = XNEW (struct options); p->opt->name = "tag"; p->opt->next = NULL; p->opt->info = (char *)$2; $$ = p; } | yacc_ids CHAR { pair_p p = XCNEW (struct pair); p->next = $1; p->line = lexer_line; p->opt = XNEW (struct options); p->opt->name = "tag"; p->opt->next = NULL; p->opt->info = xasprintf ("'%s'", $2); $$ = p; } ; struct_fields: { $$ = NULL; } | type optionsopt ID bitfieldopt ';' struct_fields { pair_p p = XNEW (struct pair); p->type = adjust_field_type ($1, $2); p->opt = $2; p->name = $3; p->next = $6; p->line = lexer_line; $$ = p; } | type optionsopt ID ARRAY ';' struct_fields { pair_p p = XNEW (struct pair); p->type = adjust_field_type (create_array ($1, $4), $2); p->opt = $2; p->name = $3; p->next = $6; p->line = lexer_line; $$ = p; } | type optionsopt ID ARRAY ARRAY ';' struct_fields { pair_p p = XNEW (struct pair); p->type = create_array (create_array ($1, $5), $4); p->opt = $2; p->name = $3; p->next = $7; p->line = lexer_line; $$ = p; } | type ':' bitfieldlen ';' struct_fields { $$ = $5; } ; bitfieldopt: /* empty */ | ':' bitfieldlen ; bitfieldlen: NUM | ID { } ; type: SCALAR { $$ = $1; } | ID { $$ = resolve_typedef ($1, &lexer_line); } | type '*' { $$ = create_pointer ($1); } | STRUCT ID '{' struct_fields '}' { new_structure ($2, 0, &lexer_line, $4, NULL); $$ = find_structure ($2, 0); } | STRUCT ID { $$ = find_structure ($2, 0); } | UNION ID '{' struct_fields '}' { new_structure ($2, 1, &lexer_line, $4, NULL); $$ = find_structure ($2, 1); } | UNION ID { $$ = find_structure ($2, 1); } | ENUM ID { $$ = create_scalar_type ($2, strlen ($2)); } | ENUM ID '{' enum_items '}' { $$ = create_scalar_type ($2, strlen ($2)); } ; enum_items: /* empty */ | ID '=' NUM ',' enum_items { } | ID ',' enum_items { } | ID enum_items { } ; optionsopt: { $$ = NULL; } | options { $$ = $1; } ; options: GTY_TOKEN '(' '(' optionseqopt ')' ')' { $$ = $4; } ; type_option : ALIAS { $$ = "ptr_alias"; } | PARAM_IS { $$ = $1; } ; option: ID { $$ = create_option ($1, (void *)""); } | ID '(' stringseq ')' { $$ = create_option ($1, (void *)$3); } | type_option '(' type ')' { $$ = create_option ($1, adjust_field_type ($3, NULL)); } | NESTED_PTR '(' type ',' stringseq ',' stringseq ')' { struct nested_ptr_data d; d.type = adjust_field_type ($3, NULL); d.convert_to = $5; d.convert_from = $7; $$ = create_option ("nested_ptr", xmemdup (&d, sizeof (d), sizeof (d))); } ; optionseq: option { $1->next = NULL; $$ = $1; } | optionseq ',' option { $3->next = $1; $$ = $3; } ; optionseqopt: { $$ = NULL; } | optionseq { $$ = $1; } ; stringseq: STRING { $$ = $1; } | stringseq STRING { size_t l1 = strlen ($1); size_t l2 = strlen ($2); char *s = XRESIZEVEC (char, $1, l1 + l2 + 1); memcpy (s + l1, $2, l2 + 1); XDELETE ($2); $$ = s; } ; %%