st.c 4.44 KB
Newer Older
1
/* Build executable statement trees.
2
   Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007
3
   Free Software Foundation, Inc.
4 5
   Contributed by Andy Vaught

6
This file is part of GCC.
7

8 9
GCC 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
10
Software Foundation; either version 3, or (at your option) any later
11
version.
12

13 14 15 16
GCC 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.
17 18

You should have received a copy of the GNU General Public License
19 20
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
21 22 23 24 25 26 27

/* 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"
28
#include "system.h"
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
#include "gfortran.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));
52
  c->loc = gfc_current_locus;
53 54 55 56 57 58 59 60
  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 *
61
gfc_append_code (gfc_code *tail, gfc_code *new)
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
{
  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
81
gfc_free_statement (gfc_code *p)
82 83 84 85 86 87 88 89 90 91
{
  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:
Paul Thomas committed
92
    case EXEC_INIT_ASSIGN:
93 94 95 96 97 98 99 100 101 102 103 104 105 106
    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:
107
    case EXEC_ENTRY:
108 109 110 111
    case EXEC_ARITHMETIC_IF:
      break;

    case EXEC_CALL:
112
    case EXEC_ASSIGN_CALL:
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
      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:
Janne Blomqvist committed
141
    case EXEC_FLUSH:
142 143 144 145 146 147 148 149 150 151 152 153 154 155
      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
156
	 be freed.  */
157 158 159 160 161 162
      break;

    case EXEC_FORALL:
      gfc_free_forall_iterator (p->ext.forall_iterator);
      break;

163 164 165 166 167 168 169 170 171 172 173 174 175
    case EXEC_OMP_DO:
    case EXEC_OMP_END_SINGLE:
    case EXEC_OMP_PARALLEL:
    case EXEC_OMP_PARALLEL_DO:
    case EXEC_OMP_PARALLEL_SECTIONS:
    case EXEC_OMP_SECTIONS:
    case EXEC_OMP_SINGLE:
    case EXEC_OMP_WORKSHARE:
    case EXEC_OMP_PARALLEL_WORKSHARE:
      gfc_free_omp_clauses (p->ext.omp_clauses);
      break;

    case EXEC_OMP_CRITICAL:
176
      gfc_free (CONST_CAST (char *, p->ext.omp_name));
177 178 179 180 181 182 183 184 185 186 187 188 189
      break;

    case EXEC_OMP_FLUSH:
      gfc_free_namelist (p->ext.omp_namelist);
      break;

    case EXEC_OMP_ATOMIC:
    case EXEC_OMP_BARRIER:
    case EXEC_OMP_MASTER:
    case EXEC_OMP_ORDERED:
    case EXEC_OMP_END_NOWAIT:
      break;

190 191 192 193 194 195 196 197 198
    default:
      gfc_internal_error ("gfc_free_statement(): Bad statement");
    }
}


/* Free a code statement and all other code structures linked to it.  */

void
199
gfc_free_statements (gfc_code *p)
200 201 202 203 204 205 206 207 208 209 210 211 212 213
{
  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);
    }
}