diff options
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 61 |
1 files changed, 51 insertions, 10 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ca9f8b9761a..fb88021e237 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2392,7 +2392,7 @@ static tree cp_parser_gnu_attributes_opt static tree cp_parser_gnu_attribute_list (cp_parser *); static tree cp_parser_std_attribute - (cp_parser *); + (cp_parser *, tree); static tree cp_parser_std_attribute_spec (cp_parser *); static tree cp_parser_std_attribute_spec_seq @@ -21594,7 +21594,7 @@ cp_parser_class_specifier_1 (cp_parser* parser) next_loc = linemap_position_for_loc_and_offset (line_table, loc, 1); rich_location richloc (line_table, next_loc); - richloc.add_fixit_insert (next_loc, ";"); + richloc.add_fixit_insert_before (next_loc, ";"); if (CLASSTYPE_DECLARED_CLASS (type)) error_at_rich_loc (&richloc, @@ -22037,7 +22037,8 @@ cp_parser_class_head (cp_parser* parser, class_head_start_location, get_finish (type_start_token->location)); rich_location richloc (line_table, reported_loc); - richloc.add_fixit_insert (class_head_start_location, "template <> "); + richloc.add_fixit_insert_before (class_head_start_location, + "template <> "); error_at_rich_loc (&richloc, "an explicit specialization must be preceded by %<template <>%>"); @@ -24055,9 +24056,9 @@ cp_parser_gnu_attribute_list (cp_parser* parser) { balanced-token-seq }. */ static tree -cp_parser_std_attribute (cp_parser *parser) +cp_parser_std_attribute (cp_parser *parser, tree attr_ns) { - tree attribute, attr_ns = NULL_TREE, attr_id = NULL_TREE, arguments; + tree attribute, attr_id = NULL_TREE, arguments; cp_token *token; /* First, parse name of the attribute, a.k.a attribute-token. */ @@ -24081,6 +24082,9 @@ cp_parser_std_attribute (cp_parser *parser) /* We are seeing a scoped attribute token. */ cp_lexer_consume_token (parser->lexer); + if (attr_ns) + error_at (token->location, "attribute using prefix used together " + "with scoped attribute token"); attr_ns = attr_id; token = cp_lexer_consume_token (parser->lexer); @@ -24088,6 +24092,8 @@ cp_parser_std_attribute (cp_parser *parser) attr_id = token->u.value; else if (token->type == CPP_KEYWORD) attr_id = ridpointers[(int) token->keyword]; + else if (token->flags & NAMED_OP) + attr_id = get_identifier (cpp_type2name (token->type, token->flags)); else { error_at (token->location, @@ -24098,6 +24104,9 @@ cp_parser_std_attribute (cp_parser *parser) NULL_TREE); token = cp_lexer_peek_token (parser->lexer); } + else if (attr_ns) + attribute = build_tree_list (build_tree_list (attr_ns, attr_id), + NULL_TREE); else { attribute = build_tree_list (build_tree_list (NULL_TREE, attr_id), @@ -24191,14 +24200,14 @@ cp_parser_check_std_attribute (tree attributes, tree attribute) */ static tree -cp_parser_std_attribute_list (cp_parser *parser) +cp_parser_std_attribute_list (cp_parser *parser, tree attr_ns) { tree attributes = NULL_TREE, attribute = NULL_TREE; cp_token *token = NULL; while (true) { - attribute = cp_parser_std_attribute (parser); + attribute = cp_parser_std_attribute (parser, attr_ns); if (attribute == error_mark_node) break; if (attribute != NULL_TREE) @@ -24226,9 +24235,12 @@ cp_parser_std_attribute_list (cp_parser *parser) /* Parse a standard C++-11 attribute specifier. attribute-specifier: - [ [ attribute-list ] ] + [ [ attribute-using-prefix [opt] attribute-list ] ] alignment-specifier + attribute-using-prefix: + using attribute-namespace : + alignment-specifier: alignas ( type-id ... [opt] ) alignas ( alignment-expression ... [opt] ). */ @@ -24242,10 +24254,39 @@ cp_parser_std_attribute_spec (cp_parser *parser) if (token->type == CPP_OPEN_SQUARE && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_SQUARE) { + tree attr_ns = NULL_TREE; + cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer); - attributes = cp_parser_std_attribute_list (parser); + if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING)) + { + token = cp_lexer_peek_nth_token (parser->lexer, 2); + if (token->type == CPP_NAME) + attr_ns = token->u.value; + else if (token->type == CPP_KEYWORD) + attr_ns = ridpointers[(int) token->keyword]; + else if (token->flags & NAMED_OP) + attr_ns = get_identifier (cpp_type2name (token->type, + token->flags)); + if (attr_ns + && cp_lexer_nth_token_is (parser->lexer, 3, CPP_COLON)) + { + if (cxx_dialect < cxx1z + && !in_system_header_at (input_location)) + pedwarn (input_location, 0, + "attribute using prefix only available " + "with -std=c++1z or -std=gnu++1z"); + + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + } + else + attr_ns = NULL_TREE; + } + + attributes = cp_parser_std_attribute_list (parser, attr_ns); if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE) || !cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE)) @@ -37712,7 +37753,7 @@ cp_parser_cilk_simd_vectorlength (cp_parser *parser, tree clauses, || !INTEGRAL_TYPE_P (TREE_TYPE (expr))) error_at (loc, "vectorlength must be an integer constant"); else if (TREE_CONSTANT (expr) - && exact_log2 (TREE_INT_CST_LOW (expr)) == -1) + && !pow2p_hwi (TREE_INT_CST_LOW (expr))) error_at (loc, "vectorlength must be a power of 2"); else { |