aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-07 04:35:08 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-07 04:35:08 +0000
commit3b2771f97edaf6dbbc99304344d20b588f52f392 (patch)
treea2db1f22fa258b5aed20835a904e972177465a6b
parent98fe46763bc650592e46cc68117a827f7e40b15b (diff)
Fix decltype-call1.C with -std=c++1z.
* parser.h (struct cp_token): Tell GTY that CPP_DECLTYPE uses tree_check_value. * parser.c (cp_parser_decltype): Use tree_check_value. (saved_checks_value): New. (cp_parser_nested_name_specifier_opt): Use it. (cp_parser_template_id): Use it. (cp_parser_simple_type_specifier): Use it. (cp_parser_pre_parsed_nested_name_specifier): Use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231353 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/parser.c67
-rw-r--r--gcc/cp/parser.h6
3 files changed, 44 insertions, 38 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9a8a2b58b04..ca9b97cba47 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,14 @@
2015-12-06 Jason Merrill <jason@redhat.com>
+ * parser.h (struct cp_token): Tell GTY that CPP_DECLTYPE uses
+ tree_check_value.
+ * parser.c (cp_parser_decltype): Use tree_check_value.
+ (saved_checks_value): New.
+ (cp_parser_nested_name_specifier_opt): Use it.
+ (cp_parser_template_id): Use it.
+ (cp_parser_simple_type_specifier): Use it.
+ (cp_parser_pre_parsed_nested_name_specifier): Use it.
+
* semantics.c (finish_qualified_id_expr): Handle
UNBOUND_CLASS_TEMPLATE.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 1c7b1d50747..ce5a21a759a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1008,6 +1008,28 @@ cp_lexer_next_token_is_decltype (cp_lexer *lexer)
return token_is_decltype (t);
}
+/* Called when processing a token with tree_check_value; perform or defer the
+ associated checks and return the value. */
+
+static tree
+saved_checks_value (struct tree_check *check_value)
+{
+ /* Perform any access checks that were deferred. */
+ vec<deferred_access_check, va_gc> *checks;
+ deferred_access_check *chk;
+ checks = check_value->checks;
+ if (checks)
+ {
+ int i;
+ FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
+ perform_or_defer_access_check (chk->binfo,
+ chk->decl,
+ chk->diag_decl, tf_warning_or_error);
+ }
+ /* Return the stored value. */
+ return check_value->value;
+}
+
/* Return a pointer to the Nth token in the token stream. If N is 1,
then this is precisely equivalent to cp_lexer_peek_token (except
that it is not inline). One would like to disallow that case, but
@@ -5818,7 +5840,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
token = cp_lexer_consume_token (parser->lexer);
error_at (token->location, "decltype evaluates to %qT, "
"which is not a class or enumeration type",
- token->u.value);
+ token->u.tree_check_value->value);
parser->scope = error_mark_node;
error_p = true;
/* As below. */
@@ -13016,7 +13038,7 @@ cp_parser_decltype (cp_parser *parser)
{
/* Already parsed. */
cp_lexer_consume_token (parser->lexer);
- return start_token->u.value;
+ return saved_checks_value (start_token->u.tree_check_value);
}
/* Look for the `decltype' token. */
@@ -13101,7 +13123,9 @@ cp_parser_decltype (cp_parser *parser)
/* Replace the decltype with a CPP_DECLTYPE so we don't need to parse
it again. */
start_token->type = CPP_DECLTYPE;
- start_token->u.value = expr;
+ start_token->u.tree_check_value = ggc_cleared_alloc<struct tree_check> ();
+ start_token->u.tree_check_value->value = expr;
+ start_token->u.tree_check_value->checks = get_deferred_access_checks ();
start_token->keyword = RID_MAX;
cp_lexer_purge_tokens_after (parser->lexer, start_token);
@@ -14617,13 +14641,10 @@ cp_parser_template_id (cp_parser *parser,
enum tag_types tag_type,
bool is_declaration)
{
- int i;
tree templ;
tree arguments;
tree template_id;
cp_token_position start_of_id = 0;
- deferred_access_check *chk;
- vec<deferred_access_check, va_gc> *access_check;
cp_token *next_token = NULL, *next_token_2 = NULL;
bool is_identifier;
@@ -14632,22 +14653,8 @@ cp_parser_template_id (cp_parser *parser,
next_token = cp_lexer_peek_token (parser->lexer);
if (next_token->type == CPP_TEMPLATE_ID)
{
- struct tree_check *check_value;
-
- /* Get the stored value. */
- check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
- /* Perform any access checks that were deferred. */
- access_check = check_value->checks;
- if (access_check)
- {
- FOR_EACH_VEC_ELT (*access_check, i, chk)
- perform_or_defer_access_check (chk->binfo,
- chk->decl,
- chk->diag_decl,
- tf_warning_or_error);
- }
- /* Return the stored value. */
- return check_value->value;
+ cp_lexer_consume_token (parser->lexer);
+ return saved_checks_value (next_token->u.tree_check_value);
}
/* Avoid performing name lookup if there is no possibility of
@@ -15999,7 +16006,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
if (token->type == CPP_DECLTYPE
&& cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
{
- type = token->u.value;
+ type = saved_checks_value (token->u.tree_check_value);
if (decl_specs)
{
cp_parser_set_decl_spec_type (decl_specs, type,
@@ -27042,24 +27049,12 @@ cp_parser_optional_template_keyword (cp_parser *parser)
static void
cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
{
- int i;
struct tree_check *check_value;
- deferred_access_check *chk;
- vec<deferred_access_check, va_gc> *checks;
/* Get the stored value. */
check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
- /* Perform any access checks that were deferred. */
- checks = check_value->checks;
- if (checks)
- {
- FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
- perform_or_defer_access_check (chk->binfo,
- chk->decl,
- chk->diag_decl, tf_warning_or_error);
- }
/* Set the scope from the stored value. */
- parser->scope = check_value->value;
+ parser->scope = saved_checks_value (check_value);
parser->qualifying_scope = check_value->qualifying_scope;
parser->object_scope = NULL_TREE;
}
diff --git a/gcc/cp/parser.h b/gcc/cp/parser.h
index a6b8e74feb6..891dd4143ef 100644
--- a/gcc/cp/parser.h
+++ b/gcc/cp/parser.h
@@ -63,11 +63,13 @@ struct GTY (()) cp_token {
location_t location;
/* The value associated with this token, if any. */
union cp_token_value {
- /* Used for CPP_NESTED_NAME_SPECIFIER and CPP_TEMPLATE_ID. */
+ /* Used for compound tokens such as CPP_NESTED_NAME_SPECIFIER. */
struct tree_check* GTY((tag ("1"))) tree_check_value;
/* Use for all other tokens. */
tree GTY((tag ("0"))) value;
- } GTY((desc ("(%1.type == CPP_TEMPLATE_ID) || (%1.type == CPP_NESTED_NAME_SPECIFIER)"))) u;
+ } GTY((desc ("(%1.type == CPP_TEMPLATE_ID)"
+ "|| (%1.type == CPP_NESTED_NAME_SPECIFIER)"
+ "|| (%1.type == CPP_DECLTYPE)"))) u;
};