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