Commit 1f51a992 by Jason Merrill Committed by Jason Merrill

semantics.c (deferred_type_access_control): Walk the entire type_lookups list.

        * semantics.c (deferred_type_access_control): Walk the entire
        type_lookups list.
        (save_type_access_control): Rename from
        initial_deferred_type_access_control.  Just remember the value.
        (decl_type_access_control): New fn.
        (begin_function_definition): Use deferred_type_access_control, after
        we've started the function.  Set type_lookups to error_mark_node.
        * parse.y (frob_specs, fn.def1): Adjust.
        (parse_decl0, parse_field, parse_field0, parse_bitfield): New fns.
        (parse_end_decl, parse_bitfield0, parse_method): New fns.
        (fn.def2, initdcl, initdcl0_innards, nomods_initdcl0): Use them.
        (after_type_component_declarator0): Likewise.
        (after_type_component_declarator): Likewise.
        (notype_component_declarator): Likewise.
        * cp-tree.h: Adjust.

        * decl.c (redeclaration_error_message): Allow redeclaration of
        namespace-scope decls.

From-SVN: r32059
parent 6d1e16d7
2000-02-18 Jason Merrill <jason@casey.cygnus.com>
* semantics.c (deferred_type_access_control): Walk the entire
type_lookups list.
(save_type_access_control): Rename from
initial_deferred_type_access_control. Just remember the value.
(decl_type_access_control): New fn.
(begin_function_definition): Use deferred_type_access_control, after
we've started the function. Set type_lookups to error_mark_node.
* parse.y (frob_specs, fn.def1): Adjust.
(parse_decl0, parse_field, parse_field0, parse_bitfield): New fns.
(parse_end_decl, parse_bitfield0, parse_method): New fns.
(fn.def2, initdcl, initdcl0_innards, nomods_initdcl0): Use them.
(after_type_component_declarator0): Likewise.
(after_type_component_declarator): Likewise.
(notype_component_declarator): Likewise.
* cp-tree.h: Adjust.
* decl.c (redeclaration_error_message): Allow redeclaration of
namespace-scope decls.
2000-02-18 Martin von Loewis <loewis@informatik.hu-berlin.de> 2000-02-18 Martin von Loewis <loewis@informatik.hu-berlin.de>
* typeck2.c (my_friendly_abort): Use GCCBUGURL. * typeck2.c (my_friendly_abort): Use GCCBUGURL.
......
...@@ -4177,9 +4177,9 @@ extern tree finish_qualified_call_expr PARAMS ((tree, tree)); ...@@ -4177,9 +4177,9 @@ extern tree finish_qualified_call_expr PARAMS ((tree, tree));
extern tree finish_label_address_expr PARAMS ((tree)); extern tree finish_label_address_expr PARAMS ((tree));
extern tree finish_unary_op_expr PARAMS ((enum tree_code, tree)); extern tree finish_unary_op_expr PARAMS ((enum tree_code, tree));
extern tree finish_id_expr PARAMS ((tree)); extern tree finish_id_expr PARAMS ((tree));
extern void deferred_type_access_control PARAMS ((void)); extern void save_type_access_control PARAMS ((tree));
extern void initial_deferred_type_access_control PARAMS ((tree)); extern void decl_type_access_control PARAMS ((tree));
extern int begin_function_definition PARAMS ((tree, tree, tree)); extern int begin_function_definition PARAMS ((tree, tree));
extern tree begin_constructor_declarator PARAMS ((tree, tree)); extern tree begin_constructor_declarator PARAMS ((tree, tree));
extern tree finish_declarator PARAMS ((tree, tree, tree, tree, int)); extern tree finish_declarator PARAMS ((tree, tree, tree, tree, int));
extern void finish_translation_unit PARAMS ((void)); extern void finish_translation_unit PARAMS ((void));
......
...@@ -4585,7 +4585,7 @@ redeclaration_error_message (newdecl, olddecl) ...@@ -4585,7 +4585,7 @@ redeclaration_error_message (newdecl, olddecl)
return "redefinition of `%#D'"; return "redefinition of `%#D'";
return 0; return 0;
} }
else if (toplevel_bindings_p ()) else if (toplevel_bindings_p () || DECL_NAMESPACE_SCOPE_P (newdecl))
{ {
/* Objects declared at top level: */ /* Objects declared at top level: */
/* If at least one is a reference, it's ok. */ /* If at least one is a reference, it's ok. */
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -62,13 +62,38 @@ extern int end_of_file; ...@@ -62,13 +62,38 @@ extern int end_of_file;
error message if the user supplies an empty conditional expression. */ error message if the user supplies an empty conditional expression. */
static const char *cond_stmt_keyword; static const char *cond_stmt_keyword;
static tree empty_parms PARAMS ((void));
static void parse_decl PARAMS ((tree, tree, tree, tree, int, tree *));
/* Nonzero if we have an `extern "C"' acting as an extern specifier. */ /* Nonzero if we have an `extern "C"' acting as an extern specifier. */
int have_extern_spec; int have_extern_spec;
int used_extern_spec; int used_extern_spec;
/* List of types and structure classes of the current declaration. */
static tree current_declspecs;
/* List of prefix attributes in effect.
Prefix attributes are parsed by the reserved_declspecs and declmods
rules. They create a list that contains *both* declspecs and attrs. */
/* ??? It is not clear yet that all cases where an attribute can now appear in
a declspec list have been updated. */
static tree prefix_attributes;
/* When defining an aggregate, this is the kind of the most recent one
being defined. (For example, this might be class_type_node.) */
static tree current_aggr;
/* When defining an enumeration, this is the type of the enumeration. */
static tree current_enum_type;
static tree empty_parms PARAMS ((void));
static tree parse_decl0 PARAMS ((tree, tree, tree, tree, int));
static tree parse_decl PARAMS ((tree, tree, int));
static void parse_end_decl PARAMS ((tree, tree, tree));
static tree parse_field0 PARAMS ((tree, tree, tree, tree, tree, tree));
static tree parse_field PARAMS ((tree, tree, tree, tree));
static tree parse_bitfield0 PARAMS ((tree, tree, tree, tree, tree));
static tree parse_bitfield PARAMS ((tree, tree, tree));
static tree parse_method PARAMS ((tree, tree, tree));
static void frob_specs PARAMS ((tree, tree));
/* Cons up an empty parameter list. */ /* Cons up an empty parameter list. */
static inline tree static inline tree
empty_parms () empty_parms ()
...@@ -83,6 +108,108 @@ empty_parms () ...@@ -83,6 +108,108 @@ empty_parms ()
return parms; return parms;
} }
/* Record the decl-specifiers, attributes and type lookups from the
decl-specifier-seq in a declaration. */
static void
frob_specs (specs_attrs, lookups)
tree specs_attrs, lookups;
{
save_type_access_control (lookups);
split_specs_attrs (specs_attrs, &current_declspecs, &prefix_attributes);
if (current_declspecs
&& TREE_CODE (current_declspecs) != TREE_LIST)
current_declspecs = build_decl_list (NULL_TREE, current_declspecs);
if (have_extern_spec && !used_extern_spec)
{
current_declspecs = decl_tree_cons (NULL_TREE,
get_identifier ("extern"),
current_declspecs);
used_extern_spec = 1;
}
}
static tree
parse_decl (declarator, attributes, initialized)
tree declarator, attributes;
int initialized;
{
return start_decl (declarator, current_declspecs, initialized,
attributes, prefix_attributes);
}
static tree
parse_decl0 (declarator, specs_attrs, lookups, attributes, initialized)
tree declarator, specs_attrs, lookups, attributes;
int initialized;
{
frob_specs (specs_attrs, lookups);
return parse_decl (declarator, attributes, initialized);
}
static void
parse_end_decl (decl, init, asmspec)
tree decl, init, asmspec;
{
decl_type_access_control (decl);
cp_finish_decl (decl, init, asmspec, init ? LOOKUP_ONLYCONVERTING : 0);
}
static tree
parse_field (declarator, attributes, asmspec, init)
tree declarator, attributes, asmspec, init;
{
tree d = grokfield (declarator, current_declspecs, init, asmspec,
build_tree_list (attributes, prefix_attributes));
decl_type_access_control (d);
return d;
}
static tree
parse_field0 (declarator, specs_attrs, lookups, attributes, asmspec, init)
tree declarator, specs_attrs, lookups, attributes, asmspec, init;
{
frob_specs (specs_attrs, lookups);
return parse_field (declarator, attributes, asmspec, init);
}
static tree
parse_bitfield (declarator, attributes, width)
tree declarator, attributes, width;
{
tree d = grokbitfield (declarator, current_declspecs, width);
cplus_decl_attributes (d, attributes, prefix_attributes);
decl_type_access_control (d);
return d;
}
static tree
parse_bitfield0 (declarator, specs_attrs, lookups, attributes, width)
tree declarator, specs_attrs, lookups, attributes, width;
{
frob_specs (specs_attrs, lookups);
return parse_bitfield (declarator, attributes, width);
}
static tree
parse_method (declarator, specs_attrs, lookups)
tree declarator, specs_attrs, lookups;
{
tree d;
frob_specs (specs_attrs, lookups);
d = start_method (current_declspecs, declarator, prefix_attributes);
decl_type_access_control (d);
return d;
}
void
cp_parse_init ()
{
ggc_add_tree_root (&current_declspecs, 1);
ggc_add_tree_root (&prefix_attributes, 1);
ggc_add_tree_root (&current_aggr, 1);
ggc_add_tree_root (&current_enum_type, 1);
}
%} %}
%start program %start program
...@@ -291,71 +418,9 @@ empty_parms () ...@@ -291,71 +418,9 @@ empty_parms ()
%token END_OF_SAVED_INPUT %token END_OF_SAVED_INPUT
%{ %{
/* List of types and structure classes of the current declaration. */
static tree current_declspecs;
/* List of prefix attributes in effect.
Prefix attributes are parsed by the reserved_declspecs and declmods
rules. They create a list that contains *both* declspecs and attrs. */
/* ??? It is not clear yet that all cases where an attribute can now appear in
a declspec list have been updated. */
static tree prefix_attributes;
/* When defining an aggregate, this is the kind of the most recent one
being defined. (For example, this might be class_type_node.) */
static tree current_aggr;
/* When defining an enumeration, this is the type of the enumeration. */
static tree current_enum_type;
/* Tell yyparse how to print a token's value, if yydebug is set. */ /* Tell yyparse how to print a token's value, if yydebug is set. */
#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
extern void yyprint PARAMS ((FILE *, int, YYSTYPE)); extern void yyprint PARAMS ((FILE *, int, YYSTYPE));
extern tree combine_strings PARAMS ((tree));
static void
frob_specs (specs_attrs, lookups)
tree specs_attrs;
tree lookups;
{
initial_deferred_type_access_control (lookups);
split_specs_attrs (specs_attrs, &current_declspecs, &prefix_attributes);
if (current_declspecs
&& TREE_CODE (current_declspecs) != TREE_LIST)
current_declspecs = build_decl_list (NULL_TREE, current_declspecs);
}
static void
parse_decl (declarator, specs_attrs, lookups, attributes, initialized, decl)
tree declarator;
tree specs_attrs;
tree lookups;
tree attributes;
int initialized;
tree* decl;
{
frob_specs (specs_attrs, lookups);
if (have_extern_spec && !used_extern_spec)
{
current_declspecs = decl_tree_cons (NULL_TREE,
get_identifier ("extern"),
current_declspecs);
used_extern_spec = 1;
}
*decl = start_decl (declarator, current_declspecs, initialized,
attributes, prefix_attributes);
}
void
cp_parse_init ()
{
ggc_add_tree_root (&current_declspecs, 1);
ggc_add_tree_root (&prefix_attributes, 1);
ggc_add_tree_root (&current_aggr, 1);
ggc_add_tree_root (&current_enum_type, 1);
}
%} %}
%% %%
...@@ -707,19 +772,19 @@ constructor_declarator: ...@@ -707,19 +772,19 @@ constructor_declarator:
fn.def1: fn.def1:
typed_declspecs declarator typed_declspecs declarator
{ if (!begin_function_definition ($1.t, $1.lookups, $2)) { if (!begin_function_definition ($1.t, $2))
YYERROR1; } YYERROR1; }
| declmods notype_declarator | declmods notype_declarator
{ if (!begin_function_definition ($1.t, NULL_TREE, $2)) { if (!begin_function_definition ($1.t, $2))
YYERROR1; } YYERROR1; }
| notype_declarator | notype_declarator
{ if (!begin_function_definition (NULL_TREE, NULL_TREE, $1)) { if (!begin_function_definition (NULL_TREE, $1))
YYERROR1; } YYERROR1; }
| declmods constructor_declarator | declmods constructor_declarator
{ if (!begin_function_definition ($1.t, NULL_TREE, $2)) { if (!begin_function_definition ($1.t, $2))
YYERROR1; } YYERROR1; }
| constructor_declarator | constructor_declarator
{ if (!begin_function_definition (NULL_TREE, NULL_TREE, $1)) { if (!begin_function_definition (NULL_TREE, $1))
YYERROR1; } YYERROR1; }
; ;
...@@ -738,10 +803,7 @@ component_constructor_declarator: ...@@ -738,10 +803,7 @@ component_constructor_declarator:
reduce/reduce conflict introduced by these rules. */ reduce/reduce conflict introduced by these rules. */
fn.def2: fn.def2:
declmods component_constructor_declarator declmods component_constructor_declarator
{ tree specs, attrs; { $$ = parse_method ($2, $1.t, $1.lookups);
split_specs_attrs ($1.t, &specs, &attrs);
attrs = build_tree_list (attrs, NULL_TREE);
$$ = start_method (specs, $2, attrs);
rest_of_mdef: rest_of_mdef:
if (! $$) if (! $$)
YYERROR1; YYERROR1;
...@@ -749,29 +811,19 @@ fn.def2: ...@@ -749,29 +811,19 @@ fn.def2:
yychar = YYLEX; yychar = YYLEX;
reinit_parse_for_method (yychar, $$); } reinit_parse_for_method (yychar, $$); }
| component_constructor_declarator | component_constructor_declarator
{ $$ = start_method (NULL_TREE, $1, NULL_TREE); { $$ = parse_method ($1, NULL_TREE, NULL_TREE);
goto rest_of_mdef; } goto rest_of_mdef; }
| typed_declspecs declarator | typed_declspecs declarator
{ tree specs, attrs; { $$ = parse_method ($2, $1.t, $1.lookups); goto rest_of_mdef;}
split_specs_attrs ($1.t, &specs, &attrs);
attrs = build_tree_list (attrs, NULL_TREE);
initial_deferred_type_access_control ($1.lookups);
$$ = start_method (specs, $2, attrs); goto rest_of_mdef; }
| declmods notype_declarator | declmods notype_declarator
{ tree specs, attrs; { $$ = parse_method ($2, $1.t, $1.lookups); goto rest_of_mdef;}
split_specs_attrs ($1.t, &specs, &attrs);
attrs = build_tree_list (attrs, NULL_TREE);
$$ = start_method (specs, $2, attrs); goto rest_of_mdef; }
| notype_declarator | notype_declarator
{ $$ = start_method (NULL_TREE, $$, NULL_TREE); { $$ = parse_method ($1, NULL_TREE, NULL_TREE);
goto rest_of_mdef; } goto rest_of_mdef; }
| declmods constructor_declarator | declmods constructor_declarator
{ tree specs, attrs; { $$ = parse_method ($2, $1.t, $1.lookups); goto rest_of_mdef;}
split_specs_attrs ($1.t, &specs, &attrs);
attrs = build_tree_list (attrs, NULL_TREE);
$$ = start_method (specs, $2, attrs); goto rest_of_mdef; }
| constructor_declarator | constructor_declarator
{ $$ = start_method (NULL_TREE, $$, NULL_TREE); { $$ = parse_method ($1, NULL_TREE, NULL_TREE);
goto rest_of_mdef; } goto rest_of_mdef; }
; ;
...@@ -1040,12 +1092,11 @@ condition: ...@@ -1040,12 +1092,11 @@ condition:
} }
} }
current_declspecs = $1.t; current_declspecs = $1.t;
$<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1, $<ttype>$ = parse_decl ($<ttype>2, $4, 1);
$4, /*prefix_attributes*/ NULL_TREE);
} }
init init
{ {
cp_finish_decl ($<ttype>6, $7, $4, LOOKUP_ONLYCONVERTING); parse_end_decl ($<ttype>6, $7, $4);
$$ = convert_from_reference ($<ttype>6); $$ = convert_from_reference ($<ttype>6);
if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE) if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE)
cp_error ("definition of array `%#D' in condition", $$); cp_error ("definition of array `%#D' in condition", $$);
...@@ -1884,20 +1935,14 @@ maybeasm: ...@@ -1884,20 +1935,14 @@ maybeasm:
initdcl: initdcl:
declarator maybeasm maybe_attribute '=' declarator maybeasm maybe_attribute '='
{ { $<ttype>$ = parse_decl ($<ttype>1, $3, 1); }
deferred_type_access_control ();
$<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1,
$3, prefix_attributes);
}
init init
/* Note how the declaration of the variable is in effect while its init is parsed! */ /* Note how the declaration of the variable is in effect while its init is parsed! */
{ cp_finish_decl ($<ttype>5, $6, $2, LOOKUP_ONLYCONVERTING); } { parse_end_decl ($<ttype>5, $6, $2); }
| declarator maybeasm maybe_attribute | declarator maybeasm maybe_attribute
{ {
deferred_type_access_control (); $<ttype>$ = parse_decl ($<ttype>1, $3, 0);
$<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0, parse_end_decl ($<ttype>$, NULL_TREE, $2);
$3, prefix_attributes);
cp_finish_decl ($<ttype>$, NULL_TREE, $2, 0);
} }
; ;
...@@ -1909,18 +1954,16 @@ initdcl: ...@@ -1909,18 +1954,16 @@ initdcl:
we need that reduce so we prefer fn.def1 when appropriate. */ we need that reduce so we prefer fn.def1 when appropriate. */
initdcl0_innards: initdcl0_innards:
maybe_attribute '=' maybe_attribute '='
{ parse_decl ($<ttype>-1, $<ftype>-2.t, $<ftype>-2.lookups, { $<ttype>$ = parse_decl0 ($<ttype>-1, $<ftype>-2.t,
$1, 1, &$<ttype>$); } $<ftype>-2.lookups, $1, 1); }
/* Note how the declaration of the variable is in effect /* Note how the declaration of the variable is in effect
while its init is parsed! */ while its init is parsed! */
init init
{ cp_finish_decl ($<ttype>3, $4, $<ttype>0, { parse_end_decl ($<ttype>3, $4, $<ttype>0); }
LOOKUP_ONLYCONVERTING); }
| maybe_attribute | maybe_attribute
{ tree d; { tree d = parse_decl0 ($<ttype>-1, $<ftype>-2.t,
parse_decl ($<ttype>-1, $<ftype>-2.t, $<ftype>-2.lookups, $<ftype>-2.lookups, $1, 0);
$1, 0, &d); parse_end_decl (d, NULL_TREE, $<ttype>0); }
cp_finish_decl (d, NULL_TREE, $<ttype>0, 0); }
; ;
initdcl0: initdcl0:
...@@ -1941,9 +1984,8 @@ nomods_initdcl0: ...@@ -1941,9 +1984,8 @@ nomods_initdcl0:
initdcl0_innards initdcl0_innards
{} {}
| constructor_declarator maybeasm maybe_attribute | constructor_declarator maybeasm maybe_attribute
{ tree d; { tree d = parse_decl0 ($1, NULL_TREE, NULL_TREE, $3, 0);
parse_decl ($1, NULL_TREE, NULL_TREE, $3, 0, &d); parse_end_decl (d, NULL_TREE, $2); }
cp_finish_decl (d, NULL_TREE, $2, 0); }
; ;
/* the * rules are dummies to accept the Apollo extended syntax /* the * rules are dummies to accept the Apollo extended syntax
...@@ -2552,53 +2594,42 @@ component_declarator: ...@@ -2552,53 +2594,42 @@ component_declarator:
after_type_component_declarator0: after_type_component_declarator0:
after_type_declarator maybeasm maybe_attribute maybe_init after_type_declarator maybeasm maybe_attribute maybe_init
{ frob_specs ($<ftype>0.t, $<ftype>0.lookups); { $$ = parse_field0 ($1, $<ftype>0.t, $<ftype>0.lookups,
$$ = grokfield ($$, current_declspecs, $4, $2, $3, $2, $4); }
build_tree_list ($3, prefix_attributes)); }
| TYPENAME ':' expr_no_commas maybe_attribute | TYPENAME ':' expr_no_commas maybe_attribute
{ frob_specs ($<ftype>0.t, $<ftype>0.lookups); { $$ = parse_bitfield0 ($1, $<ftype>0.t, $<ftype>0.lookups,
$$ = grokbitfield ($$, current_declspecs, $3); $4, $3); }
cplus_decl_attributes ($$, $4, prefix_attributes); }
; ;
notype_component_declarator0: notype_component_declarator0:
notype_declarator maybeasm maybe_attribute maybe_init notype_declarator maybeasm maybe_attribute maybe_init
{ frob_specs ($<ftype>0.t, $<ftype>0.lookups); { $$ = parse_field0 ($1, $<ftype>0.t, $<ftype>0.lookups,
$$ = grokfield ($$, current_declspecs, $4, $2, $3, $2, $4); }
build_tree_list ($3, prefix_attributes)); }
| constructor_declarator maybeasm maybe_attribute maybe_init | constructor_declarator maybeasm maybe_attribute maybe_init
{ frob_specs ($<ftype>0.t, $<ftype>0.lookups); { $$ = parse_field0 ($1, $<ftype>0.t, $<ftype>0.lookups,
$$ = grokfield ($$, current_declspecs, $4, $2, $3, $2, $4); }
build_tree_list ($3, prefix_attributes)); }
| IDENTIFIER ':' expr_no_commas maybe_attribute | IDENTIFIER ':' expr_no_commas maybe_attribute
{ frob_specs ($<ftype>0.t, $<ftype>0.lookups); { $$ = parse_bitfield0 ($1, $<ftype>0.t, $<ftype>0.lookups,
$$ = grokbitfield ($$, current_declspecs, $3); $4, $3); }
cplus_decl_attributes ($$, $4, prefix_attributes); }
| ':' expr_no_commas maybe_attribute | ':' expr_no_commas maybe_attribute
{ frob_specs ($<ftype>0.t, $<ftype>0.lookups); { $$ = parse_bitfield0 (NULL_TREE, $<ftype>0.t,
$$ = grokbitfield (NULL_TREE, current_declspecs, $2); $<ftype>0.lookups, $3, $2); }
cplus_decl_attributes ($$, $3, prefix_attributes); }
; ;
after_type_component_declarator: after_type_component_declarator:
after_type_declarator maybeasm maybe_attribute maybe_init after_type_declarator maybeasm maybe_attribute maybe_init
{ $$ = grokfield ($$, current_declspecs, $4, $2, { $$ = parse_field ($1, $3, $2, $4); }
build_tree_list ($3, prefix_attributes)); }
| TYPENAME ':' expr_no_commas maybe_attribute | TYPENAME ':' expr_no_commas maybe_attribute
{ $$ = grokbitfield ($$, current_declspecs, $3); { $$ = parse_bitfield ($1, $4, $3); }
cplus_decl_attributes ($$, $4, prefix_attributes); }
; ;
notype_component_declarator: notype_component_declarator:
notype_declarator maybeasm maybe_attribute maybe_init notype_declarator maybeasm maybe_attribute maybe_init
{ $$ = grokfield ($$, current_declspecs, $4, $2, { $$ = parse_field ($1, $3, $2, $4); }
build_tree_list ($3, prefix_attributes)); }
| IDENTIFIER ':' expr_no_commas maybe_attribute | IDENTIFIER ':' expr_no_commas maybe_attribute
{ $$ = grokbitfield ($$, current_declspecs, $3); { $$ = parse_bitfield ($1, $4, $3); }
cplus_decl_attributes ($$, $4, prefix_attributes); }
| ':' expr_no_commas maybe_attribute | ':' expr_no_commas maybe_attribute
{ $$ = grokbitfield (NULL_TREE, current_declspecs, $2); { $$ = parse_bitfield (NULL_TREE, $3, $2); }
cplus_decl_attributes ($$, $3, prefix_attributes); }
; ;
enumlist_opt: enumlist_opt:
......
...@@ -1097,15 +1097,14 @@ friend_accessible_p (scope, type, decl, binfo) ...@@ -1097,15 +1097,14 @@ friend_accessible_p (scope, type, decl, binfo)
When we are done with the decl-specifier-seq, we record the lookups we've When we are done with the decl-specifier-seq, we record the lookups we've
seen in the lookups field of the typed_declspecs nonterminal. seen in the lookups field of the typed_declspecs nonterminal.
When we process the first declarator, either in parse_decl or When we process the first declarator, either in parse_decl or
begin_function_definition, we call initial_deferred_type_access_control, begin_function_definition, we call save_type_access_control,
which processes any lookups from within that declarator, stores the which stores the lookups from the decl-specifier-seq in
lookups from the decl-specifier-seq in current_type_lookups, and sets current_type_lookups.
type_lookups to error_mark_node. As we finish with each declarator, we process everything in type_lookups
Subsequent declarators process current_type_lookups again to make sure via decl_type_access_control, which resets type_lookups to the value of
that the types are accessible to all of the declarators. Any lookups current_type_lookups for subsequent declarators.
within subsequent declarators are processed immediately. When we enter a function, we set type_lookups to error_mark_node, so all
Within a function, type_lookups is error_mark_node, so all lookups are lookups are processed immediately. */
processed immediately. */
void void
type_access_control (type, val) type_access_control (type, val)
......
...@@ -1695,10 +1695,10 @@ static tree current_type_lookups; ...@@ -1695,10 +1695,10 @@ static tree current_type_lookups;
/* Perform deferred access control for types used in the type of a /* Perform deferred access control for types used in the type of a
declaration. */ declaration. */
void static void
deferred_type_access_control () deferred_type_access_control ()
{ {
tree lookup = current_type_lookups; tree lookup = type_lookups;
if (lookup == error_mark_node) if (lookup == error_mark_node)
return; return;
...@@ -1707,46 +1707,56 @@ deferred_type_access_control () ...@@ -1707,46 +1707,56 @@ deferred_type_access_control ()
enforce_access (TREE_PURPOSE (lookup), TREE_VALUE (lookup)); enforce_access (TREE_PURPOSE (lookup), TREE_VALUE (lookup));
} }
/* Perform deferred access control for types used in the type of a
declaration. Called for the first declarator in a declaration. */
void void
initial_deferred_type_access_control (lookups) decl_type_access_control (decl)
tree lookups; tree decl;
{ {
tree lookup = type_lookups; tree save_fn;
/* First perform the checks for the current declarator; they will have if (type_lookups == error_mark_node)
been added to type_lookups since typed_declspecs saved the copy that return;
we have been passed. */
if (lookup != error_mark_node) save_fn = current_function_decl;
for (; lookup != lookups; lookup = TREE_CHAIN (lookup))
enforce_access (TREE_PURPOSE (lookup), TREE_VALUE (lookup)); if (decl && TREE_CODE (decl) == FUNCTION_DECL)
current_function_decl = decl;
current_type_lookups = lookups;
type_lookups = error_mark_node;
deferred_type_access_control (); deferred_type_access_control ();
}
current_function_decl = save_fn;
/* Now strip away the checks for the current declarator; they were
added to type_lookups after typed_declspecs saved the copy that
ended up in current_type_lookups. */
type_lookups = current_type_lookups;
}
void
save_type_access_control (lookups)
tree lookups;
{
current_type_lookups = lookups;
}
/* Begin a function definition declared with DECL_SPECS and /* Begin a function definition declared with DECL_SPECS and
DECLARATOR. Returns non-zero if the function-declaration is DECLARATOR. Returns non-zero if the function-declaration is
legal. */ legal. */
int int
begin_function_definition (decl_specs, lookups, declarator) begin_function_definition (decl_specs, declarator)
tree decl_specs; tree decl_specs;
tree lookups;
tree declarator; tree declarator;
{ {
tree specs; tree specs;
tree attrs; tree attrs;
initial_deferred_type_access_control (lookups);
split_specs_attrs (decl_specs, &specs, &attrs); split_specs_attrs (decl_specs, &specs, &attrs);
if (!start_function (specs, declarator, attrs, SF_DEFAULT)) if (!start_function (specs, declarator, attrs, SF_DEFAULT))
return 0; return 0;
deferred_type_access_control ();
type_lookups = error_mark_node;
reinit_parse_for_function (); reinit_parse_for_function ();
/* The things we're about to see are not directly qualified by any /* The things we're about to see are not directly qualified by any
template headers we've seen thus far. */ template headers we've seen thus far. */
......
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