summaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorburnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-20 21:49:12 +0000
committerburnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-20 21:49:12 +0000
commitc9c81ef3c667aaa14c498a5449ec6d134b4b66ff (patch)
tree0ac440db6513ee01deb5e5dc6142769d1e5b7b2d /gcc/cp/parser.c
parent12cdcb9d74f55c165366ca1b1eeec013a0ce72ef (diff)
parent891196d7325e4c55d92d5ac5cfe7161c4f36c0ce (diff)
downloadgcc-fortran-dev.tar.gz
Merge from trunk (r239915 to r240230)fortran-dev
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/fortran-dev@240290 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c61
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
{