summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Weinberg <zackw@panix.com>2007-03-26 21:18:43 +0000
committerZack Weinberg <zack@gcc.gnu.org>2007-03-26 21:18:43 +0000
commit01d419aec11b9ffbdfae60e78795faea19086e10 (patch)
tree92672610b9effb039afa4b4273d36d385aff54d8
parent11a675992afb01354e8d8331087177c25e97a7a6 (diff)
downloadgcc-01d419aec11b9ffbdfae60e78795faea19086e10.tar.gz
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
-rw-r--r--gcc/ChangeLog32
-rw-r--r--gcc/Makefile.in19
-rw-r--r--gcc/bitmap.h23
-rw-r--r--gcc/doc/install.texi28
-rw-r--r--gcc/gengtype-lex.l284
-rw-r--r--gcc/gengtype.c159
-rw-r--r--gcc/gengtype.h47
-rw-r--r--gcc/input.h3
8 files changed, 297 insertions, 298 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 05c173677a0..0dc2ec55301 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 2236f3bfd4c..4c351908270 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -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.
diff --git a/gcc/bitmap.h b/gcc/bitmap.h
index 515527c08e8..9a33646ccb1 100644
--- a/gcc/bitmap.h
+++ b/gcc/bitmap.h
@@ -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 */
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 76545c08996..fa17564574c 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -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
diff --git a/gcc/gengtype-lex.l b/gcc/gengtype-lex.l
index baf09bcd5fe..2d003e0c5fa 100644
--- a/gcc/gengtype-lex.l
+++ b/gcc/gengtype-lex.l
@@ -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);
+ /* Things we look for in skipping mode: */
+<INITIAL>{
+^typedef/{EOID} {
+ BEGIN(in_struct);
+ return TYPEDEF;
}
-
-[^[: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);
+^struct/{EOID} {
+ BEGIN(in_struct);
+ return STRUCT;
}
-
-[^[: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);
+^union/{EOID} {
+ BEGIN(in_struct);
+ return UNION;
}
-
-[^[: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);
+^extern/{EOID} {
+ BEGIN(in_struct);
+ return EXTERN;
}
-
-[^[: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);
-
+^static/{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 STATIC;
}
-[^[:alnum:]_](extern|static){WS}/"GTY" {
+^DEF_VEC_[OP]/{EOID} {
BEGIN(in_struct);
- update_lineno (yytext, yyleng);
- return ENT_EXTERNSTATIC;
+ return DEFVEC_OP;
}
-
-^"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_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]; }
-
-[;=] {
- if (lexer_toplevel_done)
- {
- BEGIN(INITIAL);
- lexer_toplevel_done = 0;
- }
- return yytext[0];
-}
+"..." { return ELLIPSIS; }
+[(){},*:<>;=%|-] { 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);
}
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index ce34d0016f6..e0cd6c2599f 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -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;
}
diff --git a/gcc/gengtype.h b/gcc/gengtype.h
index 345d80d9022..a23e2778e93 100644
--- a/gcc/gengtype.h
+++ b/gcc/gengtype.h
@@ -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
diff --git a/gcc/input.h b/gcc/input.h
index 2fea1a65c9b..efdfbd33854 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -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