+void
+semantic_type_code_props_set (semantic_type *type,
+ code_props_type kind,
+ code_props const *code)
+{
+ if (type->props[kind].code)
+ semantic_type_redeclaration (type, code_props_type_string (kind),
+ type->props[kind].location,
+ code->location);
+ type->props[kind] = *code;
+}
+
+/*---------------------------------------------------.
+| Get the computed %destructor or %printer for SYM. |
+`---------------------------------------------------*/
+
+code_props *
+symbol_code_props_get (symbol *sym, code_props_type kind)
+{
+ /* Per-symbol code props. */
+ if (sym->props[kind].code)
+ return &sym->props[kind];
+
+ /* Per-type code props. */
+ if (sym->type_name)
+ {
+ code_props *code =
+ &semantic_type_get (sym->type_name, NULL)->props[kind];
+ if (code->code)
+ return code;
+ }
+
+ /* Apply default code props's only to user-defined symbols. */
+ if (sym->tag[0] != '$' && sym != errtoken)
+ {
+ code_props *code =
+ &semantic_type_get (sym->type_name ? "*" : "", NULL)->props[kind];
+ if (code->code)
+ return code;
+ }
+ return &code_props_none;
+}
+
+/*-----------------------------------------------------------------.
+| Set the PRECEDENCE associated with SYM. Does nothing if invoked |
+| with UNDEF_ASSOC as ASSOC. |
+`-----------------------------------------------------------------*/
+
+void
+symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
+{
+ if (a != undef_assoc)
+ {
+ if (sym->prec != 0)
+ symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
+ loc);
+ sym->prec = prec;
+ sym->assoc = a;
+ sym->prec_location = loc;
+ }
+
+ /* Only terminals have a precedence. */
+ symbol_class_set (sym, token_sym, loc, false);
+}
+
+
+/*------------------------------------.
+| Set the CLASS associated with SYM. |
+`------------------------------------*/
+
+void
+symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
+{
+ bool warned = false;
+ if (sym->class != unknown_sym && sym->class != class)
+ {
+ complain (&loc, complaint, _("symbol %s redefined"), sym->tag);
+ /* Don't report both "redefined" and "redeclared". */
+ warned = true;
+ }
+
+ if (class == nterm_sym && sym->class != nterm_sym)
+ sym->number = nvars++;
+ else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
+ sym->number = ntokens++;
+
+ sym->class = class;
+
+ if (declaring)
+ {
+ if (sym->status == declared && !warned)
+ complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
+ sym->status = declared;
+ }
+}
+
+
+/*------------------------------------------------.
+| Set the USER_TOKEN_NUMBER associated with SYM. |
+`------------------------------------------------*/