summaryrefslogtreecommitdiff
path: root/gcc/fortran/symbol.c
diff options
context:
space:
mode:
authortobi <tobi@138bc75d-0d04-0410-961f-82ee72b054a4>2006-01-18 20:54:49 +0000
committertobi <tobi@138bc75d-0d04-0410-961f-82ee72b054a4>2006-01-18 20:54:49 +0000
commit3bd3b616e3dc0dc23dca4e150e42436ee55a997d (patch)
treed82509409506532bc64cf462617e77ad272677ad /gcc/fortran/symbol.c
parent125523c3bcb5651da42c549603917d063496b248 (diff)
downloadgcc-3bd3b616e3dc0dc23dca4e150e42436ee55a997d.tar.gz
PR fortran/18540
PR fortran/18937 * gfortran.h (BBT_HEADER): Move definition up. (gfc_st_label): Add BBT_HEADER, remove 'prev' and 'next'. * io.c (format_asterisk): Adapt initializer. * resolve.c (resolve_branch): Allow FORTRAN 66 cross-block GOTOs as extension. * symbol.c (compare_st_labels): New function. (gfc_free_st_label, free_st_labels, gfc_get_st_label): Convert to using balanced binary tree. * decl.c (match_char_length, gfc_match_old_kind_spec): Do away with 'cnt'. (warn_unused_label): Adapt to binary tree. * match.c (gfc_match_small_literal_int): Only set cnt if non-NULL. * primary.c (match_kind_param): Do away with cnt. Also converted the ChangeLog to use latin1 characters. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109914 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/symbol.c')
-rw-r--r--gcc/fortran/symbol.c71
1 files changed, 39 insertions, 32 deletions
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index c3e15f2d1dd..c4d2cf02649 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -1,6 +1,6 @@
/* Maintain binary trees of symbols.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation,
- Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
+ Foundation, Inc.
Contributed by Andy Vaught
This file is part of GCC.
@@ -1487,25 +1487,30 @@ gfc_get_component_attr (symbol_attribute * attr, gfc_component * c)
/******************** Statement label management ********************/
-/* Free a single gfc_st_label structure, making sure the list is not
+/* Comparison function for statement labels, used for managing the
+ binary tree. */
+
+static int
+compare_st_labels (void * a1, void * b1)
+{
+ int a = ((gfc_st_label *)a1)->value;
+ int b = ((gfc_st_label *)b1)->value;
+
+ return (b - a);
+}
+
+
+/* Free a single gfc_st_label structure, making sure the tree is not
messed up. This function is called only when some parse error
occurs. */
void
gfc_free_st_label (gfc_st_label * label)
{
-
if (label == NULL)
return;
- if (label->prev)
- label->prev->next = label->next;
-
- if (label->next)
- label->next->prev = label->prev;
-
- if (gfc_current_ns->st_labels == label)
- gfc_current_ns->st_labels = label->next;
+ gfc_delete_bbt (&gfc_current_ns->st_labels, label, compare_st_labels);
if (label->format != NULL)
gfc_free_expr (label->format);
@@ -1513,20 +1518,20 @@ gfc_free_st_label (gfc_st_label * label)
gfc_free (label);
}
-/* Free a whole list of gfc_st_label structures. */
+/* Free a whole tree of gfc_st_label structures. */
static void
-free_st_labels (gfc_st_label * l1)
+free_st_labels (gfc_st_label * label)
{
- gfc_st_label *l2;
+ if (label == NULL)
+ return;
- for (; l1; l1 = l2)
- {
- l2 = l1->next;
- if (l1->format != NULL)
- gfc_free_expr (l1->format);
- gfc_free (l1);
- }
+ free_st_labels (label->left);
+ free_st_labels (label->right);
+
+ if (label->format != NULL)
+ gfc_free_expr (label->format);
+ gfc_free (label);
}
@@ -1539,11 +1544,17 @@ gfc_get_st_label (int labelno)
gfc_st_label *lp;
/* First see if the label is already in this namespace. */
- for (lp = gfc_current_ns->st_labels; lp; lp = lp->next)
- if (lp->value == labelno)
- break;
- if (lp != NULL)
- return lp;
+ lp = gfc_current_ns->st_labels;
+ while (lp)
+ {
+ if (lp->value == labelno)
+ return lp;
+
+ if (lp->value < labelno)
+ lp = lp->left;
+ else
+ lp = lp->right;
+ }
lp = gfc_getmem (sizeof (gfc_st_label));
@@ -1551,11 +1562,7 @@ gfc_get_st_label (int labelno)
lp->defined = ST_LABEL_UNKNOWN;
lp->referenced = ST_LABEL_UNKNOWN;
- lp->prev = NULL;
- lp->next = gfc_current_ns->st_labels;
- if (gfc_current_ns->st_labels)
- gfc_current_ns->st_labels->prev = lp;
- gfc_current_ns->st_labels = lp;
+ gfc_insert_bbt (&gfc_current_ns->st_labels, lp, compare_st_labels);
return lp;
}