{ "wait", PRAGMA_OACC_WAIT }
};
static const struct omp_pragma_def omp_pragmas[] = {
+ { "allocate", PRAGMA_OMP_ALLOCATE },
{ "atomic", PRAGMA_OMP_ATOMIC },
{ "barrier", PRAGMA_OMP_BARRIER },
{ "cancel", PRAGMA_OMP_CANCEL },
PRAGMA_OACC_UPDATE,
PRAGMA_OACC_WAIT,
+ PRAGMA_OMP_ALLOCATE,
PRAGMA_OMP_ATOMIC,
PRAGMA_OMP_BARRIER,
PRAGMA_OMP_CANCEL,
return stmt;
}
+/* OpenMP 5.0:
+ # pragma omp allocate (list) [allocator(allocator)] */
+
+static void
+c_parser_omp_allocate (location_t loc, c_parser *parser)
+{
+ tree allocator = NULL_TREE;
+ tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
+ if (c_parser_next_token_is (parser, CPP_NAME))
+ {
+ matching_parens parens;
+ const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ c_parser_consume_token (parser);
+ if (strcmp ("allocator", p) != 0)
+ error_at (c_parser_peek_token (parser)->location,
+ "expected %<allocator%>");
+ else if (parens.require_open (parser))
+ {
+ location_t expr_loc = c_parser_peek_token (parser)->location;
+ c_expr expr = c_parser_expr_no_commas (parser, NULL);
+ expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
+ allocator = expr.value;
+ allocator = c_fully_fold (allocator, false, NULL);
+ tree orig_type
+ = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
+ orig_type = TYPE_MAIN_VARIANT (orig_type);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
+ || TREE_CODE (orig_type) != ENUMERAL_TYPE
+ || TYPE_NAME (orig_type)
+ != get_identifier ("omp_allocator_handle_t"))
+ {
+ error_at (expr_loc, "%<allocator%> clause allocator expression "
+ "has type %qT rather than "
+ "%<omp_allocator_handle_t%>",
+ TREE_TYPE (allocator));
+ allocator = NULL_TREE;
+ }
+ parens.skip_until_found_close (parser);
+ }
+ }
+ c_parser_skip_to_pragma_eol (parser);
+
+ if (allocator)
+ for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
+ OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
+
+ sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
+}
+
/* OpenMP 2.5:
# pragma omp atomic new-line
expression-stmt
strcpy (p_name, "#pragma wait");
stmt = c_parser_oacc_wait (loc, parser, p_name);
break;
+ case PRAGMA_OMP_ALLOCATE:
+ c_parser_omp_allocate (loc, parser);
+ return;
case PRAGMA_OMP_ATOMIC:
c_parser_omp_atomic (loc, parser, false);
return;
return finish_omp_structured_block (stmt);
}
+/* OpenMP 5.0:
+ # pragma omp allocate (list) [allocator(allocator)] */
+
+static void
+cp_parser_omp_allocate (cp_parser *parser, cp_token *pragma_tok)
+{
+ tree allocator = NULL_TREE;
+ location_t loc = pragma_tok->location;
+ tree nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ matching_parens parens;
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+ location_t cloc = cp_lexer_peek_token (parser->lexer)->location;
+ cp_lexer_consume_token (parser->lexer);
+ if (strcmp (p, "allocator") != 0)
+ error_at (cloc, "expected %<allocator%>");
+ else if (parens.require_open (parser))
+ {
+ allocator = cp_parser_assignment_expression (parser);
+ if (allocator == error_mark_node)
+ allocator = NULL_TREE;
+ parens.require_close (parser);
+ }
+ }
+ cp_parser_require_pragma_eol (parser, pragma_tok);
+
+ if (allocator)
+ for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
+ OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
+
+ sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
+}
+
/* OpenMP 2.5:
# pragma omp atomic new-line
expression-stmt
case PRAGMA_OACC_WAIT:
stmt = cp_parser_oacc_wait (parser, pragma_tok);
break;
+ case PRAGMA_OMP_ALLOCATE:
+ cp_parser_omp_allocate (parser, pragma_tok);
+ return;
case PRAGMA_OMP_ATOMIC:
cp_parser_omp_atomic (parser, pragma_tok, false);
return;
goto bad_stmt;
cp_parser_omp_construct (parser, pragma_tok, if_p);
return true;
-
+ case PRAGMA_OMP_ALLOCATE:
+ cp_parser_omp_allocate (parser, pragma_tok);
+ return false;
case PRAGMA_OACC_ATOMIC:
case PRAGMA_OACC_CACHE:
case PRAGMA_OACC_DATA:
--- /dev/null
+typedef enum omp_allocator_handle_t
+#if __cplusplus >= 201103L
+: __UINTPTR_TYPE__
+#endif
+{
+ omp_null_allocator = 0,
+ omp_default_mem_alloc = 1,
+ omp_large_cap_mem_alloc = 2,
+ omp_const_mem_alloc = 3,
+ omp_high_bw_mem_alloc = 4,
+ omp_low_lat_mem_alloc = 5,
+ omp_cgroup_mem_alloc = 6,
+ omp_pteam_mem_alloc = 7,
+ omp_thread_mem_alloc = 8,
+ __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+void
+foo ()
+{
+ int a, b;
+ omp_allocator_handle_t my_allocator;
+#pragma omp allocate (a) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" } */
+#pragma omp allocate (b) allocator(my_allocator) /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" } */
+}
+
+void
+bar ()
+{
+ int a, b;
+ omp_allocator_handle_t my_allocator;
+#pragma omp allocate /* { dg-error "expected '\\(' before end of line" } */
+ /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-1 } */
+#pragma omp allocate allocator(my_allocator) /* { dg-error "expected '\\(' before 'allocator'" } */
+ /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-1 } */
+#pragma omp allocate(a) foo(my_allocator) /* { dg-error "expected 'allocator'" } */
+ /* { dg-error "expected end of line before '\\(' token" "" { target *-*-* } .-1 } */
+ /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-2 } */
+#pragma omp allocate(a) allocator(b) /* { dg-error "'allocator' clause allocator expression has type 'int' rather than 'omp_allocator_handle_t'" "todo: cp/semantics.c" { xfail c++ } } */
+ /* { dg-message "sorry, unimplemented: '#pragma omp allocate' not yet supported" "" { target *-*-* } .-1 } */
+}