参照元

説明

引数

返り値

参考

実装

/* 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;
}

コメント


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-06-24 (月) 11:27:18