]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gengtype-parse.c: New file.
authorZack Weinberg <zackw@panix.com>
Mon, 26 Mar 2007 21:18:43 +0000 (21:18 +0000)
committerZack Weinberg <zack@gcc.gnu.org>
Mon, 26 Mar 2007 21:18:43 +0000 (21:18 +0000)
* 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

gcc/ChangeLog
gcc/Makefile.in
gcc/bitmap.h
gcc/doc/install.texi
gcc/gengtype-lex.l
gcc/gengtype.c
gcc/gengtype.h
gcc/input.h

index 05c173677a08022562bae6aa8d6786dd28c3a18a..0dc2ec553018a01a827680111ff033acf5805423 100644 (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.
index 2236f3bfd4c4efc0abf88098deed3a74b005bb54..4c351908270c8fce7473fc912902d967441a5556 100644 (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) $<
 
 #\f
 # Remake internationalization support.
index 515527c08e8fcd0e7d3d96e1513f4bd000c546f1..9a33646ccb1156f62d38f3e7cac63bdc1b92e7d3 100644 (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 */
index 76545c08996fbf5b1031439f87366c3be969e800..fa17564574c58c2663bbf016c935eb30940e807f 100644 (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
index baf09bcd5fe038d09b0a23c7933928eefcc9d4d3..2d003e0c5fa7d12793076f6c192ce1de07b334ce 100644 (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);
+  /* 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);
 }
index ce34d0016f6a2e57dd93a09253385380001ff2a8..e0cd6c2599fd6fe246c3a8d9924d9e87e31be134 100644 (file)
@@ -155,7 +155,7 @@ static const char * get_file_basename (const char *);
 
 \f
 /* 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;
+}
+
+\f
 /* 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
+}
+
 \f
 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;
 }
index 345d80d9022c3cb942dda2259fc705063cbb8ec0..a23e2778e93563222e15a0eda6f510817e318887 100644 (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
index 2fea1a65c9b488cb4ed2c019c4a0c31dce72401a..efdfbd33854bcd50ef10ad9aab086332acd45471 100644 (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