]> git.saurik.com Git - bison.git/commitdiff
Don't miss %merge result type warnings just because the LHS types are
authorJoel E. Denny <jdenny@ces.clemson.edu>
Mon, 26 Jun 2006 04:45:24 +0000 (04:45 +0000)
committerJoel E. Denny <jdenny@ces.clemson.edu>
Mon, 26 Jun 2006 04:45:24 +0000 (04:45 +0000)
declared after the %merge.
* src/reader.c (get_merge_function): Don't set the merger type yet.
(record_merge_function_type): New function for setting the merger type
and checking for clashes.
(grammar_current_rule_merge_set): Set the location of the %merge for
the current rule.
(packgram): Invoke record_merge_function_type for each rule now that
all symbol type declarations have been parsed.
* src/reader.h (merger_list.type_declaration_location): New member
storing the location of the first %merge from which the type for this
merging function was derived.
* src/symlist.h (symbol_list.merger_declaration_location): New member
storing the location of a rule's %merge, if any.
* tests/glr-regression.at (Missed %merge type warnings when LHS type is
declared later): New test to catch the error fixed by the above patch.

ChangeLog
src/reader.c
src/reader.h
src/symlist.h
tests/glr-regression.at

index 3abf8f82b32e2210324b64eb7cbe182c25652a62..3b1fc915ac6b173a95b82540e674bd632642f4bd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2006-06-26  Joel E. Denny  <jdenny@ces.clemson.edu>
+
+       Don't miss %merge result type warnings just because the LHS types are
+       declared after the %merge.
+       * src/reader.c (get_merge_function): Don't set the merger type yet.
+       (record_merge_function_type): New function for setting the merger type
+       and checking for clashes.
+       (grammar_current_rule_merge_set): Set the location of the %merge for
+       the current rule.
+       (packgram): Invoke record_merge_function_type for each rule now that
+       all symbol type declarations have been parsed.
+       * src/reader.h (merger_list.type_declaration_location): New member
+       storing the location of the first %merge from which the type for this
+       merging function was derived.
+       * src/symlist.h (symbol_list.merger_declaration_location): New member
+       storing the location of a rule's %merge, if any.
+       * tests/glr-regression.at (Missed %merge type warnings when LHS type is
+       declared later): New test to catch the error fixed by the above patch.
+
 2006-06-26  Joel E. Denny  <jdenny@ces.clemson.edu>
 
        Get action warnings (grammar_rule_check) right even when symbol
index 54d21c4eb476d0bb763d034df041524adc485671..31bd536dad16fc8f7b68a6dba5d99b96f9f01b0a 100644 (file)
@@ -90,14 +90,13 @@ prologue_augment (const char *prologue, location loc, bool post)
 
 \f
 
-/*-------------------------------------------------------------------.
-| Return the merger index for a merging function named NAME, whose   |
-| arguments have type TYPE.  Records the function, if new, in        |
-| MERGER_LIST.                                                      |
-`-------------------------------------------------------------------*/
+/*------------------------------------------------------------------------.
+| Return the merger index for a merging function named NAME.  Records the |
+| function, if new, in MERGER_LIST.                                       |
+`------------------------------------------------------------------------*/
 
 static int
-get_merge_function (uniqstr name, uniqstr type, location loc)
+get_merge_function (uniqstr name)
 {
   merger_list *syms;
   merger_list head;
@@ -106,9 +105,6 @@ get_merge_function (uniqstr name, uniqstr type, location loc)
   if (! glr_parser)
     return 0;
 
-  if (type == NULL)
-    type = uniqstr_new ("");
-
   head.next = merge_functions;
   for (syms = &head, n = 1; syms->next; syms = syms->next, n += 1)
     if (UNIQSTR_EQ (name, syms->next->name))
@@ -117,16 +113,54 @@ get_merge_function (uniqstr name, uniqstr type, location loc)
     {
       syms->next = xmalloc (sizeof syms->next[0]);
       syms->next->name = uniqstr_new (name);
-      syms->next->type = uniqstr_new (type);
+      /* After all symbol type declarations have been parsed, packgram invokes
+        record_merge_function_type to set the type.  */
+      syms->next->type = NULL;
       syms->next->next = NULL;
       merge_functions = head.next;
     }
-  else if (!UNIQSTR_EQ (type, syms->next->type))
-    warn_at (loc, _("result type clash on merge function %s: <%s> != <%s>"),
-            name, type, syms->next->type);
   return n;
 }
 
+/*-------------------------------------------------------------------------.
+| For the existing merging function with index MERGER, record the result   |
+| type as TYPE as required by the lhs of the rule whose %merge declaration |
+| is at DECLARATION_LOC.                                                   |
+`-------------------------------------------------------------------------*/
+
+static void
+record_merge_function_type (int merger, uniqstr type, location declaration_loc)
+{
+  int merger_find;
+  merger_list *merge_function;
+
+  if (merger <= 0)
+    return;
+
+  if (type == NULL)
+    type = uniqstr_new ("");
+
+  merger_find = 1;
+  for (merge_function = merge_functions;
+       merge_function != NULL && merger_find != merger;
+       merge_function = merge_function->next)
+    merger_find += 1;
+  assert (merge_function != NULL && merger_find == merger);
+  if (merge_function->type == NULL)
+    {
+      merge_function->type = uniqstr_new (type);
+      merge_function->type_declaration_location = declaration_loc;
+    }
+  else if (!UNIQSTR_EQ (merge_function->type, type))
+    {
+      warn_at (declaration_loc,
+              _("result type clash on merge function `%s': <%s> != <%s>"),
+              merge_function->name, type, merge_function->type);
+      warn_at (merge_function->type_declaration_location,
+              _("first declaration"));
+    }
+}
+
 /*--------------------------------------.
 | Free all merge-function definitions. |
 `--------------------------------------*/
@@ -382,8 +416,8 @@ grammar_current_rule_merge_set (uniqstr name, location loc)
     warn_at (loc, _("%s affects only GLR parsers"), "%merge");
   if (current_rule->merger != 0)
     complain_at (loc, _("only one %s allowed per rule"), "%merge");
-  current_rule->merger =
-    get_merge_function (name, current_rule->sym->type_name, loc);
+  current_rule->merger = get_merge_function (name);
+  current_rule->merger_declaration_location = loc;
 }
 
 /* Attach SYM to the current rule.  If needed, move the previous
@@ -434,6 +468,8 @@ packgram (void)
     {
       int rule_length = 0;
       symbol *ruleprec = p->ruleprec;
+      record_merge_function_type (p->merger, p->sym->type_name,
+                                 p->merger_declaration_location);
       rules[ruleno].user_number = ruleno;
       rules[ruleno].number = ruleno;
       rules[ruleno].lhs = p->sym;
index 7b2cbac6883eae9a8930897342dfadc9f3d1cbe3..52c059c4ab162963eb7beff39f88f19090f4e127 100644 (file)
@@ -33,6 +33,7 @@ typedef struct merger_list
   struct merger_list* next;
   uniqstr name;
   uniqstr type;
+  location type_declaration_location;
 } merger_list;
 
 /* From the parser.  */
index 2b901999d814748514a69375fc28ccb20d91b326..a2272608c1b90e4dfb231e96da2ba1674a333dce 100644 (file)
@@ -54,6 +54,7 @@ typedef struct symbol_list
   symbol *ruleprec;
   int dprec;
   int merger;
+  location merger_declaration_location;
 
   /* The list.  */
   struct symbol_list *next;
index 598ab8e8e80ad2890d1ddc0a9a85f497f0fab615..b4f650046100ad34cacc01b94749ed76fcdb4808 100644 (file)
@@ -1661,3 +1661,58 @@ AT_CHECK([[./glr-regr17]], 0, [],
 ])
 
 AT_CLEANUP
+
+
+## -------------------------------------------------------------##
+## Missed %merge type warnings when LHS type is declared later. ##
+## -------------------------------------------------------------##
+
+AT_SETUP([Missed %merge type warnings when LHS type is declared later])
+AT_DATA_GRAMMAR([glr-regr18.y],
+[[%glr-parser
+
+%{
+  static void yyerror (char const *);
+  static int yylex ();
+%}
+
+%union {
+  int type1;
+  int type2;
+}
+
+%%
+
+sym1: sym2 %merge<merge> { $$ = $1; } ;
+sym2: %merge<merge> { $$ = 0; } ;
+
+%type <type1> sym1;
+%type <type2> sym2;
+
+%%
+
+static void
+yyerror (char const *msg)
+{
+  fprintf (stderr, "%s\n", msg);
+}
+
+static int
+yylex ()
+{
+  return 0;
+}
+
+int
+main (void)
+{
+  return yyparse ();
+}
+]])
+
+AT_CHECK([[bison -o glr-regr18.c glr-regr18.y]], 0, [],
+[glr-regr18.y:26.13-19: warning: result type clash on merge function `merge': <type2> != <type1>
+glr-regr18.y:25.18-24: warning: first declaration
+])
+
+AT_CLEANUP