参照元†
- c_parser *parser
- enum pragma_context context
- bool *if_p
返り値†
/* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
should be considered, statements. ALLOW_STMT is true if we're within
the context of a function and such pragmas are to be allowed. Returns
true if we actually parsed such a pragma. */
static bool
c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p)
{
unsigned int id;
const char *construct = NULL;
id = c_parser_peek_token (parser)->pragma_kind;
gcc_assert (id != PRAGMA_NONE);
switch (id)
{
case PRAGMA_OACC_DECLARE:
c_parser_oacc_declare (parser);
return false;
case PRAGMA_OACC_ENTER_DATA:
if (context != pragma_compound)
{
construct = "acc enter data";
in_compound:
if (context == pragma_stmt)
{
error_at (c_parser_peek_token (parser)->location,
"%<#pragma %s%> may only be used in compound "
"statements", construct);
c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
return false;
}
goto bad_stmt;
}
c_parser_oacc_enter_exit_data (parser, true);
return false;
case PRAGMA_OACC_EXIT_DATA:
if (context != pragma_compound)
{
construct = "acc exit data";
goto in_compound;
}
c_parser_oacc_enter_exit_data (parser, false);
return false;
case PRAGMA_OACC_ROUTINE:
if (context != pragma_external)
{
error_at (c_parser_peek_token (parser)->location,
"%<#pragma acc routine%> must be at file scope");
c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
return false;
}
c_parser_oacc_routine (parser, context);
return false;
case PRAGMA_OACC_UPDATE:
if (context != pragma_compound)
{
construct = "acc update";
goto in_compound;
}
c_parser_oacc_update (parser);
return false;
case PRAGMA_OMP_BARRIER:
if (context != pragma_compound)
{
construct = "omp barrier";
goto in_compound;
}
c_parser_omp_barrier (parser);
return false;
case PRAGMA_OMP_FLUSH:
if (context != pragma_compound)
{
construct = "omp flush";
goto in_compound;
}
c_parser_omp_flush (parser);
return false;
case PRAGMA_OMP_TASKWAIT:
if (context != pragma_compound)
{
construct = "omp taskwait";
goto in_compound;
}
c_parser_omp_taskwait (parser);
return false;
case PRAGMA_OMP_TASKYIELD:
if (context != pragma_compound)
{
construct = "omp taskyield";
goto in_compound;
}
c_parser_omp_taskyield (parser);
return false;
case PRAGMA_OMP_CANCEL:
if (context != pragma_compound)
{
construct = "omp cancel";
goto in_compound;
}
c_parser_omp_cancel (parser);
return false;
case PRAGMA_OMP_CANCELLATION_POINT:
c_parser_omp_cancellation_point (parser, context);
return false;
case PRAGMA_OMP_THREADPRIVATE:
c_parser_omp_threadprivate (parser);
return false;
case PRAGMA_OMP_TARGET:
return c_parser_omp_target (parser, context, if_p);
case PRAGMA_OMP_END_DECLARE_TARGET:
c_parser_omp_end_declare_target (parser);
return false;
case PRAGMA_OMP_SECTION:
error_at (c_parser_peek_token (parser)->location,
"%<#pragma omp section%> may only be used in "
"%<#pragma omp sections%> construct");
c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
return false;
case PRAGMA_OMP_DECLARE:
c_parser_omp_declare (parser, context);
return false;
case PRAGMA_OMP_ORDERED:
return c_parser_omp_ordered (parser, context, if_p);
case PRAGMA_IVDEP:
{
const bool ivdep = c_parse_pragma_ivdep (parser);
unsigned short unroll;
if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL)
unroll = c_parser_pragma_unroll (parser);
else
unroll = 0;
if (!c_parser_next_token_is_keyword (parser, RID_FOR)
&& !c_parser_next_token_is_keyword (parser, RID_WHILE)
&& !c_parser_next_token_is_keyword (parser, RID_DO))
{
c_parser_error (parser, "for, while or do statement expected");
return false;
}
if (c_parser_next_token_is_keyword (parser, RID_FOR))
c_parser_for_statement (parser, ivdep, unroll, if_p);
else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
c_parser_while_statement (parser, ivdep, unroll, if_p);
else
c_parser_do_statement (parser, ivdep, unroll);
}
return false;
case PRAGMA_UNROLL:
{
unsigned short unroll = c_parser_pragma_unroll (parser);
bool ivdep;
if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP)
ivdep = c_parse_pragma_ivdep (parser);
else
ivdep = false;
if (!c_parser_next_token_is_keyword (parser, RID_FOR)
&& !c_parser_next_token_is_keyword (parser, RID_WHILE)
&& !c_parser_next_token_is_keyword (parser, RID_DO))
{
c_parser_error (parser, "for, while or do statement expected");
return false;
}
if (c_parser_next_token_is_keyword (parser, RID_FOR))
c_parser_for_statement (parser, ivdep, unroll, if_p);
else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
c_parser_while_statement (parser, ivdep, unroll, if_p);
else
c_parser_do_statement (parser, ivdep, unroll);
}
return false;
case PRAGMA_GCC_PCH_PREPROCESS:
c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
return false;
case PRAGMA_OACC_WAIT:
if (context != pragma_compound)
{
construct = "acc wait";
goto in_compound;
}
/* FALL THROUGH. */
default:
if (id < PRAGMA_FIRST_EXTERNAL)
{
if (context != pragma_stmt && context != pragma_compound)
{
bad_stmt:
c_parser_error (parser, "expected declaration specifiers");
c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
return false;
}
c_parser_omp_construct (parser, if_p);
return true;
}
break;
}
c_parser_consume_pragma (parser);
c_invoke_pragma_handler (id);
/* Skip to EOL, but suppress any error message. Those will have been
generated by the handler routine through calling error, as opposed
to calling c_parser_error. */
parser->error = true;
c_parser_skip_to_pragma_eol (parser);
return false;
}
コメント†