st.c 7.3 KB
Newer Older
1
/* Build executable statement trees.
2
   Copyright (C) 2000-2019 Free Software Foundation, Inc.
3 4
   Contributed by Andy Vaught

5
This file is part of GCC.
6

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

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

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

/* 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"
27
#include "system.h"
28
#include "coretypes.h"
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
#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;
}


44 45
/* Get a gfc_code structure, initialized with the current locus
   and a statement code 'op'.  */
46 47

gfc_code *
48
gfc_get_code (gfc_exec_op op)
49 50 51
{
  gfc_code *c;

52
  c = XCNEW (gfc_code);
53
  c->op = op;
54
  c->loc = gfc_current_locus;
55 56 57 58 59 60 61 62
  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 *
63
gfc_append_code (gfc_code *tail, gfc_code *new_code)
64 65 66 67 68 69
{
  if (tail != NULL)
    {
      while (tail->next != NULL)
	tail = tail->next;

70
      tail->next = new_code;
71 72
    }

73 74
  while (new_code->next != NULL)
    new_code = new_code->next;
75

76
  return new_code;
77 78 79 80 81 82
}


/* Free a single code structure, but not the actual structure itself.  */

void
83
gfc_free_statement (gfc_code *p)
84
{
85 86
  if (p->expr1)
    gfc_free_expr (p->expr1);
87 88 89 90 91 92
  if (p->expr2)
    gfc_free_expr (p->expr2);

  switch (p->op)
    {
    case EXEC_NOP:
93
    case EXEC_END_BLOCK:
94
    case EXEC_END_NESTED_BLOCK:
95
    case EXEC_ASSIGN:
Paul Thomas committed
96
    case EXEC_INIT_ASSIGN:
97 98 99
    case EXEC_GOTO:
    case EXEC_CYCLE:
    case EXEC_RETURN:
100
    case EXEC_END_PROCEDURE:
101 102 103
    case EXEC_IF:
    case EXEC_PAUSE:
    case EXEC_STOP:
104
    case EXEC_ERROR_STOP:
105 106 107 108 109 110 111 112
    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:
113
    case EXEC_ENTRY:
114
    case EXEC_ARITHMETIC_IF:
115 116 117 118
    case EXEC_CRITICAL:
    case EXEC_SYNC_ALL:
    case EXEC_SYNC_IMAGES:
    case EXEC_SYNC_MEMORY:
119 120
    case EXEC_LOCK:
    case EXEC_UNLOCK:
121 122
    case EXEC_EVENT_POST:
    case EXEC_EVENT_WAIT:
123
    case EXEC_FAIL_IMAGE:
124 125 126 127
    case EXEC_CHANGE_TEAM:
    case EXEC_END_TEAM:
    case EXEC_FORM_TEAM:
    case EXEC_SYNC_TEAM:
128 129
      break;

130
    case EXEC_BLOCK:
131 132
      gfc_free_namespace (p->ext.block.ns);
      gfc_free_association_list (p->ext.block.assoc);
133 134
      break;

135
    case EXEC_COMPCALL:
136
    case EXEC_CALL_PPC:
137
    case EXEC_CALL:
138
    case EXEC_ASSIGN_CALL:
139 140 141 142
      gfc_free_actual_arglist (p->ext.actual);
      break;

    case EXEC_SELECT:
143
    case EXEC_SELECT_TYPE:
144
    case EXEC_SELECT_RANK:
145 146
      if (p->ext.block.case_list)
	gfc_free_case_list (p->ext.block.case_list);
147 148 149 150 151 152 153 154
      break;

    case EXEC_DO:
      gfc_free_iterator (p->ext.iterator, 1);
      break;

    case EXEC_ALLOCATE:
    case EXEC_DEALLOCATE:
155
      gfc_free_alloc_list (p->ext.alloc.list);
156 157 158 159 160 161 162 163 164 165 166 167 168
      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
169
    case EXEC_FLUSH:
170 171 172 173 174 175 176
      gfc_free_filepos (p->ext.filepos);
      break;

    case EXEC_INQUIRE:
      gfc_free_inquire (p->ext.inquire);
      break;

Jerry DeLisle committed
177 178 179 180
    case EXEC_WAIT:
      gfc_free_wait (p->ext.wait);
      break;

181 182 183 184 185 186 187
    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
188
	 be freed.  */
189 190
      break;

191
    case EXEC_DO_CONCURRENT:
192 193 194 195
    case EXEC_FORALL:
      gfc_free_forall_iterator (p->ext.forall_iterator);
      break;

196 197 198 199 200
    case EXEC_OACC_DECLARE:
      if (p->ext.oacc_declare)
	gfc_free_oacc_declare_clauses (p->ext.oacc_declare);
      break;

201 202 203 204
    case EXEC_OACC_PARALLEL_LOOP:
    case EXEC_OACC_PARALLEL:
    case EXEC_OACC_KERNELS_LOOP:
    case EXEC_OACC_KERNELS:
205 206
    case EXEC_OACC_SERIAL_LOOP:
    case EXEC_OACC_SERIAL:
207 208 209 210 211 212 213 214
    case EXEC_OACC_DATA:
    case EXEC_OACC_HOST_DATA:
    case EXEC_OACC_LOOP:
    case EXEC_OACC_UPDATE:
    case EXEC_OACC_WAIT:
    case EXEC_OACC_CACHE:
    case EXEC_OACC_ENTER_DATA:
    case EXEC_OACC_EXIT_DATA:
215
    case EXEC_OACC_ROUTINE:
216 217
    case EXEC_OMP_CANCEL:
    case EXEC_OMP_CANCELLATION_POINT:
218
    case EXEC_OMP_CRITICAL:
219 220 221 222
    case EXEC_OMP_DISTRIBUTE:
    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
    case EXEC_OMP_DISTRIBUTE_SIMD:
223
    case EXEC_OMP_DO:
224
    case EXEC_OMP_DO_SIMD:
225
    case EXEC_OMP_END_SINGLE:
226
    case EXEC_OMP_ORDERED:
227 228
    case EXEC_OMP_PARALLEL:
    case EXEC_OMP_PARALLEL_DO:
229
    case EXEC_OMP_PARALLEL_DO_SIMD:
230
    case EXEC_OMP_PARALLEL_SECTIONS:
231
    case EXEC_OMP_PARALLEL_WORKSHARE:
232
    case EXEC_OMP_SECTIONS:
233
    case EXEC_OMP_SIMD:
234
    case EXEC_OMP_SINGLE:
235 236
    case EXEC_OMP_TARGET:
    case EXEC_OMP_TARGET_DATA:
237 238 239 240 241 242
    case EXEC_OMP_TARGET_ENTER_DATA:
    case EXEC_OMP_TARGET_EXIT_DATA:
    case EXEC_OMP_TARGET_PARALLEL:
    case EXEC_OMP_TARGET_PARALLEL_DO:
    case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
    case EXEC_OMP_TARGET_SIMD:
243 244 245 246 247 248
    case EXEC_OMP_TARGET_TEAMS:
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
    case EXEC_OMP_TARGET_UPDATE:
249
    case EXEC_OMP_TASK:
250 251
    case EXEC_OMP_TASKLOOP:
    case EXEC_OMP_TASKLOOP_SIMD:
252 253 254 255 256
    case EXEC_OMP_TEAMS:
    case EXEC_OMP_TEAMS_DISTRIBUTE:
    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
    case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
257 258 259 260
    case EXEC_OMP_WORKSHARE:
      gfc_free_omp_clauses (p->ext.omp_clauses);
      break;

261
    case EXEC_OMP_END_CRITICAL:
262
      free (CONST_CAST (char *, p->ext.omp_name));
263 264 265
      break;

    case EXEC_OMP_FLUSH:
266
      gfc_free_omp_namelist (p->ext.omp_namelist);
267 268
      break;

269
    case EXEC_OACC_ATOMIC:
270 271 272 273
    case EXEC_OMP_ATOMIC:
    case EXEC_OMP_BARRIER:
    case EXEC_OMP_MASTER:
    case EXEC_OMP_END_NOWAIT:
274
    case EXEC_OMP_TASKGROUP:
275
    case EXEC_OMP_TASKWAIT:
276
    case EXEC_OMP_TASKYIELD:
277 278
      break;

279 280 281 282 283 284 285 286 287
    default:
      gfc_internal_error ("gfc_free_statement(): Bad statement");
    }
}


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

void
288
gfc_free_statements (gfc_code *p)
289 290 291 292 293 294 295 296 297 298
{
  gfc_code *q;

  for (; p; p = q)
    {
      q = p->next;

      if (p->block)
	gfc_free_statements (p->block);
      gfc_free_statement (p);
299
      free (p);
300 301 302
    }
}

303 304 305 306 307 308 309 310 311 312

/* Free an association list (of an ASSOCIATE statement).  */

void
gfc_free_association_list (gfc_association_list* assoc)
{
  if (!assoc)
    return;

  gfc_free_association_list (assoc->next);
313
  free (assoc);
314
}