void gfc_free_statement (gfc_code *p) { if (p->expr1) gfc_free_expr (p->expr1); if (p->expr2) gfc_free_expr (p->expr2); switch (p->op) { case EXEC_NOP: case EXEC_END_BLOCK: case EXEC_END_NESTED_BLOCK: case EXEC_ASSIGN: case EXEC_INIT_ASSIGN: case EXEC_GOTO: case EXEC_CYCLE: case EXEC_RETURN: case EXEC_END_PROCEDURE: case EXEC_IF: case EXEC_PAUSE: case EXEC_STOP: case EXEC_ERROR_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_ENTRY: case EXEC_ARITHMETIC_IF: case EXEC_CRITICAL: case EXEC_SYNC_ALL: case EXEC_SYNC_IMAGES: case EXEC_SYNC_MEMORY: case EXEC_LOCK: case EXEC_UNLOCK: break; case EXEC_BLOCK: gfc_free_namespace (p->ext.block.ns); gfc_free_association_list (p->ext.block.assoc); break; case EXEC_COMPCALL: case EXEC_CALL_PPC: case EXEC_CALL: case EXEC_ASSIGN_CALL: gfc_free_actual_arglist (p->ext.actual); break; case EXEC_SELECT: case EXEC_SELECT_TYPE: if (p->ext.block.case_list) gfc_free_case_list (p->ext.block.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: case EXEC_FLUSH: gfc_free_filepos (p->ext.filepos); break; case EXEC_INQUIRE: gfc_free_inquire (p->ext.inquire); break; case EXEC_WAIT: gfc_free_wait (p->ext.wait); 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_DO_CONCURRENT: case EXEC_FORALL: gfc_free_forall_iterator (p->ext.forall_iterator); break; case EXEC_OMP_CANCEL: case EXEC_OMP_CANCELLATION_POINT: case EXEC_OMP_DISTRIBUTE: case EXEC_OMP_DISTRIBUTE_PARALLEL_DO: case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD: case EXEC_OMP_DISTRIBUTE_SIMD: case EXEC_OMP_DO: case EXEC_OMP_DO_SIMD: case EXEC_OMP_END_SINGLE: case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_SECTIONS: case EXEC_OMP_SIMD: case EXEC_OMP_SINGLE: case EXEC_OMP_TARGET: case EXEC_OMP_TARGET_DATA: 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: case EXEC_OMP_TASK: 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: case EXEC_OMP_WORKSHARE: case EXEC_OMP_PARALLEL_WORKSHARE: gfc_free_omp_clauses (p->ext.omp_clauses); break; case EXEC_OMP_CRITICAL: free (CONST_CAST (char *, p->ext.omp_name)); break; case EXEC_OMP_FLUSH: gfc_free_omp_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: case EXEC_OMP_TASKGROUP: case EXEC_OMP_TASKWAIT: case EXEC_OMP_TASKYIELD: break; default: gfc_internal_error ("gfc_free_statement(): Bad statement"); } }
static match gfc_match_omp_clauses (gfc_omp_clauses **cp, int mask) { gfc_omp_clauses *c = gfc_get_omp_clauses (); locus old_loc; bool needs_space = true, first = true; *cp = NULL; while (1) { if ((first || gfc_match_char (',') != MATCH_YES) && (needs_space && gfc_match_space () != MATCH_YES)) break; needs_space = false; first = false; gfc_gobble_whitespace (); if ((mask & OMP_CLAUSE_IF) && c->if_expr == NULL && gfc_match ("if ( %e )", &c->if_expr) == MATCH_YES) continue; if ((mask & OMP_CLAUSE_NUM_THREADS) && c->num_threads == NULL && gfc_match ("num_threads ( %e )", &c->num_threads) == MATCH_YES) continue; if ((mask & OMP_CLAUSE_PRIVATE) && gfc_match_omp_variable_list ("private (", &c->lists[OMP_LIST_PRIVATE], true) == MATCH_YES) continue; if ((mask & OMP_CLAUSE_FIRSTPRIVATE) && gfc_match_omp_variable_list ("firstprivate (", &c->lists[OMP_LIST_FIRSTPRIVATE], true) == MATCH_YES) continue; if ((mask & OMP_CLAUSE_LASTPRIVATE) && gfc_match_omp_variable_list ("lastprivate (", &c->lists[OMP_LIST_LASTPRIVATE], true) == MATCH_YES) continue; if ((mask & OMP_CLAUSE_COPYPRIVATE) && gfc_match_omp_variable_list ("copyprivate (", &c->lists[OMP_LIST_COPYPRIVATE], true) == MATCH_YES) continue; if ((mask & OMP_CLAUSE_SHARED) && gfc_match_omp_variable_list ("shared (", &c->lists[OMP_LIST_SHARED], true) == MATCH_YES) continue; if ((mask & OMP_CLAUSE_COPYIN) && gfc_match_omp_variable_list ("copyin (", &c->lists[OMP_LIST_COPYIN], true) == MATCH_YES) continue; old_loc = gfc_current_locus; if ((mask & OMP_CLAUSE_REDUCTION) && gfc_match ("reduction ( ") == MATCH_YES) { int reduction = OMP_LIST_NUM; char buffer[GFC_MAX_SYMBOL_LEN + 1]; if (gfc_match_char ('+') == MATCH_YES) reduction = OMP_LIST_PLUS; else if (gfc_match_char ('*') == MATCH_YES) reduction = OMP_LIST_MULT; else if (gfc_match_char ('-') == MATCH_YES) reduction = OMP_LIST_SUB; else if (gfc_match (".and.") == MATCH_YES) reduction = OMP_LIST_AND; else if (gfc_match (".or.") == MATCH_YES) reduction = OMP_LIST_OR; else if (gfc_match (".eqv.") == MATCH_YES) reduction = OMP_LIST_EQV; else if (gfc_match (".neqv.") == MATCH_YES) reduction = OMP_LIST_NEQV; else if (gfc_match_name (buffer) == MATCH_YES) { gfc_symbol *sym; const char *n = buffer; gfc_find_symbol (buffer, NULL, 1, &sym); if (sym != NULL) { if (sym->attr.intrinsic) n = sym->name; else if ((sym->attr.flavor != FL_UNKNOWN && sym->attr.flavor != FL_PROCEDURE) || sym->attr.external || sym->attr.generic || sym->attr.entry || sym->attr.result || sym->attr.dummy || sym->attr.subroutine || sym->attr.pointer || sym->attr.target || sym->attr.cray_pointer || sym->attr.cray_pointee || (sym->attr.proc != PROC_UNKNOWN && sym->attr.proc != PROC_INTRINSIC) || sym->attr.if_source != IFSRC_UNKNOWN || sym == sym->ns->proc_name) { gfc_error_now ("%s is not INTRINSIC procedure name " "at %C", buffer); sym = NULL; } else n = sym->name; } if (strcmp (n, "max") == 0) reduction = OMP_LIST_MAX; else if (strcmp (n, "min") == 0) reduction = OMP_LIST_MIN; else if (strcmp (n, "iand") == 0) reduction = OMP_LIST_IAND; else if (strcmp (n, "ior") == 0) reduction = OMP_LIST_IOR; else if (strcmp (n, "ieor") == 0) reduction = OMP_LIST_IEOR; if (reduction != OMP_LIST_NUM && sym != NULL && ! sym->attr.intrinsic && ! sym->attr.use_assoc && ((sym->attr.flavor == FL_UNKNOWN && gfc_add_flavor (&sym->attr, FL_PROCEDURE, sym->name, NULL) == FAILURE) || gfc_add_intrinsic (&sym->attr, NULL) == FAILURE)) { gfc_free_omp_clauses (c); return MATCH_ERROR; } } if (reduction != OMP_LIST_NUM && gfc_match_omp_variable_list (" :", &c->lists[reduction], false) == MATCH_YES) continue; else gfc_current_locus = old_loc; } if ((mask & OMP_CLAUSE_DEFAULT) && c->default_sharing == OMP_DEFAULT_UNKNOWN) { if (gfc_match ("default ( shared )") == MATCH_YES) c->default_sharing = OMP_DEFAULT_SHARED; else if (gfc_match ("default ( private )") == MATCH_YES) c->default_sharing = OMP_DEFAULT_PRIVATE; else if (gfc_match ("default ( none )") == MATCH_YES) c->default_sharing = OMP_DEFAULT_NONE; else if (gfc_match ("default ( firstprivate )") == MATCH_YES) c->default_sharing = OMP_DEFAULT_FIRSTPRIVATE; if (c->default_sharing != OMP_DEFAULT_UNKNOWN) continue; } old_loc = gfc_current_locus; if ((mask & OMP_CLAUSE_SCHEDULE) && c->sched_kind == OMP_SCHED_NONE && gfc_match ("schedule ( ") == MATCH_YES) { if (gfc_match ("static") == MATCH_YES) c->sched_kind = OMP_SCHED_STATIC; else if (gfc_match ("dynamic") == MATCH_YES) c->sched_kind = OMP_SCHED_DYNAMIC; else if (gfc_match ("guided") == MATCH_YES) c->sched_kind = OMP_SCHED_GUIDED; else if (gfc_match ("runtime") == MATCH_YES) c->sched_kind = OMP_SCHED_RUNTIME; else if (gfc_match ("auto") == MATCH_YES) c->sched_kind = OMP_SCHED_AUTO; if (c->sched_kind != OMP_SCHED_NONE) { match m = MATCH_NO; if (c->sched_kind != OMP_SCHED_RUNTIME && c->sched_kind != OMP_SCHED_AUTO) m = gfc_match (" , %e )", &c->chunk_size); if (m != MATCH_YES) m = gfc_match_char (')'); if (m != MATCH_YES) c->sched_kind = OMP_SCHED_NONE; } if (c->sched_kind != OMP_SCHED_NONE) continue; else gfc_current_locus = old_loc; } if ((mask & OMP_CLAUSE_ORDERED) && !c->ordered && gfc_match ("ordered") == MATCH_YES) { c->ordered = needs_space = true; continue; } if ((mask & OMP_CLAUSE_UNTIED) && !c->untied && gfc_match ("untied") == MATCH_YES) { c->untied = needs_space = true; continue; } if ((mask & OMP_CLAUSE_COLLAPSE) && !c->collapse) { gfc_expr *cexpr = NULL; match m = gfc_match ("collapse ( %e )", &cexpr); if (m == MATCH_YES) { int collapse; const char *p = gfc_extract_int (cexpr, &collapse); if (p) { gfc_error_now (p); collapse = 1; } else if (collapse <= 0) { gfc_error_now ("COLLAPSE clause argument not" " constant positive integer at %C"); collapse = 1; } c->collapse = collapse; gfc_free_expr (cexpr); continue; } } break; } if (gfc_match_omp_eos () != MATCH_YES) { gfc_free_omp_clauses (c); return MATCH_ERROR; } *cp = c; return MATCH_YES; }