mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-14 17:41:08 +08:00
gengtype.h: Remove all type definitions to gengtype.c...
* gengtype.h: Remove all type definitions to gengtype.c; leave only definitions of options_p, type_p, and pair_p as opaque pointers. Update prototypes. * gengtype.c: Many type definitions moved here from gengtype.h. Consolidate type definitions at the top of the file. (xvasprintf): Delete. (xasprintf): Make static. (create_nested_pointer_option): Add 'next' parameter. (create_field_all, create_field_at): New functions. (create_field): Now a thin wrapper around create_field_all. (create_optional_field): Rename create_optional_field_ and add line argument. Original name is now a macro which supplies __LINE__. (oprintf): Use vsnprintf directly. (close_output_files): Use fatal rather than perror/exit. (note_def_vec, note_def_vec_alloc): Use create_field_at. (main): Set progname. Don't use exit. * gengtype-yacc.y (struct_fields): Use create_field_at. (option, optionseqopt): Delete. (optionseq): Consolidate productions from option here so we can use the first argument to create_option. From-SVN: r123233
This commit is contained in:
parent
17defa6a13
commit
065ae61175
@ -1,5 +1,27 @@
|
||||
2007-03-26 Zack Weinberg <zackw@panix.com>
|
||||
|
||||
* gengtype.h: Remove all type definitions to gengtype.c; leave
|
||||
only definitions of options_p, type_p, and pair_p as opaque
|
||||
pointers. Update prototypes.
|
||||
* gengtype.c: Many type definitions moved here from gengtype.h.
|
||||
Consolidate type definitions at the top of the file.
|
||||
(xvasprintf): Delete.
|
||||
(xasprintf): Make static.
|
||||
(create_nested_pointer_option): Add 'next' parameter.
|
||||
(create_field_all, create_field_at): New functions.
|
||||
(create_field): Now a thin wrapper around create_field_all.
|
||||
(create_optional_field): Rename create_optional_field_ and add
|
||||
line argument. Original name is now a macro which supplies
|
||||
__LINE__.
|
||||
(oprintf): Use vsnprintf directly.
|
||||
(close_output_files): Use fatal rather than perror/exit.
|
||||
(note_def_vec, note_def_vec_alloc): Use create_field_at.
|
||||
(main): Set progname. Don't use exit.
|
||||
* gengtype-yacc.y (struct_fields): Use create_field_at.
|
||||
(option, optionseqopt): Delete.
|
||||
(optionseq): Consolidate productions from option here so we
|
||||
can use the first argument to create_option.
|
||||
|
||||
* gengtype-lex.l: Distinguish unions from structures in the
|
||||
token type. Don't call find_structure; return the tag as a string.
|
||||
* gengtype-yacc.y: Add new token types ENT_TYPEDEF_UNION and ENT_UNION.
|
||||
|
@ -57,7 +57,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
|
||||
%type <p> struct_fields
|
||||
%type <t> type lasttype
|
||||
%type <o> optionsopt options option optionseq optionseqopt
|
||||
%type <o> optionsopt options optionseq
|
||||
%type <s> type_option stringseq
|
||||
|
||||
%%
|
||||
@ -128,33 +128,17 @@ semiequal: ';'
|
||||
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;
|
||||
$$ = create_field_at ($6, $1, $3, $2, &lexer_line);
|
||||
}
|
||||
| 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;
|
||||
$$ = create_field_at ($6, create_array ($1, $4),
|
||||
$3, $2, &lexer_line);
|
||||
}
|
||||
| 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_p arr = create_array (create_array ($1, $5), $4);
|
||||
$$ = create_field_at ($7, arr, $3, $2, &lexer_line);
|
||||
}
|
||||
| type ':' bitfieldlen ';' struct_fields
|
||||
{ $$ = $5; }
|
||||
@ -204,7 +188,7 @@ optionsopt: { $$ = NULL; }
|
||||
| options { $$ = $1; }
|
||||
;
|
||||
|
||||
options: GTY_TOKEN '(' '(' optionseqopt ')' ')'
|
||||
options: GTY_TOKEN '(' '(' optionseq ')' ')'
|
||||
{ $$ = $4; }
|
||||
;
|
||||
|
||||
@ -214,31 +198,19 @@ type_option : ALIAS
|
||||
{ $$ = $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 ')'
|
||||
{ $$ = create_nested_ptr_option ($3, $5, $7); }
|
||||
;
|
||||
optionseq: { $$ = NULL; }
|
||||
| optionseq commaopt ID
|
||||
{ $$ = create_option ($1, $3, (void *)""); }
|
||||
| optionseq commaopt ID '(' stringseq ')'
|
||||
{ $$ = create_option ($1, $3, (void *)$5); }
|
||||
| optionseq commaopt type_option '(' type ')'
|
||||
{ $$ = create_option ($1, $3, adjust_field_type ($5, 0)); }
|
||||
| optionseq commaopt NESTED_PTR '(' type ',' stringseq ',' stringseq ')'
|
||||
{ $$ = create_nested_ptr_option ($1, $5, $7, $9); }
|
||||
|
||||
optionseq: option
|
||||
{
|
||||
$1->next = NULL;
|
||||
$$ = $1;
|
||||
}
|
||||
| optionseq ',' option
|
||||
{
|
||||
$3->next = $1;
|
||||
$$ = $3;
|
||||
}
|
||||
;
|
||||
|
||||
optionseqopt: { $$ = NULL; }
|
||||
| optionseq { $$ = $1; }
|
||||
;
|
||||
commaopt: /* nothing */
|
||||
| ','
|
||||
;
|
||||
|
||||
stringseq: STRING
|
||||
{ $$ = $1; }
|
||||
|
326
gcc/gengtype.c
326
gcc/gengtype.c
@ -22,9 +22,153 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
#include "bconfig.h"
|
||||
#include "system.h"
|
||||
#include "gengtype.h"
|
||||
#include "gtyp-gen.h"
|
||||
#include "errors.h" /* for fatal */
|
||||
|
||||
/* Data types, macros, etc. used only in this file. */
|
||||
|
||||
/* Kinds of types we can understand. */
|
||||
enum typekind {
|
||||
TYPE_SCALAR,
|
||||
TYPE_STRING,
|
||||
TYPE_STRUCT,
|
||||
TYPE_UNION,
|
||||
TYPE_POINTER,
|
||||
TYPE_ARRAY,
|
||||
TYPE_LANG_STRUCT,
|
||||
TYPE_PARAM_STRUCT
|
||||
};
|
||||
|
||||
typedef unsigned lang_bitmap;
|
||||
|
||||
/* A way to pass data through to the output end. */
|
||||
struct options
|
||||
{
|
||||
struct options *next;
|
||||
const char *name;
|
||||
const char *info;
|
||||
};
|
||||
|
||||
/* Option data for the 'nested_ptr' option. */
|
||||
struct nested_ptr_data
|
||||
{
|
||||
type_p type;
|
||||
const char *convert_to;
|
||||
const char *convert_from;
|
||||
};
|
||||
|
||||
/* A name and a type. */
|
||||
struct pair
|
||||
{
|
||||
pair_p next;
|
||||
const char *name;
|
||||
type_p type;
|
||||
struct fileloc line;
|
||||
options_p opt;
|
||||
};
|
||||
|
||||
#define NUM_PARAM 10
|
||||
|
||||
/* A description of a type. */
|
||||
enum gc_used_enum
|
||||
{
|
||||
GC_UNUSED = 0,
|
||||
GC_USED,
|
||||
GC_MAYBE_POINTED_TO,
|
||||
GC_POINTED_TO
|
||||
};
|
||||
|
||||
struct type
|
||||
{
|
||||
enum typekind kind;
|
||||
type_p next;
|
||||
type_p pointer_to;
|
||||
enum gc_used_enum gc_used;
|
||||
union {
|
||||
type_p p;
|
||||
struct {
|
||||
const char *tag;
|
||||
struct fileloc line;
|
||||
pair_p fields;
|
||||
options_p opt;
|
||||
lang_bitmap bitmap;
|
||||
type_p lang_struct;
|
||||
} s;
|
||||
bool scalar_is_char;
|
||||
struct {
|
||||
type_p p;
|
||||
const char *len;
|
||||
} a;
|
||||
struct {
|
||||
type_p stru;
|
||||
type_p param[NUM_PARAM];
|
||||
struct fileloc line;
|
||||
} param_struct;
|
||||
} u;
|
||||
};
|
||||
|
||||
#define UNION_P(x) \
|
||||
((x)->kind == TYPE_UNION || \
|
||||
((x)->kind == TYPE_LANG_STRUCT \
|
||||
&& (x)->u.s.lang_struct->kind == TYPE_UNION))
|
||||
#define UNION_OR_STRUCT_P(x) \
|
||||
((x)->kind == TYPE_UNION \
|
||||
|| (x)->kind == TYPE_STRUCT \
|
||||
|| (x)->kind == TYPE_LANG_STRUCT)
|
||||
|
||||
/* Structure representing an output file. */
|
||||
struct outf
|
||||
{
|
||||
struct outf *next;
|
||||
const char *name;
|
||||
size_t buflength;
|
||||
size_t bufused;
|
||||
char *buf;
|
||||
};
|
||||
typedef struct outf * outf_p;
|
||||
|
||||
/* An output file, suitable for definitions, that can see declarations
|
||||
made in INPUT_FILE and is linked into every language that uses
|
||||
INPUT_FILE. */
|
||||
extern outf_p get_output_file_with_visibility
|
||||
(const char *input_file);
|
||||
const char *get_output_file_name (const char *);
|
||||
|
||||
#include "gtyp-gen.h"
|
||||
|
||||
/* A bitmap that specifies which of BASE_FILES should be used to
|
||||
output a definition that is different for each language and must be
|
||||
defined once in each language that uses INPUT_FILE. */
|
||||
static lang_bitmap get_base_file_bitmap (const char *input_file);
|
||||
|
||||
/* Print, like fprintf, to O. */
|
||||
static void oprintf (outf_p o, const char *S, ...)
|
||||
ATTRIBUTE_PRINTF_2;
|
||||
|
||||
/* The list of output files. */
|
||||
static outf_p output_files;
|
||||
|
||||
/* The output header file that is included into pretty much every
|
||||
source file. */
|
||||
static outf_p header_file;
|
||||
|
||||
/* Number of files specified in gtfiles. */
|
||||
#define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
|
||||
|
||||
/* Number of files in the language files array. */
|
||||
#define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
|
||||
|
||||
/* Length of srcdir name. */
|
||||
static int srcdir_len = 0;
|
||||
|
||||
/* A list of output files suitable for definitions. There is one
|
||||
BASE_FILES entry for each language. */
|
||||
#define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
|
||||
static outf_p base_files[NUM_BASE_FILES];
|
||||
|
||||
static outf_p create_file (const char *, const char *);
|
||||
static const char * get_file_basename (const char *);
|
||||
|
||||
|
||||
/* Nonzero iff an error has occurred. */
|
||||
static int hit_error = 0;
|
||||
|
||||
@ -50,29 +194,20 @@ error_at_line (struct fileloc *pos, const char *msg, ...)
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
/* vasprintf, but produces fatal message on out-of-memory. */
|
||||
int
|
||||
xvasprintf (char **result, const char *format, va_list args)
|
||||
{
|
||||
int ret = vasprintf (result, format, args);
|
||||
if (*result == NULL || ret < 0)
|
||||
{
|
||||
fputs ("gengtype: out of memory", stderr);
|
||||
xexit (1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wrapper for xvasprintf. */
|
||||
char *
|
||||
/* asprintf, but produces fatal message on out-of-memory. */
|
||||
static char * ATTRIBUTE_PRINTF_1
|
||||
xasprintf (const char *format, ...)
|
||||
{
|
||||
int n;
|
||||
char *result;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, format);
|
||||
xvasprintf (&result, format, ap);
|
||||
n = vasprintf (&result, format, ap);
|
||||
if (result == NULL || n < 0)
|
||||
fatal ("out of memory");
|
||||
va_end (ap);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -332,14 +467,15 @@ create_option (options_p next, const char *name, const void *info)
|
||||
|
||||
/* Return an options structure for a "nested_ptr" option. */
|
||||
options_p
|
||||
create_nested_ptr_option (type_p t, const char *to, const char *from)
|
||||
create_nested_ptr_option (options_p next, type_p t,
|
||||
const char *to, const char *from)
|
||||
{
|
||||
struct nested_ptr_data *d = XNEW (struct nested_ptr_data);
|
||||
|
||||
d->type = adjust_field_type (t, 0);
|
||||
d->convert_to = to;
|
||||
d->convert_from = from;
|
||||
return create_option (NULL, "nested_ptr", d);
|
||||
return create_option (next, "nested_ptr", d);
|
||||
}
|
||||
|
||||
/* Add a variable named S of type T with options O defined at POS,
|
||||
@ -358,11 +494,10 @@ note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
|
||||
variables = n;
|
||||
}
|
||||
|
||||
/* Create a fake field with the given type and name. NEXT is the next
|
||||
field in the chain. */
|
||||
|
||||
/* Most-general structure field creator. */
|
||||
static pair_p
|
||||
create_field (pair_p next, type_p type, const char *name)
|
||||
create_field_all (pair_p next, type_p type, const char *name, options_p opt,
|
||||
const char *file, int line)
|
||||
{
|
||||
pair_p field;
|
||||
|
||||
@ -370,21 +505,37 @@ create_field (pair_p next, type_p type, const char *name)
|
||||
field->next = next;
|
||||
field->type = type;
|
||||
field->name = name;
|
||||
field->opt = NULL;
|
||||
field->line.file = __FILE__;
|
||||
field->line.line = __LINE__;
|
||||
field->opt = opt;
|
||||
field->line.file = file;
|
||||
field->line.line = line;
|
||||
return field;
|
||||
}
|
||||
|
||||
/* Create a field that came from the source code we are scanning,
|
||||
i.e. we have a 'struct fileloc', and possibly options; also,
|
||||
adjust_field_type should be called. */
|
||||
pair_p
|
||||
create_field_at (pair_p next, type_p type, const char *name, options_p opt,
|
||||
struct fileloc *pos)
|
||||
{
|
||||
return create_field_all (next, adjust_field_type (type, opt),
|
||||
name, opt, pos->file, pos->line);
|
||||
}
|
||||
|
||||
/* Create a fake field with the given type and name. NEXT is the next
|
||||
field in the chain. */
|
||||
#define create_field(next,type,name) \
|
||||
create_field_all(next,type,name, 0, __FILE__, __LINE__)
|
||||
|
||||
/* Like create_field, but the field is only valid when condition COND
|
||||
is true. */
|
||||
|
||||
static pair_p
|
||||
create_optional_field (pair_p next, type_p type, const char *name,
|
||||
const char *cond)
|
||||
create_optional_field_ (pair_p next, type_p type, const char *name,
|
||||
const char *cond, int line)
|
||||
{
|
||||
static int id = 1;
|
||||
pair_p union_fields, field;
|
||||
pair_p union_fields;
|
||||
type_p union_type;
|
||||
|
||||
/* Create a fake union type with a single nameless field of type TYPE.
|
||||
@ -398,10 +549,12 @@ create_optional_field (pair_p next, type_p type, const char *name,
|
||||
|
||||
/* Create the field and give it the new fake union type. Add a "desc"
|
||||
tag that specifies the condition under which the field is valid. */
|
||||
field = create_field (next, union_type, name);
|
||||
field->opt = create_option (field->opt, "desc", cond);
|
||||
return field;
|
||||
return create_field_all (next, union_type, name,
|
||||
create_option (0, "desc", cond),
|
||||
__FILE__, line);
|
||||
}
|
||||
#define create_optional_field(next,type,name,cond) \
|
||||
create_optional_field_(next,type,name,cond,__LINE__)
|
||||
|
||||
/* We don't care how long a CONST_DOUBLE is. */
|
||||
#define CONST_DOUBLE_FORMAT "ww"
|
||||
@ -953,27 +1106,7 @@ set_gc_used (pair_p variables)
|
||||
(but some output files have many input files), and there is one .h file
|
||||
for the whole build. */
|
||||
|
||||
/* The list of output files. */
|
||||
static outf_p output_files;
|
||||
|
||||
/* The output header file that is included into pretty much every
|
||||
source file. */
|
||||
static outf_p header_file;
|
||||
|
||||
/* Number of files specified in gtfiles. */
|
||||
#define NUM_GT_FILES (ARRAY_SIZE (all_files) - 1)
|
||||
|
||||
/* Number of files in the language files array. */
|
||||
#define NUM_LANG_FILES (ARRAY_SIZE (lang_files) - 1)
|
||||
|
||||
/* Length of srcdir name. */
|
||||
static int srcdir_len = 0;
|
||||
|
||||
#define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
|
||||
outf_p base_files[NUM_BASE_FILES];
|
||||
|
||||
static outf_p create_file (const char *, const char *);
|
||||
static const char * get_file_basename (const char *);
|
||||
/* Output file handling. */
|
||||
|
||||
/* Create and return an outf_p for a new file for NAME, to be called
|
||||
ONAME. */
|
||||
@ -1021,15 +1154,20 @@ create_file (const char *name, const char *oname)
|
||||
void
|
||||
oprintf (outf_p o, const char *format, ...)
|
||||
{
|
||||
char *s;
|
||||
size_t slength;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, format);
|
||||
slength = xvasprintf (&s, format, ap);
|
||||
/* Try first with the assumption that there is enough space. */
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, format);
|
||||
slength = vsnprintf (o->buf + o->bufused, o->buflength - o->bufused,
|
||||
format, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
if (o->bufused + slength > o->buflength)
|
||||
if (o->bufused + slength >= o->buflength)
|
||||
{
|
||||
/* There wasn't enough space. */
|
||||
size_t new_len = o->buflength;
|
||||
if (new_len == 0)
|
||||
new_len = 1024;
|
||||
@ -1038,11 +1176,21 @@ oprintf (outf_p o, const char *format, ...)
|
||||
} while (o->bufused + slength >= new_len);
|
||||
o->buf = XRESIZEVEC (char, o->buf, new_len);
|
||||
o->buflength = new_len;
|
||||
|
||||
/* We now know that there is enough space. */
|
||||
{
|
||||
size_t slen2;
|
||||
va_list ap;
|
||||
va_start (ap, format);
|
||||
slen2 = vsnprintf (o->buf + o->bufused, o->buflength - o->bufused,
|
||||
format, ap);
|
||||
va_end (ap);
|
||||
|
||||
gcc_assert (slen2 == slength);
|
||||
gcc_assert (o->bufused + slen2 < o->buflength);
|
||||
}
|
||||
}
|
||||
memcpy (o->buf + o->bufused, s, slength);
|
||||
o->bufused += slength;
|
||||
free (s);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
/* Open the global header file and the language-specific header files. */
|
||||
@ -1298,20 +1446,11 @@ close_output_files (void)
|
||||
|
||||
newfile = fopen (of->name, "w");
|
||||
if (newfile == NULL)
|
||||
{
|
||||
perror ("opening output file");
|
||||
exit (1);
|
||||
}
|
||||
fatal ("opening output file %s: %s", of->name, strerror (errno));
|
||||
if (fwrite (of->buf, 1, of->bufused, newfile) != of->bufused)
|
||||
{
|
||||
perror ("writing output file");
|
||||
exit (1);
|
||||
}
|
||||
fatal ("writing output file %s: %s", of->name, strerror (errno));
|
||||
if (fclose (newfile) != 0)
|
||||
{
|
||||
perror ("closing output file");
|
||||
exit (1);
|
||||
}
|
||||
fatal ("closing output file %s: %s", of->name, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3029,9 +3168,10 @@ write_roots (pair_p variables)
|
||||
void
|
||||
note_def_vec (const char *typename, bool is_scalar, struct fileloc *pos)
|
||||
{
|
||||
pair_p f, fields;
|
||||
pair_p fields;
|
||||
type_p t;
|
||||
options_p o;
|
||||
type_p len_ty = create_scalar_type ("unsigned");
|
||||
const char *name = concat ("VEC_", typename, "_base", (char *)0);
|
||||
|
||||
if (is_scalar)
|
||||
@ -3046,29 +3186,9 @@ note_def_vec (const char *typename, bool is_scalar, struct fileloc *pos)
|
||||
}
|
||||
|
||||
/* We assemble the field list in reverse order. */
|
||||
f = XNEW (struct pair);
|
||||
f->type = adjust_field_type (create_array (t, "1"), o);
|
||||
f->name = "vec";
|
||||
f->opt = o;
|
||||
f->line = *pos;
|
||||
f->next = 0;
|
||||
fields = f;
|
||||
|
||||
f = XNEW (struct pair);
|
||||
f->type = adjust_field_type (create_scalar_type ("unsigned"), 0);
|
||||
f->name = "alloc";
|
||||
f->opt = 0;
|
||||
f->line = *pos;
|
||||
f->next = fields;
|
||||
fields = f;
|
||||
|
||||
f = XNEW (struct pair);
|
||||
f->type = adjust_field_type (create_scalar_type ("unsigned"), 0);
|
||||
f->name = "num";
|
||||
f->opt = 0;
|
||||
f->line = *pos;
|
||||
f->next = fields;
|
||||
fields = f;
|
||||
fields = create_field_at (0, create_array (t, "1"), "vec", o, pos);
|
||||
fields = create_field_at (fields, len_ty, "alloc", 0, pos);
|
||||
fields = create_field_at (fields, len_ty, "num", 0, pos);
|
||||
|
||||
do_typedef (name, new_structure (name, 0, pos, fields, 0), pos);
|
||||
}
|
||||
@ -3086,11 +3206,8 @@ note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
|
||||
const char *astratname = concat ("VEC_", type, "_", astrat, (char *)0);
|
||||
const char *basename = concat ("VEC_", type, "_base", (char *)0);
|
||||
|
||||
pair_p field = XNEW (struct pair);
|
||||
field->name = "base";
|
||||
field->type = adjust_field_type (resolve_typedef (basename, pos), 0);
|
||||
field->line = *pos;
|
||||
field->next = 0;
|
||||
pair_p field = create_field_at (0, resolve_typedef (basename, pos),
|
||||
"base", 0, pos);
|
||||
|
||||
do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
|
||||
}
|
||||
@ -3109,6 +3226,9 @@ main (int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
|
||||
scalar_char.u.scalar_is_char = true;
|
||||
scalar_nonchar.u.scalar_is_char = false;
|
||||
|
||||
/* fatal uses this */
|
||||
progname = "gengtype";
|
||||
|
||||
gen_rtx_next ();
|
||||
|
||||
do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
|
||||
@ -3150,7 +3270,7 @@ main (int ARG_UNUSED (argc), char ** ARG_UNUSED (argv))
|
||||
}
|
||||
|
||||
if (hit_error != 0)
|
||||
exit (1);
|
||||
return 1;
|
||||
|
||||
set_gc_used (variables);
|
||||
|
||||
|
136
gcc/gengtype.h
136
gcc/gengtype.h
@ -18,6 +18,9 @@ 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. */
|
||||
|
||||
#ifndef GCC_GENGTYPE_H
|
||||
#define GCC_GENGTYPE_H
|
||||
|
||||
/* A file position, mostly for error messages.
|
||||
The FILE element may be compared using pointer equality. */
|
||||
struct fileloc {
|
||||
@ -25,92 +28,10 @@ struct fileloc {
|
||||
int line;
|
||||
};
|
||||
|
||||
/* Kinds of types we can understand. */
|
||||
enum typekind {
|
||||
TYPE_SCALAR,
|
||||
TYPE_STRING,
|
||||
TYPE_STRUCT,
|
||||
TYPE_UNION,
|
||||
TYPE_POINTER,
|
||||
TYPE_ARRAY,
|
||||
TYPE_LANG_STRUCT,
|
||||
TYPE_PARAM_STRUCT
|
||||
};
|
||||
|
||||
/* Data types handed around within, but opaque to, the lexer and parser. */
|
||||
typedef struct pair *pair_p;
|
||||
typedef struct type *type_p;
|
||||
typedef unsigned lang_bitmap;
|
||||
|
||||
/* Option data for the 'nested_ptr' option. */
|
||||
struct nested_ptr_data {
|
||||
type_p type;
|
||||
const char *convert_to;
|
||||
const char *convert_from;
|
||||
};
|
||||
|
||||
/* A way to pass data through to the output end. */
|
||||
typedef struct options {
|
||||
struct options *next;
|
||||
const char *name;
|
||||
const char *info;
|
||||
} *options_p;
|
||||
|
||||
/* A name and a type. */
|
||||
struct pair {
|
||||
pair_p next;
|
||||
const char *name;
|
||||
type_p type;
|
||||
struct fileloc line;
|
||||
options_p opt;
|
||||
};
|
||||
|
||||
#define NUM_PARAM 10
|
||||
|
||||
/* A description of a type. */
|
||||
enum gc_used_enum
|
||||
{
|
||||
GC_UNUSED = 0,
|
||||
GC_USED,
|
||||
GC_MAYBE_POINTED_TO,
|
||||
GC_POINTED_TO
|
||||
};
|
||||
|
||||
struct type {
|
||||
enum typekind kind;
|
||||
type_p next;
|
||||
type_p pointer_to;
|
||||
enum gc_used_enum gc_used;
|
||||
union {
|
||||
type_p p;
|
||||
struct {
|
||||
const char *tag;
|
||||
struct fileloc line;
|
||||
pair_p fields;
|
||||
options_p opt;
|
||||
lang_bitmap bitmap;
|
||||
type_p lang_struct;
|
||||
} s;
|
||||
bool scalar_is_char;
|
||||
struct {
|
||||
type_p p;
|
||||
const char *len;
|
||||
} a;
|
||||
struct {
|
||||
type_p stru;
|
||||
type_p param[NUM_PARAM];
|
||||
struct fileloc line;
|
||||
} param_struct;
|
||||
} u;
|
||||
};
|
||||
|
||||
#define UNION_P(x) \
|
||||
((x)->kind == TYPE_UNION || \
|
||||
((x)->kind == TYPE_LANG_STRUCT \
|
||||
&& (x)->u.s.lang_struct->kind == TYPE_UNION))
|
||||
#define UNION_OR_STRUCT_P(x) \
|
||||
((x)->kind == TYPE_UNION \
|
||||
|| (x)->kind == TYPE_STRUCT \
|
||||
|| (x)->kind == TYPE_LANG_STRUCT)
|
||||
typedef struct options *options_p;
|
||||
|
||||
/* Variables used to communicate between the lexer and the parser. */
|
||||
extern int lexer_toplevel_done;
|
||||
@ -120,13 +41,6 @@ extern struct fileloc lexer_line;
|
||||
extern void error_at_line
|
||||
(struct fileloc *pos, const char *msg, ...) ATTRIBUTE_PRINTF_2;
|
||||
|
||||
/* Combines xmalloc() and vasprintf(). */
|
||||
extern int xvasprintf (char **, const char *, va_list)
|
||||
ATTRIBUTE_PRINTF (2, 0);
|
||||
/* Like the above, but more convenient for quick coding. */
|
||||
extern char * xasprintf (const char *, ...)
|
||||
ATTRIBUTE_PRINTF_1;
|
||||
|
||||
/* Constructor routines for types. */
|
||||
extern void do_typedef (const char *s, type_p t, struct fileloc *pos);
|
||||
extern void do_scalar_typedef (const char *s, struct fileloc *pos);
|
||||
@ -139,8 +53,10 @@ extern type_p create_scalar_type (const char *name);
|
||||
extern type_p create_pointer (type_p t);
|
||||
extern type_p create_array (type_p t, const char *len);
|
||||
extern options_p create_option (options_p, const char *name, const void *info);
|
||||
extern options_p create_nested_ptr_option (type_p t, const char *from,
|
||||
const char *to);
|
||||
extern options_p create_nested_ptr_option (options_p, type_p t,
|
||||
const char *from, const char *to);
|
||||
extern pair_p create_field_at (pair_p next, type_p type, const char *name,
|
||||
options_p opt, struct fileloc *pos);
|
||||
extern type_p adjust_field_type (type_p, options_p);
|
||||
extern void note_variable (const char *s, type_p t, options_p o,
|
||||
struct fileloc *pos);
|
||||
@ -155,36 +71,4 @@ extern void yyerror (const char *);
|
||||
extern int yyparse (void);
|
||||
extern void parse_file (const char *name);
|
||||
|
||||
/* Output file handling. */
|
||||
|
||||
/* Structure representing an output file. */
|
||||
struct outf
|
||||
{
|
||||
struct outf *next;
|
||||
const char *name;
|
||||
size_t buflength;
|
||||
size_t bufused;
|
||||
char *buf;
|
||||
};
|
||||
|
||||
typedef struct outf * outf_p;
|
||||
|
||||
/* An output file, suitable for definitions, that can see declarations
|
||||
made in INPUT_FILE and is linked into every language that uses
|
||||
INPUT_FILE. */
|
||||
extern outf_p get_output_file_with_visibility
|
||||
(const char *input_file);
|
||||
const char *get_output_file_name (const char *);
|
||||
|
||||
/* A list of output files suitable for definitions. There is one
|
||||
BASE_FILES entry for each language. */
|
||||
extern outf_p base_files[];
|
||||
|
||||
/* A bitmap that specifies which of BASE_FILES should be used to
|
||||
output a definition that is different for each language and must be
|
||||
defined once in each language that uses INPUT_FILE. */
|
||||
extern lang_bitmap get_base_file_bitmap (const char *input_file);
|
||||
|
||||
/* Print, like fprintf, to O. */
|
||||
extern void oprintf (outf_p o, const char *S, ...)
|
||||
ATTRIBUTE_PRINTF_2;
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user