static tree cp_parser_cilk_simd_vectorlength
(cp_parser *, tree, bool);
static void cp_finalize_oacc_routine
- (cp_parser *, tree, bool);
+ (cp_parser *, tree, bool, bool);
/* Manifest constants. */
#define CP_LEXER_BUFFER_SIZE ((256 * 1024) / sizeof (cp_token))
static inline void
cp_ensure_no_oacc_routine (cp_parser *parser)
{
- cp_finalize_oacc_routine (parser, NULL_TREE, false);
+ cp_finalize_oacc_routine (parser, NULL_TREE, false, true);
}
\f
/* Decl-specifiers. */
static tree cp_parser_init_declarator
(cp_parser *, cp_decl_specifier_seq *, vec<deferred_access_check, va_gc> *,
- bool, bool, int, bool *, tree *, location_t *);
+ bool, bool, int, bool *, tree *, bool, location_t *);
static cp_declarator *cp_parser_declarator
(cp_parser *, cp_parser_declarator_kind, int *, bool *, bool, bool);
static cp_declarator *cp_parser_direct_declarator
static tree cp_parser_functional_cast
(cp_parser *, tree);
static tree cp_parser_save_member_function_body
- (cp_parser *, cp_decl_specifier_seq *, cp_declarator *, tree);
+ (cp_parser *, cp_decl_specifier_seq *, cp_declarator *, tree, bool);
static tree cp_parser_save_nsdmi
(cp_parser *);
static tree cp_parser_enclosed_template_argument_list
bool saw_declarator;
location_t comma_loc = UNKNOWN_LOCATION;
location_t init_loc = UNKNOWN_LOCATION;
+ bool first = true;
if (maybe_range_for_decl)
*maybe_range_for_decl = NULL_TREE;
declares_class_or_enum,
&function_definition_p,
maybe_range_for_decl,
+ first,
&init_loc);
+ first = false;
+
/* If an error occurred while parsing tentatively, exit quickly.
(That usually happens when in the body of a function; each
statement is treated as a declaration-statement until proven
done:
pop_deferring_access_checks ();
+
+ /* Reset any acc routine clauses. */
+ parser->oacc_routine = NULL;
}
/* Parse a decl-specifier-seq.
if present, will not be consumed. If returned, this declarator will be
created with SD_INITIALIZED but will not call cp_finish_decl.
+ FIRST indicates if this is the first declarator in a declaration sequence.
+
If INIT_LOC is not NULL, and *INIT_LOC is equal to UNKNOWN_LOCATION,
and there is an initializer, the pointed location_t is set to the
location of the '=' or `(', or '{' in C++11 token introducing the
int declares_class_or_enum,
bool* function_definition_p,
tree* maybe_range_for_decl,
+ bool first,
location_t* init_loc)
{
cp_token *token = NULL, *asm_spec_start_token = NULL,
decl = cp_parser_save_member_function_body (parser,
decl_specifiers,
declarator,
- prefix_attributes);
+ prefix_attributes,
+ true);
else
decl =
(cp_parser_function_definition_from_specifiers_and_declarator
range_for_decl_p? SD_INITIALIZED : is_initialized,
attributes, prefix_attributes, &pushed_scope);
cp_finalize_omp_declare_simd (parser, decl);
- cp_finalize_oacc_routine (parser, decl, false);
+ cp_finalize_oacc_routine (parser, decl, false, first);
/* Adjust location of decl if declarator->id_loc is more appropriate:
set, and decl wasn't merged with another decl, in which case its
location would be different from input_location, and more accurate. */
if (decl && TREE_CODE (decl) == FUNCTION_DECL)
cp_parser_save_default_args (parser, decl);
cp_finalize_omp_declare_simd (parser, decl);
- cp_finalize_oacc_routine (parser, decl, false);
+ cp_finalize_oacc_routine (parser, decl, false, first);
}
/* Finish processing the declaration. But, skip member
else
{
bool assume_semicolon = false;
+ bool first = true;
/* Clear attributes from the decl_specifiers but keep them
around as prefix attributes that apply them to the entity
decl = cp_parser_save_member_function_body (parser,
&decl_specifiers,
declarator,
- attributes);
+ attributes,
+ first);
+ first = false;
+
if (parser->fully_implicit_function_template_p)
decl = finish_fully_implicit_template (parser, decl);
/* If the member was not a friend, declare it here. */
}
cp_finalize_omp_declare_simd (parser, decl);
- cp_finalize_oacc_routine (parser, decl, false);
+ cp_finalize_oacc_routine (parser, decl, false, first);
+ first = false;
/* Reset PREFIX_ATTRIBUTES. */
while (attributes && TREE_CHAIN (attributes) != first_attribute)
if (assume_semicolon)
goto out;
}
+
+ /* Reset any OpenACC routine clauses. */
+ parser->oacc_routine = NULL;
}
cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
{
cp_finalize_omp_declare_simd (parser, current_function_decl);
parser->omp_declare_simd = NULL;
- cp_finalize_oacc_routine (parser, current_function_decl, true);
+ cp_finalize_oacc_routine (parser, current_function_decl, true, true);
+ parser->oacc_routine = NULL;
}
if (!success_p)
member_p,
declares_class_or_enum,
&function_definition_p,
- NULL, NULL);
+ NULL, true, NULL);
/* 7.1.1-1 [dcl.stc]
/* Save the tokens that make up the body of a member function defined
in a class-specifier. The DECL_SPECIFIERS and DECLARATOR have
already been parsed. The ATTRIBUTES are any GNU "__attribute__"
- specifiers applied to the declaration. Returns the FUNCTION_DECL
- for the member function. */
+ specifiers applied to the declaration. FIRST_DECL indicates if
+ DECLARATOR is the first declarator in a declaration sequence. Returns
+ the FUNCTION_DECL for the member function. */
static tree
cp_parser_save_member_function_body (cp_parser* parser,
cp_decl_specifier_seq *decl_specifiers,
cp_declarator *declarator,
- tree attributes)
+ tree attributes, bool first_decl)
{
cp_token *first;
cp_token *last;
/* Create the FUNCTION_DECL. */
fn = grokmethod (decl_specifiers, declarator, attributes);
cp_finalize_omp_declare_simd (parser, fn);
- cp_finalize_oacc_routine (parser, fn, true);
+ cp_finalize_oacc_routine (parser, fn, true, first_decl);
/* If something went badly wrong, bail out now. */
if (fn == error_mark_node)
{
static void
cp_parser_finish_oacc_routine (cp_parser *ARG_UNUSED (parser), tree fndecl,
- tree clauses, bool named, bool is_defn)
+ tree clauses, bool named, bool is_defn,
+ bool first)
{
location_t loc = OMP_CLAUSE_LOCATION (TREE_PURPOSE (clauses));
return;
}
- if (!fndecl || TREE_CODE (fndecl) != FUNCTION_DECL)
+ if (!fndecl || TREE_CODE (fndecl) != FUNCTION_DECL
+ || (!named && !first))
{
error_at (loc, "%<#pragma acc routine%> %s",
named ? "does not refer to a function"
clauses = tree_cons (c_head, clauses, NULL_TREE);
if (decl)
- cp_parser_finish_oacc_routine (parser, decl, clauses, true, false);
+ cp_parser_finish_oacc_routine (parser, decl, clauses, true, false, 0);
else
parser->oacc_routine = clauses;
}
declaration. */
static void
-cp_finalize_oacc_routine (cp_parser *parser, tree fndecl, bool is_defn)
+cp_finalize_oacc_routine (cp_parser *parser, tree fndecl, bool is_defn,
+ bool first)
{
if (parser->oacc_routine)
- {
- cp_parser_finish_oacc_routine (parser, fndecl, parser->oacc_routine,
- false, is_defn);
- parser->oacc_routine = NULL_TREE;
- }
+ cp_parser_finish_oacc_routine (parser, fndecl, parser->oacc_routine,
+ false, is_defn, first);
}
/* Main entry point to OpenMP statement pragmas. */