X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/cc2235ace2d91338663caeec288743092a6b3aeb..7ca7a3abf3947fc419cbd63de344c2da739adad0:/src/symtab.c diff --git a/src/symtab.c b/src/symtab.c index d3ad2fbb..fb025da7 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -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, ""); + fputs ("", 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 (); }