+2016-08-04 Thomas Schwinge <thomas@codesourcery.com>
+
+ * c-parser.c (struct oacc_routine_data): New.
+ (c_parser_declaration_or_fndef, c_parser_oacc_routine): Use it.
+ Simplify code.
+ (c_finish_oacc_routine): Likewise. Don't attach clauses to "omp
+ declare target" attribute.
+
2016-08-01 Jan Beulich <jbeulich@suse.com>
* c-fold.c (c_fully_fold_internal): Also emit shift count
NUM_PRECS
};
+/* Helper data structure for parsing #pragma acc routine. */
+struct oacc_routine_data {
+ tree clauses;
+ location_t loc;
+};
+
static void c_parser_external_declaration (c_parser *);
static void c_parser_asm_definition (c_parser *);
static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
bool, bool, tree *, vec<c_token>,
- tree = NULL_TREE);
+ struct oacc_routine_data * = NULL);
static void c_parser_static_assert_declaration_no_semi (c_parser *);
static void c_parser_static_assert_declaration (c_parser *);
static void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool,
static void c_parser_omp_end_declare_target (c_parser *);
static void c_parser_omp_declare (c_parser *, enum pragma_context);
static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
-static void c_parser_oacc_routine (c_parser *parser, enum pragma_context);
+static void c_parser_oacc_routine (c_parser *, enum pragma_context);
/* These Objective-C parser functions are only ever called when
compiling Objective-C. */
}
static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token>);
-static void c_finish_oacc_routine (c_parser *, tree, tree, bool, bool, bool);
+static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool,
+ bool, bool);
/* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
6.7, 6.9.1). If FNDEF_OK is true, a function definition is
bool nested, bool start_attr_ok,
tree *objc_foreach_object_declaration,
vec<c_token> omp_declare_simd_clauses,
- tree oacc_routine_clauses)
+ struct oacc_routine_data *oacc_routine_data)
{
struct c_declspecs *specs;
tree prefix_attrs;
pedwarn (here, 0, "empty declaration");
}
c_parser_consume_token (parser);
- if (oacc_routine_clauses)
- c_finish_oacc_routine (parser, NULL_TREE,
- oacc_routine_clauses, false, true, false);
+ if (oacc_routine_data)
+ c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false, true,
+ false);
return;
}
|| !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
omp_declare_simd_clauses);
- if (oacc_routine_clauses)
- c_finish_oacc_routine (parser, NULL_TREE,
- oacc_routine_clauses,
+ if (oacc_routine_data)
+ c_finish_oacc_routine (oacc_routine_data, NULL_TREE,
false, first, false);
c_parser_skip_to_end_of_block_or_statement (parser);
return;
init = c_parser_initializer (parser);
finish_init ();
}
- if (oacc_routine_clauses)
- c_finish_oacc_routine (parser, d, oacc_routine_clauses,
+ if (oacc_routine_data)
+ c_finish_oacc_routine (oacc_routine_data, d,
false, first, false);
if (d != error_mark_node)
{
if (parms)
temp_pop_parm_decls ();
}
- if (oacc_routine_clauses)
- c_finish_oacc_routine (parser, d, oacc_routine_clauses,
+ if (oacc_routine_data)
+ c_finish_oacc_routine (oacc_routine_data, d,
false, first, false);
if (d)
finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
|| !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
omp_declare_simd_clauses);
- if (oacc_routine_clauses)
- c_finish_oacc_routine (parser, current_function_decl,
- oacc_routine_clauses, false, first, true);
+ if (oacc_routine_data)
+ c_finish_oacc_routine (oacc_routine_data, current_function_decl,
+ false, first, true);
DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
= c_parser_peek_token (parser)->location;
fnbody = c_parser_compound_statement (parser);
c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
{
tree decl = NULL_TREE;
- /* Create a dummy claue, to record location. */
- tree c_head = build_omp_clause (c_parser_peek_token (parser)->location,
- OMP_CLAUSE_SEQ);
+ oacc_routine_data data;
+ data.clauses = NULL_TREE;
+ data.loc = c_parser_peek_token (parser)->location;
if (context != pragma_external)
c_parser_error (parser, "%<#pragma acc routine%> not at file scope");
/* Build a chain of clauses. */
parser->in_pragma = true;
- tree clauses = c_parser_oacc_all_clauses
- (parser, OACC_ROUTINE_CLAUSE_MASK, "#pragma acc routine");
+ data.clauses
+ = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
+ "#pragma acc routine");
- /* Force clauses to be non-null, by attaching context to it. */
- clauses = tree_cons (c_head, clauses, NULL_TREE);
-
if (decl)
- c_finish_oacc_routine (parser, decl, clauses, true, true, false);
+ c_finish_oacc_routine (&data, decl, true, true, false);
else if (c_parser_peek_token (parser)->type == CPP_PRAGMA)
/* This will emit an error. */
- c_finish_oacc_routine (parser, NULL_TREE, clauses, false, true, false);
+ c_finish_oacc_routine (&data, NULL_TREE, false, true, false);
else
c_parser_declaration_or_fndef (parser, true, false, false, false,
- true, NULL, vNULL, clauses);
+ true, NULL, vNULL, &data);
}
-/* Finalize an OpenACC routine pragma, applying it to FNDECL. CLAUSES
- are the parsed clauses. IS_DEFN is true if we're applying it to
- the definition (so expect FNDEF to look somewhat defined. */
+/* Finalize an OpenACC routine pragma, applying it to FNDECL.
+ IS_DEFN is true if we're applying it to the definition. */
static void
-c_finish_oacc_routine (c_parser *ARG_UNUSED (parser), tree fndecl,
- tree clauses, bool named, bool first, bool is_defn)
+c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
+ bool named, bool first, bool is_defn)
{
- location_t loc = OMP_CLAUSE_LOCATION (TREE_PURPOSE (clauses));
-
if (!fndecl || TREE_CODE (fndecl) != FUNCTION_DECL || !first)
{
if (fndecl != error_mark_node)
- error_at (loc, "%<#pragma acc routine%> %s",
+ error_at (data->loc, "%<#pragma acc routine%> %s",
named ? "does not refer to a function"
: "not followed by single function");
return;
}
if (get_oacc_fn_attrib (fndecl))
- error_at (loc, "%<#pragma acc routine%> already applied to %D", fndecl);
+ error_at (data->loc,
+ "%<#pragma acc routine%> already applied to %D", fndecl);
if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
- error_at (loc, "%<#pragma acc routine%> must be applied before %s",
+ error_at (data->loc, "%<#pragma acc routine%> must be applied before %s",
TREE_USED (fndecl) ? "use" : "definition");
- /* Process for function attrib */
- tree dims = build_oacc_routine_dims (TREE_VALUE (clauses));
+ /* Process the routine's dimension clauses. */
+ tree dims = build_oacc_routine_dims (data->clauses);
replace_oacc_fn_attrib (fndecl, dims);
- /* Also attach as a declare. */
+ /* Add an "omp declare target" attribute. */
DECL_ATTRIBUTES (fndecl)
= tree_cons (get_identifier ("omp declare target"),
- clauses, DECL_ATTRIBUTES (fndecl));
+ NULL_TREE, DECL_ATTRIBUTES (fndecl));
}
/* OpenACC 2.0:
+2016-08-04 Thomas Schwinge <thomas@codesourcery.com>
+
+ * parser.h (struct cp_omp_declare_simd_data): New.
+ (struct cp_parser): Use it for oacc_routine member.
+ * parser.c (cp_ensure_no_oacc_routine, cp_parser_oacc_routine)
+ (cp_parser_late_parsing_oacc_routine, cp_finalize_oacc_routine):
+ Use it. Simplify code.
+ (cp_parser_new): Initialize all members pointing to special
+ parsing data structures.
+ (cp_parser_cilk_simd_fn_vector_attrs): Initialize
+ parser->cilk_simd_fn_info->clauses.
+ (cp_parser_omp_declare_simd): Initialize
+ parser->omp_declare_simd->clauses.
+ (cp_parser_late_parsing_omp_declare_simd): Simplify code.
+
2016-08-04 Marek Polacek <polacek@redhat.com>
PR c++/70229
{
if (parser->oacc_routine && !parser->oacc_routine->error_seen)
{
- tree clauses = parser->oacc_routine->clauses;
- location_t loc = OMP_CLAUSE_LOCATION (TREE_PURPOSE (clauses));
-
- error_at (loc, "%<#pragma acc routine%> not followed by a function "
+ error_at (parser->oacc_routine->loc,
+ "%<#pragma acc routine%> not followed by a function "
"declaration or definition");
parser->oacc_routine = NULL;
}
/* No template parameters apply. */
parser->num_template_parameter_lists = 0;
+ /* Special parsing data structures. */
+ parser->omp_declare_simd = NULL;
+ parser->cilk_simd_fn_info = NULL;
+ parser->oacc_routine = NULL;
+
/* Not declaring an implicit function template. */
parser->auto_is_implicit_function_template_parm_p = false;
parser->fully_implicit_function_template_p = false;
parser->implicit_template_parms = 0;
parser->implicit_template_scope = 0;
- /* Active OpenACC routine clauses. */
- parser->oacc_routine = NULL;
-
/* Allow constrained-type-specifiers. */
parser->prevent_constrained_type_specifiers = 0;
Returns the type indicated by the type-id.
- In addition to this, parse any queued up omp declare simd
- clauses and Cilk Plus SIMD-enabled function's vector attributes.
+ In addition to this, parse any queued up #pragma omp declare simd
+ clauses, Cilk Plus SIMD-enabled functions' vector attributes, and
+ #pragma acc routine clauses.
QUALS is either a bitmask of cv_qualifiers or -1 for a non-member
function. */
parser->cilk_simd_fn_info->error_seen = false;
parser->cilk_simd_fn_info->fndecl_seen = false;
parser->cilk_simd_fn_info->tokens = vNULL;
+ parser->cilk_simd_fn_info->clauses = NULL_TREE;
}
int paren_scope = 0;
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
data.error_seen = false;
data.fndecl_seen = false;
data.tokens = vNULL;
+ data.clauses = NULL_TREE;
+ /* It is safe to take the address of a local variable; it will only be
+ used while this scope is live. */
parser->omp_declare_simd = &data;
}
while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL)
error ("%<#pragma omp declare simd%> not immediately followed by "
"a single function declaration or definition");
data->error_seen = true;
- return attrs;
}
if (data->error_seen)
return attrs;
enum pragma_context context)
{
bool first_p = parser->oacc_routine == NULL;
- location_t loc = pragma_tok->location;
- cp_omp_declare_simd_data data;
+ cp_oacc_routine_data data;
if (first_p)
{
data.error_seen = false;
data.fndecl_seen = false;
data.tokens = vNULL;
data.clauses = NULL_TREE;
+ data.loc = pragma_tok->location;
+ /* It is safe to take the address of a local variable; it will only be
+ used while this scope is live. */
parser->oacc_routine = &data;
}
- tree decl = NULL_TREE;
- /* Create a dummy claue, to record location. */
- tree c_head = build_omp_clause (pragma_tok->location, OMP_CLAUSE_SEQ);
-
if (context != pragma_external)
{
cp_parser_error (parser, "%<#pragma acc routine%> not at file scope");
parser->oacc_routine->error_seen = true;
cp_parser_require_pragma_eol (parser, pragma_tok);
- error_at (OMP_CLAUSE_LOCATION (parser->oacc_routine->clauses),
+ error_at (parser->oacc_routine->loc,
"%<#pragma acc routine%> not followed by a "
"function declaration or definition");
/*template_p=*/NULL,
/*declarator_p=*/false,
/*optional_p=*/false);
- decl = cp_parser_lookup_name_simple (parser, id, token->location);
+ tree 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);
/* Build a chain of clauses. */
parser->lexer->in_pragma = true;
- tree clauses = NULL_TREE;
- clauses = cp_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
- "#pragma acc routine",
- cp_lexer_peek_token
- (parser->lexer));
-
- /* Force clauses to be non-null, by attaching context to it. */
- clauses = tree_cons (c_head, clauses, NULL_TREE);
+ data.clauses
+ = cp_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
+ "#pragma acc routine",
+ cp_lexer_peek_token (parser->lexer));
if (decl && is_overloaded_fn (decl)
&& (TREE_CODE (decl) != FUNCTION_DECL
|| DECL_FUNCTION_TEMPLATE_P (decl)))
{
- error_at (loc, "%<#pragma acc routine%> names a set of overloads");
+ error_at (data.loc,
+ "%<#pragma acc routine%> names a set of overloads");
parser->oacc_routine = NULL;
return;
}
namespaces? */
if (!DECL_NAMESPACE_SCOPE_P (decl))
{
- error_at (loc, "%<#pragma acc routine%> does not refer to a "
+ error_at (data.loc,
+ "%<#pragma acc routine%> does not refer to a "
"namespace scope function");
parser->oacc_routine = NULL;
return;
if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
{
- error_at (loc,
+ error_at (data.loc,
"%<#pragma acc routine%> does not refer to a function");
parser->oacc_routine = NULL;
return;
}
- data.clauses = clauses;
-
cp_finalize_oacc_routine (parser, decl, false);
data.tokens.release ();
parser->oacc_routine = NULL;
= cp_token_cache_new (pragma_tok, cp_lexer_peek_token (parser->lexer));
parser->oacc_routine->tokens.safe_push (cp);
- if (first_p)
- parser->oacc_routine->clauses = c_head;
-
while (cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA))
cp_parser_pragma (parser, context, NULL);
if (first_p)
{
- /* Create an empty list of clauses. */
- parser->oacc_routine->clauses = tree_cons (c_head, NULL_TREE,
- NULL_TREE);
cp_parser_declaration (parser);
if (parser->oacc_routine
&& !parser->oacc_routine->error_seen
&& !parser->oacc_routine->fndecl_seen)
- error_at (loc, "%<#pragma acc routine%> not followed by a "
+ error_at (data.loc,
+ "%<#pragma acc routine%> not followed by a "
"function declaration or definition");
data.tokens.release ();
cp_parser_late_parsing_oacc_routine (cp_parser *parser, tree attrs)
{
struct cp_token_cache *ce;
- cp_omp_declare_simd_data *data = parser->oacc_routine;
- tree cl, clauses = parser->oacc_routine->clauses;
- location_t loc;
+ cp_oacc_routine_data *data = parser->oacc_routine;
- loc = OMP_CLAUSE_LOCATION (TREE_PURPOSE(clauses));
-
if ((!data->error_seen && data->fndecl_seen)
|| data->tokens.length () != 1)
{
- error_at (loc, "%<#pragma acc routine%> not followed by a "
+ error_at (data->loc,
+ "%<#pragma acc routine%> not followed by a "
"function declaration or definition");
data->error_seen = true;
- return attrs;
}
if (data->error_seen)
return attrs;
gcc_assert (cp_lexer_peek_token (parser->lexer)->type == CPP_PRAGMA);
cp_token *pragma_tok = cp_lexer_consume_token (parser->lexer);
- cl = cp_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
+ parser->oacc_routine->clauses
+ = cp_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
"#pragma acc routine", pragma_tok);
cp_parser_pop_lexer (parser);
- tree c_head = build_omp_clause (loc, OMP_CLAUSE_SEQ);
-
- /* Force clauses to be non-null, by attaching context to it. */
- parser->oacc_routine->clauses = tree_cons (c_head, cl, NULL_TREE);
-
data->fndecl_seen = true;
return attrs;
}
{
if (__builtin_expect (parser->oacc_routine != NULL, 0))
{
- tree clauses = parser->oacc_routine->clauses;
- location_t loc = OMP_CLAUSE_LOCATION (TREE_PURPOSE(clauses));
-
if (parser->oacc_routine->error_seen)
return;
if (!fndecl || TREE_CODE (fndecl) != FUNCTION_DECL)
{
- error_at (loc,
+ error_at (parser->oacc_routine->loc,
"%<#pragma acc routine%> not followed by a function "
"declaration or definition");
parser->oacc_routine = NULL;
+ return;
}
if (get_oacc_fn_attrib (fndecl))
{
- error_at (loc, "%<#pragma acc routine%> already applied to %D",
- fndecl);
+ error_at (parser->oacc_routine->loc,
+ "%<#pragma acc routine%> already applied to %D", fndecl);
parser->oacc_routine = NULL;
+ return;
}
if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
{
- error_at (loc, "%<#pragma acc routine%> must be applied before %s",
+ error_at (parser->oacc_routine->loc,
+ "%<#pragma acc routine%> must be applied before %s",
TREE_USED (fndecl) ? "use" : "definition");
parser->oacc_routine = NULL;
+ return;
}
- /* Process for function attrib */
- tree dims = build_oacc_routine_dims (TREE_VALUE (clauses));
+ /* Process the routine's dimension clauses. */
+ tree dims = build_oacc_routine_dims (parser->oacc_routine->clauses);
replace_oacc_fn_attrib (fndecl, dims);
- /* Add an "omp target" attribute. */
+ /* Add an "omp declare target" attribute. */
DECL_ATTRIBUTES (fndecl)
= tree_cons (get_identifier ("omp declare target"),
NULL_TREE, DECL_ATTRIBUTES (fndecl));
};
-/* Control structure for #pragma omp declare simd parsing. */
+/* Helper data structure for parsing #pragma omp declare simd, and Cilk Plus
+ SIMD-enabled functions' vector attribute. */
struct cp_omp_declare_simd_data {
bool error_seen; /* Set if error has been reported. */
bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */
tree clauses;
};
+/* Helper data structure for parsing #pragma acc routine. */
+struct cp_oacc_routine_data : cp_omp_declare_simd_data {
+ location_t loc;
+};
/* The cp_parser structure represents the C++ parser. */
unsigned num_template_parameter_lists;
/* When parsing #pragma omp declare simd, this is a pointer to a
- data structure with everything needed for parsing the clauses. */
+ helper data structure. */
cp_omp_declare_simd_data * GTY((skip)) omp_declare_simd;
- /* When parsing the vector attribute in Cilk Plus SIMD-enabled function,
- this is a pointer to data structure with everything needed for parsing
- the clauses. The cp_omp_declare_simd_data struct will hold all the
- necessary information, so creating another struct for this is not
- necessary. */
+ /* When parsing Cilk Plus SIMD-enabled functions' vector attributes,
+ this is a pointer to a helper data structure. */
cp_omp_declare_simd_data * GTY((skip)) cilk_simd_fn_info;
- /* Parsing information for #pragma acc routine. */
- cp_omp_declare_simd_data * GTY((skip)) oacc_routine;
+ /* When parsing #pragma acc routine, this is a pointer to a helper data
+ structure. */
+ cp_oacc_routine_data * GTY((skip)) oacc_routine;
/* Nonzero if parsing a parameter list where 'auto' should trigger an implicit
template parameter. */