Commit d6b418fa by Simon Martin Committed by Simon Martin

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
parent e6a98ba8
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> 2006-12-13 Ian Lance Taylor <iant@google.com>
PR c++/19564 PR c++/19564
......
...@@ -4234,14 +4234,29 @@ extern tree copied_binfo (tree, tree); ...@@ -4234,14 +4234,29 @@ extern tree copied_binfo (tree, tree);
extern tree original_binfo (tree, tree); extern tree original_binfo (tree, tree);
extern int shared_member_p (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 */ /* in semantics.c */
extern void push_deferring_access_checks (deferring_kind); extern void push_deferring_access_checks (deferring_kind);
extern void resume_deferring_access_checks (void); extern void resume_deferring_access_checks (void);
extern void stop_deferring_access_checks (void); extern void stop_deferring_access_checks (void);
extern void pop_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 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_deferred_access_checks (void);
extern void perform_or_defer_access_check (tree, tree, tree); extern void perform_or_defer_access_check (tree, tree, tree);
extern int stmts_are_full_exprs_p (void); extern int stmts_are_full_exprs_p (void);
......
...@@ -96,7 +96,7 @@ static tree finalize_nrv_r (tree *, int *, void *); ...@@ -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, 2. When a declaration such as a type, or a variable, is encountered,
the function `perform_or_defer_access_check' is called. It 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 3. The global `current_class_type' or `current_function_decl' is then
setup by the parser. `enforce_access' relies on these information setup by the parser. `enforce_access' relies on these information
...@@ -104,7 +104,7 @@ static tree finalize_nrv_r (tree *, int *, void *); ...@@ -104,7 +104,7 @@ static tree finalize_nrv_r (tree *, int *, void *);
4. Upon exiting the context mentioned in step 1, 4. Upon exiting the context mentioned in step 1,
`perform_deferred_access_checks' is called to check all declaration `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. called to restore the previous access checking mode.
In case of parsing error, we simply call `pop_deferring_access_checks' In case of parsing error, we simply call `pop_deferring_access_checks'
...@@ -112,7 +112,7 @@ static tree finalize_nrv_r (tree *, int *, void *); ...@@ -112,7 +112,7 @@ static tree finalize_nrv_r (tree *, int *, void *);
typedef struct deferred_access GTY(()) 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 checking access controls. We cannot check the accessibility of
names used in a decl-specifier-seq until we know what is being names used in a decl-specifier-seq until we know what is being
declared because code like: declared because code like:
...@@ -124,12 +124,8 @@ typedef struct deferred_access GTY(()) ...@@ -124,12 +124,8 @@ typedef struct deferred_access GTY(())
A::B* A::f() { return 0; } A::B* A::f() { return 0; }
is valid, even though `A::B' is not generally accessible. is valid, even though `A::B' is not generally accessible. */
VEC (deferred_access_check,gc)* GTY(()) deferred_access_checks;
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;
/* The current mode of access checks. */ /* The current mode of access checks. */
enum deferring_kind deferring_access_checks_kind; enum deferring_kind deferring_access_checks_kind;
...@@ -157,7 +153,7 @@ push_deferring_access_checks (deferring_kind deferring) ...@@ -157,7 +153,7 @@ push_deferring_access_checks (deferring_kind deferring)
deferred_access *ptr; deferred_access *ptr;
ptr = VEC_safe_push (deferred_access, gc, deferred_access_stack, NULL); 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; ptr->deferring_access_checks_kind = deferring;
} }
} }
...@@ -200,7 +196,7 @@ pop_deferring_access_checks (void) ...@@ -200,7 +196,7 @@ pop_deferring_access_checks (void)
access occurred; the TREE_VALUE is the declaration named. access occurred; the TREE_VALUE is the declaration named.
*/ */
tree VEC (deferred_access_check,gc)*
get_deferred_access_checks (void) get_deferred_access_checks (void)
{ {
if (deferred_access_no_check) if (deferred_access_no_check)
...@@ -221,7 +217,7 @@ pop_to_parent_deferring_access_checks (void) ...@@ -221,7 +217,7 @@ pop_to_parent_deferring_access_checks (void)
deferred_access_no_check--; deferred_access_no_check--;
else else
{ {
tree checks; VEC (deferred_access_check,gc) *checks;
deferred_access *ptr; deferred_access *ptr;
checks = (VEC_last (deferred_access, deferred_access_stack) checks = (VEC_last (deferred_access, deferred_access_stack)
...@@ -232,29 +228,31 @@ pop_to_parent_deferring_access_checks (void) ...@@ -232,29 +228,31 @@ pop_to_parent_deferring_access_checks (void)
if (ptr->deferring_access_checks_kind == dk_no_deferred) if (ptr->deferring_access_checks_kind == dk_no_deferred)
{ {
/* Check access. */ /* Check access. */
for (; checks; checks = TREE_CHAIN (checks)) perform_access_checks (checks);
enforce_access (TREE_PURPOSE (checks),
TREE_VALUE (checks), TREE_VALUE (checks));
} }
else else
{ {
/* Merge with parent. */ /* Merge with parent. */
tree next; int i, j;
tree original = ptr->deferred_access_checks; deferred_access_check *chk, *probe;
for (; checks; checks = next) for (i = 0 ;
VEC_iterate (deferred_access_check, checks, i, chk) ;
++i)
{ {
tree probe; for (j = 0 ;
VEC_iterate (deferred_access_check,
next = TREE_CHAIN (checks); ptr->deferred_access_checks, j, probe) ;
++j)
for (probe = original; probe; probe = TREE_CHAIN (probe)) {
if (TREE_VALUE (probe) == TREE_VALUE (checks) if (probe->binfo == chk->binfo &&
&& TREE_PURPOSE (probe) == TREE_PURPOSE (checks)) probe->decl == chk->decl &&
goto found; probe->diag_decl == chk->diag_decl)
goto found;
}
/* Insert into parent's checks. */ /* Insert into parent's checks. */
TREE_CHAIN (checks) = ptr->deferred_access_checks; VEC_safe_push (deferred_access_check, gc,
ptr->deferred_access_checks = checks; ptr->deferred_access_checks, chk);
found:; found:;
} }
} }
...@@ -266,14 +264,16 @@ pop_to_parent_deferring_access_checks (void) ...@@ -266,14 +264,16 @@ pop_to_parent_deferring_access_checks (void)
DECL node stored in the TREE_VALUE of the node. */ DECL node stored in the TREE_VALUE of the node. */
void void
perform_access_checks (tree checks) perform_access_checks (VEC (deferred_access_check,gc)* checks)
{ {
while (checks) int i;
{ deferred_access_check *chk;
enforce_access (TREE_PURPOSE (checks),
TREE_VALUE (checks), TREE_VALUE (checks)); if (!checks)
checks = TREE_CHAIN (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. /* Perform the deferred access checks.
...@@ -304,8 +304,11 @@ perform_deferred_access_checks (void) ...@@ -304,8 +304,11 @@ perform_deferred_access_checks (void)
void void
perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl) perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl)
{ {
tree check; int i;
deferred_access *ptr; 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. /* 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) ...@@ -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. */ /* See if we are already going to perform this check. */
for (check = ptr->deferred_access_checks; for (i = 0 ;
check; VEC_iterate (deferred_access_check,
check = TREE_CHAIN (check)) ptr->deferred_access_checks, i, chk) ;
if (TREE_VALUE (check) == decl && TREE_PURPOSE (check) == binfo) ++i)
return; {
if (chk->decl == decl && chk->binfo == binfo &&
chk->diag_decl == diag_decl)
{
return;
}
}
/* If not, record the check. */ /* If not, record the check. */
ptr->deferred_access_checks new_access =
= tree_cons (binfo, decl, ptr->deferred_access_checks); 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, /* Returns nonzero if the current statement is a full expression,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment