aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-03-28 14:20:58 -0400
committerJason Merrill <jason@gcc.gnu.org>2013-03-28 14:20:58 -0400
commitf5e44182eb3a89ef9cf0a51d2898d8f4111252d2 (patch)
treeb18d61a43d0cc3ed93f82c1521b98a3cfda037e1 /gcc/cp
parent374b2837482811e9d5a2ec4b2db0dabd67e6d420 (diff)
downloadgcc-f5e44182eb3a89ef9cf0a51d2898d8f4111252d2.zip
gcc-f5e44182eb3a89ef9cf0a51d2898d8f4111252d2.tar.gz
gcc-f5e44182eb3a89ef9cf0a51d2898d8f4111252d2.tar.bz2
re PR c++/56679 ([C++11] Cannot take sizeof... a template template parameter pack)
PR c++/56679 * parser.c (cp_parser_sizeof_pack): Split out from... (cp_parser_sizeof_operand): ...here. Require (id). From-SVN: r197213
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/parser.c65
2 files changed, 48 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b0a952a..0709b66 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2013-03-28 Jason Merrill <jason@redhat.com>
+ PR c++/56679
+ * parser.c (cp_parser_sizeof_pack): Split out from...
+ (cp_parser_sizeof_operand): ...here. Require (id).
+
PR c++/56701
* semantics.c (finish_this_expr): 'this' is an rvalue.
* typeck.c (cp_build_indirect_ref): Handle NOP_EXPR of 'this'.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 5e2a4e0..ec6eb08 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -22618,6 +22618,44 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
pop_unparsed_function_queues (parser);
}
+/* Subroutine of cp_parser_sizeof_operand, for handling C++11
+
+ sizeof ... ( identifier )
+
+ where the 'sizeof' token has already been consumed. */
+
+static tree
+cp_parser_sizeof_pack (cp_parser *parser)
+{
+ /* Consume the `...'. */
+ cp_lexer_consume_token (parser->lexer);
+ maybe_warn_variadic_templates ();
+
+ bool paren = cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN);
+ if (paren)
+ cp_lexer_consume_token (parser->lexer);
+ else
+ permerror (cp_lexer_peek_token (parser->lexer)->location,
+ "%<sizeof...%> argument must be surrounded by parentheses");
+
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ tree name = cp_parser_identifier (parser);
+ tree expr = cp_parser_lookup_name_simple (parser, name, token->location);
+ if (expr == error_mark_node)
+ cp_parser_name_lookup_error (parser, name, expr, NLE_NULL,
+ token->location);
+ if (TREE_CODE (expr) == TYPE_DECL)
+ expr = TREE_TYPE (expr);
+ else if (TREE_CODE (expr) == CONST_DECL)
+ expr = DECL_INITIAL (expr);
+ expr = make_pack_expansion (expr);
+
+ if (paren)
+ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
+
+ return expr;
+}
+
/* Parse the operand of `sizeof' (or a similar operator). Returns
either a TYPE or an expression, depending on the form of the
input. The KEYWORD indicates which kind of expression we have
@@ -22631,7 +22669,12 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
char *tmp;
bool saved_integral_constant_expression_p;
bool saved_non_integral_constant_expression_p;
- bool pack_expansion_p = false;
+
+ /* If it's a `...', then we are computing the length of a parameter
+ pack. */
+ if (keyword == RID_SIZEOF
+ && cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ return cp_parser_sizeof_pack (parser);
/* Types cannot be defined in a `sizeof' expression. Save away the
old message. */
@@ -22650,19 +22693,6 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
= parser->non_integral_constant_expression_p;
parser->integral_constant_expression_p = false;
- /* If it's a `...', then we are computing the length of a parameter
- pack. */
- if (keyword == RID_SIZEOF
- && cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
- {
- /* Consume the `...'. */
- cp_lexer_consume_token (parser->lexer);
- maybe_warn_variadic_templates ();
-
- /* Note that this is an expansion. */
- pack_expansion_p = true;
- }
-
/* Do not actually evaluate the expression. */
++cp_unevaluated_operand;
++c_inhibit_evaluation_warnings;
@@ -22702,9 +22732,6 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
/*attrlist=*/NULL);
}
}
- else if (pack_expansion_p)
- permerror (cp_lexer_peek_token (parser->lexer)->location,
- "%<sizeof...%> argument must be surrounded by parentheses");
/* If the type-id production did not work out, then we must be
looking at the unary-expression production. */
@@ -22712,10 +22739,6 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
expr = cp_parser_unary_expression (parser, /*address_p=*/false,
/*cast_p=*/false, NULL);
- if (pack_expansion_p)
- /* Build a pack expansion. */
- expr = make_pack_expansion (expr);
-
/* Go back to evaluating expressions. */
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;