summaryrefslogtreecommitdiff
path: root/gcc/fortran/st.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/st.c')
-rw-r--r--gcc/fortran/st.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/gcc/fortran/st.c b/gcc/fortran/st.c
new file mode 100644
index 00000000000..c4f4533e94f
--- /dev/null
+++ b/gcc/fortran/st.c
@@ -0,0 +1,186 @@
+/* Build executable statement trees.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Andy Vaught
+
+This file is part of GNU G95.
+
+GNU G95 is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU G95 is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU G95; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Executable statements are strung together into a singly linked list
+ of code structures. These structures are later translated into GCC
+ GENERIC tree structures and from there to executable code for a
+ target. */
+
+#include "config.h"
+#include "gfortran.h"
+#include <string.h>
+
+gfc_code new_st;
+
+
+/* Zeroes out the new_st structure. */
+
+void
+gfc_clear_new_st (void)
+{
+
+ memset (&new_st, '\0', sizeof (new_st));
+ new_st.op = EXEC_NOP;
+}
+
+
+/* Get a gfc_code structure. */
+
+gfc_code *
+gfc_get_code (void)
+{
+ gfc_code *c;
+
+ c = gfc_getmem (sizeof (gfc_code));
+ c->loc = *gfc_current_locus ();
+ return c;
+}
+
+
+/* Given some part of a gfc_code structure, append a set of code to
+ its tail, returning a pointer to the new tail. */
+
+gfc_code *
+gfc_append_code (gfc_code * tail, gfc_code * new)
+{
+
+ if (tail != NULL)
+ {
+ while (tail->next != NULL)
+ tail = tail->next;
+
+ tail->next = new;
+ }
+
+ while (new->next != NULL)
+ new = new->next;
+
+ return new;
+}
+
+
+/* Free a single code structure, but not the actual structure itself. */
+
+void
+gfc_free_statement (gfc_code * p)
+{
+
+ if (p->expr)
+ gfc_free_expr (p->expr);
+ if (p->expr2)
+ gfc_free_expr (p->expr2);
+
+ switch (p->op)
+ {
+ case EXEC_NOP:
+ case EXEC_ASSIGN:
+ case EXEC_GOTO:
+ case EXEC_CYCLE:
+ case EXEC_RETURN:
+ case EXEC_IF:
+ case EXEC_PAUSE:
+ case EXEC_STOP:
+ case EXEC_EXIT:
+ case EXEC_WHERE:
+ case EXEC_IOLENGTH:
+ case EXEC_POINTER_ASSIGN:
+ case EXEC_DO_WHILE:
+ case EXEC_CONTINUE:
+ case EXEC_TRANSFER:
+ case EXEC_LABEL_ASSIGN:
+
+ case EXEC_ARITHMETIC_IF:
+ break;
+
+ case EXEC_CALL:
+ gfc_free_actual_arglist (p->ext.actual);
+ break;
+
+ case EXEC_SELECT:
+ if (p->ext.case_list)
+ gfc_free_case_list (p->ext.case_list);
+ break;
+
+ case EXEC_DO:
+ gfc_free_iterator (p->ext.iterator, 1);
+ break;
+
+ case EXEC_ALLOCATE:
+ case EXEC_DEALLOCATE:
+ gfc_free_alloc_list (p->ext.alloc_list);
+ break;
+
+ case EXEC_OPEN:
+ gfc_free_open (p->ext.open);
+ break;
+
+ case EXEC_CLOSE:
+ gfc_free_close (p->ext.close);
+ break;
+
+ case EXEC_BACKSPACE:
+ case EXEC_ENDFILE:
+ case EXEC_REWIND:
+ gfc_free_filepos (p->ext.filepos);
+ break;
+
+ case EXEC_INQUIRE:
+ gfc_free_inquire (p->ext.inquire);
+ break;
+
+ case EXEC_READ:
+ case EXEC_WRITE:
+ gfc_free_dt (p->ext.dt);
+ break;
+
+ case EXEC_DT_END:
+ /* The ext.dt member is a duplicate pointer and doesn't need to
+ be freed. */
+ break;
+
+ case EXEC_FORALL:
+ gfc_free_forall_iterator (p->ext.forall_iterator);
+ break;
+
+ default:
+ gfc_internal_error ("gfc_free_statement(): Bad statement");
+ }
+}
+
+
+/* Free a code statement and all other code structures linked to it. */
+
+void
+gfc_free_statements (gfc_code * p)
+{
+ gfc_code *q;
+
+ for (; p; p = q)
+ {
+ q = p->next;
+
+ if (p->block)
+ gfc_free_statements (p->block);
+ gfc_free_statement (p);
+ gfc_free (p);
+ }
+}
+