aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorDouglas Gregor <doug.gregor@gmail.com>2006-11-21 20:23:03 +0000
committerDoug Gregor <dgregor@gcc.gnu.org>2006-11-21 20:23:03 +0000
commit55a3debe44095349b898ca6e297b0ecb9f9d16b6 (patch)
treeb93947409f894b645ef269b5199ac8efb6894453 /gcc/cp/parser.c
parent218f00156cf583db14b1398ca52da12f59383fb3 (diff)
downloadgcc-55a3debe44095349b898ca6e297b0ecb9f9d16b6.zip
gcc-55a3debe44095349b898ca6e297b0ecb9f9d16b6.tar.gz
gcc-55a3debe44095349b898ca6e297b0ecb9f9d16b6.tar.bz2
cp-tree.def (STATIC_ASSERT): New.
2006-11-21 Douglas Gregor <doug.gregor@gmail.com> * cp-tree.def (STATIC_ASSERT): New. * cp-objcp-common.c (cp_tree_size): Handle STATIC_ASSERT. * error.c (dump_decl): Handle STATIC_ASSERT. * cp-tree.h (STATIC_ASSERT_CONDITION): New. (STATIC_ASSERT_MESSAGE): New. (STATIC_ASSERT_SOURCE_LOCATION): New. (struct tree_static_assert): New. (enum cp_tree_node_structure_enum): Add TS_CP_STATIC_ASSERT. (union lang_tree_node): Add static_assertion. (finish_static_assert): Declare. * cxx-pretty-print.c (pp_cxx_statement): Handle STATIC_ASSERT. (pp_cxx_declaration): Handle STATIC_ASSERT. * pt.c (instantiate_class_template): Handle STATIC_ASSERT members. (tsubst_expr): Handle STATIC_ASSERT statements. * semantics.c (finish_static_assert): New. * lex.c (D_CPP0X): New. (reswords): Add static_assert keyword. (init_reswords): If not flag_cpp0x, mask out C++0x keywords. * parser.c (cp_parser_block_declaration): Parse static assertions. (cp_parser_static_assert): New. (cp_parser_member_declaration): Parse static assertions. From-SVN: r119066
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c86
1 files changed, 85 insertions, 1 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 8e79eab..c5dfea6 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1589,6 +1589,8 @@ static void cp_parser_asm_definition
(cp_parser *);
static void cp_parser_linkage_specification
(cp_parser *);
+static void cp_parser_static_assert
+ (cp_parser *, bool);
/* Declarators [gram.dcl.decl] */
@@ -7211,6 +7213,11 @@ cp_parser_declaration (cp_parser* parser)
__extension__ block-declaration
label-declaration
+ C++0x Extension:
+
+ block-declaration:
+ static_assert-declaration
+
If STATEMENT_P is TRUE, then this block-declaration is occurring as
part of a declaration-statement. */
@@ -7272,6 +7279,9 @@ cp_parser_block_declaration (cp_parser *parser,
cp_parser_commit_to_tentative_parse (parser);
cp_parser_label_declaration (parser);
}
+ /* If the next token is `static_assert' we have a static assertion. */
+ else if (token1->keyword == RID_STATIC_ASSERT)
+ cp_parser_static_assert (parser, /*member_p=*/false);
/* Anything else must be a simple-declaration. */
else
cp_parser_simple_declaration (parser, !statement_p);
@@ -7825,6 +7835,68 @@ cp_parser_linkage_specification (cp_parser* parser)
pop_lang_context ();
}
+/* Parse a static_assert-declaration.
+
+ static_assert-declaration:
+ static_assert ( constant-expression , string-literal ) ;
+
+ If MEMBER_P, this static_assert is a class member. */
+
+static void
+cp_parser_static_assert(cp_parser *parser, bool member_p)
+{
+ tree condition;
+ tree message;
+ cp_token *token;
+ location_t saved_loc;
+
+ /* Peek at the `static_assert' token so we can keep track of exactly
+ where the static assertion started. */
+ token = cp_lexer_peek_token (parser->lexer);
+ saved_loc = token->location;
+
+ /* Look for the `static_assert' keyword. */
+ if (!cp_parser_require_keyword (parser, RID_STATIC_ASSERT,
+ "`static_assert'"))
+ return;
+
+ /* We know we are in a static assertion; commit to any tentative
+ parse. */
+ if (cp_parser_parsing_tentatively (parser))
+ cp_parser_commit_to_tentative_parse (parser);
+
+ /* Parse the `(' starting the static assertion condition. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+
+ /* Parse the constant-expression. */
+ condition =
+ cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/false,
+ /*non_constant_p=*/NULL);
+
+ /* Parse the separating `,'. */
+ cp_parser_require (parser, CPP_COMMA, "`,'");
+
+ /* Parse the string-literal message. */
+ message = cp_parser_string_literal (parser,
+ /*translate=*/false,
+ /*wide_ok=*/true);
+
+ /* A `)' completes the static assertion. */
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'"))
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ /* A semicolon terminates the declaration. */
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+
+ /* Complete the static assertion, which may mean either processing
+ the static assert now or saving it for template instantiation. */
+ finish_static_assert (condition, message, saved_loc, member_p);
+}
+
/* Special member functions [gram.special] */
/* Parse a conversion-function-id.
@@ -13624,7 +13696,12 @@ cp_parser_member_specification_opt (cp_parser* parser)
member-declarator:
declarator attributes [opt] pure-specifier [opt]
declarator attributes [opt] constant-initializer [opt]
- identifier [opt] attributes [opt] : constant-expression */
+ identifier [opt] attributes [opt] : constant-expression
+
+ C++0x Extensions:
+
+ member-declaration:
+ static_assert-declaration */
static void
cp_parser_member_declaration (cp_parser* parser)
@@ -13687,6 +13764,13 @@ cp_parser_member_declaration (cp_parser* parser)
return;
}
+ /* If the next token is `static_assert' we have a static assertion. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC_ASSERT))
+ {
+ cp_parser_static_assert (parser, /*member_p=*/true);
+ return;
+ }
+
if (cp_parser_using_declaration (parser, /*access_declaration=*/true))
return;