mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-27 16:34:30 +08:00
class.c (alter_access): Accept a BINFO explaining how to get from the entity whose accessed is being...
* class.c (alter_access): Accept a BINFO explaining how to get from the entity whose accessed is being altered to the type doing the altering. (handle_using_decl): New function containing code split out from ... (finish_struct_1): Here. From-SVN: r20500
This commit is contained in:
parent
8f259df3c0
commit
79ad62b257
@ -1,5 +1,11 @@
|
||||
1998-06-13 Mark Mitchell <mark@markmitchell.com>
|
||||
|
||||
* class.c (alter_access): Accept a BINFO explaining how to get
|
||||
from the entity whose accessed is being altered to the type doing
|
||||
the altering.
|
||||
(handle_using_decl): New function containing code split out from ...
|
||||
(finish_struct_1): Here.
|
||||
|
||||
* cp-tree.h (complete_type_or_else): Declare.
|
||||
* init.c (build_new_1, build_delete): Use it.
|
||||
* typeck.c (require_complete_type): Use complete_type, rather than
|
||||
|
202
gcc/cp/class.c
202
gcc/cp/class.c
@ -107,7 +107,8 @@ static void add_virtual_function PROTO((tree *, tree *, int *, tree, tree));
|
||||
static tree delete_duplicate_fields_1 PROTO((tree, tree));
|
||||
static void delete_duplicate_fields PROTO((tree));
|
||||
static void finish_struct_bits PROTO((tree, int));
|
||||
static int alter_access PROTO((tree, tree, tree));
|
||||
static int alter_access PROTO((tree, tree, tree, tree));
|
||||
static void handle_using_decl PROTO((tree, tree, tree, tree));
|
||||
static int overrides PROTO((tree, tree));
|
||||
static int strictly_overrides PROTO((tree, tree));
|
||||
static void merge_overrides PROTO((tree, tree, int, tree));
|
||||
@ -1277,12 +1278,14 @@ delete_duplicate_fields (fields)
|
||||
TREE_CHAIN (x) = delete_duplicate_fields_1 (x, TREE_CHAIN (x));
|
||||
}
|
||||
|
||||
/* Change the access of FDECL to ACCESS in T.
|
||||
Return 1 if change was legit, otherwise return 0. */
|
||||
/* Change the access of FDECL to ACCESS in T. The access to FDECL is
|
||||
along the path given by BINFO. Return 1 if change was legit,
|
||||
otherwise return 0. */
|
||||
|
||||
static int
|
||||
alter_access (t, fdecl, access)
|
||||
alter_access (t, binfo, fdecl, access)
|
||||
tree t;
|
||||
tree binfo;
|
||||
tree fdecl;
|
||||
tree access;
|
||||
{
|
||||
@ -1306,7 +1309,7 @@ alter_access (t, fdecl, access)
|
||||
}
|
||||
else
|
||||
{
|
||||
enforce_access (TYPE_BINFO (t), fdecl);
|
||||
enforce_access (binfo, fdecl);
|
||||
|
||||
DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
|
||||
return 1;
|
||||
@ -1314,6 +1317,94 @@ alter_access (t, fdecl, access)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Process the USING_DECL, which is a member of T. The METHOD_VEC, if
|
||||
non-NULL, is the methods of T. The FIELDS are the fields of T.
|
||||
Returns 1 if the USING_DECL was valid, 0 otherwise. */
|
||||
|
||||
void
|
||||
handle_using_decl (using_decl, t, method_vec, fields)
|
||||
tree using_decl;
|
||||
tree t;
|
||||
tree method_vec;
|
||||
tree fields;
|
||||
{
|
||||
tree ctype = DECL_INITIAL (using_decl);
|
||||
tree name = DECL_NAME (using_decl);
|
||||
tree access
|
||||
= TREE_PRIVATE (using_decl) ? access_private_node
|
||||
: TREE_PROTECTED (using_decl) ? access_protected_node
|
||||
: access_public_node;
|
||||
tree fdecl, binfo;
|
||||
tree flist = NULL_TREE;
|
||||
tree tmp;
|
||||
int i;
|
||||
int n_methods;
|
||||
|
||||
binfo = binfo_or_else (ctype, t);
|
||||
if (! binfo)
|
||||
return;
|
||||
|
||||
if (name == constructor_name (ctype)
|
||||
|| name == constructor_name_full (ctype))
|
||||
cp_error_at ("using-declaration for constructor", using_decl);
|
||||
|
||||
fdecl = lookup_member (binfo, name, 0, 0);
|
||||
|
||||
if (!fdecl)
|
||||
{
|
||||
cp_error_at ("no members matching `%D' in `%#T'", using_decl, ctype);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Functions are represented as TREE_LIST, with the purpose
|
||||
being the type and the value the functions. Other members
|
||||
come as themselves. */
|
||||
if (TREE_CODE (fdecl) == TREE_LIST)
|
||||
/* Ignore base type this came from. */
|
||||
fdecl = TREE_VALUE (fdecl);
|
||||
|
||||
if (TREE_CODE (fdecl) == OVERLOAD)
|
||||
{
|
||||
/* We later iterate over all functions. */
|
||||
flist = fdecl;
|
||||
fdecl = OVL_FUNCTION (flist);
|
||||
}
|
||||
|
||||
name = DECL_NAME (fdecl);
|
||||
n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
|
||||
for (i = 2; i < n_methods; i++)
|
||||
if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)))
|
||||
== name)
|
||||
{
|
||||
cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
|
||||
cp_error_at (" because of local method `%#D' with same name",
|
||||
OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
|
||||
return;
|
||||
}
|
||||
|
||||
for (tmp = fields; tmp; tmp = TREE_CHAIN (tmp))
|
||||
if (DECL_NAME (tmp) == name)
|
||||
{
|
||||
cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
|
||||
cp_error_at (" because of local field `%#D' with same name", tmp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make type T see field decl FDECL with access ACCESS.*/
|
||||
if (flist)
|
||||
{
|
||||
while (flist)
|
||||
{
|
||||
if (alter_access (t, binfo, OVL_FUNCTION (flist),
|
||||
access) == 0)
|
||||
return;
|
||||
flist = OVL_CHAIN (flist);
|
||||
}
|
||||
}
|
||||
else
|
||||
alter_access (t, binfo, fdecl, access);
|
||||
}
|
||||
|
||||
/* If FOR_TYPE needs to reinitialize virtual function table pointers
|
||||
for TYPE's sub-objects, add such reinitializations to BASE_INIT_LIST.
|
||||
Returns BASE_INIT_LIST appropriately modified. */
|
||||
@ -3186,36 +3277,15 @@ finish_struct_1 (t, warn_anon)
|
||||
empty = 0;
|
||||
}
|
||||
|
||||
/* Handle access declarations. */
|
||||
if (TREE_CODE (x) == USING_DECL)
|
||||
{
|
||||
tree ctype = DECL_INITIAL (x);
|
||||
tree sname = DECL_NAME (x);
|
||||
tree access
|
||||
= TREE_PRIVATE (x) ? access_private_node
|
||||
: TREE_PROTECTED (x) ? access_protected_node
|
||||
: access_public_node;
|
||||
tree fdecl, binfo;
|
||||
|
||||
/* Save access declarations for later. */
|
||||
if (last_x)
|
||||
TREE_CHAIN (last_x) = TREE_CHAIN (x);
|
||||
else
|
||||
fields = TREE_CHAIN (x);
|
||||
|
||||
binfo = binfo_or_else (ctype, t);
|
||||
if (! binfo)
|
||||
continue;
|
||||
|
||||
if (sname == constructor_name (ctype)
|
||||
|| sname == constructor_name_full (ctype))
|
||||
cp_error_at ("using-declaration for constructor", x);
|
||||
|
||||
fdecl = lookup_member (binfo, sname, 0, 0);
|
||||
|
||||
if (fdecl)
|
||||
access_decls = scratch_tree_cons (access, fdecl, access_decls);
|
||||
else
|
||||
cp_error_at ("no members matching `%D' in `%#T'", x, ctype);
|
||||
|
||||
access_decls = scratch_tree_cons (NULL_TREE, x, access_decls);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -3658,77 +3728,9 @@ finish_struct_1 (t, warn_anon)
|
||||
TYPE_HAS_DESTRUCTOR (t) = 0;
|
||||
}
|
||||
|
||||
{
|
||||
int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
|
||||
|
||||
for (access_decls = nreverse (access_decls); access_decls;
|
||||
access_decls = TREE_CHAIN (access_decls))
|
||||
{
|
||||
tree fdecl = TREE_VALUE (access_decls);
|
||||
tree flist = NULL_TREE;
|
||||
tree name;
|
||||
tree access = TREE_PURPOSE (access_decls);
|
||||
int i = 2;
|
||||
tree tmp;
|
||||
|
||||
/* Functions are represented as TREE_LIST, with the purpose
|
||||
being the type and the value the functions. Other members
|
||||
come as themselves. */
|
||||
if (TREE_CODE (fdecl) == TREE_LIST)
|
||||
{
|
||||
/* Ignore base type this came from. */
|
||||
fdecl = TREE_VALUE (fdecl);
|
||||
}
|
||||
if (TREE_CODE (fdecl) == OVERLOAD)
|
||||
{
|
||||
/* We later iterate over all functions. */
|
||||
flist = fdecl;
|
||||
fdecl = OVL_FUNCTION (flist);
|
||||
}
|
||||
|
||||
name = DECL_NAME (fdecl);
|
||||
|
||||
for (; i < n_methods; i++)
|
||||
if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)))
|
||||
== name)
|
||||
{
|
||||
cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
|
||||
cp_error_at (" because of local method `%#D' with same name",
|
||||
OVL_CURRENT (TREE_VEC_ELT (method_vec, i)));
|
||||
fdecl = NULL_TREE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (! fdecl)
|
||||
continue;
|
||||
|
||||
for (tmp = fields; tmp; tmp = TREE_CHAIN (tmp))
|
||||
if (DECL_NAME (tmp) == name)
|
||||
{
|
||||
cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
|
||||
cp_error_at (" because of local field `%#D' with same name", tmp);
|
||||
fdecl = NULL_TREE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!fdecl)
|
||||
continue;
|
||||
|
||||
/* Make type T see field decl FDECL with access ACCESS.*/
|
||||
if (flist)
|
||||
{
|
||||
while (flist)
|
||||
{
|
||||
if (alter_access (t, OVL_FUNCTION (flist), access) == 0)
|
||||
break;
|
||||
flist = OVL_CHAIN (flist);
|
||||
}
|
||||
}
|
||||
else
|
||||
alter_access (t, fdecl, access);
|
||||
}
|
||||
|
||||
}
|
||||
for (access_decls = nreverse (access_decls); access_decls;
|
||||
access_decls = TREE_CHAIN (access_decls))
|
||||
handle_using_decl (TREE_VALUE (access_decls), t, method_vec, fields);
|
||||
|
||||
if (vfield == NULL_TREE && has_virtual)
|
||||
{
|
||||
|
@ -2,7 +2,7 @@ class D2;
|
||||
|
||||
class B {
|
||||
private:
|
||||
int a;
|
||||
int a; // ERROR - B::a is private
|
||||
protected:
|
||||
int b;
|
||||
|
||||
@ -13,7 +13,7 @@ class D : public B {
|
||||
public:
|
||||
using B::a;
|
||||
using B::b;
|
||||
};
|
||||
}; // ERROR - within this context
|
||||
|
||||
class D2 : public B {
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user