return ST_NONE;
}
+/* Like match and if spec_only, goto do_spec_only without actually
+ matching. */
+#define matcha(keyword, subr, st) \
+ do { \
+ if (spec_only && gfc_match (keyword) == MATCH_YES) \
+ goto do_spec_only; \
+ else if (match_word (keyword, subr, &old_locus) \
+ == MATCH_YES) \
+ return st; \
+ else \
+ undo_new_statement (); \
+ } while (0);
+
static gfc_statement
decode_oacc_directive (void)
{
locus old_locus;
char c;
+ bool spec_only = false;
gfc_enforce_clean_symbol_state ();
return ST_NONE;
}
+ if (gfc_current_state () == COMP_FUNCTION
+ && gfc_current_block ()->result->ts.kind == -1)
+ spec_only = true;
+
gfc_unset_implicit_pure (NULL);
old_locus = gfc_current_locus;
switch (c)
{
case 'a':
- match ("atomic", gfc_match_oacc_atomic, ST_OACC_ATOMIC);
+ matcha ("atomic", gfc_match_oacc_atomic, ST_OACC_ATOMIC);
break;
case 'c':
- match ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);
+ matcha ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);
break;
case 'd':
- match ("data", gfc_match_oacc_data, ST_OACC_DATA);
+ matcha ("data", gfc_match_oacc_data, ST_OACC_DATA);
match ("declare", gfc_match_oacc_declare, ST_OACC_DECLARE);
break;
case 'e':
- match ("end atomic", gfc_match_omp_eos, ST_OACC_END_ATOMIC);
- match ("end data", gfc_match_omp_eos, ST_OACC_END_DATA);
- match ("end host_data", gfc_match_omp_eos, ST_OACC_END_HOST_DATA);
- match ("end kernels loop", gfc_match_omp_eos, ST_OACC_END_KERNELS_LOOP);
- match ("end kernels", gfc_match_omp_eos, ST_OACC_END_KERNELS);
- match ("end loop", gfc_match_omp_eos, ST_OACC_END_LOOP);
- match ("end parallel loop", gfc_match_omp_eos, ST_OACC_END_PARALLEL_LOOP);
- match ("end parallel", gfc_match_omp_eos, ST_OACC_END_PARALLEL);
- match ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
- match ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
+ matcha ("end atomic", gfc_match_omp_eos, ST_OACC_END_ATOMIC);
+ matcha ("end data", gfc_match_omp_eos, ST_OACC_END_DATA);
+ matcha ("end host_data", gfc_match_omp_eos, ST_OACC_END_HOST_DATA);
+ matcha ("end kernels loop", gfc_match_omp_eos, ST_OACC_END_KERNELS_LOOP);
+ matcha ("end kernels", gfc_match_omp_eos, ST_OACC_END_KERNELS);
+ matcha ("end loop", gfc_match_omp_eos, ST_OACC_END_LOOP);
+ matcha ("end parallel loop", gfc_match_omp_eos,
+ ST_OACC_END_PARALLEL_LOOP);
+ matcha ("end parallel", gfc_match_omp_eos, ST_OACC_END_PARALLEL);
+ matcha ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
+ matcha ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
break;
case 'h':
- match ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
+ matcha ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
break;
case 'p':
- match ("parallel loop", gfc_match_oacc_parallel_loop, ST_OACC_PARALLEL_LOOP);
- match ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
+ matcha ("parallel loop", gfc_match_oacc_parallel_loop,
+ ST_OACC_PARALLEL_LOOP);
+ matcha ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
break;
case 'k':
- match ("kernels loop", gfc_match_oacc_kernels_loop, ST_OACC_KERNELS_LOOP);
- match ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
+ matcha ("kernels loop", gfc_match_oacc_kernels_loop,
+ ST_OACC_KERNELS_LOOP);
+ matcha ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
break;
case 'l':
- match ("loop", gfc_match_oacc_loop, ST_OACC_LOOP);
+ matcha ("loop", gfc_match_oacc_loop, ST_OACC_LOOP);
break;
case 'r':
match ("routine", gfc_match_oacc_routine, ST_OACC_ROUTINE);
break;
case 'u':
- match ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
+ matcha ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
break;
case 'w':
- match ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
+ matcha ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
break;
}
gfc_error_recovery ();
return ST_NONE;
+
+ do_spec_only:
+ reject_statement ();
+ gfc_clear_error ();
+ gfc_buffer_error (false);
+ gfc_current_locus = old_locus;
+ return ST_GET_FCN_CHARACTERISTICS;
}
/* Like match, but set a flag simd_matched if keyword matched