aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorSimon Martin <simartin@users.sourceforge.net>2006-12-16 08:51:42 +0000
committerSimon Martin <simartin@gcc.gnu.org>2006-12-16 08:51:42 +0000
commitd6b418fa0b3d5dc88ffb3f1673f82e6dbf5da6d1 (patch)
treea7b346cda4d3b77e77b9aa9c9d5fdd0dbacf5afe /gcc/cp
parente6a98ba89323ec0f641df79101ea99dadda441ce (diff)
downloadgcc-d6b418fa0b3d5dc88ffb3f1673f82e6dbf5da6d1.zip
gcc-d6b418fa0b3d5dc88ffb3f1673f82e6dbf5da6d1.tar.gz
gcc-d6b418fa0b3d5dc88ffb3f1673f82e6dbf5da6d1.tar.bz2
re PR c++/29475 (incomplete template diagnostics.)
2006-12-16 Simon Martin <simartin@users.sourceforge.net> PR c++/29475 * cp-tree.h (struct deferred_access_check): New structure to represent a deferred access check. It replaces the previous representation as a tree. (get_deferred_access_checks): Return a vector of struct deferred_access_check instead of a tree list. (perform_access_checks): Take a vector of struct deferred_access_check instead of a tree list. * semantics.c (struct deferred_access): Store the deferred access checks as a vector of struct deferred_access_check instead of a tree list. (push_deferring_access_checks): Handle the change in struct deferred_access. (get_deferred_access_checks): Likewise. (pop_to_parent_deferring_access_checks): Likewise. (perform_or_defer_access_check): Likewise. (perform_access_checks): Take a vector of struct deferred_access_check instead of a tree list. * parser.c (struct tree_check): New structure to store various data associated with a CPP_NESTED_NAME_SPECIFIER or CPP_TEMPLATE_ID token. (struct cp_token): Changed the value field to be a union with a pointer to a struct tree_check for CPP_NESTED_NAME_SPECIFIER or CPP_TEMPLATE_ID tokens and a tree field for all other tokens. (eof_token): Adjusted due to the change in struct cp_token. (cp_lexer_get_preprocessor_token): Likewise. (cp_lexer_purge_token): Likewise. (cp_lexer_purge_tokens_after): Likewise. (cp_lexer_print_token): Likewise. (cp_parser_error): Likewise. (cp_parser_identifier): Likewise. (cp_parser_string_literal): Likewise. (cp_parser_primary_expression): Likewise. (cp_parser_unqualified_id): Likewise. (cp_parser_parenthesized_expression_list): Likewise. (cp_parser_storage_class_specifier_opt): Likewise. (cp_parser_function_specifier_opt): Likewise. (cp_parser_type_specifier): Likewise. (cp_parser_simple_type_specifier): Likewise. (cp_parser_initializer_list): Likewise. (cp_parser_member_specification_opt): Likewise. (cp_parser_attribute_list): Likewise. (cp_parser_objc_expression): Likewise. (cp_parser_objc_protocol_qualifiers): Likewise. (cp_parser_objc_selector): Likewise. (cp_parser_objc_declaration): Likewise. (cp_parser_objc_statement): Likewise. (cp_parser_omp_clause_name): Likewise. (cp_parser_omp_clause_default): Likewise. (cp_parser_omp_clause_schedule): Likewise. (cp_parser_omp_parallel): Likewise. (cp_parser_initial_pragma): Likewise. (pragma_lex): Likewise. (cp_parser_pre_parsed_nested_name_specifier): Likewise. (cp_parser_nested_name_specifier_opt): Likewise. Use cp_token::u::tree_check_value to save the token's value, the associated deferred checks and its qualifying scope. (cp_parser_template_id): Likewise. (cp_parser_template_declaration_after_export): Adjusted the call to get_deferred_access_checks. (cp_parser_init_declarator): Take the access checks as a vector of struct deferred_access_check instead of a tree list. (cp_parser_single_declaration): Likewise. (cp_parser_perform_template_parameter_access_checks): Likewise. (cp_parser_simple_declaration): Adjusted the call to cp_parser_init_declarator. (cp_parser_explicit_specialization): Adjusted the call to cp_parser_single_declaration. From-SVN: r119961
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog68
-rw-r--r--gcc/cp/cp-tree.h19
-rw-r--r--gcc/cp/parser.c210
-rw-r--r--gcc/cp/semantics.c99
4 files changed, 265 insertions, 131 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5f8b607..b51ebc0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,71 @@
+2006-12-16 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/29475
+ * cp-tree.h (struct deferred_access_check): New structure to represent a
+ deferred access check. It replaces the previous representation as a tree.
+ (get_deferred_access_checks): Return a vector of struct
+ deferred_access_check instead of a tree list.
+ (perform_access_checks): Take a vector of struct deferred_access_check
+ instead of a tree list.
+ * semantics.c (struct deferred_access): Store the deferred access checks
+ as a vector of struct deferred_access_check instead of a tree list.
+ (push_deferring_access_checks): Handle the change in struct
+ deferred_access.
+ (get_deferred_access_checks): Likewise.
+ (pop_to_parent_deferring_access_checks): Likewise.
+ (perform_or_defer_access_check): Likewise.
+ (perform_access_checks): Take a vector of struct deferred_access_check
+ instead of a tree list.
+ * parser.c (struct tree_check): New structure to store various data
+ associated with a CPP_NESTED_NAME_SPECIFIER or CPP_TEMPLATE_ID token.
+ (struct cp_token): Changed the value field to be a union with a pointer to
+ a struct tree_check for CPP_NESTED_NAME_SPECIFIER or CPP_TEMPLATE_ID
+ tokens and a tree field for all other tokens.
+ (eof_token): Adjusted due to the change in struct cp_token.
+ (cp_lexer_get_preprocessor_token): Likewise.
+ (cp_lexer_purge_token): Likewise.
+ (cp_lexer_purge_tokens_after): Likewise.
+ (cp_lexer_print_token): Likewise.
+ (cp_parser_error): Likewise.
+ (cp_parser_identifier): Likewise.
+ (cp_parser_string_literal): Likewise.
+ (cp_parser_primary_expression): Likewise.
+ (cp_parser_unqualified_id): Likewise.
+ (cp_parser_parenthesized_expression_list): Likewise.
+ (cp_parser_storage_class_specifier_opt): Likewise.
+ (cp_parser_function_specifier_opt): Likewise.
+ (cp_parser_type_specifier): Likewise.
+ (cp_parser_simple_type_specifier): Likewise.
+ (cp_parser_initializer_list): Likewise.
+ (cp_parser_member_specification_opt): Likewise.
+ (cp_parser_attribute_list): Likewise.
+ (cp_parser_objc_expression): Likewise.
+ (cp_parser_objc_protocol_qualifiers): Likewise.
+ (cp_parser_objc_selector): Likewise.
+ (cp_parser_objc_declaration): Likewise.
+ (cp_parser_objc_statement): Likewise.
+ (cp_parser_omp_clause_name): Likewise.
+ (cp_parser_omp_clause_default): Likewise.
+ (cp_parser_omp_clause_schedule): Likewise.
+ (cp_parser_omp_parallel): Likewise.
+ (cp_parser_initial_pragma): Likewise.
+ (pragma_lex): Likewise.
+ (cp_parser_pre_parsed_nested_name_specifier): Likewise.
+ (cp_parser_nested_name_specifier_opt): Likewise.
+ Use cp_token::u::tree_check_value to save the token's value, the
+ associated deferred checks and its qualifying scope.
+ (cp_parser_template_id): Likewise.
+ (cp_parser_template_declaration_after_export): Adjusted the call to
+ get_deferred_access_checks.
+ (cp_parser_init_declarator): Take the access checks as a vector of struct
+ deferred_access_check instead of a tree list.
+ (cp_parser_single_declaration): Likewise.
+ (cp_parser_perform_template_parameter_access_checks): Likewise.
+ (cp_parser_simple_declaration): Adjusted the call to
+ cp_parser_init_declarator.
+ (cp_parser_explicit_specialization): Adjusted the call to
+ cp_parser_single_declaration.
+
2006-12-13 Ian Lance Taylor <iant@google.com>
PR c++/19564
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3f63b8f..3968f96 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4234,14 +4234,29 @@ extern tree copied_binfo (tree, tree);
extern tree original_binfo (tree, tree);
extern int shared_member_p (tree);
+
+/* The representation of a deferred access check. */
+
+typedef struct deferred_access_check GTY(())
+{
+ /* The base class in which the declaration is referenced. */
+ tree binfo;
+ /* The declaration whose access must be checked. */
+ tree decl;
+ /* The declaration that should be used in the error message. */
+ tree diag_decl;
+} deferred_access_check;
+DEF_VEC_O(deferred_access_check);
+DEF_VEC_ALLOC_O(deferred_access_check,gc);
+
/* in semantics.c */
extern void push_deferring_access_checks (deferring_kind);
extern void resume_deferring_access_checks (void);
extern void stop_deferring_access_checks (void);
extern void pop_deferring_access_checks (void);
-extern tree get_deferred_access_checks (void);
+extern VEC (deferred_access_check,gc)* get_deferred_access_checks (void);
extern void pop_to_parent_deferring_access_checks (void);
-extern void perform_access_checks (tree);
+extern void perform_access_checks (VEC (deferred_access_check,gc)*);
extern void perform_deferred_access_checks (void);
extern void perform_or_defer_access_check (tree, tree, tree);
extern int stmts_are_full_exprs_p (void);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 0521136..ae2b4a0 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -45,6 +45,20 @@
/* The cp_lexer_* routines mediate between the lexer proper (in libcpp
and c-lex.c) and the C++ parser. */
+/* A token's value and its associated deferred access checks and
+ qualifying scope. */
+
+struct tree_check GTY(())
+{
+ /* The value associated with the token. */
+ tree value;
+ /* The checks that have been associated with value. */
+ VEC (deferred_access_check, gc)* checks;
+ /* The token's qualifying scope (used when it is a
+ CPP_NESTED_NAME_SPECIFIER). */
+ tree qualifying_scope;
+};
+
/* A C++ token. */
typedef struct cp_token GTY (())
@@ -69,7 +83,12 @@ typedef struct cp_token GTY (())
/* The input file stack index at which this token was found. */
unsigned input_file_stack_index : INPUT_FILE_STACK_BITS;
/* The value associated with this token, if any. */
- tree value;
+ union cp_token_value {
+ /* Used for CPP_NESTED_NAME_SPECIFIER and CPP_TEMPLATE_ID. */
+ 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;
/* The location at which this token was found. */
location_t location;
} cp_token;
@@ -81,7 +100,7 @@ DEF_VEC_ALLOC_P (cp_token_position,heap);
static const cp_token eof_token =
{
- CPP_EOF, RID_MAX, 0, PRAGMA_NONE, 0, 0, false, 0, NULL_TREE,
+ CPP_EOF, RID_MAX, 0, PRAGMA_NONE, 0, 0, false, 0, { NULL },
#if USE_MAPPED_LOCATION
0
#else
@@ -394,7 +413,7 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED ,
/* Get a new token from the preprocessor. */
token->type
- = c_lex_with_flags (&token->value, &token->location, &token->flags);
+ = c_lex_with_flags (&token->u.value, &token->location, &token->flags);
token->input_file_stack_index = input_file_stack_tick;
token->keyword = RID_MAX;
token->pragma_kind = PRAGMA_NONE;
@@ -410,17 +429,17 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED ,
/* Check to see if this token is a keyword. */
if (token->type == CPP_NAME)
{
- if (C_IS_RESERVED_WORD (token->value))
+ if (C_IS_RESERVED_WORD (token->u.value))
{
/* Mark this token as a keyword. */
token->type = CPP_KEYWORD;
/* Record which keyword. */
- token->keyword = C_RID_CODE (token->value);
+ token->keyword = C_RID_CODE (token->u.value);
/* Update the value. Some keywords are mapped to particular
entities, rather than simply having the value of the
corresponding IDENTIFIER_NODE. For example, `__const' is
mapped to `const'. */
- token->value = ridpointers[token->keyword];
+ token->u.value = ridpointers[token->keyword];
}
else
{
@@ -432,7 +451,7 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED ,
else if (token->type == CPP_AT_NAME)
{
token->type = CPP_KEYWORD;
- switch (C_RID_CODE (token->value))
+ switch (C_RID_CODE (token->u.value))
{
/* Map 'class' to '@class', 'private' to '@private', etc. */
case RID_CLASS: token->keyword = RID_AT_CLASS; break;
@@ -442,14 +461,14 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED ,
case RID_THROW: token->keyword = RID_AT_THROW; break;
case RID_TRY: token->keyword = RID_AT_TRY; break;
case RID_CATCH: token->keyword = RID_AT_CATCH; break;
- default: token->keyword = C_RID_CODE (token->value);
+ default: token->keyword = C_RID_CODE (token->u.value);
}
}
else if (token->type == CPP_PRAGMA)
{
/* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
- token->pragma_kind = TREE_INT_CST_LOW (token->value);
- token->value = NULL;
+ token->pragma_kind = TREE_INT_CST_LOW (token->u.value);
+ token->u.value = NULL_TREE;
}
}
@@ -641,7 +660,7 @@ cp_lexer_purge_token (cp_lexer *lexer)
gcc_assert (tok != &eof_token);
tok->type = CPP_PURGED;
tok->location = UNKNOWN_LOCATION;
- tok->value = NULL_TREE;
+ tok->u.value = NULL_TREE;
tok->keyword = RID_MAX;
do
@@ -675,7 +694,7 @@ cp_lexer_purge_tokens_after (cp_lexer *lexer, cp_token *tok)
{
tok->type = CPP_PURGED;
tok->location = UNKNOWN_LOCATION;
- tok->value = NULL_TREE;
+ tok->u.value = NULL_TREE;
tok->keyword = RID_MAX;
}
}
@@ -753,16 +772,16 @@ cp_lexer_print_token (FILE * stream, cp_token *token)
case CPP_KEYWORD:
/* Some keywords have a value that is not an IDENTIFIER_NODE.
For example, `struct' is mapped to an INTEGER_CST. */
- if (TREE_CODE (token->value) != IDENTIFIER_NODE)
+ if (TREE_CODE (token->u.value) != IDENTIFIER_NODE)
break;
/* else fall through */
case CPP_NAME:
- fputs (IDENTIFIER_POINTER (token->value), stream);
+ fputs (IDENTIFIER_POINTER (token->u.value), stream);
break;
case CPP_STRING:
case CPP_WSTRING:
- fprintf (stream, " \"%s\"", TREE_STRING_POINTER (token->value));
+ fprintf (stream, " \"%s\"", TREE_STRING_POINTER (token->u.value));
break;
default:
@@ -1606,7 +1625,7 @@ static void cp_parser_static_assert
/* Declarators [gram.dcl.decl] */
static tree cp_parser_init_declarator
- (cp_parser *, cp_decl_specifier_seq *, tree, bool, bool, int, bool *);
+ (cp_parser *, cp_decl_specifier_seq *, VEC (deferred_access_check,gc)*, bool, bool, int, bool *);
static cp_declarator *cp_parser_declarator
(cp_parser *, cp_parser_declarator_kind, int *, bool *, bool);
static cp_declarator *cp_parser_direct_declarator
@@ -1806,9 +1825,9 @@ static tree cp_parser_function_definition_after_declarator
static void cp_parser_template_declaration_after_export
(cp_parser *, bool);
static void cp_parser_perform_template_parameter_access_checks
- (tree);
+ (VEC (deferred_access_check,gc)*);
static tree cp_parser_single_declaration
- (cp_parser *, tree, bool, bool *);
+ (cp_parser *, VEC (deferred_access_check,gc)*, bool, bool *);
static tree cp_parser_functional_cast
(cp_parser *, tree);
static tree cp_parser_save_member_function_body
@@ -1962,7 +1981,7 @@ cp_parser_error (cp_parser* parser, const char* message)
CPP_KEYWORD, keywords are treated like
identifiers. */
(token->type == CPP_KEYWORD ? CPP_NAME : token->type),
- token->value);
+ token->u.value);
}
}
@@ -2703,7 +2722,7 @@ cp_parser_identifier (cp_parser* parser)
/* Look for the identifier. */
token = cp_parser_require (parser, CPP_NAME, "identifier");
/* Return the value. */
- return token ? token->value : error_mark_node;
+ return token ? token->u.value : error_mark_node;
}
/* Parse a sequence of adjacent string constants. Returns a
@@ -2744,8 +2763,8 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
{
cp_lexer_consume_token (parser->lexer);
- str.text = (const unsigned char *)TREE_STRING_POINTER (tok->value);
- str.len = TREE_STRING_LENGTH (tok->value);
+ str.text = (const unsigned char *)TREE_STRING_POINTER (tok->u.value);
+ str.len = TREE_STRING_LENGTH (tok->u.value);
count = 1;
if (tok->type == CPP_WSTRING)
wide = true;
@@ -2761,8 +2780,8 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
{
cp_lexer_consume_token (parser->lexer);
count++;
- str.text = (unsigned char *)TREE_STRING_POINTER (tok->value);
- str.len = TREE_STRING_LENGTH (tok->value);
+ str.text = (unsigned char *)TREE_STRING_POINTER (tok->u.value);
+ str.len = TREE_STRING_LENGTH (tok->u.value);
if (tok->type == CPP_WSTRING)
wide = true;
@@ -2929,7 +2948,7 @@ cp_parser_primary_expression (cp_parser *parser,
/* Floating-point literals are only allowed in an integral
constant expression if they are cast to an integral or
enumeration type. */
- if (TREE_CODE (token->value) == REAL_CST
+ if (TREE_CODE (token->u.value) == REAL_CST
&& parser->integral_constant_expression_p
&& pedantic)
{
@@ -2966,7 +2985,7 @@ cp_parser_primary_expression (cp_parser *parser,
cp_parser_non_integral_constant_expression
(parser, "floating-point literal");
}
- return token->value;
+ return token->u.value;
case CPP_STRING:
case CPP_WSTRING:
@@ -3082,7 +3101,7 @@ cp_parser_primary_expression (cp_parser *parser,
Consume the token. */
token = cp_lexer_consume_token (parser->lexer);
/* Look up the name. */
- return finish_fname (token->value);
+ return finish_fname (token->u.value);
case RID_VA_ARG:
{
@@ -3519,7 +3538,7 @@ cp_parser_unqualified_id (cp_parser* parser,
&& token->type == CPP_NAME
&& (cp_lexer_peek_nth_token (parser->lexer, 2)->type
== CPP_OPEN_PAREN)
- && constructor_name_p (token->value, scope))
+ && constructor_name_p (token->u.value, scope))
{
cp_lexer_consume_token (parser->lexer);
return build_nt (BIT_NOT_EXPR, scope);
@@ -3820,7 +3839,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
tree decl;
tree ambiguous_decls;
- decl = cp_parser_lookup_name (parser, token->value,
+ decl = cp_parser_lookup_name (parser, token->u.value,
none_type,
/*is_template=*/false,
/*is_namespace=*/false,
@@ -3831,13 +3850,13 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
else if (ambiguous_decls)
{
error ("reference to %qD is ambiguous",
- token->value);
+ token->u.value);
print_candidates (ambiguous_decls);
decl = error_mark_node;
}
else
cp_parser_name_lookup_error
- (parser, token->value, decl,
+ (parser, token->u.value, decl,
"is not a class or namespace");
}
parser->scope = error_mark_node;
@@ -3896,17 +3915,17 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
if (success && start)
{
cp_token *token;
- tree access_checks;
token = cp_lexer_token_at (parser->lexer, start);
/* Reset the contents of the START token. */
token->type = CPP_NESTED_NAME_SPECIFIER;
/* Retrieve any deferred checks. Do not pop this access checks yet
so the memory will not be reclaimed during token replacing below. */
- access_checks = get_deferred_access_checks ();
- token->value = build_tree_list (copy_list (access_checks),
- parser->scope);
- TREE_TYPE (token->value) = parser->qualifying_scope;
+ token->u.tree_check_value = GGC_CNEW (struct tree_check);
+ token->u.tree_check_value->value = parser->scope;
+ token->u.tree_check_value->checks = get_deferred_access_checks ();
+ token->u.tree_check_value->qualifying_scope =
+ parser->qualifying_scope;
token->keyword = RID_MAX;
/* Purge all subsequent tokens. */
@@ -4764,7 +4783,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
/* Consume the identifier. */
token = cp_lexer_consume_token (parser->lexer);
/* Save the identifier. */
- identifier = token->value;
+ identifier = token->u.value;
}
else
{
@@ -7451,7 +7470,7 @@ cp_parser_simple_declaration (cp_parser* parser,
/* Parse the init-declarator. */
decl = cp_parser_init_declarator (parser, &decl_specifiers,
- /*checks=*/NULL_TREE,
+ /*checks=*/NULL,
function_definition_allowed_p,
/*member_p=*/false,
declares_class_or_enum,
@@ -7789,7 +7808,7 @@ cp_parser_storage_class_specifier_opt (cp_parser* parser)
case RID_MUTABLE:
case RID_THREAD:
/* Consume the token. */
- return cp_lexer_consume_token (parser->lexer)->value;
+ return cp_lexer_consume_token (parser->lexer)->u.value;
default:
return NULL_TREE;
@@ -7837,7 +7856,7 @@ cp_parser_function_specifier_opt (cp_parser* parser,
}
/* Consume the token. */
- return cp_lexer_consume_token (parser->lexer)->value;
+ return cp_lexer_consume_token (parser->lexer)->u.value;
}
/* Parse a linkage-specification.
@@ -8876,11 +8895,13 @@ cp_parser_template_id (cp_parser *parser,
bool check_dependency_p,
bool is_declaration)
{
+ int i;
tree template;
tree arguments;
tree template_id;
cp_token_position start_of_id = 0;
- tree access_check = NULL_TREE;
+ deferred_access_check *chk;
+ VEC (deferred_access_check,gc) *access_check;
cp_token *next_token, *next_token_2;
bool is_identifier;
@@ -8889,18 +8910,25 @@ cp_parser_template_id (cp_parser *parser,
next_token = cp_lexer_peek_token (parser->lexer);
if (next_token->type == CPP_TEMPLATE_ID)
{
- tree value;
- tree check;
+ struct tree_check *check_value;
/* Get the stored value. */
- value = cp_lexer_consume_token (parser->lexer)->value;
+ check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
/* Perform any access checks that were deferred. */
- for (check = TREE_PURPOSE (value); check; check = TREE_CHAIN (check))
- perform_or_defer_access_check (TREE_PURPOSE (check),
- TREE_VALUE (check),
- TREE_VALUE (check));
+ access_check = check_value->checks;
+ if (access_check)
+ {
+ for (i = 0 ;
+ VEC_iterate (deferred_access_check, access_check, i, chk) ;
+ ++i)
+ {
+ perform_or_defer_access_check (chk->binfo,
+ chk->decl,
+ chk->diag_decl);
+ }
+ }
/* Return the stored value. */
- return TREE_VALUE (value);
+ return check_value->value;
}
/* Avoid performing name lookup if there is no possibility of
@@ -9016,10 +9044,6 @@ cp_parser_template_id (cp_parser *parser,
template_id = lookup_template_function (template, arguments);
}
- /* Retrieve any deferred checks. Do not pop this access checks yet
- so the memory will not be reclaimed during token replacing below. */
- access_check = get_deferred_access_checks ();
-
/* If parsing tentatively, replace the sequence of tokens that makes
up the template-id with a CPP_TEMPLATE_ID token. That way,
should we re-parse the token stream, we will not have to repeat
@@ -9032,7 +9056,11 @@ cp_parser_template_id (cp_parser *parser,
/* Reset the contents of the START_OF_ID token. */
token->type = CPP_TEMPLATE_ID;
- token->value = build_tree_list (access_check, template_id);
+ /* Retrieve any deferred checks. Do not pop this access checks yet
+ so the memory will not be reclaimed during token replacing below. */
+ token->u.tree_check_value = GGC_CNEW (struct tree_check);
+ token->u.tree_check_value->value = template_id;
+ token->u.tree_check_value->checks = get_deferred_access_checks ();
token->keyword = RID_MAX;
/* Purge all subsequent tokens. */
@@ -9697,7 +9725,7 @@ cp_parser_explicit_specialization (cp_parser* parser)
else
/* Parse the dependent declaration. */
cp_parser_single_declaration (parser,
- /*checks=*/NULL_TREE,
+ /*checks=*/NULL,
/*member_p=*/false,
/*friend_p=*/NULL);
/* We're done with the specialization. */
@@ -9864,7 +9892,7 @@ cp_parser_type_specifier (cp_parser* parser,
++decl_specs->specs[(int)ds];
decl_specs->any_specifiers_p = true;
}
- return cp_lexer_consume_token (parser->lexer)->value;
+ return cp_lexer_consume_token (parser->lexer)->u.value;
}
/* If we do not already have a type-specifier, assume we are looking
@@ -10007,7 +10035,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
decl_specs->any_specifiers_p = true;
/* Consume the token. */
- id = cp_lexer_consume_token (parser->lexer)->value;
+ id = cp_lexer_consume_token (parser->lexer)->u.value;
/* There is no valid C++ program where a non-template type is
followed by a "<". That usually indicates that the user thought
@@ -11150,7 +11178,7 @@ cp_parser_asm_definition (cp_parser* parser)
static tree
cp_parser_init_declarator (cp_parser* parser,
cp_decl_specifier_seq *decl_specifiers,
- tree checks,
+ VEC (deferred_access_check,gc)* checks,
bool function_definition_allowed_p,
bool member_p,
int declares_class_or_enum,
@@ -12948,7 +12976,7 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
if (pedantic)
pedwarn ("ISO C++ does not allow designated initializers");
/* Consume the identifier. */
- identifier = cp_lexer_consume_token (parser->lexer)->value;
+ identifier = cp_lexer_consume_token (parser->lexer)->u.value;
/* Consume the `:'. */
cp_lexer_consume_token (parser->lexer);
}
@@ -13753,7 +13781,7 @@ cp_parser_member_specification_opt (cp_parser* parser)
/* Consume the access-specifier. */
cp_lexer_consume_token (parser->lexer);
/* Remember which access-specifier is active. */
- current_access_specifier = token->value;
+ current_access_specifier = token->u.value;
/* Look for the `:'. */
cp_parser_require (parser, CPP_COLON, "`:'");
break;
@@ -14933,7 +14961,7 @@ cp_parser_attribute_list (cp_parser* parser)
/* Save away the identifier that indicates which attribute
this is. */
- identifier = token->value;
+ identifier = token->u.value;
attribute = build_tree_list (identifier, NULL_TREE);
/* Peek at the next token. */
@@ -15766,7 +15794,7 @@ static void
cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
{
tree decl = NULL_TREE;
- tree checks;
+ VEC (deferred_access_check,gc) *checks;
tree parameter_list;
bool friend_p = false;
bool need_lang_pop;
@@ -15889,7 +15917,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
get_deferred_access_checks. */
static void
-cp_parser_perform_template_parameter_access_checks (tree checks)
+cp_parser_perform_template_parameter_access_checks (VEC (deferred_access_check,gc)* checks)
{
++processing_template_parmlist;
perform_access_checks (checks);
@@ -15905,7 +15933,7 @@ cp_parser_perform_template_parameter_access_checks (tree checks)
static tree
cp_parser_single_declaration (cp_parser* parser,
- tree checks,
+ VEC (deferred_access_check,gc)* checks,
bool member_p,
bool* friend_p)
{
@@ -16851,19 +16879,29 @@ cp_parser_optional_template_keyword (cp_parser *parser)
static void
cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
{
- tree value;
- tree check;
+ int i;
+ struct tree_check *check_value;
+ deferred_access_check *chk;
+ VEC (deferred_access_check,gc) *checks;
/* Get the stored value. */
- value = cp_lexer_consume_token (parser->lexer)->value;
+ check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
/* Perform any access checks that were deferred. */
- for (check = TREE_PURPOSE (value); check; check = TREE_CHAIN (check))
- perform_or_defer_access_check (TREE_PURPOSE (check),
- TREE_VALUE (check),
- TREE_VALUE (check));
+ checks = check_value->checks;
+ if (checks)
+ {
+ for (i = 0 ;
+ VEC_iterate (deferred_access_check, checks, i, chk) ;
+ ++i)
+ {
+ perform_or_defer_access_check (chk->binfo,
+ chk->decl,
+ chk->diag_decl);
+ }
+ }
/* Set the scope from the stored value. */
- parser->scope = TREE_VALUE (value);
- parser->qualifying_scope = TREE_TYPE (value);
+ parser->scope = check_value->value;
+ parser->qualifying_scope = check_value->qualifying_scope;
parser->object_scope = NULL_TREE;
}
@@ -17051,7 +17089,7 @@ cp_parser_objc_expression (cp_parser* parser)
case CPP_OBJC_STRING:
kwd = cp_lexer_consume_token (parser->lexer);
- return objc_build_string_object (kwd->value);
+ return objc_build_string_object (kwd->u.value);
case CPP_KEYWORD:
switch (kwd->keyword)
@@ -17069,7 +17107,7 @@ cp_parser_objc_expression (cp_parser* parser)
break;
}
default:
- error ("misplaced %<@%D%> Objective-C++ construct", kwd->value);
+ error ("misplaced %<@%D%> Objective-C++ construct", kwd->u.value);
cp_parser_skip_to_end_of_block_or_statement (parser);
}
@@ -17459,7 +17497,7 @@ cp_parser_objc_protocol_qualifiers (cp_parser* parser)
tree quals = NULL_TREE, node;
cp_token *token = cp_lexer_peek_token (parser->lexer);
- node = token->value;
+ node = token->u.value;
while (node && TREE_CODE (node) == IDENTIFIER_NODE
&& (node == ridpointers [(int) RID_IN]
@@ -17472,7 +17510,7 @@ cp_parser_objc_protocol_qualifiers (cp_parser* parser)
quals = tree_cons (NULL_TREE, node, quals);
cp_lexer_consume_token (parser->lexer);
token = cp_lexer_peek_token (parser->lexer);
- node = token->value;
+ node = token->u.value;
}
return quals;
@@ -17543,7 +17581,7 @@ cp_parser_objc_selector (cp_parser* parser)
case CPP_OR_EQ: return get_identifier ("or_eq");
case CPP_XOR: return get_identifier ("xor");
case CPP_XOR_EQ: return get_identifier ("xor_eq");
- default: return token->value;
+ default: return token->u.value;
}
}
@@ -17992,7 +18030,7 @@ cp_parser_objc_declaration (cp_parser* parser)
cp_parser_objc_end_implementation (parser);
break;
default:
- error ("misplaced %<@%D%> Objective-C++ construct", kwd->value);
+ error ("misplaced %<@%D%> Objective-C++ construct", kwd->u.value);
cp_parser_skip_to_end_of_block_or_statement (parser);
}
}
@@ -18123,7 +18161,7 @@ cp_parser_objc_statement (cp_parser * parser) {
case RID_AT_THROW:
return cp_parser_objc_throw_statement (parser);
default:
- error ("misplaced %<@%D%> Objective-C++ construct", kwd->value);
+ error ("misplaced %<@%D%> Objective-C++ construct", kwd->u.value);
cp_parser_skip_to_end_of_block_or_statement (parser);
}
@@ -18150,7 +18188,7 @@ cp_parser_omp_clause_name (cp_parser *parser)
result = PRAGMA_OMP_CLAUSE_PRIVATE;
else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
- tree id = cp_lexer_peek_token (parser->lexer)->value;
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
switch (p[0])
@@ -18304,7 +18342,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list)
return list;
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
- tree id = cp_lexer_peek_token (parser->lexer)->value;
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
switch (p[0])
@@ -18515,7 +18553,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list)
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
- tree id = cp_lexer_peek_token (parser->lexer)->value;
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
switch (p[0])
@@ -19164,7 +19202,7 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok)
}
else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
- tree id = cp_lexer_peek_token (parser->lexer)->value;
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
if (strcmp (p, "sections") == 0)
{
@@ -19320,7 +19358,7 @@ cp_parser_initial_pragma (cp_token *first_token)
cp_lexer_get_preprocessor_token (NULL, first_token);
if (first_token->type == CPP_STRING)
{
- name = first_token->value;
+ name = first_token->u.value;
cp_lexer_get_preprocessor_token (NULL, first_token);
if (first_token->type != CPP_PRAGMA_EOL)
@@ -19440,7 +19478,7 @@ pragma_lex (tree *value)
tok = cp_lexer_peek_token (the_parser->lexer);
ret = tok->type;
- *value = tok->value;
+ *value = tok->u.value;
if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
ret = CPP_EOF;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 9192aff..41d2be9 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -96,7 +96,7 @@ static tree finalize_nrv_r (tree *, int *, void *);
2. When a declaration such as a type, or a variable, is encountered,
the function `perform_or_defer_access_check' is called. It
- maintains a TREE_LIST of all deferred checks.
+ maintains a VEC of all deferred checks.
3. The global `current_class_type' or `current_function_decl' is then
setup by the parser. `enforce_access' relies on these information
@@ -104,7 +104,7 @@ static tree finalize_nrv_r (tree *, int *, void *);
4. Upon exiting the context mentioned in step 1,
`perform_deferred_access_checks' is called to check all declaration
- stored in the TREE_LIST. `pop_deferring_access_checks' is then
+ stored in the VEC. `pop_deferring_access_checks' is then
called to restore the previous access checking mode.
In case of parsing error, we simply call `pop_deferring_access_checks'
@@ -112,7 +112,7 @@ static tree finalize_nrv_r (tree *, int *, void *);
typedef struct deferred_access GTY(())
{
- /* A TREE_LIST representing name-lookups for which we have deferred
+ /* A VEC representing name-lookups for which we have deferred
checking access controls. We cannot check the accessibility of
names used in a decl-specifier-seq until we know what is being
declared because code like:
@@ -124,12 +124,8 @@ typedef struct deferred_access GTY(())
A::B* A::f() { return 0; }
- is valid, even though `A::B' is not generally accessible.
-
- The TREE_PURPOSE of each node is the scope used to qualify the
- name being looked up; the TREE_VALUE is the DECL to which the
- name was resolved. */
- tree deferred_access_checks;
+ is valid, even though `A::B' is not generally accessible. */
+ VEC (deferred_access_check,gc)* GTY(()) deferred_access_checks;
/* The current mode of access checks. */
enum deferring_kind deferring_access_checks_kind;
@@ -157,7 +153,7 @@ push_deferring_access_checks (deferring_kind deferring)
deferred_access *ptr;
ptr = VEC_safe_push (deferred_access, gc, deferred_access_stack, NULL);
- ptr->deferred_access_checks = NULL_TREE;
+ ptr->deferred_access_checks = NULL;
ptr->deferring_access_checks_kind = deferring;
}
}
@@ -200,7 +196,7 @@ pop_deferring_access_checks (void)
access occurred; the TREE_VALUE is the declaration named.
*/
-tree
+VEC (deferred_access_check,gc)*
get_deferred_access_checks (void)
{
if (deferred_access_no_check)
@@ -221,7 +217,7 @@ pop_to_parent_deferring_access_checks (void)
deferred_access_no_check--;
else
{
- tree checks;
+ VEC (deferred_access_check,gc) *checks;
deferred_access *ptr;
checks = (VEC_last (deferred_access, deferred_access_stack)
@@ -232,29 +228,31 @@ pop_to_parent_deferring_access_checks (void)
if (ptr->deferring_access_checks_kind == dk_no_deferred)
{
/* Check access. */
- for (; checks; checks = TREE_CHAIN (checks))
- enforce_access (TREE_PURPOSE (checks),
- TREE_VALUE (checks), TREE_VALUE (checks));
+ perform_access_checks (checks);
}
else
{
/* Merge with parent. */
- tree next;
- tree original = ptr->deferred_access_checks;
+ int i, j;
+ deferred_access_check *chk, *probe;
- for (; checks; checks = next)
+ for (i = 0 ;
+ VEC_iterate (deferred_access_check, checks, i, chk) ;
+ ++i)
{
- tree probe;
-
- next = TREE_CHAIN (checks);
-
- for (probe = original; probe; probe = TREE_CHAIN (probe))
- if (TREE_VALUE (probe) == TREE_VALUE (checks)
- && TREE_PURPOSE (probe) == TREE_PURPOSE (checks))
- goto found;
+ for (j = 0 ;
+ VEC_iterate (deferred_access_check,
+ ptr->deferred_access_checks, j, probe) ;
+ ++j)
+ {
+ if (probe->binfo == chk->binfo &&
+ probe->decl == chk->decl &&
+ probe->diag_decl == chk->diag_decl)
+ goto found;
+ }
/* Insert into parent's checks. */
- TREE_CHAIN (checks) = ptr->deferred_access_checks;
- ptr->deferred_access_checks = checks;
+ VEC_safe_push (deferred_access_check, gc,
+ ptr->deferred_access_checks, chk);
found:;
}
}
@@ -266,14 +264,16 @@ pop_to_parent_deferring_access_checks (void)
DECL node stored in the TREE_VALUE of the node. */
void
-perform_access_checks (tree checks)
+perform_access_checks (VEC (deferred_access_check,gc)* checks)
{
- while (checks)
- {
- enforce_access (TREE_PURPOSE (checks),
- TREE_VALUE (checks), TREE_VALUE (checks));
- checks = TREE_CHAIN (checks);
- }
+ int i;
+ deferred_access_check *chk;
+
+ if (!checks)
+ return;
+
+ for (i = 0 ; VEC_iterate (deferred_access_check, checks, i, chk) ; ++i)
+ enforce_access (chk->binfo, chk->decl, chk->diag_decl);
}
/* Perform the deferred access checks.
@@ -304,8 +304,11 @@ perform_deferred_access_checks (void)
void
perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl)
{
- tree check;
+ int i;
deferred_access *ptr;
+ deferred_access_check *chk;
+ deferred_access_check *new_access;
+
/* Exit if we are in a context that no access checking is performed.
*/
@@ -324,14 +327,24 @@ perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl)
}
/* See if we are already going to perform this check. */
- for (check = ptr->deferred_access_checks;
- check;
- check = TREE_CHAIN (check))
- if (TREE_VALUE (check) == decl && TREE_PURPOSE (check) == binfo)
- return;
+ for (i = 0 ;
+ VEC_iterate (deferred_access_check,
+ ptr->deferred_access_checks, i, chk) ;
+ ++i)
+ {
+ if (chk->decl == decl && chk->binfo == binfo &&
+ chk->diag_decl == diag_decl)
+ {
+ return;
+ }
+ }
/* If not, record the check. */
- ptr->deferred_access_checks
- = tree_cons (binfo, decl, ptr->deferred_access_checks);
+ new_access =
+ VEC_safe_push (deferred_access_check, gc,
+ ptr->deferred_access_checks, 0);
+ new_access->binfo = binfo;
+ new_access->decl = decl;
+ new_access->diag_decl = diag_decl;
}
/* Returns nonzero if the current statement is a full expression,