Hi!

Some users of C/C++ OpenACC are surprised to see code such as:

    #pragma acc routine (F)
    [declaration or definition of F]

... run into "error: 'F' has not been declared".  If the routine
directive is meant to apply to the lexically following function
declaration or definition, either don't specify '(F)' here:

    #pragma acc routine
    [declaration or definition of F]

..., or place a function declaration before the directive:

    [declaration of F]
    #pragma acc routine (F)
    
    [definition or use of F]

OK for trunk?

commit 83442d8baef0d0c09128368879b69873cbf9bf01
Author: Thomas Schwinge <tho...@codesourcery.com>
Date:   Tue May 24 17:21:54 2016 +0200

    C/C++ OpenACC routine directive, undeclared name error: try to help the 
user, once
    
        gcc/c/
        * c-parser.c (c_parser_oacc_routine): If running into an
        undeclared name error, try to help the user, once.
        gcc/cp/
        * parser.c (cp_parser_oacc_routine): If running into an undeclared
        name error, try to help the user, once.
        gcc/testsuite/
        * c-c++-common/goacc/routine-5.c: Update.
---
 gcc/c/c-parser.c                             | 17 +++++++++++++++--
 gcc/cp/parser.c                              | 17 +++++++++++++++--
 gcc/testsuite/c-c++-common/goacc/routine-5.c | 15 ++++++++++++++-
 3 files changed, 44 insertions(+), 5 deletions(-)

diff --git gcc/c/c-parser.c gcc/c/c-parser.c
index cbd4e4c..6b589a4 100644
--- gcc/c/c-parser.c
+++ gcc/c/c-parser.c
@@ -13989,8 +13989,21 @@ c_parser_oacc_routine (c_parser *parser, enum 
pragma_context context)
        {
          decl = lookup_name (token->value);
          if (!decl)
-           error_at (token->location, "%qE has not been declared",
-                     token->value);
+           {
+             error_at (token->location, "%qE has not been declared",
+                       token->value);
+             static bool informed_once = false;
+             if (!informed_once)
+               {
+                 inform (token->location,
+                         "if the routine directive is meant to apply to the "
+                         "lexically following function declaration or "
+                         "definition, either don't specify %<(%E)%> here, or "
+                         "place a function declaration before the directive",
+                         token->value);
+                 informed_once = true;
+               }
+           }
          c_parser_consume_token (parser);
        }
       else
diff --git gcc/cp/parser.c gcc/cp/parser.c
index 6485cbd..4d542a0 100644
--- gcc/cp/parser.c
+++ gcc/cp/parser.c
@@ -36504,8 +36504,21 @@ cp_parser_oacc_routine (cp_parser *parser, cp_token 
*pragma_tok,
                                         /*optional_p=*/false);
       decl = cp_parser_lookup_name_simple (parser, id, token->location);
       if (id != error_mark_node && decl == error_mark_node)
-       cp_parser_name_lookup_error (parser, id, decl, NLE_NULL,
-                                    token->location);
+       {
+         cp_parser_name_lookup_error (parser, id, decl, NLE_NULL,
+                                      token->location);
+         static bool informed_once = false;
+         if (!informed_once)
+           {
+             inform (token->location,
+                     "if the routine directive is meant to apply to the "
+                     "lexically following function declaration or "
+                     "definition, either don't specify %<(%E)%> here, or "
+                     "place a function declaration before the directive",
+                     id);
+             informed_once = true;
+           }
+       }
 
       if (decl == error_mark_node
          || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
diff --git gcc/testsuite/c-c++-common/goacc/routine-5.c 
gcc/testsuite/c-c++-common/goacc/routine-5.c
index 1efd154..9c30e87 100644
--- gcc/testsuite/c-c++-common/goacc/routine-5.c
+++ gcc/testsuite/c-c++-common/goacc/routine-5.c
@@ -71,7 +71,20 @@ void Foo ()
 
 #pragma acc routine (Foo) gang // { dg-error "must be applied before 
definition" }
 
-#pragma acc routine (Baz) // { dg-error "not been declared" }
+#pragma acc routine (Baz) worker
+/* { dg-error ".Baz. has not been declared" "" { target *-*-* } 74 }
+   Try to help the user:
+   { dg-message "note: if the routine directive" "" { target *-*-* } 74 } */
+
+#pragma acc routine (Baz) vector
+/* { dg-error ".Baz. has not been declared" "" { target *-*-* } 79 }
+   Don't try to help the user again:
+   { dg-bogus "note: if the routine directive" "" { target *-*-* } 79 } */
+
+#pragma acc routine (Qux) seq
+/* { dg-error ".Qux. has not been declared" "" { target *-*-* } 84 }
+   Don't try to help the user again:
+   { dg-bogus "note: if the routine directive" "" { target *-*-* } 84 } */
 
 
 int vb1;               /* { dg-error "directive for use" } */


Grüße
 Thomas

Reply via email to