From cc925ff8a771863b60b773cd296362dd07773ace Mon Sep 17 00:00:00 2001 From: tschwinge Date: Thu, 4 Aug 2016 13:35:19 +0000 Subject: C/C++: Simplify handling of location information for OpenACC routine directives gcc/c/ * 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. gcc/cp/ * 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. upstream hash: 5f429ee2993ea1795d88c5589251c500e6e9062a git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@239127 138bc75d-0d04-0410-961f-82ee72b054a4 Change-Id: I6e8b2ad2102b50798fd0fb7b373e6c4ccb17acd7 --- gcc/c/c-parser.c | 86 ++++++++++++++++++++++---------------------- gcc/cp/parser.c | 108 ++++++++++++++++++++++++------------------------------- gcc/cp/parser.h | 21 ++++++----- 3 files changed, 103 insertions(+), 112 deletions(-) diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index e8fee5360b6..99a2314ef75 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -1267,11 +1267,17 @@ enum c_parser_prec { 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, - 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, @@ -1363,7 +1369,7 @@ static bool c_parser_omp_target (c_parser *, enum pragma_context, 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. */ @@ -1555,7 +1561,8 @@ c_parser_external_declaration (c_parser *parser) } static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec); -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 @@ -1634,7 +1641,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool nested, bool start_attr_ok, tree *objc_foreach_object_declaration, vec omp_declare_simd_clauses, - tree oacc_routine_clauses) + struct oacc_routine_data *oacc_routine_data) { struct c_declspecs *specs; tree prefix_attrs; @@ -1704,9 +1711,9 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, 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; } @@ -1823,9 +1830,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, || !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; @@ -1950,8 +1956,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, finish_init (); processing_static_variable = false; } - 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) { @@ -1996,8 +2002,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, 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, @@ -2109,9 +2115,9 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, || !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); @@ -13972,9 +13978,9 @@ static void 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"); @@ -14010,56 +14016,52 @@ c_parser_oacc_routine (c_parser *parser, enum pragma_context context) /* 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: diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index b66b7e1946a..c163dbadc89 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1384,10 +1384,8 @@ cp_ensure_no_oacc_routine (cp_parser *parser) { 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; } @@ -3756,15 +3754,17 @@ cp_parser_new (void) /* 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; @@ -19839,8 +19839,9 @@ parsing_nsdmi (void) 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. */ @@ -23717,6 +23718,7 @@ cp_parser_cilk_simd_fn_vector_attrs (cp_parser *parser, cp_token *v_token) 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)) @@ -35718,6 +35720,9 @@ cp_parser_omp_declare_simd (cp_parser *parser, cp_token *pragma_tok, 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) @@ -35835,7 +35840,6 @@ cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs) 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; @@ -36549,21 +36553,19 @@ cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok, 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"); @@ -36584,7 +36586,7 @@ cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok, 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"); @@ -36604,7 +36606,7 @@ cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok, /*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); @@ -36619,20 +36621,17 @@ cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok, /* 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; } @@ -36641,7 +36640,8 @@ cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok, 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; @@ -36649,14 +36649,12 @@ cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok, 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; @@ -36674,23 +36672,18 @@ cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok, = 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 (); @@ -36706,19 +36699,15 @@ static tree 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; @@ -36730,15 +36719,11 @@ cp_parser_late_parsing_oacc_routine (cp_parser *parser, tree 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; } @@ -36751,9 +36736,6 @@ cp_finalize_oacc_routine (cp_parser *parser, tree fndecl, bool is_defn) { 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; @@ -36771,31 +36753,35 @@ cp_finalize_oacc_routine (cp_parser *parser, tree fndecl, bool is_defn) 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)); diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h index ccbace9e0bf..a777a843267 100644 --- a/gcc/cp/parser.h +++ b/gcc/cp/parser.h @@ -199,7 +199,8 @@ struct GTY (()) cp_parser_context { }; -/* 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. */ @@ -207,6 +208,10 @@ struct cp_omp_declare_simd_data { 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. */ @@ -363,18 +368,16 @@ struct GTY(()) cp_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. */ -- cgit v1.2.3