Hi!

The following patch adds parsing of the device_type clause (though it is in
the end ignored right now, I have some omp-lang questions on what exactly is
the semantics supposed to be, where exactly we should apply the excluded
definitions), plus declare target is now explicitly allowed to be nested.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk.

2019-08-10  Jakub Jelinek  <ja...@redhat.com>

        * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_DEVICE_TYPE.
        (enum omp_clause_device_type_kind): New enum.
        (struct tree_omp_clause): Add subcode.device_type_kind.
        * tree.h (OMP_CLAUSE_DEVICE_TYPE_KIND): Define.
        * tree.c (omp_clause_num_ops, omp_clause_code_name): Add entries
        for device_type clause.
        (walk_tree_1): Handle OMP_CLAUSE_DEVICE_TYPE.
        * tree-pretty-print.c (dump_omp_clause): Likewise.
c-family/
        * c-pragma.h (enum pragma_omp_clause): Add
        PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
c/
        * c-parser.c (c_parser_omp_clause_name): Parse device_type.
        (c_parser_omp_clause_device_type): New function.
        (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
        (OMP_DECLARE_TARGET_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
        (c_parser_omp_declare_target): Handle device_type clauses.  Remove
        diagnostics for declare target with clauses nested in clause-less
        declare target declaration-definition-seq.
        * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_DEVICE_TYPE.
cp/
        * parser.c (cp_parser_omp_clause_name): Parse device_type.
        (cp_parser_omp_clause_device_type): New function.
        (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
        (OMP_DECLARE_TARGET_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
        (cp_parser_omp_declare_target): Handle device_type clauses.  Remove
        diagnostics for declare target with clauses nested in clause-less
        declare target declaration-definition-seq.
        * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_DEVICE_TYPE.
testsuite/
        * c-c++-common/gomp/declare-target-2.c: Don't expect error for
        declare target with clauses in between declare target without clauses
        and end declare target.
        * c-c++-common/gomp/declare-target-4.c: New test.

--- gcc/tree-core.h.jj  2019-08-09 09:19:55.193457848 +0200
+++ gcc/tree-core.h     2019-08-09 13:03:24.467253157 +0200
@@ -415,6 +415,9 @@ enum omp_clause_code {
   /* OpenMP clause: simdlen (constant-integer-expression).  */
   OMP_CLAUSE_SIMDLEN,
 
+  /* OpenMP clause: device_type ({host,nohost,any}).  */
+  OMP_CLAUSE_DEVICE_TYPE,
+
   /* OpenMP clause: for.  */
   OMP_CLAUSE_FOR,
 
@@ -1468,6 +1471,13 @@ enum omp_clause_proc_bind_kind
   OMP_CLAUSE_PROC_BIND_LAST
 };
 
+enum omp_clause_device_type_kind
+{
+  OMP_CLAUSE_DEVICE_TYPE_HOST = 1,
+  OMP_CLAUSE_DEVICE_TYPE_NOHOST = 2,
+  OMP_CLAUSE_DEVICE_TYPE_ANY = 3
+};
+
 enum omp_clause_linear_kind
 {
   OMP_CLAUSE_LINEAR_DEFAULT,
@@ -1544,6 +1554,7 @@ struct GTY(()) tree_omp_clause {
     enum tree_code                 if_modifier;
     enum omp_clause_defaultmap_kind defaultmap_kind;
     enum omp_clause_bind_kind      bind_kind;
+    enum omp_clause_device_type_kind device_type_kind;
     /* The dimension a OMP_CLAUSE__GRIDDIM_ clause of a gridified target
        construct describes.  */
     unsigned int                  dimension;
--- gcc/tree.h.jj       2019-08-09 09:19:54.925461880 +0200
+++ gcc/tree.h  2019-08-09 13:03:24.463253217 +0200
@@ -1620,6 +1620,9 @@ class auto_suppress_location_wrappers
 #define OMP_CLAUSE_PROC_BIND_KIND(NODE) \
   (OMP_CLAUSE_SUBCODE_CHECK (NODE, 
OMP_CLAUSE_PROC_BIND)->omp_clause.subcode.proc_bind_kind)
 
+#define OMP_CLAUSE_DEVICE_TYPE_KIND(NODE) \
+  (OMP_CLAUSE_SUBCODE_CHECK (NODE, 
OMP_CLAUSE_DEVICE_TYPE)->omp_clause.subcode.device_type_kind)
+
 #define OMP_CLAUSE_COLLAPSE_EXPR(NODE) \
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_COLLAPSE), 0)
 #define OMP_CLAUSE_COLLAPSE_ITERVAR(NODE) \
--- gcc/tree.c.jj       2019-08-09 09:19:54.877462601 +0200
+++ gcc/tree.c  2019-08-09 13:03:24.466253172 +0200
@@ -332,6 +332,7 @@ unsigned const char omp_clause_num_ops[]
   0, /* OMP_CLAUSE_PROC_BIND  */
   1, /* OMP_CLAUSE_SAFELEN  */
   1, /* OMP_CLAUSE_SIMDLEN  */
+  0, /* OMP_CLAUSE_DEVICE_TYPE  */
   0, /* OMP_CLAUSE_FOR  */
   0, /* OMP_CLAUSE_PARALLEL  */
   0, /* OMP_CLAUSE_SECTIONS  */
@@ -416,6 +417,7 @@ const char * const omp_clause_code_name[
   "proc_bind",
   "safelen",
   "simdlen",
+  "device_type",
   "for",
   "parallel",
   "sections",
@@ -12404,6 +12406,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func
        case OMP_CLAUSE_UNTIED:
        case OMP_CLAUSE_MERGEABLE:
        case OMP_CLAUSE_PROC_BIND:
+       case OMP_CLAUSE_DEVICE_TYPE:
        case OMP_CLAUSE_INBRANCH:
        case OMP_CLAUSE_NOTINBRANCH:
        case OMP_CLAUSE_FOR:
--- gcc/tree-pretty-print.c.jj  2019-08-09 09:19:54.826463369 +0200
+++ gcc/tree-pretty-print.c     2019-08-09 13:03:24.464253202 +0200
@@ -951,6 +951,25 @@ dump_omp_clause (pretty_printer *pp, tre
       pp_right_paren (pp);
       break;
 
+    case OMP_CLAUSE_DEVICE_TYPE:
+      pp_string (pp, "device_type(");
+      switch (OMP_CLAUSE_DEVICE_TYPE_KIND (clause))
+       {
+       case OMP_CLAUSE_DEVICE_TYPE_HOST:
+         pp_string (pp, "host");
+         break;
+       case OMP_CLAUSE_DEVICE_TYPE_NOHOST:
+         pp_string (pp, "nohost");
+         break;
+       case OMP_CLAUSE_DEVICE_TYPE_ANY:
+         pp_string (pp, "any");
+         break;
+       default:
+         gcc_unreachable ();
+       }
+      pp_right_paren (pp);
+      break;
+
     case OMP_CLAUSE_SAFELEN:
       pp_string (pp, "safelen(");
       dump_generic_node (pp, OMP_CLAUSE_SAFELEN_EXPR (clause),
--- gcc/c-family/c-pragma.h.jj  2019-08-09 09:19:55.020460451 +0200
+++ gcc/c-family/c-pragma.h     2019-08-09 13:03:24.467253157 +0200
@@ -93,6 +93,7 @@ enum pragma_omp_clause {
   PRAGMA_OMP_CLAUSE_DEFAULTMAP,
   PRAGMA_OMP_CLAUSE_DEPEND,
   PRAGMA_OMP_CLAUSE_DEVICE,
+  PRAGMA_OMP_CLAUSE_DEVICE_TYPE,
   PRAGMA_OMP_CLAUSE_DIST_SCHEDULE,
   PRAGMA_OMP_CLAUSE_FINAL,
   PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
--- gcc/c/c-parser.c.jj 2019-08-09 09:23:51.417905026 +0200
+++ gcc/c/c-parser.c    2019-08-09 13:45:52.683127529 +0200
@@ -11720,6 +11720,8 @@ c_parser_omp_clause_name (c_parser *pars
            result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
          else if (!strcmp ("device_resident", p))
            result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
+         else if (!strcmp ("device_type", p))
+           result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
          else if (!strcmp ("dist_schedule", p))
            result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
          break;
@@ -14863,6 +14865,50 @@ c_parser_omp_clause_proc_bind (c_parser
   return list;
 }
 
+/* OpenMP 5.0:
+   device_type ( host | nohost | any )  */
+
+static tree
+c_parser_omp_clause_device_type (c_parser *parser, tree list)
+{
+  location_t clause_loc = c_parser_peek_token (parser)->location;
+  enum omp_clause_device_type_kind kind;
+  tree c;
+
+  matching_parens parens;
+  if (!parens.require_open (parser))
+    return list;
+
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+      if (strcmp ("host", p) == 0)
+       kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
+      else if (strcmp ("nohost", p) == 0)
+       kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
+      else if (strcmp ("any", p) == 0)
+       kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
+      else
+       goto invalid_kind;
+    }
+  else
+    goto invalid_kind;
+
+  /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
+                               "device_type");  */
+  c_parser_consume_token (parser);
+  parens.skip_until_found_close (parser);
+  c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
+  OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
+  OMP_CLAUSE_CHAIN (c) = list;
+  return c;
+
+ invalid_kind:
+  c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
+  parens.skip_until_found_close (parser);
+  return list;
+}
+
 /* OpenMP 4.0:
    to ( variable-list ) */
 
@@ -15350,6 +15396,10 @@ c_parser_omp_all_clauses (c_parser *pars
          clauses = c_parser_omp_clause_proc_bind (parser, clauses);
          c_name = "proc_bind";
          break;
+       case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
+         clauses = c_parser_omp_clause_device_type (parser, clauses);
+         c_name = "device_type";
+         break;
        case PRAGMA_OMP_CLAUSE_SAFELEN:
          clauses = c_parser_omp_clause_safelen (parser, clauses);
          c_name = "safelen";
@@ -18997,13 +19047,15 @@ c_finish_omp_declare_simd (c_parser *par
 
 #define OMP_DECLARE_TARGET_CLAUSE_MASK                         \
        ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)           \
-       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK))
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)         \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
 
 static void
 c_parser_omp_declare_target (c_parser *parser)
 {
-  location_t loc = c_parser_peek_token (parser)->location;
   tree clauses = NULL_TREE;
+  int device_type = 0;
+  bool only_device_type = true;
   if (c_parser_next_token_is (parser, CPP_NAME))
     clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
                                        "#pragma omp declare target");
@@ -19020,16 +19072,18 @@ c_parser_omp_declare_target (c_parser *p
       current_omp_declare_target_attribute++;
       return;
     }
-  if (current_omp_declare_target_attribute)
-    error_at (loc, "%<#pragma omp declare target%> with clauses in between "
-                  "%<#pragma omp declare target%> without clauses and "
-                  "%<#pragma omp end declare target%>");
+  for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+      device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
     {
+      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+       continue;
       tree t = OMP_CLAUSE_DECL (c), id;
       tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
       tree at2 = lookup_attribute ("omp declare target link",
                                   DECL_ATTRIBUTES (t));
+      only_device_type = false;
       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
        {
          id = get_identifier ("omp declare target link");
@@ -19062,7 +19116,34 @@ c_parser_omp_declare_target (c_parser *p
                }
            }
        }
+      if (TREE_CODE (t) != FUNCTION_DECL)
+       continue;
+      if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
+       {
+         tree at3 = lookup_attribute ("omp declare target host",
+                                      DECL_ATTRIBUTES (t));
+         if (at3 == NULL_TREE)
+           {
+             id = get_identifier ("omp declare target host");
+             DECL_ATTRIBUTES (t)
+               = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+           }
+       }
+      if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
+       {
+         tree at3 = lookup_attribute ("omp declare target nohost",
+                                      DECL_ATTRIBUTES (t));
+         if (at3 == NULL_TREE)
+           {
+             id = get_identifier ("omp declare target nohost");
+             DECL_ATTRIBUTES (t)
+               = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+           }
+       }
     }
+  if (device_type && only_device_type)
+    warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
+               "directive with only %<device_type%> clauses ignored");
 }
 
 static void
--- gcc/c/c-typeck.c.jj 2019-08-08 08:37:11.282830677 +0200
+++ gcc/c/c-typeck.c    2019-08-09 14:40:12.684468581 +0200
@@ -14690,6 +14690,7 @@ c_finish_omp_clauses (tree clauses, enum
        case OMP_CLAUSE_SECTIONS:
        case OMP_CLAUSE_TASKGROUP:
        case OMP_CLAUSE_PROC_BIND:
+       case OMP_CLAUSE_DEVICE_TYPE:
        case OMP_CLAUSE_PRIORITY:
        case OMP_CLAUSE_GRAINSIZE:
        case OMP_CLAUSE_NUM_TASKS:
--- gcc/cp/parser.c.jj  2019-08-09 09:23:51.424904920 +0200
+++ gcc/cp/parser.c     2019-08-09 13:46:09.197880368 +0200
@@ -32510,6 +32510,8 @@ cp_parser_omp_clause_name (cp_parser *pa
            result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
          else if (!strcmp ("device_resident", p))
            result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
+         else if (!strcmp ("device_type", p))
+           result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
          else if (!strcmp ("dist_schedule", p))
            result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
          break;
@@ -35321,6 +35323,56 @@ cp_parser_omp_clause_proc_bind (cp_parse
   return list;
 }
 
+/* OpenMP 5.0:
+   device_type ( host | nohost | any )  */
+
+static tree
+cp_parser_omp_clause_device_type (cp_parser *parser, tree list,
+                                 location_t location)
+{
+  tree c;
+  enum omp_clause_device_type_kind kind;
+
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+    return list;
+
+  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+    {
+      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+      const char *p = IDENTIFIER_POINTER (id);
+
+      if (strcmp ("host", p) == 0)
+       kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
+      else if (strcmp ("nohost", p) == 0)
+       kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
+      else if (strcmp ("any", p) == 0)
+       kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
+      else
+       goto invalid_kind;
+    }
+  else
+    goto invalid_kind;
+
+  cp_lexer_consume_token (parser->lexer);
+  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
+    goto resync_fail;
+
+  c = build_omp_clause (location, OMP_CLAUSE_DEVICE_TYPE);
+  /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, "device_type",
+                               location);  */
+  OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
+  OMP_CLAUSE_CHAIN (c) = list;
+  return c;
+
+ invalid_kind:
+  cp_parser_error (parser, "invalid depend kind");
+ resync_fail:
+  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+                                        /*or_comma=*/false,
+                                        /*consume_paren=*/true);
+  return list;
+}
+
 /* OpenACC:
    async [( int-expr )] */
 
@@ -35849,6 +35901,11 @@ cp_parser_omp_all_clauses (cp_parser *pa
                                                    token->location);
          c_name = "proc_bind";
          break;
+       case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
+         clauses = cp_parser_omp_clause_device_type (parser, clauses,
+                                                     token->location);
+         c_name = "device_type";
+         break;
        case PRAGMA_OMP_CLAUSE_SAFELEN:
          clauses = cp_parser_omp_clause_safelen (parser, clauses,
                                                  token->location);
@@ -39831,12 +39888,15 @@ cp_parser_late_parsing_omp_declare_simd
 
 #define OMP_DECLARE_TARGET_CLAUSE_MASK                         \
        ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)           \
-       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK))
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)         \
+       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
 
 static void
 cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
 {
   tree clauses = NULL_TREE;
+  int device_type = 0;
+  bool only_device_type = true;
   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
     clauses
       = cp_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
@@ -39854,17 +39914,18 @@ cp_parser_omp_declare_target (cp_parser
       scope_chain->omp_declare_target_attribute++;
       return;
     }
-  if (scope_chain->omp_declare_target_attribute)
-    error_at (pragma_tok->location,
-             "%<#pragma omp declare target%> with clauses in between "
-             "%<#pragma omp declare target%> without clauses and "
-             "%<#pragma omp end declare target%>");
+  for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+      device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
     {
+      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+       continue;
       tree t = OMP_CLAUSE_DECL (c), id;
       tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
       tree at2 = lookup_attribute ("omp declare target link",
                                   DECL_ATTRIBUTES (t));
+      only_device_type = false;
       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
        {
          id = get_identifier ("omp declare target link");
@@ -39897,7 +39958,34 @@ cp_parser_omp_declare_target (cp_parser
                }
            }
        }
+      if (TREE_CODE (t) != FUNCTION_DECL)
+       continue;
+      if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
+       {
+         tree at3 = lookup_attribute ("omp declare target host",
+                                      DECL_ATTRIBUTES (t));
+         if (at3 == NULL_TREE)
+           {
+             id = get_identifier ("omp declare target host");
+             DECL_ATTRIBUTES (t)
+               = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+           }
+       }
+      if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
+       {
+         tree at3 = lookup_attribute ("omp declare target nohost",
+                                      DECL_ATTRIBUTES (t));
+         if (at3 == NULL_TREE)
+           {
+             id = get_identifier ("omp declare target nohost");
+             DECL_ATTRIBUTES (t)
+               = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+           }
+       }
     }
+  if (device_type && only_device_type)
+    warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
+               "directive with only %<device_type%> clauses ignored");
 }
 
 static void
--- gcc/cp/semantics.c.jj       2019-08-08 08:37:11.283830662 +0200
+++ gcc/cp/semantics.c  2019-08-09 14:40:39.631070356 +0200
@@ -7578,6 +7578,7 @@ finish_omp_clauses (tree clauses, enum c
        case OMP_CLAUSE_SECTIONS:
        case OMP_CLAUSE_TASKGROUP:
        case OMP_CLAUSE_PROC_BIND:
+       case OMP_CLAUSE_DEVICE_TYPE:
        case OMP_CLAUSE_NOGROUP:
        case OMP_CLAUSE_THREADS:
        case OMP_CLAUSE_SIMD:
--- gcc/testsuite/c-c++-common/gomp/declare-target-2.c.jj       2015-11-05 
16:03:52.985122520 +0100
+++ gcc/testsuite/c-c++-common/gomp/declare-target-2.c  2019-08-09 
13:51:58.084661466 +0200
@@ -3,7 +3,7 @@
 
 extern int a;
 #pragma omp declare target
-#pragma omp declare target to (a)              /* { dg-error "with clauses in 
between" } */
+#pragma omp declare target to (a)
 #pragma omp end declare target
 int b;
 #pragma omp declare target to (b) link (b)     /* { dg-error "appears more 
than once on the same .declare target. directive" } */
--- gcc/testsuite/c-c++-common/gomp/declare-target-4.c.jj       2019-08-09 
14:38:03.344387170 +0200
+++ gcc/testsuite/c-c++-common/gomp/declare-target-4.c  2019-08-09 
14:44:44.829446768 +0200
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+#pragma omp declare target device_type (any)           /* { dg-warning 
"directive with only 'device_type' clauses ignored" } */
+
+void f1 (void) {}
+void f2 (void);
+#pragma omp declare target to (f1) device_type (any) to (f2)
+
+void f3 (void) {}
+void f4 (void) {}
+#pragma omp declare target device_type (host) to (f3)
+#pragma omp declare target to (f4) device_type (nohost)
+
+#pragma omp declare target
+void f5 (void);
+void f6 (void) {}
+void f7 (void) {}
+#pragma omp declare target to (f7)
+void f8 (void) {}
+#pragma omp declare target to (f8, f5)
+#pragma omp declare target to (f5) to(f8)
+#pragma omp declare target to (f8) device_type (host)
+void f9 (void) {}
+#pragma omp declare target to (f9) device_type (nohost)
+#pragma omp declare target to (f9)
+void f10 (void) {}
+#pragma omp declare target device_type (any) to (f10)
+void f11 (void) {}
+#pragma omp end declare target
+
+void f12 (void) {}
+#pragma omp declare target device_type (any) to (f12)
+#pragma omp declare target to (f12) device_type (host)
+void f13 (void) {}
+#pragma omp declare target device_type (host) to (f13)
+#pragma omp declare target to (f13) device_type (nohost)
+void f14 (void) {}
+#pragma omp declare target device_type (nohost) to (f14)
+#pragma omp declare target device_type (any) to (f14)
+void f15 (void) {}
+#pragma omp declare target device_type (host) to (f15) device_type (nohost)
+void f16 (void) {}
+#pragma omp declare target device_type (any) to (f15) device_type (any)

        Jakub

Reply via email to