]> git.saurik.com Git - bison.git/blobdiff - src/symtab.c
maint: post-release administrivia
[bison.git] / src / symtab.c
index d3ad2fbbdfc4babffcde095f12ba5e78459cc894..fb025da75367818d6dbe1f647f8e270c2814b755 100644 (file)
@@ -1,6 +1,6 @@
 /* Symbol table manager for Bison.
 
-   Copyright (C) 1984, 1989, 2000-2002, 2004-2013 Free Software
+   Copyright (C) 1984, 1989, 2000-2002, 2004-2015 Free Software
    Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
@@ -100,6 +100,41 @@ symbol_new (uniqstr tag, location loc)
   return res;
 }
 
+/* If needed, swap first and second so that first has the earliest
+   location (according to location_cmp).
+
+   Many symbol features (e.g., user token numbers) are not assigned
+   during the parsing, but in a second step, via a traversal of the
+   symbol table sorted on tag.
+
+   However, error messages make more sense if we keep the first
+   declaration first.
+*/
+
+static
+void symbols_sort (symbol **first, symbol **second)
+{
+  if (0 < location_cmp ((*first)->location, (*second)->location))
+    {
+      symbol* tmp = *first;
+      *first = *second;
+      *second = tmp;
+    }
+}
+
+/* Likewise, for locations.  */
+
+static
+void locations_sort (location *first, location *second)
+{
+  if (0 < location_cmp (*first, *second))
+    {
+      location tmp = *first;
+      *first = *second;
+      *second = tmp;
+    }
+}
+
 char const *
 code_props_type_string (code_props_type kind)
 {
@@ -110,7 +145,7 @@ code_props_type_string (code_props_type kind)
     case printer:
       return "%printer";
     }
-  assert (0);
+  abort ();
 }
 
 /*----------------------------------------.
@@ -153,13 +188,13 @@ symbol_print (symbol const *s, FILE *f)
 {
   if (s)
     {
-      fprintf (f, "\"%s\"", s->tag);
+      fputs (s->tag, f);
       SYMBOL_ATTR_PRINT (type_name);
       SYMBOL_CODE_PRINT (destructor);
       SYMBOL_CODE_PRINT (printer);
     }
   else
-    fprintf (f, "<NULL>");
+    fputs ("<NULL>", f);
 }
 
 #undef SYMBOL_ATTR_PRINT
@@ -210,6 +245,7 @@ symbol_redeclaration (symbol *s, const char *what, location first,
                       location second)
 {
   unsigned i = 0;
+  locations_sort (&first, &second);
   complain_indent (&second, complaint, &i,
                    _("%s redeclaration for %s"), what, s->tag);
   i += SUB_INDENT;
@@ -222,6 +258,7 @@ semantic_type_redeclaration (semantic_type *s, const char *what, location first,
                              location second)
 {
   unsigned i = 0;
+  locations_sort (&first, &second);
   complain_indent (&second, complaint, &i,
                    _("%s redeclaration for <%s>"), what, s->tag);
   i += SUB_INDENT;
@@ -243,9 +280,12 @@ symbol_type_set (symbol *sym, uniqstr type_name, location loc)
     {
       if (sym->type_name)
         symbol_redeclaration (sym, "%type", sym->type_location, loc);
-      uniqstr_assert (type_name);
-      sym->type_name = type_name;
-      sym->type_location = loc;
+      else
+        {
+          uniqstr_assert (type_name);
+          sym->type_name = type_name;
+          sym->type_location = loc;
+        }
     }
 }
 
@@ -261,7 +301,8 @@ symbol_code_props_set (symbol *sym, code_props_type kind,
     symbol_redeclaration (sym, code_props_type_string (kind),
                           sym->props[kind].location,
                           code->location);
-  sym->props[kind] = *code;
+  else
+    sym->props[kind] = *code;
 }
 
 /*-----------------------------------------------------.
@@ -277,7 +318,8 @@ semantic_type_code_props_set (semantic_type *type,
     semantic_type_redeclaration (type, code_props_type_string (kind),
                                  type->props[kind].location,
                                  code->location);
-  type->props[kind] = *code;
+  else
+    type->props[kind] = *code;
 }
 
 /*---------------------------------------------------.
@@ -321,12 +363,15 @@ symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
 {
   if (a != undef_assoc)
     {
-      if (sym->prec != 0)
+      if (sym->prec)
         symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
                               loc);
-      sym->prec = prec;
-      sym->assoc = a;
-      sym->prec_location = loc;
+      else
+        {
+          sym->prec = prec;
+          sym->assoc = a;
+          sym->prec_location = loc;
+        }
     }
 
   /* Only terminals have a precedence. */
@@ -360,7 +405,8 @@ symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
     {
       if (sym->status == declared && !warned)
         complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
-      sym->status = declared;
+      else
+        sym->status = declared;
     }
 }
 
@@ -441,7 +487,7 @@ semantic_type_check_defined (semantic_type *sem_type)
   /* <*> and <> do not have to be "declared".  */
   if (sem_type->status == declared
       || !*sem_type->tag
-      || STREQ(sem_type->tag, "*"))
+      || STREQ (sem_type->tag, "*"))
     {
       int i;
       for (i = 0; i < 2; ++i)
@@ -578,17 +624,7 @@ static void
 user_token_number_redeclaration (int num, symbol *first, symbol *second)
 {
   unsigned i = 0;
-  /* User token numbers are not assigned during the parsing, but in a
-     second step, via a traversal of the symbol table sorted on tag.
-
-     However, error messages make more sense if we keep the first
-     declaration first.  */
-  if (location_cmp (first->location, second->location) > 0)
-    {
-      symbol* tmp = first;
-      first = second;
-      second = tmp;
-    }
+  symbols_sort (&first, &second);
   complain_indent (&second->location, complaint, &i,
                    _("user token number %d redeclaration for %s"),
                    num, second->tag);
@@ -615,8 +651,8 @@ symbol_translation (symbol *this)
           (this->user_token_number,
            symbols[token_translations[this->user_token_number]],
            this);
-
-      token_translations[this->user_token_number] = this->number;
+      else
+        token_translations[this->user_token_number] = this->number;
     }
 
   return true;
@@ -1057,6 +1093,42 @@ register_precedence (graphid first, graphid snd)
 }
 
 
+/*---------------------------------------.
+| Deep clear a linked / adjacency list). |
+`---------------------------------------*/
+
+static void
+linkedlist_free (symgraphlink *node)
+{
+  if (node)
+    {
+      while (node->next)
+        {
+          symgraphlink *tmp = node->next;
+          free (node);
+          node = tmp;
+        }
+      free (node);
+    }
+}
+
+/*----------------------------------------------.
+| Clear and destroy association tracking table. |
+`----------------------------------------------*/
+
+static void
+assoc_free (void)
+{
+  int i;
+  for (i = 0; i < nsyms; ++i)
+    {
+      linkedlist_free (prec_nodes[i]->pred);
+      linkedlist_free (prec_nodes[i]->succ);
+      free (prec_nodes[i]);
+    }
+  free (prec_nodes);
+}
+
 /*---------------------------------------.
 | Initialize association tracking table. |
 `---------------------------------------*/
@@ -1065,7 +1137,7 @@ static void
 init_assoc (void)
 {
   graphid i;
-  used_assoc = xcalloc(nsyms, sizeof(*used_assoc));
+  used_assoc = xcalloc (nsyms, sizeof *used_assoc);
   for (i = 0; i < nsyms; ++i)
     used_assoc[i] = false;
 }
@@ -1117,14 +1189,16 @@ print_precedence_warnings (void)
           && !prec_nodes[i]->succ)
         {
           if (is_assoc_useless (s))
-            complain (&s->location, Wprecedence,
+            complain (&s->prec_location, Wprecedence,
                       _("useless precedence and associativity for %s"), s->tag);
           else if (s->assoc == precedence_assoc)
-            complain (&s->location, Wprecedence,
+            complain (&s->prec_location, Wprecedence,
                       _("useless precedence for %s"), s->tag);
         }
       else if (is_assoc_useless (s))
-        complain (&s->location, Wprecedence,
+        complain (&s->prec_location, Wprecedence,
                   _("useless associativity for %s, use %%precedence"), s->tag);
     }
+  free (used_assoc);
+  assoc_free ();
 }