318 lines
7.1 KiB
Plaintext
318 lines
7.1 KiB
Plaintext
/* -*- 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, 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301, 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 <t>ENT_TYPEDEF_STRUCT
|
|
%token <t>ENT_STRUCT
|
|
%token ENT_EXTERNSTATIC
|
|
%token ENT_YACCUNION
|
|
%token GTY_TOKEN
|
|
%token UNION
|
|
%token STRUCT
|
|
%token ENUM
|
|
%token ALIAS
|
|
%token NESTED_PTR
|
|
%token <s>PARAM_IS
|
|
%token NUM
|
|
%token PERCENTPERCENT "%%"
|
|
%token <t>SCALAR
|
|
%token <s>ID
|
|
%token <s>STRING
|
|
%token <s>ARRAY
|
|
%token <s>PERCENT_ID
|
|
%token <s>CHAR
|
|
|
|
%type <p> struct_fields yacc_ids yacc_typematch
|
|
%type <t> type lasttype
|
|
%type <o> optionsopt options option optionseq optionseqopt
|
|
%type <s> 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); }
|
|
| STRUCT ID
|
|
{ $$ = find_structure ($2, 0); }
|
|
| UNION ID '{' struct_fields '}'
|
|
{ $$ = new_structure ($2, 1, &lexer_line, $4, NULL); }
|
|
| 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 (NULL, $1, (void *)""); }
|
|
| ID '(' stringseq ')'
|
|
{ $$ = create_option (NULL, $1, (void *)$3); }
|
|
| type_option '(' type ')'
|
|
{ $$ = create_option (NULL, $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 (NULL, "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;
|
|
}
|
|
;
|
|
%%
|