Commit cf22909c by Kriang Lerdsuwanakij Committed by Kriang Lerdsuwanakij

config-lang.in: Add semantics.c to gtfiles.

	* config-lang.in: Add semantics.c to gtfiles.
	* cp-tree.h (flagged_type_tree_s): Remove lookups field.
	(saved_scope): Likewise.
	(type_lookups): Remove.
	(deferred_access): New structure.
	(type_access_control): Remove.
	(save_type_access_control): Likewise.
	(reset_type_access_control): Likewise.
	(decl_type_access_control): Likewise.
	(push_deferring_access_checks): Declare.
	(resume_deferring_access_checks): Likewise.
	(stop_deferring_access_checks): Likewise.
	(pop_deferring_access_checks): Likewise.
	(get_deferred_access_checks): Likewise.
	(pop_to_parent_deferring_access_checks): Likewise.
	(perform_deferred_access_checks): Likewise.
	(perform_or_defer_access_check): Likewise.
	* decl.c (make_typename_type): Use perform_or_defer_access_check.
	(make_unbound_class_template): Likewise.
	(grokdeclarator): Don't call decl_type_access_control.
	* parser.c (cp_parser_context): Remove deferred_access_checks
	and deferring_access_checks_p fields.
	(cp_parser_context_new): Adjust.
	(cp_parser): Remove access_checks_lists.
	(cp_parser_defer_access_check): Remove.
	(cp_parser_start_deferring_access_checks): Remove.
	(cp_parser_stop_deferring_access_checks): Remove.
	(cp_parser_perform_deferred_access_checks): Remove.
	(cp_parser_nested_name_specifier_opt): Use new deferred access
	functions.
	(cp_parser_simple_declaration): Likewise.
	(cp_parser_template_id): Likewise.
	(cp_parser_function_definition): Likewise.
	(cp_parser_class_specifier): Likewise.
	(cp_parser_lookup_name): Likewise.
	(cp_parser_single_declaration): Likewise.
	(cp_parser_pre_parsed_nested_name_specifier): Likewise.
	(cp_parser_parse_tentatively): Likewise.
	(cp_parser_parse_definitely): Likewise.
	(yyparse): Likewise.
	(cp_parser_init_declarator): Remove access_checks parameter.
	Use new deferred access functions.
	(cp_parser_function_definition_from_specifiers_and_declarator):
	Likewise.
	(cp_parser_class_head): Remove deferring_access_checks_p and
	saved_access_checks parameters.  Use new deferred access functions.
	(cp_parser_member_specification_opt): Don't call
	reset_type_access_control.
	* search.c (type_access_control): Remove.
	* semantics.c: Include "gt-cp-semantics.h".
	(deferred_type_access_control): Remove.
	(deferred_access_stack): New variable.
	(deferred_access_free_list): Likewise.
	(push_deferring_access_checks): New function.
	(resume_deferring_access_checks): Likewise.
	(stop_deferring_access_checks): Likewise.
	(pop_deferring_access_checks): Likewise.
	(get_deferred_access_checks): Likewise.
	(pop_to_parent_deferring_access_checks): Likewise.
	(perform_deferred_access_checks): New function, adapted from
	cp_parser_perform_deferred_access_checks.
	(perform_or_defer_access_check): New function, adapted from
	cp_parser_defer_access_check.
	(current_type_lookups): Remove.
	(deferred_type_access_control): Likewise.
	(decl_type_access_control): Likewise.
	(save_type_access_control): Likewise.
	(reset_type_access_control): Likewise.
	(begin_function_definition): Adjust.
	(begin_class_definiton): Likewise.

From-SVN: r61283
parent a686ea5b
2003-01-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
* config-lang.in: Add semantics.c to gtfiles.
* cp-tree.h (flagged_type_tree_s): Remove lookups field.
(saved_scope): Likewise.
(type_lookups): Remove.
(deferred_access): New structure.
(type_access_control): Remove.
(save_type_access_control): Likewise.
(reset_type_access_control): Likewise.
(decl_type_access_control): Likewise.
(push_deferring_access_checks): Declare.
(resume_deferring_access_checks): Likewise.
(stop_deferring_access_checks): Likewise.
(pop_deferring_access_checks): Likewise.
(get_deferred_access_checks): Likewise.
(pop_to_parent_deferring_access_checks): Likewise.
(perform_deferred_access_checks): Likewise.
(perform_or_defer_access_check): Likewise.
* decl.c (make_typename_type): Use perform_or_defer_access_check.
(make_unbound_class_template): Likewise.
(grokdeclarator): Don't call decl_type_access_control.
* parser.c (cp_parser_context): Remove deferred_access_checks
and deferring_access_checks_p fields.
(cp_parser_context_new): Adjust.
(cp_parser): Remove access_checks_lists.
(cp_parser_defer_access_check): Remove.
(cp_parser_start_deferring_access_checks): Remove.
(cp_parser_stop_deferring_access_checks): Remove.
(cp_parser_perform_deferred_access_checks): Remove.
(cp_parser_nested_name_specifier_opt): Use new deferred access
functions.
(cp_parser_simple_declaration): Likewise.
(cp_parser_template_id): Likewise.
(cp_parser_function_definition): Likewise.
(cp_parser_class_specifier): Likewise.
(cp_parser_lookup_name): Likewise.
(cp_parser_single_declaration): Likewise.
(cp_parser_pre_parsed_nested_name_specifier): Likewise.
(cp_parser_parse_tentatively): Likewise.
(cp_parser_parse_definitely): Likewise.
(yyparse): Likewise.
(cp_parser_init_declarator): Remove access_checks parameter.
Use new deferred access functions.
(cp_parser_function_definition_from_specifiers_and_declarator):
Likewise.
(cp_parser_class_head): Remove deferring_access_checks_p and
saved_access_checks parameters. Use new deferred access functions.
(cp_parser_member_specification_opt): Don't call
reset_type_access_control.
* search.c (type_access_control): Remove.
* semantics.c: Include "gt-cp-semantics.h".
(deferred_type_access_control): Remove.
(deferred_access_stack): New variable.
(deferred_access_free_list): Likewise.
(push_deferring_access_checks): New function.
(resume_deferring_access_checks): Likewise.
(stop_deferring_access_checks): Likewise.
(pop_deferring_access_checks): Likewise.
(get_deferred_access_checks): Likewise.
(pop_to_parent_deferring_access_checks): Likewise.
(perform_deferred_access_checks): New function, adapted from
cp_parser_perform_deferred_access_checks.
(perform_or_defer_access_check): New function, adapted from
cp_parser_defer_access_check.
(current_type_lookups): Remove.
(deferred_type_access_control): Likewise.
(decl_type_access_control): Likewise.
(save_type_access_control): Likewise.
(reset_type_access_control): Likewise.
(begin_function_definition): Adjust.
(begin_class_definiton): Likewise.
2003-01-13 Jason Merrill <jason@redhat.com>
PR c++/8748
......
......@@ -34,4 +34,4 @@ stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)"
target_libs="${libstdcxx_version} target-gperf"
gtfiles="\$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c"
gtfiles="\$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c"
......@@ -257,7 +257,6 @@ typedef struct flagged_type_tree_s GTY(())
{
tree t;
int new_type_flag;
tree lookups;
} flagged_type_tree;
typedef struct template_parm_index_s GTY(())
......@@ -784,7 +783,6 @@ struct saved_scope GTY(())
tree x_previous_class_type;
tree x_previous_class_values;
tree x_saved_tree;
tree lookups;
tree last_parms;
HOST_WIDE_INT x_processing_template_decl;
......@@ -851,8 +849,6 @@ struct saved_scope GTY(())
/* A list of private types mentioned, for deferred access checking. */
#define type_lookups scope_chain->lookups
extern GTY(()) struct saved_scope *scope_chain;
/* Global state pertinent to the current function. */
......@@ -3197,6 +3193,32 @@ extern GTY(()) tree anonymous_namespace_name;
function, two inside the body of a function in a local class, etc.) */
extern int function_depth;
typedef struct deferred_access GTY(())
{
/* A TREE_LIST 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:
class A {
class B {};
B* f();
}
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;
/* TRUE iff we are deferring access checks. */
bool deferring_access_checks_p;
/* The next deferred access data in stack or linked-list. */
struct deferred_access *next;
} deferred_access;
/* in pt.c */
/* These values are used for the `STRICT' parameter to type_unification and
......@@ -4097,7 +4119,6 @@ extern tree lookup_base (tree, tree, base_access, base_kind *);
extern int types_overlap_p (tree, tree);
extern tree get_vbase (tree, tree);
extern tree get_dynamic_cast_base_type (tree, tree);
extern void type_access_control (tree, tree);
extern int accessible_p (tree, tree);
extern tree lookup_field (tree, tree, int, int);
extern int lookup_fnfields_1 (tree, tree);
......@@ -4147,6 +4168,14 @@ extern tree build_baselink (tree, tree, tree, tree);
extern tree adjust_result_of_qualified_name_lookup
(tree, tree, tree);
/* in semantics.c */
extern void push_deferring_access_checks (bool defer_p);
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 void pop_to_parent_deferring_access_checks (void);
extern void perform_deferred_access_checks (void);
extern void perform_or_defer_access_check (tree, tree);
extern void init_cp_semantics (void);
extern tree finish_expr_stmt (tree);
extern tree begin_if_stmt (void);
......@@ -4207,9 +4236,6 @@ extern tree finish_pseudo_destructor_expr (tree, tree, tree);
extern tree finish_unary_op_expr (enum tree_code, tree);
extern tree finish_compound_literal (tree, tree);
extern tree finish_fname (tree);
extern void save_type_access_control (tree);
extern void reset_type_access_control (void);
extern void decl_type_access_control (tree);
extern int begin_function_definition (tree, tree, tree);
extern tree begin_constructor_declarator (tree, tree);
extern tree finish_declarator (tree, tree, tree, tree, int);
......
......@@ -5544,7 +5544,7 @@ make_typename_type (tree context, tree name, tsubst_flags_t complain)
if (complain & tf_error)
{
if (complain & tf_parsing)
type_access_control (context, tmpl);
perform_or_defer_access_check (context, tmpl);
else
enforce_access (context, tmpl);
}
......@@ -5579,7 +5579,7 @@ make_typename_type (tree context, tree name, tsubst_flags_t complain)
if (complain & tf_error)
{
if (complain & tf_parsing)
type_access_control (context, t);
perform_or_defer_access_check (context, t);
else
enforce_access (context, t);
}
......@@ -5651,7 +5651,7 @@ make_unbound_class_template (tree context, tree name, tsubst_flags_t complain)
if (complain & tf_error)
{
if (complain & tf_parsing)
type_access_control (context, tmpl);
perform_or_defer_access_check (context, tmpl);
else
enforce_access (context, tmpl);
}
......@@ -9854,7 +9854,6 @@ grokdeclarator (tree declarator,
decl = start_decl (declarator, declspecs, 1,
attributes, NULL_TREE);
decl_type_access_control (decl);
if (decl)
{
/* Look for __unused__ attribute */
......@@ -11407,8 +11406,6 @@ grokdeclarator (tree declarator,
/* Only try to do this stuff if we didn't already give up. */
if (type != integer_type_node)
{
decl_type_access_control (TYPE_NAME (type));
/* A friendly class? */
if (current_class_type)
make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type));
......
......@@ -979,41 +979,6 @@ friend_accessible_p (scope, decl, binfo)
return 0;
}
/* Perform access control on TYPE_DECL or TEMPLATE_DECL VAL, which was
looked up in TYPE. This is fairly complex, so here's the design:
The lang_extdef nonterminal sets type_lookups to NULL_TREE before we
start to process a top-level declaration.
As we process the decl-specifier-seq for the declaration, any types we
see that might need access control are passed to type_access_control,
which defers checking by adding them to type_lookups.
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.
When we process the first declarator, either in parse_decl or
begin_function_definition, we call save_type_access_control,
which stores the lookups from the decl-specifier-seq in
current_type_lookups.
As we finish with each declarator, we process everything in type_lookups
via decl_type_access_control, which resets type_lookups to the value of
current_type_lookups for subsequent declarators.
When we enter a function, we set type_lookups to error_mark_node, so all
lookups are processed immediately. */
void
type_access_control (type, val)
tree type, val;
{
if (val == NULL_TREE
|| (TREE_CODE (val) != TEMPLATE_DECL && TREE_CODE (val) != TYPE_DECL)
|| ! DECL_CLASS_SCOPE_P (val))
return;
if (type_lookups == error_mark_node)
enforce_access (type, val);
else if (! accessible_p (type, val))
type_lookups = tree_cons (type, val, type_lookups);
}
/* DECL is a declaration from a base class of TYPE, which was the
class used to name DECL. Return nonzero if, in the current
context, DECL is accessible. If TYPE is actually a BINFO node,
......
......@@ -52,7 +52,6 @@
static tree maybe_convert_cond PARAMS ((tree));
static tree simplify_aggr_init_exprs_r PARAMS ((tree *, int *, void *));
static void deferred_type_access_control PARAMS ((void));
static void emit_associated_thunks PARAMS ((tree));
static void genrtl_try_block PARAMS ((tree));
static void genrtl_eh_spec_block PARAMS ((tree));
......@@ -79,6 +78,145 @@ static tree clear_decl_rtl PARAMS ((tree *, int *, void *));
(SUBSTMT) = (COND); \
} while (0)
/* Data for deferred access checking. */
static GTY(()) deferred_access *deferred_access_stack;
static GTY(()) deferred_access *deferred_access_free_list;
/* Save the current deferred access states and start deferred
access checking iff DEFER_P is true. */
void push_deferring_access_checks (bool deferring_p)
{
deferred_access *d;
/* Recycle previously used free store if available. */
if (deferred_access_free_list)
{
d = deferred_access_free_list;
deferred_access_free_list = d->next;
}
else
d = (deferred_access *) ggc_alloc (sizeof (deferred_access));
d->next = deferred_access_stack;
d->deferred_access_checks = NULL_TREE;
d->deferring_access_checks_p = deferring_p;
deferred_access_stack = d;
}
/* Resume deferring access checks again after we stopped doing
this previously. */
void resume_deferring_access_checks (void)
{
deferred_access_stack->deferring_access_checks_p = true;
}
/* Stop deferring access checks. */
void stop_deferring_access_checks (void)
{
deferred_access_stack->deferring_access_checks_p = false;
}
/* Discard the current deferred access checks and restore the
previous states. */
void pop_deferring_access_checks (void)
{
deferred_access *d = deferred_access_stack;
deferred_access_stack = d->next;
/* Remove references to access checks TREE_LIST. */
d->deferred_access_checks = NULL_TREE;
/* Store in free list for later use. */
d->next = deferred_access_free_list;
deferred_access_free_list = d;
}
/* Returns a TREE_LIST representing the deferred checks.
The TREE_PURPOSE of each node is the type through which the
access occurred; the TREE_VALUE is the declaration named.
*/
tree get_deferred_access_checks (void)
{
return deferred_access_stack->deferred_access_checks;
}
/* Take current deferred checks and combine with the
previous states if we also defer checks previously.
Otherwise perform checks now. */
void pop_to_parent_deferring_access_checks (void)
{
tree deferred_check = get_deferred_access_checks ();
deferred_access *d1 = deferred_access_stack;
deferred_access *d2 = deferred_access_stack->next;
deferred_access *d3 = deferred_access_stack->next->next;
/* Temporary swap the order of the top two states, just to make
sure the garbage collector will not reclaim the memory during
processing below. */
deferred_access_stack = d2;
d2->next = d1;
d1->next = d3;
for ( ; deferred_check; deferred_check = TREE_CHAIN (deferred_check))
/* Perform deferred check if required. */
perform_or_defer_access_check (TREE_PURPOSE (deferred_check),
TREE_VALUE (deferred_check));
deferred_access_stack = d1;
d1->next = d2;
d2->next = d3;
pop_deferring_access_checks ();
}
/* Perform the deferred access checks. */
void perform_deferred_access_checks (void)
{
tree deferred_check;
for (deferred_check = deferred_access_stack->deferred_access_checks;
deferred_check;
deferred_check = TREE_CHAIN (deferred_check))
/* Check access. */
enforce_access (TREE_PURPOSE (deferred_check),
TREE_VALUE (deferred_check));
/* No more deferred checks. */
deferred_access_stack->deferred_access_checks = NULL_TREE;
}
/* Defer checking the accessibility of DECL, when looked up in
CLASS_TYPE. */
void perform_or_defer_access_check (tree class_type, tree decl)
{
tree check;
/* If we are not supposed to defer access checks, just check now. */
if (!deferred_access_stack->deferring_access_checks_p)
{
enforce_access (class_type, decl);
return;
}
/* See if we are already going to perform this check. */
for (check = deferred_access_stack->deferred_access_checks;
check;
check = TREE_CHAIN (check))
if (TREE_VALUE (check) == decl
&& same_type_p (TREE_PURPOSE (check), class_type))
return;
/* If not, record the check. */
deferred_access_stack->deferred_access_checks
= tree_cons (class_type, decl,
deferred_access_stack->deferred_access_checks);
}
/* Returns nonzero if the current statement is a full expression,
i.e. temporaries created during that statement should be destroyed
at the end of the statement. */
......@@ -1506,63 +1644,6 @@ finish_fname (tree id)
return decl;
}
static tree current_type_lookups;
/* Perform deferred access control for types used in the type of a
declaration. */
static void
deferred_type_access_control ()
{
tree lookup = type_lookups;
if (lookup == error_mark_node)
return;
for (; lookup; lookup = TREE_CHAIN (lookup))
enforce_access (TREE_PURPOSE (lookup), TREE_VALUE (lookup));
}
void
decl_type_access_control (decl)
tree decl;
{
tree save_fn;
if (type_lookups == error_mark_node)
return;
save_fn = current_function_decl;
if (decl && TREE_CODE (decl) == FUNCTION_DECL)
current_function_decl = decl;
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;
}
/* Reset the deferred access control. */
void
reset_type_access_control ()
{
type_lookups = NULL_TREE;
current_type_lookups = NULL_TREE;
}
/* Begin a function definition declared with DECL_SPECS, ATTRIBUTES,
and DECLARATOR. Returns nonzero if the function-declaration is
valid. */
......@@ -1576,9 +1657,6 @@ begin_function_definition (decl_specs, attributes, declarator)
if (!start_function (decl_specs, declarator, attributes, SF_DEFAULT))
return 0;
deferred_type_access_control ();
type_lookups = error_mark_node;
/* The things we're about to see are not directly qualified by any
template headers we've seen thus far. */
reset_specialization ();
......@@ -1714,10 +1792,6 @@ begin_class_definition (t)
if (t == error_mark_node)
return error_mark_node;
/* Check the bases are accessible. */
decl_type_access_control (TYPE_NAME (t));
reset_type_access_control ();
if (processing_template_parmlist)
{
error ("definition of `%#T' inside template parameter list", t);
......@@ -2690,3 +2764,5 @@ init_cp_semantics ()
{
lang_expand_stmt = cp_expand_stmt;
}
#include "gt-cp-semantics.h"
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