aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/symbol.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/symbol.c')
-rw-r--r--gcc/fortran/symbol.c67
1 files changed, 51 insertions, 16 deletions
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 9a28df6..33af725 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -1345,7 +1345,7 @@ switch_types (gfc_symtree * st, gfc_symbol * from, gfc_symbol * to)
gfc_symbol *
gfc_use_derived (gfc_symbol * sym)
{
- gfc_symbol *s, *p;
+ gfc_symbol *s;
gfc_typespec *t;
gfc_symtree *st;
int i;
@@ -1379,15 +1379,7 @@ gfc_use_derived (gfc_symbol * sym)
s->refs++;
/* Unlink from list of modified symbols. */
- if (changed_syms == sym)
- changed_syms = sym->tlink;
- else
- for (p = changed_syms; p; p = p->tlink)
- if (p->tlink == sym)
- {
- p->tlink = sym->tlink;
- break;
- }
+ gfc_commit_symbol (sym);
switch_types (sym->ns->sym_root, sym, s);
@@ -2238,6 +2230,26 @@ gfc_undo_symbols (void)
}
+/* Free sym->old_symbol. sym->old_symbol is mostly a shallow copy of sym; but
+ few components might have been given new values. */
+
+static void
+free_old_symbol (gfc_symbol * sym)
+{
+ if (sym->old_symbol == NULL)
+ return;
+
+ if (sym->old_symbol->as != sym->as)
+ gfc_free_array_spec (sym->old_symbol->as);
+
+ if (sym->old_symbol->value != sym->value)
+ gfc_free_expr (sym->old_symbol->value);
+
+ gfc_free (sym->old_symbol);
+ sym->old_symbol = NULL;
+}
+
+
/* Makes the changes made in the current statement permanent-- gets
rid of undo information. */
@@ -2253,17 +2265,40 @@ gfc_commit_symbols (void)
p->mark = 0;
p->new = 0;
- if (p->old_symbol != NULL)
- {
- gfc_free (p->old_symbol);
- p->old_symbol = NULL;
- }
+ free_old_symbol (p);
}
-
changed_syms = NULL;
}
+/* Makes the changes made in one symbol permanent -- gets rid of undo
+ information. */
+
+void
+gfc_commit_symbol (gfc_symbol * sym)
+{
+ gfc_symbol *p;
+
+ if (changed_syms == sym)
+ changed_syms = sym->tlink;
+ else
+ {
+ for (p = changed_syms; p; p = p->tlink)
+ if (p->tlink == sym)
+ {
+ p->tlink = sym->tlink;
+ break;
+ }
+ }
+
+ sym->tlink = NULL;
+ sym->mark = 0;
+ sym->new = 0;
+
+ free_old_symbol (sym);
+}
+
+
/* Recursive function that deletes an entire tree and all the common
head structures it points to. */