gengtype-parse.c: New file.

* gengtype-parse.c: New file.
	* gengtype-yacc.y: Delete.
	* gengtype-lex.l: Don't include gengtype-yacc.h.
	Define YY_DECL and yyterminate appropriately for recursive
	descent parser.  yylval is now a string out-parameter to yylex.
	(HWS, EOID): New shorthand.
	(IWORD): Add a couple more types.
	(yylex): Add a setup stanza.  Remove the complex rules for
	detecting GTY'ed types and typedefs; replace with simple
	keyword detectors.  Adjust everything for the changed
	definition of yylval.  Ignore all pp-directives, not just #define.
	(yyerror): Delete.
	(parse_file): Rename yybegin; do not call yyparse.
	(yyend): New.
	* gengtype.c (xasprintf): Export again.
	(this_file): New.  Use everywhere __FILE__ was being used.
	(get_lang_bitmap): Special case types defined in gengtype.c.
	(do_typedef, new_structure): Suppress definition of certain types.
	(new_structure): Improve diagnostics of duplicate definitions.
	Make sure location_s is associated with input.h.
	(nreverse_pairs, define_location_structures): New functions.
	(main): Improve tagging of kludge types.  Remove old kludges
	for input.h types; use define_location_structures.
	* gengtype.h: Update prototypes.  Define token codes here.
	* Makefile.in: Remove all references to gengtype-yacc.
	Add rules for gengtype-parse.o.  Adjust rules for gengtype-lex.o
	and gengtype.
	* bitmap.h (struct bitmap_head_def): Coalesce definitions,
	add GTY((skip)) to the field that's only conditionally there.
	* doc/install.texi: Document that Bison is no longer required
	unless building treelang.

From-SVN: r123235
This commit is contained in:
Zack Weinberg 2007-03-26 21:18:43 +00:00 committed by Zack Weinberg
parent 11a675992a
commit 01d419aec1
8 changed files with 301 additions and 302 deletions

View File

@ -1,5 +1,37 @@
2007-03-26 Zack Weinberg <zackw@panix.com>
* gengtype-parse.c: New file.
* gengtype-yacc.y: Delete.
* gengtype-lex.l: Don't include gengtype-yacc.h.
Define YY_DECL and yyterminate appropriately for recursive
descent parser. yylval is now a string out-parameter to yylex.
(HWS, EOID): New shorthand.
(IWORD): Add a couple more types.
(yylex): Add a setup stanza. Remove the complex rules for
detecting GTY'ed types and typedefs; replace with simple
keyword detectors. Adjust everything for the changed
definition of yylval. Ignore all pp-directives, not just #define.
(yyerror): Delete.
(parse_file): Rename yybegin; do not call yyparse.
(yyend): New.
* gengtype.c (xasprintf): Export again.
(this_file): New. Use everywhere __FILE__ was being used.
(get_lang_bitmap): Special case types defined in gengtype.c.
(do_typedef, new_structure): Suppress definition of certain types.
(new_structure): Improve diagnostics of duplicate definitions.
Make sure location_s is associated with input.h.
(nreverse_pairs, define_location_structures): New functions.
(main): Improve tagging of kludge types. Remove old kludges
for input.h types; use define_location_structures.
* gengtype.h: Update prototypes. Define token codes here.
* Makefile.in: Remove all references to gengtype-yacc.
Add rules for gengtype-parse.o. Adjust rules for gengtype-lex.o
and gengtype.
* bitmap.h (struct bitmap_head_def): Coalesce definitions,
add GTY((skip)) to the field that's only conditionally there.
* doc/install.texi: Document that Bison is no longer required
unless building treelang.
* gengtype.c: Don't include gtyp-gen.h.
(srcdir): Declare here.
(base_files, lang_dir_names): Allocate dynamically.

View File

@ -188,8 +188,6 @@ GCC_WARN_CFLAGS = $(LOOSE_WARN) $($(@D)-warn) $(NOCOMMON_FLAG) $($@-warn)
# These files are to have specific diagnostics suppressed, or are not to
# be subject to -Werror:
# Bison-1.75 output often yields (harmless) -Wtraditional warnings
build/gengtype-yacc.o-warn = -Wno-error
# flex output may yield harmless "no previous prototype" warnings
build/gengtype-lex.o-warn = -Wno-error
# SYSCALLS.c misses prototypes
@ -1699,7 +1697,7 @@ c-parser.o : c-parser.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
srcextra: gcc.srcextra lang.srcextra
gcc.srcextra: gengtype-lex.c gengtype-yacc.c gengtype-yacc.h
gcc.srcextra: gengtype-lex.c
-cp -p $^ $(srcdir)
c-incpath.o: c-incpath.c c-incpath.h $(CONFIG_H) $(SYSTEM_H) $(CPPLIB_H) \
@ -3105,9 +3103,8 @@ build/genextract.o : genextract.c $(RTL_BASE_H) $(BCONFIG_H) \
build/genflags.o : genflags.c $(RTL_BASE_H) $(OBSTACK_H) $(BCONFIG_H) \
$(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
build/gengenrtl.o : gengenrtl.c $(BCONFIG_H) $(SYSTEM_H) rtl.def
build/gengtype-lex.o : gengtype-lex.c gengtype.h gengtype-yacc.h \
$(BCONFIG_H) $(SYSTEM_H)
build/gengtype-yacc.o : gengtype-yacc.c gengtype.h $(BCONFIG_H) \
build/gengtype-lex.o : gengtype-lex.c gengtype.h $(BCONFIG_H) $(SYSTEM_H)
build/gengtype-parse.o : gengtype-parse.c gengtype.h $(BCONFIG_H) \
$(SYSTEM_H)
build/gengtype.o : gengtype.c $(BCONFIG_H) $(SYSTEM_H) gengtype.h \
rtl.def insn-notes.def errors.h
@ -3147,18 +3144,12 @@ build/genautomata$(build_exeext) : BUILD_LIBS += -lm
# These programs are not linked with the MD reader.
build/gengenrtl$(build_exeext) : $(BUILD_ERRORS)
build/genmodes$(build_exeext) : $(BUILD_ERRORS)
build/gengtype$(build_exeext) : build/gengtype-lex.o \
build/gengtype-yacc.o $(BUILD_ERRORS)
build/gengtype$(build_exeext) : build/gengtype-lex.o build/gengtype-parse.o \
$(BUILD_ERRORS)
# Generated source files for gengtype.
gengtype-lex.c : gengtype-lex.l
-$(FLEX) $(FLEXFLAGS) -o$@ $<
# This is a pattern rule solely so that Make knows it need not run the
# command twice. The modifier to $@ ensures that Bison is asked to
# produce a .c file, whether or not Make decides it needs the .h file
# first.
gengtype-y%.c gengtype-y%.h: gengtype-y%.y
-$(BISON) $(BISONFLAGS) -d -o $(@:.h=.c) $<
#
# Remake internationalization support.

View File

@ -70,29 +70,20 @@ typedef struct bitmap_element_def GTY(())
} bitmap_element;
struct bitmap_descriptor;
/* Head of bitmap linked list.
The gengtype doesn't cope with ifdefs inside the definition,
but for statistics we need bitmap descriptor pointer in.
Trick it by two copies of the definition. This is safe
because the bitmap descriptor is not grabagecollected. */
#ifndef GATHER_STATISTICS
/* Head of bitmap linked list. gengtype ignores ifdefs, but for
statistics we need to add a bitmap descriptor pointer. As it is
not collected, we can just GTY((skip)) it. */
typedef struct bitmap_head_def GTY(()) {
bitmap_element *first; /* First element in linked list. */
bitmap_element *current; /* Last element looked at. */
unsigned int indx; /* Index of last element looked at. */
bitmap_obstack *obstack; /* Obstack to allocate elements from.
If NULL, then use ggc_alloc. */
} bitmap_head;
#else
typedef struct bitmap_head_def {
bitmap_element *first; /* First element in linked list. */
bitmap_element *current; /* Last element looked at. */
unsigned int indx; /* Index of last element looked at. */
bitmap_obstack *obstack; /* Obstack to allocate elements from.
If NULL, then use ggc_alloc. */
struct bitmap_descriptor *desc;
} bitmap_head;
#ifndef GATHER_STATISTICS
struct bitmap_descriptor GTY((skip)) *desc;
#endif
} bitmap_head;
/* Global data */
extern bitmap_element bitmap_zero_bits; /* Zero bitmap element */

View File

@ -375,14 +375,14 @@ Necessary to regenerate the top level @file{Makefile.in} file from
@file{Makefile.tpl} and @file{Makefile.def}.
@item GNU Bison version 1.28 (or later)
Berkeley @command{yacc} (@command{byacc}) is also reported to work other
than for GCJ.
Necessary when modifying @file{*.y} files.
Necessary when modifying @file{*.y} files. Necessary to build the
@code{treelang} front end (which is not enabled by default) from a
checkout of the SVN repository; the generated files are not in the
repository. They are included in releases.
Necessary to build GCC during development because the generated output
files are not included in the SVN repository. They are included in
releases.
Berkeley @command{yacc} (@command{byacc}) has been reported to work
as well.
@item Flex version 2.5.4 (or later)
@ -1650,10 +1650,18 @@ that type mismatches occur, this could be the cause.
The solution is not to use such a directory for building GCC@.
When building from SVN or snapshots, or if you modify parser sources,
you need the Bison parser generator installed. If you do not modify
parser sources, releases contain the Bison-generated files and you do
not need Bison installed to build them.
When building from SVN or snapshots and enabling the @code{treelang}
front end, or if you modify @file{*.y} files, you need the Bison parser
generator installed. If you do not modify @file{*.y} files, releases
contain the Bison-generated files and you do not need Bison installed
to build them. Note that most front ends now use hand-written parsers,
which can be modified with no need for Bison.
Similarly, when building from SVN or snapshots, or if you modify
@file{*.l} files, you need the Flex lexical analyzer generator installed.
There is still one Flex-based lexical analyzer (part of the build
machinery, not of GCC itself) that is used even if you only build the
C front end.
When building from SVN or snapshots, or if you modify Texinfo
documentation, you need version 4.4 or later of Texinfo installed if you

View File

@ -27,7 +27,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#define realloc xrealloc
#include "gengtype.h"
#include "gengtype-yacc.h"
#define YY_DECL int yylex (const char **yylval)
#define yyterminate() return EOF_TOKEN
struct fileloc lexer_line;
int lexer_toplevel_done;
@ -44,199 +46,58 @@ update_lineno (const char *l, size_t len)
ID [[:alpha:]_][[:alnum:]_]*
WS [[:space:]]+
IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD
HWS [ \t\r\v\f]*
IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD|CPPCHAR_SIGNED_T|ino_t|dev_t
ITYPE {IWORD}({WS}{IWORD})*
EOID [^[:alnum:]_]
%x in_struct in_struct_comment in_comment
%option warn noyywrap nounput nodefault perf-report
%option 8bit never-interactive
%%
/* Do this on entry to yylex(): */
*yylval = 0;
if (lexer_toplevel_done)
{
BEGIN(INITIAL);
lexer_toplevel_done = 0;
}
[^[: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;
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--)
;
typestart[typelen] = '\0';
do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1),
create_scalar_type (typestart),
&lexer_line);
update_lineno (yytext, yyleng);
}
[^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" {
char *namestart;
size_t namelen;
for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
;
for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
;
namestart -= namelen - 1;
do_scalar_typedef ((const char *) xmemdup (namestart, namelen, namelen+1),
&lexer_line);
update_lineno (yytext, yyleng);
}
[^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
char *namestart;
size_t namelen;
for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
;
for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
;
namestart -= namelen - 1;
do_scalar_typedef ((const char *) xmemdup (namestart, namelen, namelen+1),
&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.s = (const char *) xmemdup (tagstart, taglen, taglen + 1);
/* Things we look for in skipping mode: */
<INITIAL>{
^typedef/{EOID} {
BEGIN(in_struct);
update_lineno (yytext, yyleng);
return union_p ? (typedef_p ? ENT_TYPEDEF_UNION : ENT_UNION)
: (typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT);
return TYPEDEF;
}
[^[:alnum:]_](extern|static){WS}/"GTY" {
^struct/{EOID} {
BEGIN(in_struct);
update_lineno (yytext, yyleng);
return ENT_EXTERNSTATIC;
return STRUCT;
}
^union/{EOID} {
BEGIN(in_struct);
return UNION;
}
^extern/{EOID} {
BEGIN(in_struct);
return EXTERN;
}
^static/{EOID} {
BEGIN(in_struct);
return STATIC;
}
^"DEF_VEC_"[IPO]{WS}?"("{WS}?{ID}{WS}?")" {
/* Definition of a generic VEC structure. If the letter after
DEF_VEC_ is "I", the structure definition is slightly different
than if it is "P" or "O". */
char *p = yytext + sizeof("DEF_VEC_") - 1;
char *q;
const char *type;
bool is_I = (*p == 'I');
/* Extract the argument to the macro. */
p++;
while (!ISALNUM(*p) && *p != '_')
p++;
q = p;
while (ISALNUM(*q) || *q == '_')
++;
type = xmemdup (p, q - p, q - p + 1);
note_def_vec (type, is_I, &lexer_line);
note_def_vec_alloc (type, "none", &lexer_line);
^DEF_VEC_[OP]/{EOID} {
BEGIN(in_struct);
return DEFVEC_OP;
}
^DEF_VEC_I/{EOID} {
BEGIN(in_struct);
return DEFVEC_I;
}
^DEF_VEC_ALLOC_[IOP]/{EOID} {
BEGIN(in_struct);
return DEFVEC_ALLOC;
}
^"DEF_VEC_ALLOC_"[IPO]{WS}?"("{WS}?{ID}{WS}?","{WS}?{ID}{WS}?")" {
/* Definition of an allocation strategy for a VEC structure. For
purposes of gengtype, this just declares a wrapper structure. */
char *p = yytext + sizeof("DEF_VEC_ALLOC_I") - 1;
char *q;
char *type, *astrat;
/* Extract the two arguments to the macro. */
while (!ISALNUM(*p) && *p != '_')
p++;
q = p;
while (ISALNUM(*q) || *q == '_')
q++;
type = alloca (q - p + 1);
memcpy (type, p, q - p);
type[q - p] = '\0';
p = q;
while (!ISALNUM(*p) && *p != '_')
p++;
q = p;
while (ISALNUM(*q) || *q == '_')
q++;
astrat = alloca (q - p + 1);
memcpy (astrat, p, q - p);
astrat[q - p] = '\0';
note_def_vec_alloc (type, astrat, &lexer_line);
}
<in_struct>{
@ -245,63 +106,57 @@ ITYPE {IWORD}({WS}{IWORD})*
{WS} { update_lineno (yytext, yyleng); }
"const"/[^[:alnum:]_] /* don't care */
"GTY"/[^[:alnum:]_] { return GTY_TOKEN; }
"VEC"/[^[:alnum:]_] { return VEC_TOKEN; }
"union"/[^[:alnum:]_] { return UNION; }
"struct"/[^[:alnum:]_] { return STRUCT; }
"enum"/[^[:alnum:]_] { return ENUM; }
"ptr_alias"/[^[:alnum:]_] { return ALIAS; }
"nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; }
"const"/{EOID} /* don't care */
"GTY"/{EOID} { return GTY_TOKEN; }
"VEC"/{EOID} { return VEC_TOKEN; }
"union"/{EOID} { return UNION; }
"struct"/{EOID} { return STRUCT; }
"enum"/{EOID} { return ENUM; }
"ptr_alias"/{EOID} { return PTR_ALIAS; }
"nested_ptr"/{EOID} { return NESTED_PTR; }
[0-9]+ { return NUM; }
"param"[0-9]*"_is"/[^[:alnum:]_] {
yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
"param"[0-9]*"_is"/{EOID} {
*yylval = xmemdup (yytext, yyleng, yyleng+1);
return PARAM_IS;
}
{IWORD}({WS}{IWORD})*/[^[:alnum:]_] |
{IWORD}({WS}{IWORD})*/{EOID} |
"ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" {
size_t len;
for (len = yyleng; ISSPACE (yytext[len-1]); len--)
;
yylval.s = (const char *) xmemdup (yytext, len, len+1);
*yylval = xmemdup (yytext, len, len+1);
update_lineno (yytext, yyleng);
return SCALAR;
}
{ID}/[^[:alnum:]_] {
yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
{ID}/{EOID} {
*yylval = xmemdup (yytext, yyleng, yyleng+1);
return ID;
}
\"([^"\\]|\\.)*\" {
yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
*yylval = xmemdup (yytext+1, yyleng-2, yyleng-1);
return STRING;
}
/* This "terminal" avoids having to parse integer constant expressions. */
"["[^\[\]]*"]" {
yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
*yylval = xmemdup (yytext+1, yyleng-2, yyleng-1);
return ARRAY;
}
"'"("\\".|[^\\])"'" {
yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng);
*yylval = xmemdup (yytext+1, yyleng-2, yyleng);
return CHAR;
}
[(){},*:<>] { return yytext[0]; }
"..." { return ELLIPSIS; }
[(){},*:<>;=%|-] { return yytext[0]; }
[;=] {
if (lexer_toplevel_done)
{
BEGIN(INITIAL);
lexer_toplevel_done = 0;
}
return yytext[0];
}
"#define"[^\n]*\n {lexer_line.line++;}
/* ignore pp-directives */
^{HWS}"#"{HWS}[a-z_]+[^\n]*\n {lexer_line.line++;}
. {
error_at_line (&lexer_line, "unexpected character `%s'", yytext);
@ -339,23 +194,20 @@ ITYPE {IWORD}({WS}{IWORD})*
%%
void
yyerror (const char *s)
{
error_at_line (&lexer_line, s);
}
void
parse_file (const char *fname)
yybegin (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);
lexer_line.file = fname;
lexer_line.line = 1;
}
void
yyend (void)
{
fclose (yyin);
}

View File

@ -155,7 +155,7 @@ static const char * get_file_basename (const char *);
/* Nonzero iff an error has occurred. */
static int hit_error = 0;
bool hit_error = false;
static void gen_rtx_next (void);
static void write_rtx_next (void);
@ -174,13 +174,13 @@ error_at_line (struct fileloc *pos, const char *msg, ...)
fprintf (stderr, "%s:%d: ", pos->file, pos->line);
vfprintf (stderr, msg, ap);
fputc ('\n', stderr);
hit_error = 1;
hit_error = true;
va_end (ap);
}
/* asprintf, but produces fatal message on out-of-memory. */
static char * ATTRIBUTE_PRINTF_1
char *
xasprintf (const char *format, ...)
{
int n;
@ -202,6 +202,11 @@ xasprintf (const char *format, ...)
static const char **gt_files;
static size_t num_gt_files;
/* A number of places use the name of this file for a location for
things that we can't rely on the source to define. Make sure we
can still use pointer comparison on filenames. */
static const char this_file[] = __FILE__;
/* Vector of per-language directories. */
static const char **lang_dir_names;
static size_t num_lang_dirs;
@ -225,11 +230,18 @@ static outf_p *base_files;
static lang_bitmap
get_lang_bitmap (const char *gtfile)
{
lang_bitmap n = 0;
int i;
for (i = -(int) sizeof (lang_bitmap); i < 0; i++)
n = (n << CHAR_BIT) + (unsigned char)gtfile[i];
return n;
if (gtfile == this_file)
/* Things defined in this file are universal. */
return (((lang_bitmap)1) << num_lang_dirs) - 1;
else
{
lang_bitmap n = 0;
int i;
for (i = -(int) sizeof (lang_bitmap); i < 0; i++)
n = (n << CHAR_BIT) + (unsigned char)gtfile[i];
return n;
}
}
/* Set the bitmap returned by get_lang_bitmap. The only legitimate
@ -509,6 +521,18 @@ do_typedef (const char *s, type_p t, struct fileloc *pos)
{
pair_p p;
/* temporary kludge - gengtype doesn't handle conditionals or macros.
Ignore any attempt to typedef CUMULATIVE_ARGS, location_t,
expanded_location, or source_locus, unless it is coming from
this file (main() sets them up with safe dummy definitions). */
if ((!strcmp (s, "CUMULATIVE_ARGS")
|| !strcmp (s, "location_t")
|| !strcmp (s, "source_locus")
|| !strcmp (s, "source_location")
|| !strcmp (s, "expanded_location"))
&& pos->file != this_file)
return;
for (p = typedefs; p != NULL; p = p->next)
if (strcmp (p->name, s) == 0)
{
@ -562,6 +586,13 @@ new_structure (const char *name, int isunion, struct fileloc *pos,
type_p s = NULL;
lang_bitmap bitmap = get_lang_bitmap (pos->file);
/* temporary kludge - gengtype doesn't handle conditionals or
macros. Ignore any attempt to define struct location_s, unless
it is coming from this file (main() sets it up safely). */
if (!strcmp (name, "location_s") && !isunion
&& pos->file != this_file)
return find_structure (name, 0);
for (si = structures; si != NULL; si = si->next)
if (strcmp (name, si->u.s.tag) == 0
&& UNION_P (si) == isunion)
@ -610,7 +641,8 @@ new_structure (const char *name, int isunion, struct fileloc *pos,
if (s->u.s.line.file != NULL
|| (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
{
error_at_line (pos, "duplicate structure definition");
error_at_line (pos, "duplicate definition of '%s %s'",
isunion ? "union" : "struct", s->u.s.tag);
error_at_line (&s->u.s.line, "previous definition here");
}
@ -623,7 +655,22 @@ new_structure (const char *name, int isunion, struct fileloc *pos,
if (s->u.s.lang_struct)
s->u.s.lang_struct->u.s.bitmap |= bitmap;
return s;
/* Reset location_s's location to input.h so that we know where to
write out its mark routine. */
if (!strcmp (name, "location_s") && !isunion
&& pos->file == this_file)
{
size_t n;
for (n = 0; n < num_gt_files; n++)
if (!strcmp (gt_files[n] + strlen (gt_files[n]) - strlen ("input.h"),
"input.h"))
{
s->u.s.line.file = gt_files[n];
break;
}
}
return s;
}
/* Return the previously-defined structure with tag NAME (or a union
@ -788,7 +835,7 @@ create_field_at (pair_p next, type_p type, const char *name, options_p opt,
/* 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__)
create_field_all(next,type,name, 0, this_file, __LINE__)
/* Like create_field, but the field is only valid when condition COND
is true. */
@ -814,11 +861,26 @@ create_optional_field_ (pair_p next, type_p type, const char *name,
tag that specifies the condition under which the field is valid. */
return create_field_all (next, union_type, name,
create_option (0, "desc", cond),
__FILE__, line);
this_file, line);
}
#define create_optional_field(next,type,name,cond) \
create_optional_field_(next,type,name,cond,__LINE__)
/* Reverse a linked list of 'struct pair's in place. */
pair_p
nreverse_pairs (pair_p list)
{
pair_p prev = 0, p, next;
for (p = list; p; p = next)
{
next = p->next;
p->next = prev;
prev = p;
}
return prev;
}
/* We don't care how long a CONST_DOUBLE is. */
#define CONST_DOUBLE_FORMAT "ww"
/* We don't want to see codes that are only for generator files. */
@ -3420,12 +3482,42 @@ note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
}
/* Yet more temporary kludge since gengtype doesn't understand conditionals.
This must be kept in sync with input.h. */
static void
define_location_structures (void)
{
pair_p fields;
type_p locs;
static struct fileloc pos = { this_file, __LINE__ };
do_scalar_typedef ("source_location", &pos);
#ifdef USE_MAPPED_LOCATION
fields = create_field (0, &scalar_nonchar, "column");
fields = create_field (fields, &scalar_nonchar, "line");
fields = create_field (fields, &string_type, "file");
locs = new_structure ("anon:expanded_location", 0, &pos, fields, 0);
do_typedef ("expanded_location", locs, &pos);
do_scalar_typedef ("location_t", &pos);
do_scalar_typedef ("source_locus", &pos);
#else
fields = create_field (0, &scalar_nonchar, "line");
fields = create_field (fields, &string_type, "file");
locs = new_structure ("location_s", 0, &pos, fields, 0);
do_typedef ("expanded_location", locs, &pos);
do_typedef ("location_t", locs, &pos);
do_typedef ("source_locus", create_pointer (locs), &pos);
#endif
}
int
main (int argc, char **argv)
{
size_t i;
static struct fileloc pos = { __FILE__, __LINE__ };
static struct fileloc pos = { this_file, 0 };
/* fatal uses this */
progname = "gengtype";
@ -3444,34 +3536,23 @@ main (int argc, char **argv)
scalar_nonchar.u.scalar_is_char = false;
gen_rtx_next ();
do_scalar_typedef ("CUMULATIVE_ARGS", &pos);
do_scalar_typedef ("REAL_VALUE_TYPE", &pos);
do_scalar_typedef ("double_int", &pos);
do_scalar_typedef ("uint8", &pos);
do_scalar_typedef ("jword", &pos);
do_scalar_typedef ("JCF_u2", &pos);
#ifdef USE_MAPPED_LOCATION
do_scalar_typedef ("location_t", &pos);
do_scalar_typedef ("source_locus", &pos);
#endif
do_scalar_typedef ("void", &pos);
/* These types are set up with #define or else outside of where
we can see them. */
pos.line = __LINE__ + 1;
do_scalar_typedef ("CUMULATIVE_ARGS", &pos); pos.line++;
do_scalar_typedef ("REAL_VALUE_TYPE", &pos); pos.line++;
do_scalar_typedef ("double_int", &pos); pos.line++;
do_scalar_typedef ("uint8", &pos); pos.line++;
do_scalar_typedef ("jword", &pos); pos.line++;
do_scalar_typedef ("JCF_u2", &pos); pos.line++;
do_scalar_typedef ("void", &pos); pos.line++;
do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
do_typedef ("HARD_REG_SET", create_array (&scalar_nonchar, "2"), &pos);
define_location_structures ();
for (i = 0; i < num_gt_files; i++)
{
parse_file (gt_files[i]);
#ifndef USE_MAPPED_LOCATION
/* temporary kludge - gengtype doesn't handle conditionals.
Manually add source_locus *after* we've processed input.h. */
if (i == 0)
do_typedef ("source_locus", create_pointer (resolve_typedef ("location_t", &pos)), &pos);
#endif
}
parse_file (gt_files[i]);
if (hit_error != 0)
if (hit_error)
return 1;
set_gc_used (variables);
@ -3485,5 +3566,7 @@ main (int argc, char **argv)
write_rtx_next ();
close_output_files ();
return (hit_error != 0);
if (hit_error)
return 1;
return 0;
}

View File

@ -41,6 +41,9 @@ extern struct fileloc lexer_line;
extern void error_at_line
(struct fileloc *pos, const char *msg, ...) ATTRIBUTE_PRINTF_2;
/* Like asprintf, but calls fatal() on out of memory. */
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);
@ -57,6 +60,7 @@ 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 pair_p nreverse_pairs (pair_p list);
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);
@ -65,10 +69,45 @@ extern void note_def_vec (const char *typename, bool is_scalar,
extern void note_def_vec_alloc (const char *type, const char *astrat,
struct fileloc *pos);
/* Lexer and parser routines, most automatically generated. */
extern int yylex (void);
extern void yyerror (const char *);
extern int yyparse (void);
/* Lexer and parser routines. */
extern int yylex (const char **yylval);
extern void yybegin (const char *fname);
extern void yyend (void);
extern void parse_file (const char *name);
extern bool hit_error;
/* Token codes. */
enum {
EOF_TOKEN = 0,
/* Per standard convention, codes in the range (0, UCHAR_MAX]
represent single characters with those character codes. */
CHAR_TOKEN_OFFSET = UCHAR_MAX + 1,
GTY_TOKEN = CHAR_TOKEN_OFFSET,
TYPEDEF,
EXTERN,
STATIC,
UNION,
STRUCT,
ENUM,
VEC_TOKEN,
DEFVEC_OP,
DEFVEC_I,
DEFVEC_ALLOC,
ELLIPSIS,
PTR_ALIAS,
NESTED_PTR,
PARAM_IS,
NUM,
SCALAR,
ID,
STRING,
CHAR,
ARRAY,
/* print_token assumes that any token >= FIRST_TOKEN_WITH_VALUE may have
a meaningful value to be printed. */
FIRST_TOKEN_WITH_VALUE = PARAM_IS
};
#endif

View File

@ -28,6 +28,9 @@ extern struct line_maps line_table;
/* The location for declarations in "<built-in>" */
#define BUILTINS_LOCATION ((source_location) 2)
/* Note: if any of the types defined inside this #ifdef are changed,
gengtype.c:define_location_structures must be updated to match. */
#ifdef USE_MAPPED_LOCATION
typedef struct