138fd1498Szrj /* Breadth-first and depth-first routines for
238fd1498Szrj searching multiple-inheritance lattice for GNU C++.
338fd1498Szrj Copyright (C) 1987-2018 Free Software Foundation, Inc.
438fd1498Szrj Contributed by Michael Tiemann (tiemann@cygnus.com)
538fd1498Szrj
638fd1498Szrj This file is part of GCC.
738fd1498Szrj
838fd1498Szrj GCC is free software; you can redistribute it and/or modify
938fd1498Szrj it under the terms of the GNU General Public License as published by
1038fd1498Szrj the Free Software Foundation; either version 3, or (at your option)
1138fd1498Szrj any later version.
1238fd1498Szrj
1338fd1498Szrj GCC is distributed in the hope that it will be useful,
1438fd1498Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
1538fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1638fd1498Szrj GNU General Public License for more details.
1738fd1498Szrj
1838fd1498Szrj You should have received a copy of the GNU General Public License
1938fd1498Szrj along with GCC; see the file COPYING3. If not see
2038fd1498Szrj <http://www.gnu.org/licenses/>. */
2138fd1498Szrj
2238fd1498Szrj /* High-level class interface. */
2338fd1498Szrj
2438fd1498Szrj #include "config.h"
2538fd1498Szrj #include "system.h"
2638fd1498Szrj #include "coretypes.h"
2738fd1498Szrj #include "cp-tree.h"
2838fd1498Szrj #include "intl.h"
2938fd1498Szrj #include "toplev.h"
3038fd1498Szrj #include "spellcheck-tree.h"
3138fd1498Szrj #include "stringpool.h"
3238fd1498Szrj #include "attribs.h"
3338fd1498Szrj
3438fd1498Szrj static int is_subobject_of_p (tree, tree);
3538fd1498Szrj static tree dfs_lookup_base (tree, void *);
3638fd1498Szrj static tree dfs_dcast_hint_pre (tree, void *);
3738fd1498Szrj static tree dfs_dcast_hint_post (tree, void *);
3838fd1498Szrj static tree dfs_debug_mark (tree, void *);
3938fd1498Szrj static int check_hidden_convs (tree, int, int, tree, tree, tree);
4038fd1498Szrj static tree split_conversions (tree, tree, tree, tree);
4138fd1498Szrj static int lookup_conversions_r (tree, int, int, tree, tree, tree *);
4238fd1498Szrj static int look_for_overrides_r (tree, tree);
4338fd1498Szrj static tree lookup_field_r (tree, void *);
4438fd1498Szrj static tree dfs_accessible_post (tree, void *);
4538fd1498Szrj static tree dfs_walk_once_accessible (tree, bool,
4638fd1498Szrj tree (*pre_fn) (tree, void *),
4738fd1498Szrj tree (*post_fn) (tree, void *),
4838fd1498Szrj void *data);
4938fd1498Szrj static tree dfs_access_in_type (tree, void *);
5038fd1498Szrj static access_kind access_in_type (tree, tree);
5138fd1498Szrj static tree dfs_get_pure_virtuals (tree, void *);
5238fd1498Szrj
5338fd1498Szrj
5438fd1498Szrj /* Data for lookup_base and its workers. */
5538fd1498Szrj
5638fd1498Szrj struct lookup_base_data_s
5738fd1498Szrj {
5838fd1498Szrj tree t; /* type being searched. */
5938fd1498Szrj tree base; /* The base type we're looking for. */
6038fd1498Szrj tree binfo; /* Found binfo. */
6138fd1498Szrj bool via_virtual; /* Found via a virtual path. */
6238fd1498Szrj bool ambiguous; /* Found multiply ambiguous */
6338fd1498Szrj bool repeated_base; /* Whether there are repeated bases in the
6438fd1498Szrj hierarchy. */
6538fd1498Szrj bool want_any; /* Whether we want any matching binfo. */
6638fd1498Szrj };
6738fd1498Szrj
6838fd1498Szrj /* Worker function for lookup_base. See if we've found the desired
6938fd1498Szrj base and update DATA_ (a pointer to LOOKUP_BASE_DATA_S). */
7038fd1498Szrj
7138fd1498Szrj static tree
dfs_lookup_base(tree binfo,void * data_)7238fd1498Szrj dfs_lookup_base (tree binfo, void *data_)
7338fd1498Szrj {
7438fd1498Szrj struct lookup_base_data_s *data = (struct lookup_base_data_s *) data_;
7538fd1498Szrj
7638fd1498Szrj if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->base))
7738fd1498Szrj {
7838fd1498Szrj if (!data->binfo)
7938fd1498Szrj {
8038fd1498Szrj data->binfo = binfo;
8138fd1498Szrj data->via_virtual
8238fd1498Szrj = binfo_via_virtual (data->binfo, data->t) != NULL_TREE;
8338fd1498Szrj
8438fd1498Szrj if (!data->repeated_base)
8538fd1498Szrj /* If there are no repeated bases, we can stop now. */
8638fd1498Szrj return binfo;
8738fd1498Szrj
8838fd1498Szrj if (data->want_any && !data->via_virtual)
8938fd1498Szrj /* If this is a non-virtual base, then we can't do
9038fd1498Szrj better. */
9138fd1498Szrj return binfo;
9238fd1498Szrj
9338fd1498Szrj return dfs_skip_bases;
9438fd1498Szrj }
9538fd1498Szrj else
9638fd1498Szrj {
9738fd1498Szrj gcc_assert (binfo != data->binfo);
9838fd1498Szrj
9938fd1498Szrj /* We've found more than one matching binfo. */
10038fd1498Szrj if (!data->want_any)
10138fd1498Szrj {
10238fd1498Szrj /* This is immediately ambiguous. */
10338fd1498Szrj data->binfo = NULL_TREE;
10438fd1498Szrj data->ambiguous = true;
10538fd1498Szrj return error_mark_node;
10638fd1498Szrj }
10738fd1498Szrj
10838fd1498Szrj /* Prefer one via a non-virtual path. */
10938fd1498Szrj if (!binfo_via_virtual (binfo, data->t))
11038fd1498Szrj {
11138fd1498Szrj data->binfo = binfo;
11238fd1498Szrj data->via_virtual = false;
11338fd1498Szrj return binfo;
11438fd1498Szrj }
11538fd1498Szrj
11638fd1498Szrj /* There must be repeated bases, otherwise we'd have stopped
11738fd1498Szrj on the first base we found. */
11838fd1498Szrj return dfs_skip_bases;
11938fd1498Szrj }
12038fd1498Szrj }
12138fd1498Szrj
12238fd1498Szrj return NULL_TREE;
12338fd1498Szrj }
12438fd1498Szrj
12538fd1498Szrj /* Returns true if type BASE is accessible in T. (BASE is known to be
12638fd1498Szrj a (possibly non-proper) base class of T.) If CONSIDER_LOCAL_P is
12738fd1498Szrj true, consider any special access of the current scope, or access
12838fd1498Szrj bestowed by friendship. */
12938fd1498Szrj
13038fd1498Szrj bool
accessible_base_p(tree t,tree base,bool consider_local_p)13138fd1498Szrj accessible_base_p (tree t, tree base, bool consider_local_p)
13238fd1498Szrj {
13338fd1498Szrj tree decl;
13438fd1498Szrj
13538fd1498Szrj /* [class.access.base]
13638fd1498Szrj
13738fd1498Szrj A base class is said to be accessible if an invented public
13838fd1498Szrj member of the base class is accessible.
13938fd1498Szrj
14038fd1498Szrj If BASE is a non-proper base, this condition is trivially
14138fd1498Szrj true. */
14238fd1498Szrj if (same_type_p (t, base))
14338fd1498Szrj return true;
14438fd1498Szrj /* Rather than inventing a public member, we use the implicit
14538fd1498Szrj public typedef created in the scope of every class. */
14638fd1498Szrj decl = TYPE_FIELDS (base);
14738fd1498Szrj while (!DECL_SELF_REFERENCE_P (decl))
14838fd1498Szrj decl = DECL_CHAIN (decl);
14938fd1498Szrj while (ANON_AGGR_TYPE_P (t))
15038fd1498Szrj t = TYPE_CONTEXT (t);
15138fd1498Szrj return accessible_p (t, decl, consider_local_p);
15238fd1498Szrj }
15338fd1498Szrj
15438fd1498Szrj /* Lookup BASE in the hierarchy dominated by T. Do access checking as
15538fd1498Szrj ACCESS specifies. Return the binfo we discover. If KIND_PTR is
15638fd1498Szrj non-NULL, fill with information about what kind of base we
15738fd1498Szrj discovered.
15838fd1498Szrj
15938fd1498Szrj If the base is inaccessible, or ambiguous, then error_mark_node is
16038fd1498Szrj returned. If the tf_error bit of COMPLAIN is not set, no error
16138fd1498Szrj is issued. */
16238fd1498Szrj
16338fd1498Szrj tree
lookup_base(tree t,tree base,base_access access,base_kind * kind_ptr,tsubst_flags_t complain)16438fd1498Szrj lookup_base (tree t, tree base, base_access access,
16538fd1498Szrj base_kind *kind_ptr, tsubst_flags_t complain)
16638fd1498Szrj {
16738fd1498Szrj tree binfo;
16838fd1498Szrj tree t_binfo;
16938fd1498Szrj base_kind bk;
17038fd1498Szrj
17138fd1498Szrj /* "Nothing" is definitely not derived from Base. */
17238fd1498Szrj if (t == NULL_TREE)
17338fd1498Szrj {
17438fd1498Szrj if (kind_ptr)
17538fd1498Szrj *kind_ptr = bk_not_base;
17638fd1498Szrj return NULL_TREE;
17738fd1498Szrj }
17838fd1498Szrj
17938fd1498Szrj if (t == error_mark_node || base == error_mark_node)
18038fd1498Szrj {
18138fd1498Szrj if (kind_ptr)
18238fd1498Szrj *kind_ptr = bk_not_base;
18338fd1498Szrj return error_mark_node;
18438fd1498Szrj }
18538fd1498Szrj gcc_assert (TYPE_P (base));
18638fd1498Szrj
18738fd1498Szrj if (!TYPE_P (t))
18838fd1498Szrj {
18938fd1498Szrj t_binfo = t;
19038fd1498Szrj t = BINFO_TYPE (t);
19138fd1498Szrj }
19238fd1498Szrj else
19338fd1498Szrj {
19438fd1498Szrj t = complete_type (TYPE_MAIN_VARIANT (t));
195*58e805e6Szrj if (dependent_type_p (t))
196*58e805e6Szrj if (tree open = currently_open_class (t))
197*58e805e6Szrj t = open;
19838fd1498Szrj t_binfo = TYPE_BINFO (t);
19938fd1498Szrj }
20038fd1498Szrj
20138fd1498Szrj base = TYPE_MAIN_VARIANT (base);
20238fd1498Szrj
20338fd1498Szrj /* If BASE is incomplete, it can't be a base of T--and instantiating it
20438fd1498Szrj might cause an error. */
20538fd1498Szrj if (t_binfo && CLASS_TYPE_P (base) && COMPLETE_OR_OPEN_TYPE_P (base))
20638fd1498Szrj {
20738fd1498Szrj struct lookup_base_data_s data;
20838fd1498Szrj
20938fd1498Szrj data.t = t;
21038fd1498Szrj data.base = base;
21138fd1498Szrj data.binfo = NULL_TREE;
21238fd1498Szrj data.ambiguous = data.via_virtual = false;
21338fd1498Szrj data.repeated_base = CLASSTYPE_REPEATED_BASE_P (t);
21438fd1498Szrj data.want_any = access == ba_any;
21538fd1498Szrj
21638fd1498Szrj dfs_walk_once (t_binfo, dfs_lookup_base, NULL, &data);
21738fd1498Szrj binfo = data.binfo;
21838fd1498Szrj
21938fd1498Szrj if (!binfo)
22038fd1498Szrj bk = data.ambiguous ? bk_ambig : bk_not_base;
22138fd1498Szrj else if (binfo == t_binfo)
22238fd1498Szrj bk = bk_same_type;
22338fd1498Szrj else if (data.via_virtual)
22438fd1498Szrj bk = bk_via_virtual;
22538fd1498Szrj else
22638fd1498Szrj bk = bk_proper_base;
22738fd1498Szrj }
22838fd1498Szrj else
22938fd1498Szrj {
23038fd1498Szrj binfo = NULL_TREE;
23138fd1498Szrj bk = bk_not_base;
23238fd1498Szrj }
23338fd1498Szrj
23438fd1498Szrj /* Check that the base is unambiguous and accessible. */
23538fd1498Szrj if (access != ba_any)
23638fd1498Szrj switch (bk)
23738fd1498Szrj {
23838fd1498Szrj case bk_not_base:
23938fd1498Szrj break;
24038fd1498Szrj
24138fd1498Szrj case bk_ambig:
24238fd1498Szrj if (complain & tf_error)
24338fd1498Szrj error ("%qT is an ambiguous base of %qT", base, t);
24438fd1498Szrj binfo = error_mark_node;
24538fd1498Szrj break;
24638fd1498Szrj
24738fd1498Szrj default:
24838fd1498Szrj if ((access & ba_check_bit)
24938fd1498Szrj /* If BASE is incomplete, then BASE and TYPE are probably
25038fd1498Szrj the same, in which case BASE is accessible. If they
25138fd1498Szrj are not the same, then TYPE is invalid. In that case,
25238fd1498Szrj there's no need to issue another error here, and
25338fd1498Szrj there's no implicit typedef to use in the code that
25438fd1498Szrj follows, so we skip the check. */
25538fd1498Szrj && COMPLETE_TYPE_P (base)
25638fd1498Szrj && !accessible_base_p (t, base, !(access & ba_ignore_scope)))
25738fd1498Szrj {
25838fd1498Szrj if (complain & tf_error)
25938fd1498Szrj error ("%qT is an inaccessible base of %qT", base, t);
26038fd1498Szrj binfo = error_mark_node;
26138fd1498Szrj bk = bk_inaccessible;
26238fd1498Szrj }
26338fd1498Szrj break;
26438fd1498Szrj }
26538fd1498Szrj
26638fd1498Szrj if (kind_ptr)
26738fd1498Szrj *kind_ptr = bk;
26838fd1498Szrj
26938fd1498Szrj return binfo;
27038fd1498Szrj }
27138fd1498Szrj
27238fd1498Szrj /* Data for dcast_base_hint walker. */
27338fd1498Szrj
27438fd1498Szrj struct dcast_data_s
27538fd1498Szrj {
27638fd1498Szrj tree subtype; /* The base type we're looking for. */
27738fd1498Szrj int virt_depth; /* Number of virtual bases encountered from most
27838fd1498Szrj derived. */
27938fd1498Szrj tree offset; /* Best hint offset discovered so far. */
28038fd1498Szrj bool repeated_base; /* Whether there are repeated bases in the
28138fd1498Szrj hierarchy. */
28238fd1498Szrj };
28338fd1498Szrj
28438fd1498Szrj /* Worker for dcast_base_hint. Search for the base type being cast
28538fd1498Szrj from. */
28638fd1498Szrj
28738fd1498Szrj static tree
dfs_dcast_hint_pre(tree binfo,void * data_)28838fd1498Szrj dfs_dcast_hint_pre (tree binfo, void *data_)
28938fd1498Szrj {
29038fd1498Szrj struct dcast_data_s *data = (struct dcast_data_s *) data_;
29138fd1498Szrj
29238fd1498Szrj if (BINFO_VIRTUAL_P (binfo))
29338fd1498Szrj data->virt_depth++;
29438fd1498Szrj
29538fd1498Szrj if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->subtype))
29638fd1498Szrj {
29738fd1498Szrj if (data->virt_depth)
29838fd1498Szrj {
29938fd1498Szrj data->offset = ssize_int (-1);
30038fd1498Szrj return data->offset;
30138fd1498Szrj }
30238fd1498Szrj if (data->offset)
30338fd1498Szrj data->offset = ssize_int (-3);
30438fd1498Szrj else
30538fd1498Szrj data->offset = BINFO_OFFSET (binfo);
30638fd1498Szrj
30738fd1498Szrj return data->repeated_base ? dfs_skip_bases : data->offset;
30838fd1498Szrj }
30938fd1498Szrj
31038fd1498Szrj return NULL_TREE;
31138fd1498Szrj }
31238fd1498Szrj
31338fd1498Szrj /* Worker for dcast_base_hint. Track the virtual depth. */
31438fd1498Szrj
31538fd1498Szrj static tree
dfs_dcast_hint_post(tree binfo,void * data_)31638fd1498Szrj dfs_dcast_hint_post (tree binfo, void *data_)
31738fd1498Szrj {
31838fd1498Szrj struct dcast_data_s *data = (struct dcast_data_s *) data_;
31938fd1498Szrj
32038fd1498Szrj if (BINFO_VIRTUAL_P (binfo))
32138fd1498Szrj data->virt_depth--;
32238fd1498Szrj
32338fd1498Szrj return NULL_TREE;
32438fd1498Szrj }
32538fd1498Szrj
32638fd1498Szrj /* The dynamic cast runtime needs a hint about how the static SUBTYPE type
32738fd1498Szrj started from is related to the required TARGET type, in order to optimize
32838fd1498Szrj the inheritance graph search. This information is independent of the
32938fd1498Szrj current context, and ignores private paths, hence get_base_distance is
33038fd1498Szrj inappropriate. Return a TREE specifying the base offset, BOFF.
33138fd1498Szrj BOFF >= 0, there is only one public non-virtual SUBTYPE base at offset BOFF,
33238fd1498Szrj and there are no public virtual SUBTYPE bases.
33338fd1498Szrj BOFF == -1, SUBTYPE occurs as multiple public virtual or non-virtual bases.
33438fd1498Szrj BOFF == -2, SUBTYPE is not a public base.
33538fd1498Szrj BOFF == -3, SUBTYPE occurs as multiple public non-virtual bases. */
33638fd1498Szrj
33738fd1498Szrj tree
dcast_base_hint(tree subtype,tree target)33838fd1498Szrj dcast_base_hint (tree subtype, tree target)
33938fd1498Szrj {
34038fd1498Szrj struct dcast_data_s data;
34138fd1498Szrj
34238fd1498Szrj data.subtype = subtype;
34338fd1498Szrj data.virt_depth = 0;
34438fd1498Szrj data.offset = NULL_TREE;
34538fd1498Szrj data.repeated_base = CLASSTYPE_REPEATED_BASE_P (target);
34638fd1498Szrj
34738fd1498Szrj dfs_walk_once_accessible (TYPE_BINFO (target), /*friends=*/false,
34838fd1498Szrj dfs_dcast_hint_pre, dfs_dcast_hint_post, &data);
34938fd1498Szrj return data.offset ? data.offset : ssize_int (-2);
35038fd1498Szrj }
35138fd1498Szrj
35238fd1498Szrj /* Search for a member with name NAME in a multiple inheritance
35338fd1498Szrj lattice specified by TYPE. If it does not exist, return NULL_TREE.
35438fd1498Szrj If the member is ambiguously referenced, return `error_mark_node'.
35538fd1498Szrj Otherwise, return a DECL with the indicated name. If WANT_TYPE is
35638fd1498Szrj true, type declarations are preferred. */
35738fd1498Szrj
35838fd1498Szrj /* Return the FUNCTION_DECL, RECORD_TYPE, UNION_TYPE, or
35938fd1498Szrj NAMESPACE_DECL corresponding to the innermost non-block scope. */
36038fd1498Szrj
36138fd1498Szrj tree
current_scope(void)36238fd1498Szrj current_scope (void)
36338fd1498Szrj {
36438fd1498Szrj /* There are a number of cases we need to be aware of here:
36538fd1498Szrj current_class_type current_function_decl
36638fd1498Szrj global NULL NULL
36738fd1498Szrj fn-local NULL SET
36838fd1498Szrj class-local SET NULL
36938fd1498Szrj class->fn SET SET
37038fd1498Szrj fn->class SET SET
37138fd1498Szrj
37238fd1498Szrj Those last two make life interesting. If we're in a function which is
37338fd1498Szrj itself inside a class, we need decls to go into the fn's decls (our
37438fd1498Szrj second case below). But if we're in a class and the class itself is
37538fd1498Szrj inside a function, we need decls to go into the decls for the class. To
37638fd1498Szrj achieve this last goal, we must see if, when both current_class_ptr and
37738fd1498Szrj current_function_decl are set, the class was declared inside that
37838fd1498Szrj function. If so, we know to put the decls into the class's scope. */
37938fd1498Szrj if (current_function_decl && current_class_type
38038fd1498Szrj && ((DECL_FUNCTION_MEMBER_P (current_function_decl)
38138fd1498Szrj && same_type_p (DECL_CONTEXT (current_function_decl),
38238fd1498Szrj current_class_type))
38338fd1498Szrj || (DECL_FRIEND_CONTEXT (current_function_decl)
38438fd1498Szrj && same_type_p (DECL_FRIEND_CONTEXT (current_function_decl),
38538fd1498Szrj current_class_type))))
38638fd1498Szrj return current_function_decl;
38738fd1498Szrj
38838fd1498Szrj if (current_class_type)
38938fd1498Szrj return current_class_type;
39038fd1498Szrj
39138fd1498Szrj if (current_function_decl)
39238fd1498Szrj return current_function_decl;
39338fd1498Szrj
39438fd1498Szrj return current_namespace;
39538fd1498Szrj }
39638fd1498Szrj
39738fd1498Szrj /* Returns nonzero if we are currently in a function scope. Note
39838fd1498Szrj that this function returns zero if we are within a local class, but
39938fd1498Szrj not within a member function body of the local class. */
40038fd1498Szrj
40138fd1498Szrj int
at_function_scope_p(void)40238fd1498Szrj at_function_scope_p (void)
40338fd1498Szrj {
40438fd1498Szrj tree cs = current_scope ();
40538fd1498Szrj /* Also check cfun to make sure that we're really compiling
40638fd1498Szrj this function (as opposed to having set current_function_decl
40738fd1498Szrj for access checking or some such). */
40838fd1498Szrj return (cs && TREE_CODE (cs) == FUNCTION_DECL
40938fd1498Szrj && cfun && cfun->decl == current_function_decl);
41038fd1498Szrj }
41138fd1498Szrj
41238fd1498Szrj /* Returns true if the innermost active scope is a class scope. */
41338fd1498Szrj
41438fd1498Szrj bool
at_class_scope_p(void)41538fd1498Szrj at_class_scope_p (void)
41638fd1498Szrj {
41738fd1498Szrj tree cs = current_scope ();
41838fd1498Szrj return cs && TYPE_P (cs);
41938fd1498Szrj }
42038fd1498Szrj
42138fd1498Szrj /* Returns true if the innermost active scope is a namespace scope. */
42238fd1498Szrj
42338fd1498Szrj bool
at_namespace_scope_p(void)42438fd1498Szrj at_namespace_scope_p (void)
42538fd1498Szrj {
42638fd1498Szrj tree cs = current_scope ();
42738fd1498Szrj return cs && TREE_CODE (cs) == NAMESPACE_DECL;
42838fd1498Szrj }
42938fd1498Szrj
43038fd1498Szrj /* Return the scope of DECL, as appropriate when doing name-lookup. */
43138fd1498Szrj
43238fd1498Szrj tree
context_for_name_lookup(tree decl)43338fd1498Szrj context_for_name_lookup (tree decl)
43438fd1498Szrj {
43538fd1498Szrj /* [class.union]
43638fd1498Szrj
43738fd1498Szrj For the purposes of name lookup, after the anonymous union
43838fd1498Szrj definition, the members of the anonymous union are considered to
43938fd1498Szrj have been defined in the scope in which the anonymous union is
44038fd1498Szrj declared. */
44138fd1498Szrj tree context = DECL_CONTEXT (decl);
44238fd1498Szrj
44338fd1498Szrj while (context && TYPE_P (context)
44438fd1498Szrj && (ANON_AGGR_TYPE_P (context) || UNSCOPED_ENUM_P (context)))
44538fd1498Szrj context = TYPE_CONTEXT (context);
44638fd1498Szrj if (!context)
44738fd1498Szrj context = global_namespace;
44838fd1498Szrj
44938fd1498Szrj return context;
45038fd1498Szrj }
45138fd1498Szrj
45238fd1498Szrj /* Returns true iff DECL is declared in TYPE. */
45338fd1498Szrj
45438fd1498Szrj static bool
member_declared_in_type(tree decl,tree type)45538fd1498Szrj member_declared_in_type (tree decl, tree type)
45638fd1498Szrj {
45738fd1498Szrj /* A normal declaration obviously counts. */
45838fd1498Szrj if (context_for_name_lookup (decl) == type)
45938fd1498Szrj return true;
46038fd1498Szrj /* So does a using or access declaration. */
46138fd1498Szrj if (DECL_LANG_SPECIFIC (decl) && !DECL_DISCRIMINATOR_P (decl)
46238fd1498Szrj && purpose_member (type, DECL_ACCESS (decl)))
46338fd1498Szrj return true;
46438fd1498Szrj return false;
46538fd1498Szrj }
46638fd1498Szrj
46738fd1498Szrj /* The accessibility routines use BINFO_ACCESS for scratch space
46838fd1498Szrj during the computation of the accessibility of some declaration. */
46938fd1498Szrj
47038fd1498Szrj /* Avoid walking up past a declaration of the member. */
47138fd1498Szrj
47238fd1498Szrj static tree
dfs_access_in_type_pre(tree binfo,void * data)47338fd1498Szrj dfs_access_in_type_pre (tree binfo, void *data)
47438fd1498Szrj {
47538fd1498Szrj tree decl = (tree) data;
47638fd1498Szrj tree type = BINFO_TYPE (binfo);
47738fd1498Szrj if (member_declared_in_type (decl, type))
47838fd1498Szrj return dfs_skip_bases;
47938fd1498Szrj return NULL_TREE;
48038fd1498Szrj }
48138fd1498Szrj
48238fd1498Szrj #define BINFO_ACCESS(NODE) \
48338fd1498Szrj ((access_kind) ((TREE_PUBLIC (NODE) << 1) | TREE_PRIVATE (NODE)))
48438fd1498Szrj
48538fd1498Szrj /* Set the access associated with NODE to ACCESS. */
48638fd1498Szrj
48738fd1498Szrj #define SET_BINFO_ACCESS(NODE, ACCESS) \
48838fd1498Szrj ((TREE_PUBLIC (NODE) = ((ACCESS) & 2) != 0), \
48938fd1498Szrj (TREE_PRIVATE (NODE) = ((ACCESS) & 1) != 0))
49038fd1498Szrj
49138fd1498Szrj /* Called from access_in_type via dfs_walk. Calculate the access to
49238fd1498Szrj DATA (which is really a DECL) in BINFO. */
49338fd1498Szrj
49438fd1498Szrj static tree
dfs_access_in_type(tree binfo,void * data)49538fd1498Szrj dfs_access_in_type (tree binfo, void *data)
49638fd1498Szrj {
49738fd1498Szrj tree decl = (tree) data;
49838fd1498Szrj tree type = BINFO_TYPE (binfo);
49938fd1498Szrj access_kind access = ak_none;
50038fd1498Szrj
50138fd1498Szrj if (context_for_name_lookup (decl) == type)
50238fd1498Szrj {
50338fd1498Szrj /* If we have descended to the scope of DECL, just note the
50438fd1498Szrj appropriate access. */
50538fd1498Szrj if (TREE_PRIVATE (decl))
50638fd1498Szrj access = ak_private;
50738fd1498Szrj else if (TREE_PROTECTED (decl))
50838fd1498Szrj access = ak_protected;
50938fd1498Szrj else
51038fd1498Szrj access = ak_public;
51138fd1498Szrj }
51238fd1498Szrj else
51338fd1498Szrj {
51438fd1498Szrj /* First, check for an access-declaration that gives us more
51538fd1498Szrj access to the DECL. */
51638fd1498Szrj if (DECL_LANG_SPECIFIC (decl) && !DECL_DISCRIMINATOR_P (decl))
51738fd1498Szrj {
51838fd1498Szrj tree decl_access = purpose_member (type, DECL_ACCESS (decl));
51938fd1498Szrj
52038fd1498Szrj if (decl_access)
52138fd1498Szrj {
52238fd1498Szrj decl_access = TREE_VALUE (decl_access);
52338fd1498Szrj
52438fd1498Szrj if (decl_access == access_public_node)
52538fd1498Szrj access = ak_public;
52638fd1498Szrj else if (decl_access == access_protected_node)
52738fd1498Szrj access = ak_protected;
52838fd1498Szrj else if (decl_access == access_private_node)
52938fd1498Szrj access = ak_private;
53038fd1498Szrj else
53138fd1498Szrj gcc_unreachable ();
53238fd1498Szrj }
53338fd1498Szrj }
53438fd1498Szrj
53538fd1498Szrj if (!access)
53638fd1498Szrj {
53738fd1498Szrj int i;
53838fd1498Szrj tree base_binfo;
53938fd1498Szrj vec<tree, va_gc> *accesses;
54038fd1498Szrj
54138fd1498Szrj /* Otherwise, scan our baseclasses, and pick the most favorable
54238fd1498Szrj access. */
54338fd1498Szrj accesses = BINFO_BASE_ACCESSES (binfo);
54438fd1498Szrj for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
54538fd1498Szrj {
54638fd1498Szrj tree base_access = (*accesses)[i];
54738fd1498Szrj access_kind base_access_now = BINFO_ACCESS (base_binfo);
54838fd1498Szrj
54938fd1498Szrj if (base_access_now == ak_none || base_access_now == ak_private)
55038fd1498Szrj /* If it was not accessible in the base, or only
55138fd1498Szrj accessible as a private member, we can't access it
55238fd1498Szrj all. */
55338fd1498Szrj base_access_now = ak_none;
55438fd1498Szrj else if (base_access == access_protected_node)
55538fd1498Szrj /* Public and protected members in the base become
55638fd1498Szrj protected here. */
55738fd1498Szrj base_access_now = ak_protected;
55838fd1498Szrj else if (base_access == access_private_node)
55938fd1498Szrj /* Public and protected members in the base become
56038fd1498Szrj private here. */
56138fd1498Szrj base_access_now = ak_private;
56238fd1498Szrj
56338fd1498Szrj /* See if the new access, via this base, gives more
56438fd1498Szrj access than our previous best access. */
56538fd1498Szrj if (base_access_now != ak_none
56638fd1498Szrj && (access == ak_none || base_access_now < access))
56738fd1498Szrj {
56838fd1498Szrj access = base_access_now;
56938fd1498Szrj
57038fd1498Szrj /* If the new access is public, we can't do better. */
57138fd1498Szrj if (access == ak_public)
57238fd1498Szrj break;
57338fd1498Szrj }
57438fd1498Szrj }
57538fd1498Szrj }
57638fd1498Szrj }
57738fd1498Szrj
57838fd1498Szrj /* Note the access to DECL in TYPE. */
57938fd1498Szrj SET_BINFO_ACCESS (binfo, access);
58038fd1498Szrj
58138fd1498Szrj return NULL_TREE;
58238fd1498Szrj }
58338fd1498Szrj
58438fd1498Szrj /* Return the access to DECL in TYPE. */
58538fd1498Szrj
58638fd1498Szrj static access_kind
access_in_type(tree type,tree decl)58738fd1498Szrj access_in_type (tree type, tree decl)
58838fd1498Szrj {
58938fd1498Szrj tree binfo = TYPE_BINFO (type);
59038fd1498Szrj
59138fd1498Szrj /* We must take into account
59238fd1498Szrj
59338fd1498Szrj [class.paths]
59438fd1498Szrj
59538fd1498Szrj If a name can be reached by several paths through a multiple
59638fd1498Szrj inheritance graph, the access is that of the path that gives
59738fd1498Szrj most access.
59838fd1498Szrj
59938fd1498Szrj The algorithm we use is to make a post-order depth-first traversal
60038fd1498Szrj of the base-class hierarchy. As we come up the tree, we annotate
60138fd1498Szrj each node with the most lenient access. */
60238fd1498Szrj dfs_walk_once (binfo, dfs_access_in_type_pre, dfs_access_in_type, decl);
60338fd1498Szrj
60438fd1498Szrj return BINFO_ACCESS (binfo);
60538fd1498Szrj }
60638fd1498Szrj
60738fd1498Szrj /* Returns nonzero if it is OK to access DECL named in TYPE through an object
60838fd1498Szrj of OTYPE in the context of DERIVED. */
60938fd1498Szrj
61038fd1498Szrj static int
protected_accessible_p(tree decl,tree derived,tree type,tree otype)61138fd1498Szrj protected_accessible_p (tree decl, tree derived, tree type, tree otype)
61238fd1498Szrj {
61338fd1498Szrj /* We're checking this clause from [class.access.base]
61438fd1498Szrj
61538fd1498Szrj m as a member of N is protected, and the reference occurs in a
61638fd1498Szrj member or friend of class N, or in a member or friend of a
61738fd1498Szrj class P derived from N, where m as a member of P is public, private
61838fd1498Szrj or protected.
61938fd1498Szrj
62038fd1498Szrj Here DERIVED is a possible P, DECL is m and TYPE is N. */
62138fd1498Szrj
62238fd1498Szrj /* If DERIVED isn't derived from N, then it can't be a P. */
62338fd1498Szrj if (!DERIVED_FROM_P (type, derived))
62438fd1498Szrj return 0;
62538fd1498Szrj
62638fd1498Szrj /* [class.protected]
62738fd1498Szrj
62838fd1498Szrj When a friend or a member function of a derived class references
62938fd1498Szrj a protected nonstatic member of a base class, an access check
63038fd1498Szrj applies in addition to those described earlier in clause
63138fd1498Szrj _class.access_) Except when forming a pointer to member
63238fd1498Szrj (_expr.unary.op_), the access must be through a pointer to,
63338fd1498Szrj reference to, or object of the derived class itself (or any class
63438fd1498Szrj derived from that class) (_expr.ref_). If the access is to form
63538fd1498Szrj a pointer to member, the nested-name-specifier shall name the
63638fd1498Szrj derived class (or any class derived from that class). */
63738fd1498Szrj if (DECL_NONSTATIC_MEMBER_P (decl)
63838fd1498Szrj && !DERIVED_FROM_P (derived, otype))
63938fd1498Szrj return 0;
64038fd1498Szrj
64138fd1498Szrj return 1;
64238fd1498Szrj }
64338fd1498Szrj
64438fd1498Szrj /* Returns nonzero if SCOPE is a type or a friend of a type which would be able
64538fd1498Szrj to access DECL through TYPE. OTYPE is the type of the object. */
64638fd1498Szrj
64738fd1498Szrj static int
friend_accessible_p(tree scope,tree decl,tree type,tree otype)64838fd1498Szrj friend_accessible_p (tree scope, tree decl, tree type, tree otype)
64938fd1498Szrj {
65038fd1498Szrj /* We're checking this clause from [class.access.base]
65138fd1498Szrj
65238fd1498Szrj m as a member of N is protected, and the reference occurs in a
65338fd1498Szrj member or friend of class N, or in a member or friend of a
65438fd1498Szrj class P derived from N, where m as a member of P is public, private
65538fd1498Szrj or protected.
65638fd1498Szrj
65738fd1498Szrj Here DECL is m and TYPE is N. SCOPE is the current context,
65838fd1498Szrj and we check all its possible Ps. */
65938fd1498Szrj tree befriending_classes;
66038fd1498Szrj tree t;
66138fd1498Szrj
66238fd1498Szrj if (!scope)
66338fd1498Szrj return 0;
66438fd1498Szrj
66538fd1498Szrj if (is_global_friend (scope))
66638fd1498Szrj return 1;
66738fd1498Szrj
66838fd1498Szrj /* Is SCOPE itself a suitable P? */
66938fd1498Szrj if (TYPE_P (scope) && protected_accessible_p (decl, scope, type, otype))
67038fd1498Szrj return 1;
67138fd1498Szrj
67238fd1498Szrj if (DECL_DECLARES_FUNCTION_P (scope))
67338fd1498Szrj befriending_classes = DECL_BEFRIENDING_CLASSES (scope);
67438fd1498Szrj else if (TYPE_P (scope))
67538fd1498Szrj befriending_classes = CLASSTYPE_BEFRIENDING_CLASSES (scope);
67638fd1498Szrj else
67738fd1498Szrj return 0;
67838fd1498Szrj
67938fd1498Szrj for (t = befriending_classes; t; t = TREE_CHAIN (t))
68038fd1498Szrj if (protected_accessible_p (decl, TREE_VALUE (t), type, otype))
68138fd1498Szrj return 1;
68238fd1498Szrj
68338fd1498Szrj /* Nested classes have the same access as their enclosing types, as
68438fd1498Szrj per DR 45 (this is a change from C++98). */
68538fd1498Szrj if (TYPE_P (scope))
68638fd1498Szrj if (friend_accessible_p (TYPE_CONTEXT (scope), decl, type, otype))
68738fd1498Szrj return 1;
68838fd1498Szrj
68938fd1498Szrj if (DECL_DECLARES_FUNCTION_P (scope))
69038fd1498Szrj {
69138fd1498Szrj /* Perhaps this SCOPE is a member of a class which is a
69238fd1498Szrj friend. */
69338fd1498Szrj if (DECL_CLASS_SCOPE_P (scope)
69438fd1498Szrj && friend_accessible_p (DECL_CONTEXT (scope), decl, type, otype))
69538fd1498Szrj return 1;
69638fd1498Szrj }
69738fd1498Szrj
69838fd1498Szrj /* Maybe scope's template is a friend. */
69938fd1498Szrj if (tree tinfo = get_template_info (scope))
70038fd1498Szrj {
70138fd1498Szrj tree tmpl = TI_TEMPLATE (tinfo);
70238fd1498Szrj if (DECL_CLASS_TEMPLATE_P (tmpl))
70338fd1498Szrj tmpl = TREE_TYPE (tmpl);
70438fd1498Szrj else
70538fd1498Szrj tmpl = DECL_TEMPLATE_RESULT (tmpl);
70638fd1498Szrj if (tmpl != scope)
70738fd1498Szrj {
70838fd1498Szrj /* Increment processing_template_decl to make sure that
70938fd1498Szrj dependent_type_p works correctly. */
71038fd1498Szrj ++processing_template_decl;
71138fd1498Szrj int ret = friend_accessible_p (tmpl, decl, type, otype);
71238fd1498Szrj --processing_template_decl;
71338fd1498Szrj if (ret)
71438fd1498Szrj return 1;
71538fd1498Szrj }
71638fd1498Szrj }
71738fd1498Szrj
71838fd1498Szrj /* If is_friend is true, we should have found a befriending class. */
71938fd1498Szrj gcc_checking_assert (!is_friend (type, scope));
72038fd1498Szrj
72138fd1498Szrj return 0;
72238fd1498Szrj }
72338fd1498Szrj
72438fd1498Szrj struct dfs_accessible_data
72538fd1498Szrj {
72638fd1498Szrj tree decl;
72738fd1498Szrj tree object_type;
72838fd1498Szrj };
72938fd1498Szrj
73038fd1498Szrj /* Avoid walking up past a declaration of the member. */
73138fd1498Szrj
73238fd1498Szrj static tree
dfs_accessible_pre(tree binfo,void * data)73338fd1498Szrj dfs_accessible_pre (tree binfo, void *data)
73438fd1498Szrj {
73538fd1498Szrj dfs_accessible_data *d = (dfs_accessible_data *)data;
73638fd1498Szrj tree type = BINFO_TYPE (binfo);
73738fd1498Szrj if (member_declared_in_type (d->decl, type))
73838fd1498Szrj return dfs_skip_bases;
73938fd1498Szrj return NULL_TREE;
74038fd1498Szrj }
74138fd1498Szrj
74238fd1498Szrj /* Called via dfs_walk_once_accessible from accessible_p */
74338fd1498Szrj
74438fd1498Szrj static tree
dfs_accessible_post(tree binfo,void * data)74538fd1498Szrj dfs_accessible_post (tree binfo, void *data)
74638fd1498Szrj {
74738fd1498Szrj /* access_in_type already set BINFO_ACCESS for us. */
74838fd1498Szrj access_kind access = BINFO_ACCESS (binfo);
74938fd1498Szrj tree N = BINFO_TYPE (binfo);
75038fd1498Szrj dfs_accessible_data *d = (dfs_accessible_data *)data;
75138fd1498Szrj tree decl = d->decl;
75238fd1498Szrj tree scope = current_nonlambda_scope ();
75338fd1498Szrj
75438fd1498Szrj /* A member m is accessible at the point R when named in class N if */
75538fd1498Szrj switch (access)
75638fd1498Szrj {
75738fd1498Szrj case ak_none:
75838fd1498Szrj return NULL_TREE;
75938fd1498Szrj
76038fd1498Szrj case ak_public:
76138fd1498Szrj /* m as a member of N is public, or */
76238fd1498Szrj return binfo;
76338fd1498Szrj
76438fd1498Szrj case ak_private:
76538fd1498Szrj {
76638fd1498Szrj /* m as a member of N is private, and R occurs in a member or friend of
76738fd1498Szrj class N, or */
76838fd1498Szrj if (scope && TREE_CODE (scope) != NAMESPACE_DECL
76938fd1498Szrj && is_friend (N, scope))
77038fd1498Szrj return binfo;
77138fd1498Szrj return NULL_TREE;
77238fd1498Szrj }
77338fd1498Szrj
77438fd1498Szrj case ak_protected:
77538fd1498Szrj {
77638fd1498Szrj /* m as a member of N is protected, and R occurs in a member or friend
77738fd1498Szrj of class N, or in a member or friend of a class P derived from N,
77838fd1498Szrj where m as a member of P is public, private, or protected */
77938fd1498Szrj if (friend_accessible_p (scope, decl, N, d->object_type))
78038fd1498Szrj return binfo;
78138fd1498Szrj return NULL_TREE;
78238fd1498Szrj }
78338fd1498Szrj
78438fd1498Szrj default:
78538fd1498Szrj gcc_unreachable ();
78638fd1498Szrj }
78738fd1498Szrj }
78838fd1498Szrj
78938fd1498Szrj /* Like accessible_p below, but within a template returns true iff DECL is
79038fd1498Szrj accessible in TYPE to all possible instantiations of the template. */
79138fd1498Szrj
79238fd1498Szrj int
accessible_in_template_p(tree type,tree decl)79338fd1498Szrj accessible_in_template_p (tree type, tree decl)
79438fd1498Szrj {
79538fd1498Szrj int save_ptd = processing_template_decl;
79638fd1498Szrj processing_template_decl = 0;
79738fd1498Szrj int val = accessible_p (type, decl, false);
79838fd1498Szrj processing_template_decl = save_ptd;
79938fd1498Szrj return val;
80038fd1498Szrj }
80138fd1498Szrj
80238fd1498Szrj /* DECL is a declaration from a base class of TYPE, which was the
80338fd1498Szrj class used to name DECL. Return nonzero if, in the current
80438fd1498Szrj context, DECL is accessible. If TYPE is actually a BINFO node,
80538fd1498Szrj then we can tell in what context the access is occurring by looking
80638fd1498Szrj at the most derived class along the path indicated by BINFO. If
80738fd1498Szrj CONSIDER_LOCAL is true, do consider special access the current
80838fd1498Szrj scope or friendship thereof we might have. */
80938fd1498Szrj
81038fd1498Szrj int
accessible_p(tree type,tree decl,bool consider_local_p)81138fd1498Szrj accessible_p (tree type, tree decl, bool consider_local_p)
81238fd1498Szrj {
81338fd1498Szrj tree binfo;
81438fd1498Szrj access_kind access;
81538fd1498Szrj
81638fd1498Szrj /* If this declaration is in a block or namespace scope, there's no
81738fd1498Szrj access control. */
81838fd1498Szrj if (!TYPE_P (context_for_name_lookup (decl)))
81938fd1498Szrj return 1;
82038fd1498Szrj
82138fd1498Szrj /* There is no need to perform access checks inside a thunk. */
82238fd1498Szrj if (current_function_decl && DECL_THUNK_P (current_function_decl))
82338fd1498Szrj return 1;
82438fd1498Szrj
82538fd1498Szrj /* In a template declaration, we cannot be sure whether the
82638fd1498Szrj particular specialization that is instantiated will be a friend
82738fd1498Szrj or not. Therefore, all access checks are deferred until
82838fd1498Szrj instantiation. However, PROCESSING_TEMPLATE_DECL is set in the
82938fd1498Szrj parameter list for a template (because we may see dependent types
83038fd1498Szrj in default arguments for template parameters), and access
83138fd1498Szrj checking should be performed in the outermost parameter list. */
83238fd1498Szrj if (processing_template_decl
83338fd1498Szrj && !expanding_concept ()
83438fd1498Szrj && (!processing_template_parmlist || processing_template_decl > 1))
83538fd1498Szrj return 1;
83638fd1498Szrj
83738fd1498Szrj tree otype = NULL_TREE;
83838fd1498Szrj if (!TYPE_P (type))
83938fd1498Szrj {
84038fd1498Szrj /* When accessing a non-static member, the most derived type in the
84138fd1498Szrj binfo chain is the type of the object; remember that type for
84238fd1498Szrj protected_accessible_p. */
84338fd1498Szrj for (tree b = type; b; b = BINFO_INHERITANCE_CHAIN (b))
84438fd1498Szrj otype = BINFO_TYPE (b);
84538fd1498Szrj type = BINFO_TYPE (type);
84638fd1498Szrj }
84738fd1498Szrj else
84838fd1498Szrj otype = type;
84938fd1498Szrj
85038fd1498Szrj /* [class.access.base]
85138fd1498Szrj
85238fd1498Szrj A member m is accessible when named in class N if
85338fd1498Szrj
85438fd1498Szrj --m as a member of N is public, or
85538fd1498Szrj
85638fd1498Szrj --m as a member of N is private, and the reference occurs in a
85738fd1498Szrj member or friend of class N, or
85838fd1498Szrj
85938fd1498Szrj --m as a member of N is protected, and the reference occurs in a
86038fd1498Szrj member or friend of class N, or in a member or friend of a
86138fd1498Szrj class P derived from N, where m as a member of P is public, private or
86238fd1498Szrj protected, or
86338fd1498Szrj
86438fd1498Szrj --there exists a base class B of N that is accessible at the point
86538fd1498Szrj of reference, and m is accessible when named in class B.
86638fd1498Szrj
86738fd1498Szrj We walk the base class hierarchy, checking these conditions. */
86838fd1498Szrj
86938fd1498Szrj /* We walk using TYPE_BINFO (type) because access_in_type will set
87038fd1498Szrj BINFO_ACCESS on it and its bases. */
87138fd1498Szrj binfo = TYPE_BINFO (type);
87238fd1498Szrj
87338fd1498Szrj /* Compute the accessibility of DECL in the class hierarchy
87438fd1498Szrj dominated by type. */
87538fd1498Szrj access = access_in_type (type, decl);
87638fd1498Szrj if (access == ak_public)
87738fd1498Szrj return 1;
87838fd1498Szrj
87938fd1498Szrj /* If we aren't considering the point of reference, only the first bullet
88038fd1498Szrj applies. */
88138fd1498Szrj if (!consider_local_p)
88238fd1498Szrj return 0;
88338fd1498Szrj
88438fd1498Szrj dfs_accessible_data d = { decl, otype };
88538fd1498Szrj
88638fd1498Szrj /* Walk the hierarchy again, looking for a base class that allows
88738fd1498Szrj access. */
88838fd1498Szrj return dfs_walk_once_accessible (binfo, /*friends=*/true,
88938fd1498Szrj dfs_accessible_pre,
89038fd1498Szrj dfs_accessible_post, &d)
89138fd1498Szrj != NULL_TREE;
89238fd1498Szrj }
89338fd1498Szrj
89438fd1498Szrj struct lookup_field_info {
89538fd1498Szrj /* The type in which we're looking. */
89638fd1498Szrj tree type;
89738fd1498Szrj /* The name of the field for which we're looking. */
89838fd1498Szrj tree name;
89938fd1498Szrj /* If non-NULL, the current result of the lookup. */
90038fd1498Szrj tree rval;
90138fd1498Szrj /* The path to RVAL. */
90238fd1498Szrj tree rval_binfo;
90338fd1498Szrj /* If non-NULL, the lookup was ambiguous, and this is a list of the
90438fd1498Szrj candidates. */
90538fd1498Szrj tree ambiguous;
90638fd1498Szrj /* If nonzero, we are looking for types, not data members. */
90738fd1498Szrj int want_type;
90838fd1498Szrj /* If something went wrong, a message indicating what. */
90938fd1498Szrj const char *errstr;
91038fd1498Szrj };
91138fd1498Szrj
91238fd1498Szrj /* Nonzero for a class member means that it is shared between all objects
91338fd1498Szrj of that class.
91438fd1498Szrj
91538fd1498Szrj [class.member.lookup]:If the resulting set of declarations are not all
91638fd1498Szrj from sub-objects of the same type, or the set has a nonstatic member
91738fd1498Szrj and includes members from distinct sub-objects, there is an ambiguity
91838fd1498Szrj and the program is ill-formed.
91938fd1498Szrj
92038fd1498Szrj This function checks that T contains no nonstatic members. */
92138fd1498Szrj
92238fd1498Szrj int
shared_member_p(tree t)92338fd1498Szrj shared_member_p (tree t)
92438fd1498Szrj {
92538fd1498Szrj if (VAR_P (t) || TREE_CODE (t) == TYPE_DECL \
92638fd1498Szrj || TREE_CODE (t) == CONST_DECL)
92738fd1498Szrj return 1;
92838fd1498Szrj if (is_overloaded_fn (t))
92938fd1498Szrj {
93038fd1498Szrj for (ovl_iterator iter (get_fns (t)); iter; ++iter)
93138fd1498Szrj if (DECL_NONSTATIC_MEMBER_FUNCTION_P (*iter))
93238fd1498Szrj return 0;
93338fd1498Szrj return 1;
93438fd1498Szrj }
93538fd1498Szrj return 0;
93638fd1498Szrj }
93738fd1498Szrj
93838fd1498Szrj /* Routine to see if the sub-object denoted by the binfo PARENT can be
93938fd1498Szrj found as a base class and sub-object of the object denoted by
94038fd1498Szrj BINFO. */
94138fd1498Szrj
94238fd1498Szrj static int
is_subobject_of_p(tree parent,tree binfo)94338fd1498Szrj is_subobject_of_p (tree parent, tree binfo)
94438fd1498Szrj {
94538fd1498Szrj tree probe;
94638fd1498Szrj
94738fd1498Szrj for (probe = parent; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
94838fd1498Szrj {
94938fd1498Szrj if (probe == binfo)
95038fd1498Szrj return 1;
95138fd1498Szrj if (BINFO_VIRTUAL_P (probe))
95238fd1498Szrj return (binfo_for_vbase (BINFO_TYPE (probe), BINFO_TYPE (binfo))
95338fd1498Szrj != NULL_TREE);
95438fd1498Szrj }
95538fd1498Szrj return 0;
95638fd1498Szrj }
95738fd1498Szrj
95838fd1498Szrj /* DATA is really a struct lookup_field_info. Look for a field with
95938fd1498Szrj the name indicated there in BINFO. If this function returns a
96038fd1498Szrj non-NULL value it is the result of the lookup. Called from
96138fd1498Szrj lookup_field via breadth_first_search. */
96238fd1498Szrj
96338fd1498Szrj static tree
lookup_field_r(tree binfo,void * data)96438fd1498Szrj lookup_field_r (tree binfo, void *data)
96538fd1498Szrj {
96638fd1498Szrj struct lookup_field_info *lfi = (struct lookup_field_info *) data;
96738fd1498Szrj tree type = BINFO_TYPE (binfo);
96838fd1498Szrj tree nval = NULL_TREE;
96938fd1498Szrj
97038fd1498Szrj /* If this is a dependent base, don't look in it. */
97138fd1498Szrj if (BINFO_DEPENDENT_BASE_P (binfo))
97238fd1498Szrj return NULL_TREE;
97338fd1498Szrj
97438fd1498Szrj /* If this base class is hidden by the best-known value so far, we
97538fd1498Szrj don't need to look. */
97638fd1498Szrj if (lfi->rval_binfo && BINFO_INHERITANCE_CHAIN (binfo) == lfi->rval_binfo
97738fd1498Szrj && !BINFO_VIRTUAL_P (binfo))
97838fd1498Szrj return dfs_skip_bases;
97938fd1498Szrj
98038fd1498Szrj nval = get_class_binding (type, lfi->name, lfi->want_type);
98138fd1498Szrj
98238fd1498Szrj /* If we're looking up a type (as with an elaborated type specifier)
98338fd1498Szrj we ignore all non-types we find. */
98438fd1498Szrj if (lfi->want_type && nval && !DECL_DECLARES_TYPE_P (nval))
98538fd1498Szrj {
98638fd1498Szrj nval = NULL_TREE;
98738fd1498Szrj if (CLASSTYPE_NESTED_UTDS (type))
98838fd1498Szrj if (binding_entry e = binding_table_find (CLASSTYPE_NESTED_UTDS (type),
98938fd1498Szrj lfi->name))
99038fd1498Szrj nval = TYPE_MAIN_DECL (e->type);
99138fd1498Szrj }
99238fd1498Szrj
99338fd1498Szrj /* If there is no declaration with the indicated name in this type,
99438fd1498Szrj then there's nothing to do. */
99538fd1498Szrj if (!nval)
99638fd1498Szrj goto done;
99738fd1498Szrj
99838fd1498Szrj /* If the lookup already found a match, and the new value doesn't
99938fd1498Szrj hide the old one, we might have an ambiguity. */
100038fd1498Szrj if (lfi->rval_binfo
100138fd1498Szrj && !is_subobject_of_p (lfi->rval_binfo, binfo))
100238fd1498Szrj
100338fd1498Szrj {
100438fd1498Szrj if (nval == lfi->rval && shared_member_p (nval))
100538fd1498Szrj /* The two things are really the same. */
100638fd1498Szrj ;
100738fd1498Szrj else if (is_subobject_of_p (binfo, lfi->rval_binfo))
100838fd1498Szrj /* The previous value hides the new one. */
100938fd1498Szrj ;
101038fd1498Szrj else
101138fd1498Szrj {
101238fd1498Szrj /* We have a real ambiguity. We keep a chain of all the
101338fd1498Szrj candidates. */
101438fd1498Szrj if (!lfi->ambiguous && lfi->rval)
101538fd1498Szrj {
101638fd1498Szrj /* This is the first time we noticed an ambiguity. Add
101738fd1498Szrj what we previously thought was a reasonable candidate
101838fd1498Szrj to the list. */
101938fd1498Szrj lfi->ambiguous = tree_cons (NULL_TREE, lfi->rval, NULL_TREE);
102038fd1498Szrj TREE_TYPE (lfi->ambiguous) = error_mark_node;
102138fd1498Szrj }
102238fd1498Szrj
102338fd1498Szrj /* Add the new value. */
102438fd1498Szrj lfi->ambiguous = tree_cons (NULL_TREE, nval, lfi->ambiguous);
102538fd1498Szrj TREE_TYPE (lfi->ambiguous) = error_mark_node;
102638fd1498Szrj lfi->errstr = G_("request for member %qD is ambiguous");
102738fd1498Szrj }
102838fd1498Szrj }
102938fd1498Szrj else
103038fd1498Szrj {
103138fd1498Szrj lfi->rval = nval;
103238fd1498Szrj lfi->rval_binfo = binfo;
103338fd1498Szrj }
103438fd1498Szrj
103538fd1498Szrj done:
103638fd1498Szrj /* Don't look for constructors or destructors in base classes. */
103738fd1498Szrj if (IDENTIFIER_CDTOR_P (lfi->name))
103838fd1498Szrj return dfs_skip_bases;
103938fd1498Szrj return NULL_TREE;
104038fd1498Szrj }
104138fd1498Szrj
104238fd1498Szrj /* Return a "baselink" with BASELINK_BINFO, BASELINK_ACCESS_BINFO,
104338fd1498Szrj BASELINK_FUNCTIONS, and BASELINK_OPTYPE set to BINFO, ACCESS_BINFO,
104438fd1498Szrj FUNCTIONS, and OPTYPE respectively. */
104538fd1498Szrj
104638fd1498Szrj tree
build_baselink(tree binfo,tree access_binfo,tree functions,tree optype)104738fd1498Szrj build_baselink (tree binfo, tree access_binfo, tree functions, tree optype)
104838fd1498Szrj {
104938fd1498Szrj tree baselink;
105038fd1498Szrj
105138fd1498Szrj gcc_assert (TREE_CODE (functions) == FUNCTION_DECL
105238fd1498Szrj || TREE_CODE (functions) == TEMPLATE_DECL
105338fd1498Szrj || TREE_CODE (functions) == TEMPLATE_ID_EXPR
105438fd1498Szrj || TREE_CODE (functions) == OVERLOAD);
105538fd1498Szrj gcc_assert (!optype || TYPE_P (optype));
105638fd1498Szrj gcc_assert (TREE_TYPE (functions));
105738fd1498Szrj
105838fd1498Szrj baselink = make_node (BASELINK);
105938fd1498Szrj TREE_TYPE (baselink) = TREE_TYPE (functions);
106038fd1498Szrj BASELINK_BINFO (baselink) = binfo;
106138fd1498Szrj BASELINK_ACCESS_BINFO (baselink) = access_binfo;
106238fd1498Szrj BASELINK_FUNCTIONS (baselink) = functions;
106338fd1498Szrj BASELINK_OPTYPE (baselink) = optype;
106438fd1498Szrj
106538fd1498Szrj return baselink;
106638fd1498Szrj }
106738fd1498Szrj
106838fd1498Szrj /* Look for a member named NAME in an inheritance lattice dominated by
106938fd1498Szrj XBASETYPE. If PROTECT is 0 or two, we do not check access. If it
107038fd1498Szrj is 1, we enforce accessibility. If PROTECT is zero, then, for an
107138fd1498Szrj ambiguous lookup, we return NULL. If PROTECT is 1, we issue error
107238fd1498Szrj messages about inaccessible or ambiguous lookup. If PROTECT is 2,
107338fd1498Szrj we return a TREE_LIST whose TREE_TYPE is error_mark_node and whose
107438fd1498Szrj TREE_VALUEs are the list of ambiguous candidates.
107538fd1498Szrj
107638fd1498Szrj WANT_TYPE is 1 when we should only return TYPE_DECLs.
107738fd1498Szrj
107838fd1498Szrj If nothing can be found return NULL_TREE and do not issue an error.
107938fd1498Szrj
108038fd1498Szrj If non-NULL, failure information is written back to AFI. */
108138fd1498Szrj
108238fd1498Szrj tree
lookup_member(tree xbasetype,tree name,int protect,bool want_type,tsubst_flags_t complain,access_failure_info * afi)108338fd1498Szrj lookup_member (tree xbasetype, tree name, int protect, bool want_type,
108438fd1498Szrj tsubst_flags_t complain, access_failure_info *afi)
108538fd1498Szrj {
108638fd1498Szrj tree rval, rval_binfo = NULL_TREE;
108738fd1498Szrj tree type = NULL_TREE, basetype_path = NULL_TREE;
108838fd1498Szrj struct lookup_field_info lfi;
108938fd1498Szrj
109038fd1498Szrj /* rval_binfo is the binfo associated with the found member, note,
109138fd1498Szrj this can be set with useful information, even when rval is not
109238fd1498Szrj set, because it must deal with ALL members, not just non-function
109338fd1498Szrj members. It is used for ambiguity checking and the hidden
109438fd1498Szrj checks. Whereas rval is only set if a proper (not hidden)
109538fd1498Szrj non-function member is found. */
109638fd1498Szrj
109738fd1498Szrj const char *errstr = 0;
109838fd1498Szrj
109938fd1498Szrj if (name == error_mark_node
110038fd1498Szrj || xbasetype == NULL_TREE
110138fd1498Szrj || xbasetype == error_mark_node)
110238fd1498Szrj return NULL_TREE;
110338fd1498Szrj
110438fd1498Szrj gcc_assert (identifier_p (name));
110538fd1498Szrj
110638fd1498Szrj if (TREE_CODE (xbasetype) == TREE_BINFO)
110738fd1498Szrj {
110838fd1498Szrj type = BINFO_TYPE (xbasetype);
110938fd1498Szrj basetype_path = xbasetype;
111038fd1498Szrj }
111138fd1498Szrj else
111238fd1498Szrj {
111338fd1498Szrj if (!RECORD_OR_UNION_CODE_P (TREE_CODE (xbasetype)))
111438fd1498Szrj return NULL_TREE;
111538fd1498Szrj type = xbasetype;
111638fd1498Szrj xbasetype = NULL_TREE;
111738fd1498Szrj }
111838fd1498Szrj
111938fd1498Szrj type = complete_type (type);
112038fd1498Szrj
112138fd1498Szrj /* Make sure we're looking for a member of the current instantiation in the
112238fd1498Szrj right partial specialization. */
1123*58e805e6Szrj if (dependent_type_p (type))
112438fd1498Szrj if (tree t = currently_open_class (type))
112538fd1498Szrj type = t;
112638fd1498Szrj
112738fd1498Szrj if (!basetype_path)
112838fd1498Szrj basetype_path = TYPE_BINFO (type);
112938fd1498Szrj
113038fd1498Szrj if (!basetype_path)
113138fd1498Szrj return NULL_TREE;
113238fd1498Szrj
113338fd1498Szrj memset (&lfi, 0, sizeof (lfi));
113438fd1498Szrj lfi.type = type;
113538fd1498Szrj lfi.name = name;
113638fd1498Szrj lfi.want_type = want_type;
113738fd1498Szrj dfs_walk_all (basetype_path, &lookup_field_r, NULL, &lfi);
113838fd1498Szrj rval = lfi.rval;
113938fd1498Szrj rval_binfo = lfi.rval_binfo;
114038fd1498Szrj if (rval_binfo)
114138fd1498Szrj type = BINFO_TYPE (rval_binfo);
114238fd1498Szrj errstr = lfi.errstr;
114338fd1498Szrj
114438fd1498Szrj /* If we are not interested in ambiguities, don't report them;
114538fd1498Szrj just return NULL_TREE. */
114638fd1498Szrj if (!protect && lfi.ambiguous)
114738fd1498Szrj return NULL_TREE;
114838fd1498Szrj
114938fd1498Szrj if (protect == 2)
115038fd1498Szrj {
115138fd1498Szrj if (lfi.ambiguous)
115238fd1498Szrj return lfi.ambiguous;
115338fd1498Szrj else
115438fd1498Szrj protect = 0;
115538fd1498Szrj }
115638fd1498Szrj
115738fd1498Szrj /* [class.access]
115838fd1498Szrj
115938fd1498Szrj In the case of overloaded function names, access control is
116038fd1498Szrj applied to the function selected by overloaded resolution.
116138fd1498Szrj
116238fd1498Szrj We cannot check here, even if RVAL is only a single non-static
116338fd1498Szrj member function, since we do not know what the "this" pointer
116438fd1498Szrj will be. For:
116538fd1498Szrj
116638fd1498Szrj class A { protected: void f(); };
116738fd1498Szrj class B : public A {
116838fd1498Szrj void g(A *p) {
116938fd1498Szrj f(); // OK
117038fd1498Szrj p->f(); // Not OK.
117138fd1498Szrj }
117238fd1498Szrj };
117338fd1498Szrj
117438fd1498Szrj only the first call to "f" is valid. However, if the function is
117538fd1498Szrj static, we can check. */
117638fd1498Szrj if (rval && protect
117738fd1498Szrj && !really_overloaded_fn (rval))
117838fd1498Szrj {
117938fd1498Szrj tree decl = is_overloaded_fn (rval) ? get_first_fn (rval) : rval;
118038fd1498Szrj if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
118138fd1498Szrj && !perform_or_defer_access_check (basetype_path, decl, decl,
118238fd1498Szrj complain, afi))
118338fd1498Szrj rval = error_mark_node;
118438fd1498Szrj }
118538fd1498Szrj
118638fd1498Szrj if (errstr && protect)
118738fd1498Szrj {
118838fd1498Szrj if (complain & tf_error)
118938fd1498Szrj {
119038fd1498Szrj error (errstr, name, type);
119138fd1498Szrj if (lfi.ambiguous)
119238fd1498Szrj print_candidates (lfi.ambiguous);
119338fd1498Szrj }
119438fd1498Szrj rval = error_mark_node;
119538fd1498Szrj }
119638fd1498Szrj
119738fd1498Szrj if (rval && is_overloaded_fn (rval))
119838fd1498Szrj rval = build_baselink (rval_binfo, basetype_path, rval,
119938fd1498Szrj (IDENTIFIER_CONV_OP_P (name)
120038fd1498Szrj ? TREE_TYPE (name): NULL_TREE));
120138fd1498Szrj return rval;
120238fd1498Szrj }
120338fd1498Szrj
120438fd1498Szrj /* Helper class for lookup_member_fuzzy. */
120538fd1498Szrj
120638fd1498Szrj class lookup_field_fuzzy_info
120738fd1498Szrj {
120838fd1498Szrj public:
lookup_field_fuzzy_info(bool want_type_p)120938fd1498Szrj lookup_field_fuzzy_info (bool want_type_p) :
121038fd1498Szrj m_want_type_p (want_type_p), m_candidates () {}
121138fd1498Szrj
121238fd1498Szrj void fuzzy_lookup_field (tree type);
121338fd1498Szrj
121438fd1498Szrj /* If true, we are looking for types, not data members. */
121538fd1498Szrj bool m_want_type_p;
121638fd1498Szrj /* The result: a vec of identifiers. */
121738fd1498Szrj auto_vec<tree> m_candidates;
121838fd1498Szrj };
121938fd1498Szrj
122038fd1498Szrj /* Locate all fields within TYPE, append them to m_candidates. */
122138fd1498Szrj
122238fd1498Szrj void
fuzzy_lookup_field(tree type)122338fd1498Szrj lookup_field_fuzzy_info::fuzzy_lookup_field (tree type)
122438fd1498Szrj {
122538fd1498Szrj if (!CLASS_TYPE_P (type))
122638fd1498Szrj return;
122738fd1498Szrj
122838fd1498Szrj for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
122938fd1498Szrj {
1230*58e805e6Szrj if (m_want_type_p && !DECL_DECLARES_TYPE_P (field))
1231*58e805e6Szrj continue;
1232*58e805e6Szrj
1233*58e805e6Szrj if (!DECL_NAME (field))
1234*58e805e6Szrj continue;
1235*58e805e6Szrj
1236*58e805e6Szrj if (is_lambda_ignored_entity (field))
1237*58e805e6Szrj continue;
1238*58e805e6Szrj
123938fd1498Szrj m_candidates.safe_push (DECL_NAME (field));
124038fd1498Szrj }
124138fd1498Szrj }
124238fd1498Szrj
124338fd1498Szrj
124438fd1498Szrj /* Helper function for lookup_member_fuzzy, called via dfs_walk_all
124538fd1498Szrj DATA is really a lookup_field_fuzzy_info. Look for a field with
124638fd1498Szrj the name indicated there in BINFO. Gathers pertinent identifiers into
124738fd1498Szrj m_candidates. */
124838fd1498Szrj
124938fd1498Szrj static tree
lookup_field_fuzzy_r(tree binfo,void * data)125038fd1498Szrj lookup_field_fuzzy_r (tree binfo, void *data)
125138fd1498Szrj {
125238fd1498Szrj lookup_field_fuzzy_info *lffi = (lookup_field_fuzzy_info *) data;
125338fd1498Szrj tree type = BINFO_TYPE (binfo);
125438fd1498Szrj
125538fd1498Szrj lffi->fuzzy_lookup_field (type);
125638fd1498Szrj
125738fd1498Szrj return NULL_TREE;
125838fd1498Szrj }
125938fd1498Szrj
126038fd1498Szrj /* Like lookup_member, but try to find the closest match for NAME,
126138fd1498Szrj rather than an exact match, and return an identifier (or NULL_TREE).
126238fd1498Szrj Do not complain. */
126338fd1498Szrj
126438fd1498Szrj tree
lookup_member_fuzzy(tree xbasetype,tree name,bool want_type_p)126538fd1498Szrj lookup_member_fuzzy (tree xbasetype, tree name, bool want_type_p)
126638fd1498Szrj {
126738fd1498Szrj tree type = NULL_TREE, basetype_path = NULL_TREE;
126838fd1498Szrj struct lookup_field_fuzzy_info lffi (want_type_p);
126938fd1498Szrj
127038fd1498Szrj /* rval_binfo is the binfo associated with the found member, note,
127138fd1498Szrj this can be set with useful information, even when rval is not
127238fd1498Szrj set, because it must deal with ALL members, not just non-function
127338fd1498Szrj members. It is used for ambiguity checking and the hidden
127438fd1498Szrj checks. Whereas rval is only set if a proper (not hidden)
127538fd1498Szrj non-function member is found. */
127638fd1498Szrj
127738fd1498Szrj if (name == error_mark_node
127838fd1498Szrj || xbasetype == NULL_TREE
127938fd1498Szrj || xbasetype == error_mark_node)
128038fd1498Szrj return NULL_TREE;
128138fd1498Szrj
128238fd1498Szrj gcc_assert (identifier_p (name));
128338fd1498Szrj
128438fd1498Szrj if (TREE_CODE (xbasetype) == TREE_BINFO)
128538fd1498Szrj {
128638fd1498Szrj type = BINFO_TYPE (xbasetype);
128738fd1498Szrj basetype_path = xbasetype;
128838fd1498Szrj }
128938fd1498Szrj else
129038fd1498Szrj {
129138fd1498Szrj if (!RECORD_OR_UNION_CODE_P (TREE_CODE (xbasetype)))
129238fd1498Szrj return NULL_TREE;
129338fd1498Szrj type = xbasetype;
129438fd1498Szrj xbasetype = NULL_TREE;
129538fd1498Szrj }
129638fd1498Szrj
129738fd1498Szrj type = complete_type (type);
129838fd1498Szrj
129938fd1498Szrj /* Make sure we're looking for a member of the current instantiation in the
130038fd1498Szrj right partial specialization. */
130138fd1498Szrj if (flag_concepts && dependent_type_p (type))
130238fd1498Szrj type = currently_open_class (type);
130338fd1498Szrj
130438fd1498Szrj if (!basetype_path)
130538fd1498Szrj basetype_path = TYPE_BINFO (type);
130638fd1498Szrj
130738fd1498Szrj if (!basetype_path)
130838fd1498Szrj return NULL_TREE;
130938fd1498Szrj
131038fd1498Szrj /* Populate lffi.m_candidates. */
131138fd1498Szrj dfs_walk_all (basetype_path, &lookup_field_fuzzy_r, NULL, &lffi);
131238fd1498Szrj
131338fd1498Szrj return find_closest_identifier (name, &lffi.m_candidates);
131438fd1498Szrj }
131538fd1498Szrj
131638fd1498Szrj /* Like lookup_member, except that if we find a function member we
131738fd1498Szrj return NULL_TREE. */
131838fd1498Szrj
131938fd1498Szrj tree
lookup_field(tree xbasetype,tree name,int protect,bool want_type)132038fd1498Szrj lookup_field (tree xbasetype, tree name, int protect, bool want_type)
132138fd1498Szrj {
132238fd1498Szrj tree rval = lookup_member (xbasetype, name, protect, want_type,
132338fd1498Szrj tf_warning_or_error);
132438fd1498Szrj
132538fd1498Szrj /* Ignore functions, but propagate the ambiguity list. */
132638fd1498Szrj if (!error_operand_p (rval)
132738fd1498Szrj && (rval && BASELINK_P (rval)))
132838fd1498Szrj return NULL_TREE;
132938fd1498Szrj
133038fd1498Szrj return rval;
133138fd1498Szrj }
133238fd1498Szrj
133338fd1498Szrj /* Like lookup_member, except that if we find a non-function member we
133438fd1498Szrj return NULL_TREE. */
133538fd1498Szrj
133638fd1498Szrj tree
lookup_fnfields(tree xbasetype,tree name,int protect)133738fd1498Szrj lookup_fnfields (tree xbasetype, tree name, int protect)
133838fd1498Szrj {
133938fd1498Szrj tree rval = lookup_member (xbasetype, name, protect, /*want_type=*/false,
134038fd1498Szrj tf_warning_or_error);
134138fd1498Szrj
134238fd1498Szrj /* Ignore non-functions, but propagate the ambiguity list. */
134338fd1498Szrj if (!error_operand_p (rval)
134438fd1498Szrj && (rval && !BASELINK_P (rval)))
134538fd1498Szrj return NULL_TREE;
134638fd1498Szrj
134738fd1498Szrj return rval;
134838fd1498Szrj }
134938fd1498Szrj
135038fd1498Szrj /* DECL is the result of a qualified name lookup. QUALIFYING_SCOPE is
135138fd1498Szrj the class or namespace used to qualify the name. CONTEXT_CLASS is
135238fd1498Szrj the class corresponding to the object in which DECL will be used.
135338fd1498Szrj Return a possibly modified version of DECL that takes into account
135438fd1498Szrj the CONTEXT_CLASS.
135538fd1498Szrj
135638fd1498Szrj In particular, consider an expression like `B::m' in the context of
135738fd1498Szrj a derived class `D'. If `B::m' has been resolved to a BASELINK,
135838fd1498Szrj then the most derived class indicated by the BASELINK_BINFO will be
135938fd1498Szrj `B', not `D'. This function makes that adjustment. */
136038fd1498Szrj
136138fd1498Szrj tree
adjust_result_of_qualified_name_lookup(tree decl,tree qualifying_scope,tree context_class)136238fd1498Szrj adjust_result_of_qualified_name_lookup (tree decl,
136338fd1498Szrj tree qualifying_scope,
136438fd1498Szrj tree context_class)
136538fd1498Szrj {
136638fd1498Szrj if (context_class && context_class != error_mark_node
136738fd1498Szrj && CLASS_TYPE_P (context_class)
136838fd1498Szrj && CLASS_TYPE_P (qualifying_scope)
136938fd1498Szrj && DERIVED_FROM_P (qualifying_scope, context_class)
137038fd1498Szrj && BASELINK_P (decl))
137138fd1498Szrj {
137238fd1498Szrj tree base;
137338fd1498Szrj
137438fd1498Szrj /* Look for the QUALIFYING_SCOPE as a base of the CONTEXT_CLASS.
137538fd1498Szrj Because we do not yet know which function will be chosen by
137638fd1498Szrj overload resolution, we cannot yet check either accessibility
137738fd1498Szrj or ambiguity -- in either case, the choice of a static member
137838fd1498Szrj function might make the usage valid. */
137938fd1498Szrj base = lookup_base (context_class, qualifying_scope,
138038fd1498Szrj ba_unique, NULL, tf_none);
138138fd1498Szrj if (base && base != error_mark_node)
138238fd1498Szrj {
138338fd1498Szrj BASELINK_ACCESS_BINFO (decl) = base;
138438fd1498Szrj tree decl_binfo
138538fd1498Szrj = lookup_base (base, BINFO_TYPE (BASELINK_BINFO (decl)),
138638fd1498Szrj ba_unique, NULL, tf_none);
138738fd1498Szrj if (decl_binfo && decl_binfo != error_mark_node)
138838fd1498Szrj BASELINK_BINFO (decl) = decl_binfo;
138938fd1498Szrj }
139038fd1498Szrj }
139138fd1498Szrj
139238fd1498Szrj if (BASELINK_P (decl))
139338fd1498Szrj BASELINK_QUALIFIED_P (decl) = true;
139438fd1498Szrj
139538fd1498Szrj return decl;
139638fd1498Szrj }
139738fd1498Szrj
139838fd1498Szrj
139938fd1498Szrj /* Walk the class hierarchy within BINFO, in a depth-first traversal.
140038fd1498Szrj PRE_FN is called in preorder, while POST_FN is called in postorder.
140138fd1498Szrj If PRE_FN returns DFS_SKIP_BASES, child binfos will not be
140238fd1498Szrj walked. If PRE_FN or POST_FN returns a different non-NULL value,
140338fd1498Szrj that value is immediately returned and the walk is terminated. One
140438fd1498Szrj of PRE_FN and POST_FN can be NULL. At each node, PRE_FN and
140538fd1498Szrj POST_FN are passed the binfo to examine and the caller's DATA
140638fd1498Szrj value. All paths are walked, thus virtual and morally virtual
140738fd1498Szrj binfos can be multiply walked. */
140838fd1498Szrj
140938fd1498Szrj tree
dfs_walk_all(tree binfo,tree (* pre_fn)(tree,void *),tree (* post_fn)(tree,void *),void * data)141038fd1498Szrj dfs_walk_all (tree binfo, tree (*pre_fn) (tree, void *),
141138fd1498Szrj tree (*post_fn) (tree, void *), void *data)
141238fd1498Szrj {
141338fd1498Szrj tree rval;
141438fd1498Szrj unsigned ix;
141538fd1498Szrj tree base_binfo;
141638fd1498Szrj
141738fd1498Szrj /* Call the pre-order walking function. */
141838fd1498Szrj if (pre_fn)
141938fd1498Szrj {
142038fd1498Szrj rval = pre_fn (binfo, data);
142138fd1498Szrj if (rval)
142238fd1498Szrj {
142338fd1498Szrj if (rval == dfs_skip_bases)
142438fd1498Szrj goto skip_bases;
142538fd1498Szrj return rval;
142638fd1498Szrj }
142738fd1498Szrj }
142838fd1498Szrj
142938fd1498Szrj /* Find the next child binfo to walk. */
143038fd1498Szrj for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
143138fd1498Szrj {
143238fd1498Szrj rval = dfs_walk_all (base_binfo, pre_fn, post_fn, data);
143338fd1498Szrj if (rval)
143438fd1498Szrj return rval;
143538fd1498Szrj }
143638fd1498Szrj
143738fd1498Szrj skip_bases:
143838fd1498Szrj /* Call the post-order walking function. */
143938fd1498Szrj if (post_fn)
144038fd1498Szrj {
144138fd1498Szrj rval = post_fn (binfo, data);
144238fd1498Szrj gcc_assert (rval != dfs_skip_bases);
144338fd1498Szrj return rval;
144438fd1498Szrj }
144538fd1498Szrj
144638fd1498Szrj return NULL_TREE;
144738fd1498Szrj }
144838fd1498Szrj
144938fd1498Szrj /* Worker for dfs_walk_once. This behaves as dfs_walk_all, except
145038fd1498Szrj that binfos are walked at most once. */
145138fd1498Szrj
145238fd1498Szrj static tree
dfs_walk_once_r(tree binfo,tree (* pre_fn)(tree,void *),tree (* post_fn)(tree,void *),hash_set<tree> * pset,void * data)145338fd1498Szrj dfs_walk_once_r (tree binfo, tree (*pre_fn) (tree, void *),
145438fd1498Szrj tree (*post_fn) (tree, void *), hash_set<tree> *pset,
145538fd1498Szrj void *data)
145638fd1498Szrj {
145738fd1498Szrj tree rval;
145838fd1498Szrj unsigned ix;
145938fd1498Szrj tree base_binfo;
146038fd1498Szrj
146138fd1498Szrj /* Call the pre-order walking function. */
146238fd1498Szrj if (pre_fn)
146338fd1498Szrj {
146438fd1498Szrj rval = pre_fn (binfo, data);
146538fd1498Szrj if (rval)
146638fd1498Szrj {
146738fd1498Szrj if (rval == dfs_skip_bases)
146838fd1498Szrj goto skip_bases;
146938fd1498Szrj
147038fd1498Szrj return rval;
147138fd1498Szrj }
147238fd1498Szrj }
147338fd1498Szrj
147438fd1498Szrj /* Find the next child binfo to walk. */
147538fd1498Szrj for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
147638fd1498Szrj {
147738fd1498Szrj if (BINFO_VIRTUAL_P (base_binfo))
147838fd1498Szrj if (pset->add (base_binfo))
147938fd1498Szrj continue;
148038fd1498Szrj
148138fd1498Szrj rval = dfs_walk_once_r (base_binfo, pre_fn, post_fn, pset, data);
148238fd1498Szrj if (rval)
148338fd1498Szrj return rval;
148438fd1498Szrj }
148538fd1498Szrj
148638fd1498Szrj skip_bases:
148738fd1498Szrj /* Call the post-order walking function. */
148838fd1498Szrj if (post_fn)
148938fd1498Szrj {
149038fd1498Szrj rval = post_fn (binfo, data);
149138fd1498Szrj gcc_assert (rval != dfs_skip_bases);
149238fd1498Szrj return rval;
149338fd1498Szrj }
149438fd1498Szrj
149538fd1498Szrj return NULL_TREE;
149638fd1498Szrj }
149738fd1498Szrj
149838fd1498Szrj /* Like dfs_walk_all, except that binfos are not multiply walked. For
149938fd1498Szrj non-diamond shaped hierarchies this is the same as dfs_walk_all.
150038fd1498Szrj For diamond shaped hierarchies we must mark the virtual bases, to
150138fd1498Szrj avoid multiple walks. */
150238fd1498Szrj
150338fd1498Szrj tree
dfs_walk_once(tree binfo,tree (* pre_fn)(tree,void *),tree (* post_fn)(tree,void *),void * data)150438fd1498Szrj dfs_walk_once (tree binfo, tree (*pre_fn) (tree, void *),
150538fd1498Szrj tree (*post_fn) (tree, void *), void *data)
150638fd1498Szrj {
150738fd1498Szrj static int active = 0; /* We must not be called recursively. */
150838fd1498Szrj tree rval;
150938fd1498Szrj
151038fd1498Szrj gcc_assert (pre_fn || post_fn);
151138fd1498Szrj gcc_assert (!active);
151238fd1498Szrj active++;
151338fd1498Szrj
151438fd1498Szrj if (!CLASSTYPE_DIAMOND_SHAPED_P (BINFO_TYPE (binfo)))
151538fd1498Szrj /* We are not diamond shaped, and therefore cannot encounter the
151638fd1498Szrj same binfo twice. */
151738fd1498Szrj rval = dfs_walk_all (binfo, pre_fn, post_fn, data);
151838fd1498Szrj else
151938fd1498Szrj {
152038fd1498Szrj hash_set<tree> pset;
152138fd1498Szrj rval = dfs_walk_once_r (binfo, pre_fn, post_fn, &pset, data);
152238fd1498Szrj }
152338fd1498Szrj
152438fd1498Szrj active--;
152538fd1498Szrj
152638fd1498Szrj return rval;
152738fd1498Szrj }
152838fd1498Szrj
152938fd1498Szrj /* Worker function for dfs_walk_once_accessible. Behaves like
153038fd1498Szrj dfs_walk_once_r, except (a) FRIENDS_P is true if special
153138fd1498Szrj access given by the current context should be considered, (b) ONCE
153238fd1498Szrj indicates whether bases should be marked during traversal. */
153338fd1498Szrj
153438fd1498Szrj static tree
dfs_walk_once_accessible_r(tree binfo,bool friends_p,hash_set<tree> * pset,tree (* pre_fn)(tree,void *),tree (* post_fn)(tree,void *),void * data)153538fd1498Szrj dfs_walk_once_accessible_r (tree binfo, bool friends_p, hash_set<tree> *pset,
153638fd1498Szrj tree (*pre_fn) (tree, void *),
153738fd1498Szrj tree (*post_fn) (tree, void *), void *data)
153838fd1498Szrj {
153938fd1498Szrj tree rval = NULL_TREE;
154038fd1498Szrj unsigned ix;
154138fd1498Szrj tree base_binfo;
154238fd1498Szrj
154338fd1498Szrj /* Call the pre-order walking function. */
154438fd1498Szrj if (pre_fn)
154538fd1498Szrj {
154638fd1498Szrj rval = pre_fn (binfo, data);
154738fd1498Szrj if (rval)
154838fd1498Szrj {
154938fd1498Szrj if (rval == dfs_skip_bases)
155038fd1498Szrj goto skip_bases;
155138fd1498Szrj
155238fd1498Szrj return rval;
155338fd1498Szrj }
155438fd1498Szrj }
155538fd1498Szrj
155638fd1498Szrj /* Find the next child binfo to walk. */
155738fd1498Szrj for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
155838fd1498Szrj {
155938fd1498Szrj bool mark = pset && BINFO_VIRTUAL_P (base_binfo);
156038fd1498Szrj
156138fd1498Szrj if (mark && pset->contains (base_binfo))
156238fd1498Szrj continue;
156338fd1498Szrj
156438fd1498Szrj /* If the base is inherited via private or protected
156538fd1498Szrj inheritance, then we can't see it, unless we are a friend of
156638fd1498Szrj the current binfo. */
156738fd1498Szrj if (BINFO_BASE_ACCESS (binfo, ix) != access_public_node)
156838fd1498Szrj {
156938fd1498Szrj tree scope;
157038fd1498Szrj if (!friends_p)
157138fd1498Szrj continue;
157238fd1498Szrj scope = current_scope ();
157338fd1498Szrj if (!scope
157438fd1498Szrj || TREE_CODE (scope) == NAMESPACE_DECL
157538fd1498Szrj || !is_friend (BINFO_TYPE (binfo), scope))
157638fd1498Szrj continue;
157738fd1498Szrj }
157838fd1498Szrj
157938fd1498Szrj if (mark)
158038fd1498Szrj pset->add (base_binfo);
158138fd1498Szrj
158238fd1498Szrj rval = dfs_walk_once_accessible_r (base_binfo, friends_p, pset,
158338fd1498Szrj pre_fn, post_fn, data);
158438fd1498Szrj if (rval)
158538fd1498Szrj return rval;
158638fd1498Szrj }
158738fd1498Szrj
158838fd1498Szrj skip_bases:
158938fd1498Szrj /* Call the post-order walking function. */
159038fd1498Szrj if (post_fn)
159138fd1498Szrj {
159238fd1498Szrj rval = post_fn (binfo, data);
159338fd1498Szrj gcc_assert (rval != dfs_skip_bases);
159438fd1498Szrj return rval;
159538fd1498Szrj }
159638fd1498Szrj
159738fd1498Szrj return NULL_TREE;
159838fd1498Szrj }
159938fd1498Szrj
160038fd1498Szrj /* Like dfs_walk_once except that only accessible bases are walked.
160138fd1498Szrj FRIENDS_P indicates whether friendship of the local context
160238fd1498Szrj should be considered when determining accessibility. */
160338fd1498Szrj
160438fd1498Szrj static tree
dfs_walk_once_accessible(tree binfo,bool friends_p,tree (* pre_fn)(tree,void *),tree (* post_fn)(tree,void *),void * data)160538fd1498Szrj dfs_walk_once_accessible (tree binfo, bool friends_p,
160638fd1498Szrj tree (*pre_fn) (tree, void *),
160738fd1498Szrj tree (*post_fn) (tree, void *), void *data)
160838fd1498Szrj {
160938fd1498Szrj hash_set<tree> *pset = NULL;
161038fd1498Szrj if (CLASSTYPE_DIAMOND_SHAPED_P (BINFO_TYPE (binfo)))
161138fd1498Szrj pset = new hash_set<tree>;
161238fd1498Szrj tree rval = dfs_walk_once_accessible_r (binfo, friends_p, pset,
161338fd1498Szrj pre_fn, post_fn, data);
161438fd1498Szrj
161538fd1498Szrj if (pset)
161638fd1498Szrj delete pset;
161738fd1498Szrj return rval;
161838fd1498Szrj }
161938fd1498Szrj
162038fd1498Szrj /* Return true iff the code of T is CODE, and it has compatible
162138fd1498Szrj type with TYPE. */
162238fd1498Szrj
162338fd1498Szrj static bool
matches_code_and_type_p(tree t,enum tree_code code,tree type)162438fd1498Szrj matches_code_and_type_p (tree t, enum tree_code code, tree type)
162538fd1498Szrj {
162638fd1498Szrj if (TREE_CODE (t) != code)
162738fd1498Szrj return false;
162838fd1498Szrj if (!cxx_types_compatible_p (TREE_TYPE (t), type))
162938fd1498Szrj return false;
163038fd1498Szrj return true;
163138fd1498Szrj }
163238fd1498Szrj
163338fd1498Szrj /* Subroutine of direct_accessor_p and reference_accessor_p.
163438fd1498Szrj Determine if COMPONENT_REF is a simple field lookup of this->FIELD_DECL.
163538fd1498Szrj We expect a tree of the form:
163638fd1498Szrj <component_ref:
163738fd1498Szrj <indirect_ref:S>
163838fd1498Szrj <nop_expr:P*
163938fd1498Szrj <parm_decl (this)>
164038fd1498Szrj <field_decl (FIELD_DECL)>>>. */
164138fd1498Szrj
164238fd1498Szrj static bool
field_access_p(tree component_ref,tree field_decl,tree field_type)164338fd1498Szrj field_access_p (tree component_ref, tree field_decl, tree field_type)
164438fd1498Szrj {
164538fd1498Szrj if (!matches_code_and_type_p (component_ref, COMPONENT_REF, field_type))
164638fd1498Szrj return false;
164738fd1498Szrj
164838fd1498Szrj tree indirect_ref = TREE_OPERAND (component_ref, 0);
164938fd1498Szrj if (!INDIRECT_REF_P (indirect_ref))
165038fd1498Szrj return false;
165138fd1498Szrj
165238fd1498Szrj tree ptr = STRIP_NOPS (TREE_OPERAND (indirect_ref, 0));
165338fd1498Szrj if (!is_this_parameter (ptr))
165438fd1498Szrj return false;
165538fd1498Szrj
165638fd1498Szrj /* Must access the correct field. */
165738fd1498Szrj if (TREE_OPERAND (component_ref, 1) != field_decl)
165838fd1498Szrj return false;
165938fd1498Szrj return true;
166038fd1498Szrj }
166138fd1498Szrj
166238fd1498Szrj /* Subroutine of field_accessor_p.
166338fd1498Szrj
166438fd1498Szrj Assuming that INIT_EXPR has already had its code and type checked,
166538fd1498Szrj determine if it is a simple accessor for FIELD_DECL
166638fd1498Szrj (of type FIELD_TYPE).
166738fd1498Szrj
166838fd1498Szrj Specifically, a simple accessor within struct S of the form:
166938fd1498Szrj T get_field () { return m_field; }
167038fd1498Szrj should have a constexpr_fn_retval (saved_tree) of the form:
167138fd1498Szrj <init_expr:T
167238fd1498Szrj <result_decl:T
167338fd1498Szrj <nop_expr:T
167438fd1498Szrj <component_ref:
167538fd1498Szrj <indirect_ref:S>
167638fd1498Szrj <nop_expr:P*
167738fd1498Szrj <parm_decl (this)>
167838fd1498Szrj <field_decl (FIELD_DECL)>>>>>. */
167938fd1498Szrj
168038fd1498Szrj static bool
direct_accessor_p(tree init_expr,tree field_decl,tree field_type)168138fd1498Szrj direct_accessor_p (tree init_expr, tree field_decl, tree field_type)
168238fd1498Szrj {
168338fd1498Szrj tree result_decl = TREE_OPERAND (init_expr, 0);
168438fd1498Szrj if (!matches_code_and_type_p (result_decl, RESULT_DECL, field_type))
168538fd1498Szrj return false;
168638fd1498Szrj
168738fd1498Szrj tree component_ref = STRIP_NOPS (TREE_OPERAND (init_expr, 1));
168838fd1498Szrj if (!field_access_p (component_ref, field_decl, field_type))
168938fd1498Szrj return false;
169038fd1498Szrj
169138fd1498Szrj return true;
169238fd1498Szrj }
169338fd1498Szrj
169438fd1498Szrj /* Subroutine of field_accessor_p.
169538fd1498Szrj
169638fd1498Szrj Assuming that INIT_EXPR has already had its code and type checked,
169738fd1498Szrj determine if it is a "reference" accessor for FIELD_DECL
169838fd1498Szrj (of type FIELD_REFERENCE_TYPE).
169938fd1498Szrj
170038fd1498Szrj Specifically, a simple accessor within struct S of the form:
170138fd1498Szrj T& get_field () { return m_field; }
170238fd1498Szrj should have a constexpr_fn_retval (saved_tree) of the form:
170338fd1498Szrj <init_expr:T&
170438fd1498Szrj <result_decl:T&
170538fd1498Szrj <nop_expr: T&
170638fd1498Szrj <addr_expr: T*
170738fd1498Szrj <component_ref:T
170838fd1498Szrj <indirect_ref:S
170938fd1498Szrj <nop_expr
171038fd1498Szrj <parm_decl (this)>>
171138fd1498Szrj <field (FIELD_DECL)>>>>>>. */
171238fd1498Szrj static bool
reference_accessor_p(tree init_expr,tree field_decl,tree field_type,tree field_reference_type)171338fd1498Szrj reference_accessor_p (tree init_expr, tree field_decl, tree field_type,
171438fd1498Szrj tree field_reference_type)
171538fd1498Szrj {
171638fd1498Szrj tree result_decl = TREE_OPERAND (init_expr, 0);
171738fd1498Szrj if (!matches_code_and_type_p (result_decl, RESULT_DECL, field_reference_type))
171838fd1498Szrj return false;
171938fd1498Szrj
172038fd1498Szrj tree field_pointer_type = build_pointer_type (field_type);
172138fd1498Szrj tree addr_expr = STRIP_NOPS (TREE_OPERAND (init_expr, 1));
172238fd1498Szrj if (!matches_code_and_type_p (addr_expr, ADDR_EXPR, field_pointer_type))
172338fd1498Szrj return false;
172438fd1498Szrj
172538fd1498Szrj tree component_ref = STRIP_NOPS (TREE_OPERAND (addr_expr, 0));
172638fd1498Szrj
172738fd1498Szrj if (!field_access_p (component_ref, field_decl, field_type))
172838fd1498Szrj return false;
172938fd1498Szrj
173038fd1498Szrj return true;
173138fd1498Szrj }
173238fd1498Szrj
173338fd1498Szrj /* Return true if FN is an accessor method for FIELD_DECL.
173438fd1498Szrj i.e. a method of the form { return FIELD; }, with no
173538fd1498Szrj conversions.
173638fd1498Szrj
173738fd1498Szrj If CONST_P, then additionally require that FN be a const
173838fd1498Szrj method. */
173938fd1498Szrj
174038fd1498Szrj static bool
field_accessor_p(tree fn,tree field_decl,bool const_p)174138fd1498Szrj field_accessor_p (tree fn, tree field_decl, bool const_p)
174238fd1498Szrj {
174338fd1498Szrj if (TREE_CODE (fn) != FUNCTION_DECL)
174438fd1498Szrj return false;
174538fd1498Szrj
174638fd1498Szrj /* We don't yet support looking up static data, just fields. */
174738fd1498Szrj if (TREE_CODE (field_decl) != FIELD_DECL)
174838fd1498Szrj return false;
174938fd1498Szrj
175038fd1498Szrj tree fntype = TREE_TYPE (fn);
175138fd1498Szrj if (TREE_CODE (fntype) != METHOD_TYPE)
175238fd1498Szrj return false;
175338fd1498Szrj
175438fd1498Szrj /* If the field is accessed via a const "this" argument, verify
175538fd1498Szrj that the "this" parameter is const. */
175638fd1498Szrj if (const_p)
175738fd1498Szrj {
175838fd1498Szrj tree this_class = class_of_this_parm (fntype);
175938fd1498Szrj if (!TYPE_READONLY (this_class))
176038fd1498Szrj return false;
176138fd1498Szrj }
176238fd1498Szrj
176338fd1498Szrj tree saved_tree = DECL_SAVED_TREE (fn);
176438fd1498Szrj
176538fd1498Szrj if (saved_tree == NULL_TREE)
176638fd1498Szrj return false;
176738fd1498Szrj
176838fd1498Szrj /* Attempt to extract a single return value from the function,
176938fd1498Szrj if it has one. */
177038fd1498Szrj tree retval = constexpr_fn_retval (saved_tree);
177138fd1498Szrj if (retval == NULL_TREE || retval == error_mark_node)
177238fd1498Szrj return false;
177338fd1498Szrj /* Require an INIT_EXPR. */
177438fd1498Szrj if (TREE_CODE (retval) != INIT_EXPR)
177538fd1498Szrj return false;
177638fd1498Szrj tree init_expr = retval;
177738fd1498Szrj
177838fd1498Szrj /* Determine if this is a simple accessor within struct S of the form:
177938fd1498Szrj T get_field () { return m_field; }. */
178038fd1498Szrj tree field_type = TREE_TYPE (field_decl);
178138fd1498Szrj if (cxx_types_compatible_p (TREE_TYPE (init_expr), field_type))
178238fd1498Szrj return direct_accessor_p (init_expr, field_decl, field_type);
178338fd1498Szrj
178438fd1498Szrj /* Failing that, determine if it is an accessor of the form:
178538fd1498Szrj T& get_field () { return m_field; }. */
178638fd1498Szrj tree field_reference_type = cp_build_reference_type (field_type, false);
178738fd1498Szrj if (cxx_types_compatible_p (TREE_TYPE (init_expr), field_reference_type))
178838fd1498Szrj return reference_accessor_p (init_expr, field_decl, field_type,
178938fd1498Szrj field_reference_type);
179038fd1498Szrj
179138fd1498Szrj return false;
179238fd1498Szrj }
179338fd1498Szrj
179438fd1498Szrj /* Callback data for dfs_locate_field_accessor_pre. */
179538fd1498Szrj
179638fd1498Szrj struct locate_field_data
179738fd1498Szrj {
locate_field_datalocate_field_data179838fd1498Szrj locate_field_data (tree field_decl_, bool const_p_)
179938fd1498Szrj : field_decl (field_decl_), const_p (const_p_) {}
180038fd1498Szrj
180138fd1498Szrj tree field_decl;
180238fd1498Szrj bool const_p;
180338fd1498Szrj };
180438fd1498Szrj
180538fd1498Szrj /* Return a FUNCTION_DECL that is an "accessor" method for DATA, a FIELD_DECL,
180638fd1498Szrj callable via binfo, if one exists, otherwise return NULL_TREE.
180738fd1498Szrj
180838fd1498Szrj Callback for dfs_walk_once_accessible for use within
180938fd1498Szrj locate_field_accessor. */
181038fd1498Szrj
181138fd1498Szrj static tree
dfs_locate_field_accessor_pre(tree binfo,void * data)181238fd1498Szrj dfs_locate_field_accessor_pre (tree binfo, void *data)
181338fd1498Szrj {
181438fd1498Szrj locate_field_data *lfd = (locate_field_data *)data;
181538fd1498Szrj tree type = BINFO_TYPE (binfo);
181638fd1498Szrj
181738fd1498Szrj vec<tree, va_gc> *member_vec;
181838fd1498Szrj tree fn;
181938fd1498Szrj size_t i;
182038fd1498Szrj
182138fd1498Szrj if (!CLASS_TYPE_P (type))
182238fd1498Szrj return NULL_TREE;
182338fd1498Szrj
182438fd1498Szrj member_vec = CLASSTYPE_MEMBER_VEC (type);
182538fd1498Szrj if (!member_vec)
182638fd1498Szrj return NULL_TREE;
182738fd1498Szrj
182838fd1498Szrj for (i = 0; vec_safe_iterate (member_vec, i, &fn); ++i)
182938fd1498Szrj if (fn)
183038fd1498Szrj if (field_accessor_p (fn, lfd->field_decl, lfd->const_p))
183138fd1498Szrj return fn;
183238fd1498Szrj
183338fd1498Szrj return NULL_TREE;
183438fd1498Szrj }
183538fd1498Szrj
183638fd1498Szrj /* Return a FUNCTION_DECL that is an "accessor" method for FIELD_DECL,
183738fd1498Szrj callable via BASETYPE_PATH, if one exists, otherwise return NULL_TREE. */
183838fd1498Szrj
183938fd1498Szrj tree
locate_field_accessor(tree basetype_path,tree field_decl,bool const_p)184038fd1498Szrj locate_field_accessor (tree basetype_path, tree field_decl, bool const_p)
184138fd1498Szrj {
184238fd1498Szrj if (TREE_CODE (basetype_path) != TREE_BINFO)
184338fd1498Szrj return NULL_TREE;
184438fd1498Szrj
184538fd1498Szrj /* Walk the hierarchy, looking for a method of some base class that allows
184638fd1498Szrj access to the field. */
184738fd1498Szrj locate_field_data lfd (field_decl, const_p);
184838fd1498Szrj return dfs_walk_once_accessible (basetype_path, /*friends=*/true,
184938fd1498Szrj dfs_locate_field_accessor_pre,
185038fd1498Szrj NULL, &lfd);
185138fd1498Szrj }
185238fd1498Szrj
185338fd1498Szrj /* Check that virtual overrider OVERRIDER is acceptable for base function
185438fd1498Szrj BASEFN. Issue diagnostic, and return zero, if unacceptable. */
185538fd1498Szrj
185638fd1498Szrj static int
check_final_overrider(tree overrider,tree basefn)185738fd1498Szrj check_final_overrider (tree overrider, tree basefn)
185838fd1498Szrj {
185938fd1498Szrj tree over_type = TREE_TYPE (overrider);
186038fd1498Szrj tree base_type = TREE_TYPE (basefn);
186138fd1498Szrj tree over_return = fndecl_declared_return_type (overrider);
186238fd1498Szrj tree base_return = fndecl_declared_return_type (basefn);
186338fd1498Szrj tree over_throw, base_throw;
186438fd1498Szrj
186538fd1498Szrj int fail = 0;
186638fd1498Szrj
186738fd1498Szrj if (DECL_INVALID_OVERRIDER_P (overrider))
186838fd1498Szrj return 0;
186938fd1498Szrj
187038fd1498Szrj if (same_type_p (base_return, over_return))
187138fd1498Szrj /* OK */;
187238fd1498Szrj else if ((CLASS_TYPE_P (over_return) && CLASS_TYPE_P (base_return))
187338fd1498Szrj || (TREE_CODE (base_return) == TREE_CODE (over_return)
187438fd1498Szrj && POINTER_TYPE_P (base_return)))
187538fd1498Szrj {
187638fd1498Szrj /* Potentially covariant. */
187738fd1498Szrj unsigned base_quals, over_quals;
187838fd1498Szrj
187938fd1498Szrj fail = !POINTER_TYPE_P (base_return);
188038fd1498Szrj if (!fail)
188138fd1498Szrj {
188238fd1498Szrj fail = cp_type_quals (base_return) != cp_type_quals (over_return);
188338fd1498Szrj
188438fd1498Szrj base_return = TREE_TYPE (base_return);
188538fd1498Szrj over_return = TREE_TYPE (over_return);
188638fd1498Szrj }
188738fd1498Szrj base_quals = cp_type_quals (base_return);
188838fd1498Szrj over_quals = cp_type_quals (over_return);
188938fd1498Szrj
189038fd1498Szrj if ((base_quals & over_quals) != over_quals)
189138fd1498Szrj fail = 1;
189238fd1498Szrj
189338fd1498Szrj if (CLASS_TYPE_P (base_return) && CLASS_TYPE_P (over_return))
189438fd1498Szrj {
189538fd1498Szrj /* Strictly speaking, the standard requires the return type to be
189638fd1498Szrj complete even if it only differs in cv-quals, but that seems
189738fd1498Szrj like a bug in the wording. */
189838fd1498Szrj if (!same_type_ignoring_top_level_qualifiers_p (base_return,
189938fd1498Szrj over_return))
190038fd1498Szrj {
190138fd1498Szrj tree binfo = lookup_base (over_return, base_return,
190238fd1498Szrj ba_check, NULL, tf_none);
190338fd1498Szrj
190438fd1498Szrj if (!binfo || binfo == error_mark_node)
190538fd1498Szrj fail = 1;
190638fd1498Szrj }
190738fd1498Szrj }
190838fd1498Szrj else if (can_convert_standard (TREE_TYPE (base_type),
190938fd1498Szrj TREE_TYPE (over_type),
191038fd1498Szrj tf_warning_or_error))
191138fd1498Szrj /* GNU extension, allow trivial pointer conversions such as
191238fd1498Szrj converting to void *, or qualification conversion. */
191338fd1498Szrj {
191438fd1498Szrj if (pedwarn (DECL_SOURCE_LOCATION (overrider), 0,
191538fd1498Szrj "invalid covariant return type for %q#D", overrider))
191638fd1498Szrj inform (DECL_SOURCE_LOCATION (basefn),
191738fd1498Szrj "overridden function is %q#D", basefn);
191838fd1498Szrj }
191938fd1498Szrj else
192038fd1498Szrj fail = 2;
192138fd1498Szrj }
192238fd1498Szrj else
192338fd1498Szrj fail = 2;
192438fd1498Szrj if (!fail)
192538fd1498Szrj /* OK */;
192638fd1498Szrj else
192738fd1498Szrj {
192838fd1498Szrj if (fail == 1)
192938fd1498Szrj {
193038fd1498Szrj error ("invalid covariant return type for %q+#D", overrider);
193138fd1498Szrj inform (DECL_SOURCE_LOCATION (basefn),
193238fd1498Szrj "overridden function is %q#D", basefn);
193338fd1498Szrj }
193438fd1498Szrj else
193538fd1498Szrj {
193638fd1498Szrj error ("conflicting return type specified for %q+#D", overrider);
193738fd1498Szrj inform (DECL_SOURCE_LOCATION (basefn),
193838fd1498Szrj "overridden function is %q#D", basefn);
193938fd1498Szrj }
194038fd1498Szrj DECL_INVALID_OVERRIDER_P (overrider) = 1;
194138fd1498Szrj return 0;
194238fd1498Szrj }
194338fd1498Szrj
194438fd1498Szrj /* Check throw specifier is at least as strict. */
194538fd1498Szrj maybe_instantiate_noexcept (basefn);
194638fd1498Szrj maybe_instantiate_noexcept (overrider);
194738fd1498Szrj base_throw = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (basefn));
194838fd1498Szrj over_throw = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (overrider));
194938fd1498Szrj
195038fd1498Szrj if (!comp_except_specs (base_throw, over_throw, ce_derived))
195138fd1498Szrj {
195238fd1498Szrj error ("looser throw specifier for %q+#F", overrider);
195338fd1498Szrj inform (DECL_SOURCE_LOCATION (basefn),
195438fd1498Szrj "overridden function is %q#F", basefn);
195538fd1498Szrj DECL_INVALID_OVERRIDER_P (overrider) = 1;
195638fd1498Szrj return 0;
195738fd1498Szrj }
195838fd1498Szrj
195938fd1498Szrj /* Check for conflicting type attributes. But leave transaction_safe for
196038fd1498Szrj set_one_vmethod_tm_attributes. */
196138fd1498Szrj if (!comp_type_attributes (over_type, base_type)
196238fd1498Szrj && !tx_safe_fn_type_p (base_type)
196338fd1498Szrj && !tx_safe_fn_type_p (over_type))
196438fd1498Szrj {
196538fd1498Szrj error ("conflicting type attributes specified for %q+#D", overrider);
196638fd1498Szrj inform (DECL_SOURCE_LOCATION (basefn),
196738fd1498Szrj "overridden function is %q#D", basefn);
196838fd1498Szrj DECL_INVALID_OVERRIDER_P (overrider) = 1;
196938fd1498Szrj return 0;
197038fd1498Szrj }
197138fd1498Szrj
197238fd1498Szrj /* A function declared transaction_safe_dynamic that overrides a function
197338fd1498Szrj declared transaction_safe (but not transaction_safe_dynamic) is
197438fd1498Szrj ill-formed. */
197538fd1498Szrj if (tx_safe_fn_type_p (base_type)
197638fd1498Szrj && lookup_attribute ("transaction_safe_dynamic",
197738fd1498Szrj DECL_ATTRIBUTES (overrider))
197838fd1498Szrj && !lookup_attribute ("transaction_safe_dynamic",
197938fd1498Szrj DECL_ATTRIBUTES (basefn)))
198038fd1498Szrj {
198138fd1498Szrj error_at (DECL_SOURCE_LOCATION (overrider),
198238fd1498Szrj "%qD declared %<transaction_safe_dynamic%>", overrider);
198338fd1498Szrj inform (DECL_SOURCE_LOCATION (basefn),
198438fd1498Szrj "overriding %qD declared %<transaction_safe%>", basefn);
198538fd1498Szrj }
198638fd1498Szrj
198738fd1498Szrj if (DECL_DELETED_FN (basefn) != DECL_DELETED_FN (overrider))
198838fd1498Szrj {
198938fd1498Szrj if (DECL_DELETED_FN (overrider))
199038fd1498Szrj {
199138fd1498Szrj error ("deleted function %q+D overriding non-deleted function",
199238fd1498Szrj overrider);
199338fd1498Szrj inform (DECL_SOURCE_LOCATION (basefn),
199438fd1498Szrj "overridden function is %qD", basefn);
199538fd1498Szrj maybe_explain_implicit_delete (overrider);
199638fd1498Szrj }
199738fd1498Szrj else
199838fd1498Szrj {
199938fd1498Szrj error ("non-deleted function %q+D overriding deleted function",
200038fd1498Szrj overrider);
200138fd1498Szrj inform (DECL_SOURCE_LOCATION (basefn),
200238fd1498Szrj "overridden function is %qD", basefn);
200338fd1498Szrj }
200438fd1498Szrj return 0;
200538fd1498Szrj }
200638fd1498Szrj if (DECL_FINAL_P (basefn))
200738fd1498Szrj {
200838fd1498Szrj error ("virtual function %q+D overriding final function", overrider);
200938fd1498Szrj inform (DECL_SOURCE_LOCATION (basefn),
201038fd1498Szrj "overridden function is %qD", basefn);
201138fd1498Szrj return 0;
201238fd1498Szrj }
201338fd1498Szrj return 1;
201438fd1498Szrj }
201538fd1498Szrj
201638fd1498Szrj /* Given a class TYPE, and a function decl FNDECL, look for
201738fd1498Szrj virtual functions in TYPE's hierarchy which FNDECL overrides.
201838fd1498Szrj We do not look in TYPE itself, only its bases.
201938fd1498Szrj
202038fd1498Szrj Returns nonzero, if we find any. Set FNDECL's DECL_VIRTUAL_P, if we
202138fd1498Szrj find that it overrides anything.
202238fd1498Szrj
202338fd1498Szrj We check that every function which is overridden, is correctly
202438fd1498Szrj overridden. */
202538fd1498Szrj
202638fd1498Szrj int
look_for_overrides(tree type,tree fndecl)202738fd1498Szrj look_for_overrides (tree type, tree fndecl)
202838fd1498Szrj {
202938fd1498Szrj tree binfo = TYPE_BINFO (type);
203038fd1498Szrj tree base_binfo;
203138fd1498Szrj int ix;
203238fd1498Szrj int found = 0;
203338fd1498Szrj
203438fd1498Szrj /* A constructor for a class T does not override a function T
203538fd1498Szrj in a base class. */
203638fd1498Szrj if (DECL_CONSTRUCTOR_P (fndecl))
203738fd1498Szrj return 0;
203838fd1498Szrj
203938fd1498Szrj for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
204038fd1498Szrj {
204138fd1498Szrj tree basetype = BINFO_TYPE (base_binfo);
204238fd1498Szrj
204338fd1498Szrj if (TYPE_POLYMORPHIC_P (basetype))
204438fd1498Szrj found += look_for_overrides_r (basetype, fndecl);
204538fd1498Szrj }
204638fd1498Szrj return found;
204738fd1498Szrj }
204838fd1498Szrj
204938fd1498Szrj /* Look in TYPE for virtual functions with the same signature as
205038fd1498Szrj FNDECL. */
205138fd1498Szrj
205238fd1498Szrj tree
look_for_overrides_here(tree type,tree fndecl)205338fd1498Szrj look_for_overrides_here (tree type, tree fndecl)
205438fd1498Szrj {
205538fd1498Szrj tree ovl = get_class_binding (type, DECL_NAME (fndecl));
205638fd1498Szrj
205738fd1498Szrj for (ovl_iterator iter (ovl); iter; ++iter)
205838fd1498Szrj {
205938fd1498Szrj tree fn = *iter;
206038fd1498Szrj
206138fd1498Szrj if (!DECL_VIRTUAL_P (fn))
206238fd1498Szrj /* Not a virtual. */;
206338fd1498Szrj else if (DECL_CONTEXT (fn) != type)
206438fd1498Szrj /* Introduced with a using declaration. */;
206538fd1498Szrj else if (DECL_STATIC_FUNCTION_P (fndecl))
206638fd1498Szrj {
206738fd1498Szrj tree btypes = TYPE_ARG_TYPES (TREE_TYPE (fn));
206838fd1498Szrj tree dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
206938fd1498Szrj if (compparms (TREE_CHAIN (btypes), dtypes))
207038fd1498Szrj return fn;
207138fd1498Szrj }
207238fd1498Szrj else if (same_signature_p (fndecl, fn))
207338fd1498Szrj return fn;
207438fd1498Szrj }
207538fd1498Szrj
207638fd1498Szrj return NULL_TREE;
207738fd1498Szrj }
207838fd1498Szrj
207938fd1498Szrj /* Look in TYPE for virtual functions overridden by FNDECL. Check both
208038fd1498Szrj TYPE itself and its bases. */
208138fd1498Szrj
208238fd1498Szrj static int
look_for_overrides_r(tree type,tree fndecl)208338fd1498Szrj look_for_overrides_r (tree type, tree fndecl)
208438fd1498Szrj {
208538fd1498Szrj tree fn = look_for_overrides_here (type, fndecl);
208638fd1498Szrj if (fn)
208738fd1498Szrj {
208838fd1498Szrj if (DECL_STATIC_FUNCTION_P (fndecl))
208938fd1498Szrj {
209038fd1498Szrj /* A static member function cannot match an inherited
209138fd1498Szrj virtual member function. */
209238fd1498Szrj error ("%q+#D cannot be declared", fndecl);
209338fd1498Szrj error (" since %q+#D declared in base class", fn);
209438fd1498Szrj }
209538fd1498Szrj else
209638fd1498Szrj {
209738fd1498Szrj /* It's definitely virtual, even if not explicitly set. */
209838fd1498Szrj DECL_VIRTUAL_P (fndecl) = 1;
209938fd1498Szrj check_final_overrider (fndecl, fn);
210038fd1498Szrj }
210138fd1498Szrj return 1;
210238fd1498Szrj }
210338fd1498Szrj
210438fd1498Szrj /* We failed to find one declared in this class. Look in its bases. */
210538fd1498Szrj return look_for_overrides (type, fndecl);
210638fd1498Szrj }
210738fd1498Szrj
210838fd1498Szrj /* Called via dfs_walk from dfs_get_pure_virtuals. */
210938fd1498Szrj
211038fd1498Szrj static tree
dfs_get_pure_virtuals(tree binfo,void * data)211138fd1498Szrj dfs_get_pure_virtuals (tree binfo, void *data)
211238fd1498Szrj {
211338fd1498Szrj tree type = (tree) data;
211438fd1498Szrj
211538fd1498Szrj /* We're not interested in primary base classes; the derived class
211638fd1498Szrj of which they are a primary base will contain the information we
211738fd1498Szrj need. */
211838fd1498Szrj if (!BINFO_PRIMARY_P (binfo))
211938fd1498Szrj {
212038fd1498Szrj tree virtuals;
212138fd1498Szrj
212238fd1498Szrj for (virtuals = BINFO_VIRTUALS (binfo);
212338fd1498Szrj virtuals;
212438fd1498Szrj virtuals = TREE_CHAIN (virtuals))
212538fd1498Szrj if (DECL_PURE_VIRTUAL_P (BV_FN (virtuals)))
212638fd1498Szrj vec_safe_push (CLASSTYPE_PURE_VIRTUALS (type), BV_FN (virtuals));
212738fd1498Szrj }
212838fd1498Szrj
212938fd1498Szrj return NULL_TREE;
213038fd1498Szrj }
213138fd1498Szrj
213238fd1498Szrj /* Set CLASSTYPE_PURE_VIRTUALS for TYPE. */
213338fd1498Szrj
213438fd1498Szrj void
get_pure_virtuals(tree type)213538fd1498Szrj get_pure_virtuals (tree type)
213638fd1498Szrj {
213738fd1498Szrj /* Clear the CLASSTYPE_PURE_VIRTUALS list; whatever is already there
213838fd1498Szrj is going to be overridden. */
213938fd1498Szrj CLASSTYPE_PURE_VIRTUALS (type) = NULL;
214038fd1498Szrj /* Now, run through all the bases which are not primary bases, and
214138fd1498Szrj collect the pure virtual functions. We look at the vtable in
214238fd1498Szrj each class to determine what pure virtual functions are present.
214338fd1498Szrj (A primary base is not interesting because the derived class of
214438fd1498Szrj which it is a primary base will contain vtable entries for the
214538fd1498Szrj pure virtuals in the base class. */
214638fd1498Szrj dfs_walk_once (TYPE_BINFO (type), NULL, dfs_get_pure_virtuals, type);
214738fd1498Szrj }
214838fd1498Szrj
214938fd1498Szrj /* Debug info for C++ classes can get very large; try to avoid
215038fd1498Szrj emitting it everywhere.
215138fd1498Szrj
215238fd1498Szrj Note that this optimization wins even when the target supports
215338fd1498Szrj BINCL (if only slightly), and reduces the amount of work for the
215438fd1498Szrj linker. */
215538fd1498Szrj
215638fd1498Szrj void
maybe_suppress_debug_info(tree t)215738fd1498Szrj maybe_suppress_debug_info (tree t)
215838fd1498Szrj {
215938fd1498Szrj if (write_symbols == NO_DEBUG)
216038fd1498Szrj return;
216138fd1498Szrj
216238fd1498Szrj /* We might have set this earlier in cp_finish_decl. */
216338fd1498Szrj TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 0;
216438fd1498Szrj
216538fd1498Szrj /* Always emit the information for each class every time. */
216638fd1498Szrj if (flag_emit_class_debug_always)
216738fd1498Szrj return;
216838fd1498Szrj
216938fd1498Szrj /* If we already know how we're handling this class, handle debug info
217038fd1498Szrj the same way. */
217138fd1498Szrj if (CLASSTYPE_INTERFACE_KNOWN (t))
217238fd1498Szrj {
217338fd1498Szrj if (CLASSTYPE_INTERFACE_ONLY (t))
217438fd1498Szrj TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
217538fd1498Szrj /* else don't set it. */
217638fd1498Szrj }
217738fd1498Szrj /* If the class has a vtable, write out the debug info along with
217838fd1498Szrj the vtable. */
217938fd1498Szrj else if (TYPE_CONTAINS_VPTR_P (t))
218038fd1498Szrj TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1;
218138fd1498Szrj
218238fd1498Szrj /* Otherwise, just emit the debug info normally. */
218338fd1498Szrj }
218438fd1498Szrj
218538fd1498Szrj /* Note that we want debugging information for a base class of a class
218638fd1498Szrj whose vtable is being emitted. Normally, this would happen because
218738fd1498Szrj calling the constructor for a derived class implies calling the
218838fd1498Szrj constructors for all bases, which involve initializing the
218938fd1498Szrj appropriate vptr with the vtable for the base class; but in the
219038fd1498Szrj presence of optimization, this initialization may be optimized
219138fd1498Szrj away, so we tell finish_vtable_vardecl that we want the debugging
219238fd1498Szrj information anyway. */
219338fd1498Szrj
219438fd1498Szrj static tree
dfs_debug_mark(tree binfo,void *)219538fd1498Szrj dfs_debug_mark (tree binfo, void * /*data*/)
219638fd1498Szrj {
219738fd1498Szrj tree t = BINFO_TYPE (binfo);
219838fd1498Szrj
219938fd1498Szrj if (CLASSTYPE_DEBUG_REQUESTED (t))
220038fd1498Szrj return dfs_skip_bases;
220138fd1498Szrj
220238fd1498Szrj CLASSTYPE_DEBUG_REQUESTED (t) = 1;
220338fd1498Szrj
220438fd1498Szrj return NULL_TREE;
220538fd1498Szrj }
220638fd1498Szrj
220738fd1498Szrj /* Write out the debugging information for TYPE, whose vtable is being
220838fd1498Szrj emitted. Also walk through our bases and note that we want to
220938fd1498Szrj write out information for them. This avoids the problem of not
221038fd1498Szrj writing any debug info for intermediate basetypes whose
221138fd1498Szrj constructors, and thus the references to their vtables, and thus
221238fd1498Szrj the vtables themselves, were optimized away. */
221338fd1498Szrj
221438fd1498Szrj void
note_debug_info_needed(tree type)221538fd1498Szrj note_debug_info_needed (tree type)
221638fd1498Szrj {
221738fd1498Szrj if (TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (type)))
221838fd1498Szrj {
221938fd1498Szrj TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (type)) = 0;
222038fd1498Szrj rest_of_type_compilation (type, namespace_bindings_p ());
222138fd1498Szrj }
222238fd1498Szrj
222338fd1498Szrj dfs_walk_all (TYPE_BINFO (type), dfs_debug_mark, NULL, 0);
222438fd1498Szrj }
222538fd1498Szrj
222638fd1498Szrj /* Helper for lookup_conversions_r. TO_TYPE is the type converted to
222738fd1498Szrj by a conversion op in base BINFO. VIRTUAL_DEPTH is nonzero if
222838fd1498Szrj BINFO is morally virtual, and VIRTUALNESS is nonzero if virtual
222938fd1498Szrj bases have been encountered already in the tree walk. PARENT_CONVS
223038fd1498Szrj is the list of lists of conversion functions that could hide CONV
223138fd1498Szrj and OTHER_CONVS is the list of lists of conversion functions that
223238fd1498Szrj could hide or be hidden by CONV, should virtualness be involved in
223338fd1498Szrj the hierarchy. Merely checking the conversion op's name is not
223438fd1498Szrj enough because two conversion operators to the same type can have
223538fd1498Szrj different names. Return nonzero if we are visible. */
223638fd1498Szrj
223738fd1498Szrj static int
check_hidden_convs(tree binfo,int virtual_depth,int virtualness,tree to_type,tree parent_convs,tree other_convs)223838fd1498Szrj check_hidden_convs (tree binfo, int virtual_depth, int virtualness,
223938fd1498Szrj tree to_type, tree parent_convs, tree other_convs)
224038fd1498Szrj {
224138fd1498Szrj tree level, probe;
224238fd1498Szrj
224338fd1498Szrj /* See if we are hidden by a parent conversion. */
224438fd1498Szrj for (level = parent_convs; level; level = TREE_CHAIN (level))
224538fd1498Szrj for (probe = TREE_VALUE (level); probe; probe = TREE_CHAIN (probe))
224638fd1498Szrj if (same_type_p (to_type, TREE_TYPE (probe)))
224738fd1498Szrj return 0;
224838fd1498Szrj
224938fd1498Szrj if (virtual_depth || virtualness)
225038fd1498Szrj {
225138fd1498Szrj /* In a virtual hierarchy, we could be hidden, or could hide a
225238fd1498Szrj conversion function on the other_convs list. */
225338fd1498Szrj for (level = other_convs; level; level = TREE_CHAIN (level))
225438fd1498Szrj {
225538fd1498Szrj int we_hide_them;
225638fd1498Szrj int they_hide_us;
225738fd1498Szrj tree *prev, other;
225838fd1498Szrj
225938fd1498Szrj if (!(virtual_depth || TREE_STATIC (level)))
226038fd1498Szrj /* Neither is morally virtual, so cannot hide each other. */
226138fd1498Szrj continue;
226238fd1498Szrj
226338fd1498Szrj if (!TREE_VALUE (level))
226438fd1498Szrj /* They evaporated away already. */
226538fd1498Szrj continue;
226638fd1498Szrj
226738fd1498Szrj they_hide_us = (virtual_depth
226838fd1498Szrj && original_binfo (binfo, TREE_PURPOSE (level)));
226938fd1498Szrj we_hide_them = (!they_hide_us && TREE_STATIC (level)
227038fd1498Szrj && original_binfo (TREE_PURPOSE (level), binfo));
227138fd1498Szrj
227238fd1498Szrj if (!(we_hide_them || they_hide_us))
227338fd1498Szrj /* Neither is within the other, so no hiding can occur. */
227438fd1498Szrj continue;
227538fd1498Szrj
227638fd1498Szrj for (prev = &TREE_VALUE (level), other = *prev; other;)
227738fd1498Szrj {
227838fd1498Szrj if (same_type_p (to_type, TREE_TYPE (other)))
227938fd1498Szrj {
228038fd1498Szrj if (they_hide_us)
228138fd1498Szrj /* We are hidden. */
228238fd1498Szrj return 0;
228338fd1498Szrj
228438fd1498Szrj if (we_hide_them)
228538fd1498Szrj {
228638fd1498Szrj /* We hide the other one. */
228738fd1498Szrj other = TREE_CHAIN (other);
228838fd1498Szrj *prev = other;
228938fd1498Szrj continue;
229038fd1498Szrj }
229138fd1498Szrj }
229238fd1498Szrj prev = &TREE_CHAIN (other);
229338fd1498Szrj other = *prev;
229438fd1498Szrj }
229538fd1498Szrj }
229638fd1498Szrj }
229738fd1498Szrj return 1;
229838fd1498Szrj }
229938fd1498Szrj
230038fd1498Szrj /* Helper for lookup_conversions_r. PARENT_CONVS is a list of lists
230138fd1498Szrj of conversion functions, the first slot will be for the current
230238fd1498Szrj binfo, if MY_CONVS is non-NULL. CHILD_CONVS is the list of lists
230338fd1498Szrj of conversion functions from children of the current binfo,
230438fd1498Szrj concatenated with conversions from elsewhere in the hierarchy --
230538fd1498Szrj that list begins with OTHER_CONVS. Return a single list of lists
230638fd1498Szrj containing only conversions from the current binfo and its
230738fd1498Szrj children. */
230838fd1498Szrj
230938fd1498Szrj static tree
split_conversions(tree my_convs,tree parent_convs,tree child_convs,tree other_convs)231038fd1498Szrj split_conversions (tree my_convs, tree parent_convs,
231138fd1498Szrj tree child_convs, tree other_convs)
231238fd1498Szrj {
231338fd1498Szrj tree t;
231438fd1498Szrj tree prev;
231538fd1498Szrj
231638fd1498Szrj /* Remove the original other_convs portion from child_convs. */
231738fd1498Szrj for (prev = NULL, t = child_convs;
231838fd1498Szrj t != other_convs; prev = t, t = TREE_CHAIN (t))
231938fd1498Szrj continue;
232038fd1498Szrj
232138fd1498Szrj if (prev)
232238fd1498Szrj TREE_CHAIN (prev) = NULL_TREE;
232338fd1498Szrj else
232438fd1498Szrj child_convs = NULL_TREE;
232538fd1498Szrj
232638fd1498Szrj /* Attach the child convs to any we had at this level. */
232738fd1498Szrj if (my_convs)
232838fd1498Szrj {
232938fd1498Szrj my_convs = parent_convs;
233038fd1498Szrj TREE_CHAIN (my_convs) = child_convs;
233138fd1498Szrj }
233238fd1498Szrj else
233338fd1498Szrj my_convs = child_convs;
233438fd1498Szrj
233538fd1498Szrj return my_convs;
233638fd1498Szrj }
233738fd1498Szrj
233838fd1498Szrj /* Worker for lookup_conversions. Lookup conversion functions in
233938fd1498Szrj BINFO and its children. VIRTUAL_DEPTH is nonzero, if BINFO is in a
234038fd1498Szrj morally virtual base, and VIRTUALNESS is nonzero, if we've
234138fd1498Szrj encountered virtual bases already in the tree walk. PARENT_CONVS
234238fd1498Szrj is a list of conversions within parent binfos. OTHER_CONVS are
234338fd1498Szrj conversions found elsewhere in the tree. Return the conversions
234438fd1498Szrj found within this portion of the graph in CONVS. Return nonzero if
234538fd1498Szrj we encountered virtualness. We keep template and non-template
234638fd1498Szrj conversions separate, to avoid unnecessary type comparisons.
234738fd1498Szrj
234838fd1498Szrj The located conversion functions are held in lists of lists. The
234938fd1498Szrj TREE_VALUE of the outer list is the list of conversion functions
235038fd1498Szrj found in a particular binfo. The TREE_PURPOSE of both the outer
235138fd1498Szrj and inner lists is the binfo at which those conversions were
235238fd1498Szrj found. TREE_STATIC is set for those lists within of morally
235338fd1498Szrj virtual binfos. The TREE_VALUE of the inner list is the conversion
235438fd1498Szrj function or overload itself. The TREE_TYPE of each inner list node
235538fd1498Szrj is the converted-to type. */
235638fd1498Szrj
235738fd1498Szrj static int
lookup_conversions_r(tree binfo,int virtual_depth,int virtualness,tree parent_convs,tree other_convs,tree * convs)235838fd1498Szrj lookup_conversions_r (tree binfo, int virtual_depth, int virtualness,
235938fd1498Szrj tree parent_convs, tree other_convs, tree *convs)
236038fd1498Szrj {
236138fd1498Szrj int my_virtualness = 0;
236238fd1498Szrj tree my_convs = NULL_TREE;
236338fd1498Szrj tree child_convs = NULL_TREE;
236438fd1498Szrj
236538fd1498Szrj /* If we have no conversion operators, then don't look. */
236638fd1498Szrj if (!TYPE_HAS_CONVERSION (BINFO_TYPE (binfo)))
236738fd1498Szrj {
236838fd1498Szrj *convs = NULL_TREE;
236938fd1498Szrj
237038fd1498Szrj return 0;
237138fd1498Szrj }
237238fd1498Szrj
237338fd1498Szrj if (BINFO_VIRTUAL_P (binfo))
237438fd1498Szrj virtual_depth++;
237538fd1498Szrj
237638fd1498Szrj /* First, locate the unhidden ones at this level. */
237738fd1498Szrj if (tree conv = get_class_binding (BINFO_TYPE (binfo), conv_op_identifier))
237838fd1498Szrj for (ovl_iterator iter (conv); iter; ++iter)
237938fd1498Szrj {
238038fd1498Szrj tree fn = *iter;
238138fd1498Szrj tree type = DECL_CONV_FN_TYPE (fn);
238238fd1498Szrj
238338fd1498Szrj if (TREE_CODE (fn) != TEMPLATE_DECL && type_uses_auto (type))
238438fd1498Szrj {
238538fd1498Szrj mark_used (fn);
238638fd1498Szrj type = DECL_CONV_FN_TYPE (fn);
238738fd1498Szrj }
238838fd1498Szrj
238938fd1498Szrj if (check_hidden_convs (binfo, virtual_depth, virtualness,
239038fd1498Szrj type, parent_convs, other_convs))
239138fd1498Szrj {
239238fd1498Szrj my_convs = tree_cons (binfo, fn, my_convs);
239338fd1498Szrj TREE_TYPE (my_convs) = type;
239438fd1498Szrj if (virtual_depth)
239538fd1498Szrj {
239638fd1498Szrj TREE_STATIC (my_convs) = 1;
239738fd1498Szrj my_virtualness = 1;
239838fd1498Szrj }
239938fd1498Szrj }
240038fd1498Szrj }
240138fd1498Szrj
240238fd1498Szrj if (my_convs)
240338fd1498Szrj {
240438fd1498Szrj parent_convs = tree_cons (binfo, my_convs, parent_convs);
240538fd1498Szrj if (virtual_depth)
240638fd1498Szrj TREE_STATIC (parent_convs) = 1;
240738fd1498Szrj }
240838fd1498Szrj
240938fd1498Szrj child_convs = other_convs;
241038fd1498Szrj
241138fd1498Szrj /* Now iterate over each base, looking for more conversions. */
241238fd1498Szrj unsigned i;
241338fd1498Szrj tree base_binfo;
241438fd1498Szrj for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
241538fd1498Szrj {
241638fd1498Szrj tree base_convs;
241738fd1498Szrj unsigned base_virtualness;
241838fd1498Szrj
241938fd1498Szrj base_virtualness = lookup_conversions_r (base_binfo,
242038fd1498Szrj virtual_depth, virtualness,
242138fd1498Szrj parent_convs, child_convs,
242238fd1498Szrj &base_convs);
242338fd1498Szrj if (base_virtualness)
242438fd1498Szrj my_virtualness = virtualness = 1;
242538fd1498Szrj child_convs = chainon (base_convs, child_convs);
242638fd1498Szrj }
242738fd1498Szrj
242838fd1498Szrj *convs = split_conversions (my_convs, parent_convs,
242938fd1498Szrj child_convs, other_convs);
243038fd1498Szrj
243138fd1498Szrj return my_virtualness;
243238fd1498Szrj }
243338fd1498Szrj
243438fd1498Szrj /* Return a TREE_LIST containing all the non-hidden user-defined
243538fd1498Szrj conversion functions for TYPE (and its base-classes). The
243638fd1498Szrj TREE_VALUE of each node is the FUNCTION_DECL of the conversion
243738fd1498Szrj function. The TREE_PURPOSE is the BINFO from which the conversion
243838fd1498Szrj functions in this node were selected. This function is effectively
243938fd1498Szrj performing a set of member lookups as lookup_fnfield does, but
244038fd1498Szrj using the type being converted to as the unique key, rather than the
244138fd1498Szrj field name. */
244238fd1498Szrj
244338fd1498Szrj tree
lookup_conversions(tree type)244438fd1498Szrj lookup_conversions (tree type)
244538fd1498Szrj {
244638fd1498Szrj tree convs;
244738fd1498Szrj
244838fd1498Szrj complete_type (type);
244938fd1498Szrj if (!CLASS_TYPE_P (type) || !TYPE_BINFO (type))
245038fd1498Szrj return NULL_TREE;
245138fd1498Szrj
245238fd1498Szrj lookup_conversions_r (TYPE_BINFO (type), 0, 0, NULL_TREE, NULL_TREE, &convs);
245338fd1498Szrj
245438fd1498Szrj tree list = NULL_TREE;
245538fd1498Szrj
245638fd1498Szrj /* Flatten the list-of-lists */
245738fd1498Szrj for (; convs; convs = TREE_CHAIN (convs))
245838fd1498Szrj {
245938fd1498Szrj tree probe, next;
246038fd1498Szrj
246138fd1498Szrj for (probe = TREE_VALUE (convs); probe; probe = next)
246238fd1498Szrj {
246338fd1498Szrj next = TREE_CHAIN (probe);
246438fd1498Szrj
246538fd1498Szrj TREE_CHAIN (probe) = list;
246638fd1498Szrj list = probe;
246738fd1498Szrj }
246838fd1498Szrj }
246938fd1498Szrj
247038fd1498Szrj return list;
247138fd1498Szrj }
247238fd1498Szrj
247338fd1498Szrj /* Returns the binfo of the first direct or indirect virtual base derived
247438fd1498Szrj from BINFO, or NULL if binfo is not via virtual. */
247538fd1498Szrj
247638fd1498Szrj tree
binfo_from_vbase(tree binfo)247738fd1498Szrj binfo_from_vbase (tree binfo)
247838fd1498Szrj {
247938fd1498Szrj for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo))
248038fd1498Szrj {
248138fd1498Szrj if (BINFO_VIRTUAL_P (binfo))
248238fd1498Szrj return binfo;
248338fd1498Szrj }
248438fd1498Szrj return NULL_TREE;
248538fd1498Szrj }
248638fd1498Szrj
248738fd1498Szrj /* Returns the binfo of the first direct or indirect virtual base derived
248838fd1498Szrj from BINFO up to the TREE_TYPE, LIMIT, or NULL if binfo is not
248938fd1498Szrj via virtual. */
249038fd1498Szrj
249138fd1498Szrj tree
binfo_via_virtual(tree binfo,tree limit)249238fd1498Szrj binfo_via_virtual (tree binfo, tree limit)
249338fd1498Szrj {
249438fd1498Szrj if (limit && !CLASSTYPE_VBASECLASSES (limit))
249538fd1498Szrj /* LIMIT has no virtual bases, so BINFO cannot be via one. */
249638fd1498Szrj return NULL_TREE;
249738fd1498Szrj
249838fd1498Szrj for (; binfo && !SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), limit);
249938fd1498Szrj binfo = BINFO_INHERITANCE_CHAIN (binfo))
250038fd1498Szrj {
250138fd1498Szrj if (BINFO_VIRTUAL_P (binfo))
250238fd1498Szrj return binfo;
250338fd1498Szrj }
250438fd1498Szrj return NULL_TREE;
250538fd1498Szrj }
250638fd1498Szrj
250738fd1498Szrj /* BINFO is for a base class in some hierarchy. Return true iff it is a
250838fd1498Szrj direct base. */
250938fd1498Szrj
251038fd1498Szrj bool
binfo_direct_p(tree binfo)251138fd1498Szrj binfo_direct_p (tree binfo)
251238fd1498Szrj {
251338fd1498Szrj tree d_binfo = BINFO_INHERITANCE_CHAIN (binfo);
251438fd1498Szrj if (BINFO_INHERITANCE_CHAIN (d_binfo))
251538fd1498Szrj /* A second inheritance chain means indirect. */
251638fd1498Szrj return false;
251738fd1498Szrj if (!BINFO_VIRTUAL_P (binfo))
251838fd1498Szrj /* Non-virtual, so only one inheritance chain means direct. */
251938fd1498Szrj return true;
252038fd1498Szrj /* A virtual base looks like a direct base, so we need to look through the
252138fd1498Szrj direct bases to see if it's there. */
252238fd1498Szrj tree b_binfo;
252338fd1498Szrj for (int i = 0; BINFO_BASE_ITERATE (d_binfo, i, b_binfo); ++i)
252438fd1498Szrj if (b_binfo == binfo)
252538fd1498Szrj return true;
252638fd1498Szrj return false;
252738fd1498Szrj }
252838fd1498Szrj
252938fd1498Szrj /* BINFO is a base binfo in the complete type BINFO_TYPE (HERE).
253038fd1498Szrj Find the equivalent binfo within whatever graph HERE is located.
253138fd1498Szrj This is the inverse of original_binfo. */
253238fd1498Szrj
253338fd1498Szrj tree
copied_binfo(tree binfo,tree here)253438fd1498Szrj copied_binfo (tree binfo, tree here)
253538fd1498Szrj {
253638fd1498Szrj tree result = NULL_TREE;
253738fd1498Szrj
253838fd1498Szrj if (BINFO_VIRTUAL_P (binfo))
253938fd1498Szrj {
254038fd1498Szrj tree t;
254138fd1498Szrj
254238fd1498Szrj for (t = here; BINFO_INHERITANCE_CHAIN (t);
254338fd1498Szrj t = BINFO_INHERITANCE_CHAIN (t))
254438fd1498Szrj continue;
254538fd1498Szrj
254638fd1498Szrj result = binfo_for_vbase (BINFO_TYPE (binfo), BINFO_TYPE (t));
254738fd1498Szrj }
254838fd1498Szrj else if (BINFO_INHERITANCE_CHAIN (binfo))
254938fd1498Szrj {
255038fd1498Szrj tree cbinfo;
255138fd1498Szrj tree base_binfo;
255238fd1498Szrj int ix;
255338fd1498Szrj
255438fd1498Szrj cbinfo = copied_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
255538fd1498Szrj for (ix = 0; BINFO_BASE_ITERATE (cbinfo, ix, base_binfo); ix++)
255638fd1498Szrj if (SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo), BINFO_TYPE (binfo)))
255738fd1498Szrj {
255838fd1498Szrj result = base_binfo;
255938fd1498Szrj break;
256038fd1498Szrj }
256138fd1498Szrj }
256238fd1498Szrj else
256338fd1498Szrj {
256438fd1498Szrj gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (here), BINFO_TYPE (binfo)));
256538fd1498Szrj result = here;
256638fd1498Szrj }
256738fd1498Szrj
256838fd1498Szrj gcc_assert (result);
256938fd1498Szrj return result;
257038fd1498Szrj }
257138fd1498Szrj
257238fd1498Szrj tree
binfo_for_vbase(tree base,tree t)257338fd1498Szrj binfo_for_vbase (tree base, tree t)
257438fd1498Szrj {
257538fd1498Szrj unsigned ix;
257638fd1498Szrj tree binfo;
257738fd1498Szrj vec<tree, va_gc> *vbases;
257838fd1498Szrj
257938fd1498Szrj for (vbases = CLASSTYPE_VBASECLASSES (t), ix = 0;
258038fd1498Szrj vec_safe_iterate (vbases, ix, &binfo); ix++)
258138fd1498Szrj if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), base))
258238fd1498Szrj return binfo;
258338fd1498Szrj return NULL;
258438fd1498Szrj }
258538fd1498Szrj
258638fd1498Szrj /* BINFO is some base binfo of HERE, within some other
258738fd1498Szrj hierarchy. Return the equivalent binfo, but in the hierarchy
258838fd1498Szrj dominated by HERE. This is the inverse of copied_binfo. If BINFO
258938fd1498Szrj is not a base binfo of HERE, returns NULL_TREE. */
259038fd1498Szrj
259138fd1498Szrj tree
original_binfo(tree binfo,tree here)259238fd1498Szrj original_binfo (tree binfo, tree here)
259338fd1498Szrj {
259438fd1498Szrj tree result = NULL;
259538fd1498Szrj
259638fd1498Szrj if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), BINFO_TYPE (here)))
259738fd1498Szrj result = here;
259838fd1498Szrj else if (BINFO_VIRTUAL_P (binfo))
259938fd1498Szrj result = (CLASSTYPE_VBASECLASSES (BINFO_TYPE (here))
260038fd1498Szrj ? binfo_for_vbase (BINFO_TYPE (binfo), BINFO_TYPE (here))
260138fd1498Szrj : NULL_TREE);
260238fd1498Szrj else if (BINFO_INHERITANCE_CHAIN (binfo))
260338fd1498Szrj {
260438fd1498Szrj tree base_binfos;
260538fd1498Szrj
260638fd1498Szrj base_binfos = original_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
260738fd1498Szrj if (base_binfos)
260838fd1498Szrj {
260938fd1498Szrj int ix;
261038fd1498Szrj tree base_binfo;
261138fd1498Szrj
261238fd1498Szrj for (ix = 0; (base_binfo = BINFO_BASE_BINFO (base_binfos, ix)); ix++)
261338fd1498Szrj if (SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo),
261438fd1498Szrj BINFO_TYPE (binfo)))
261538fd1498Szrj {
261638fd1498Szrj result = base_binfo;
261738fd1498Szrj break;
261838fd1498Szrj }
261938fd1498Szrj }
262038fd1498Szrj }
262138fd1498Szrj
262238fd1498Szrj return result;
262338fd1498Szrj }
262438fd1498Szrj
262538fd1498Szrj /* True iff TYPE has any dependent bases (and therefore we can't say
262638fd1498Szrj definitively that another class is not a base of an instantiation of
262738fd1498Szrj TYPE). */
262838fd1498Szrj
262938fd1498Szrj bool
any_dependent_bases_p(tree type)263038fd1498Szrj any_dependent_bases_p (tree type)
263138fd1498Szrj {
263238fd1498Szrj if (!type || !CLASS_TYPE_P (type) || !uses_template_parms (type))
263338fd1498Szrj return false;
263438fd1498Szrj
263538fd1498Szrj /* If we haven't set TYPE_BINFO yet, we don't know anything about the bases.
263638fd1498Szrj Return false because in this situation we aren't actually looking up names
263738fd1498Szrj in the scope of the class, so it doesn't matter whether it has dependent
263838fd1498Szrj bases. */
263938fd1498Szrj if (!TYPE_BINFO (type))
264038fd1498Szrj return false;
264138fd1498Szrj
264238fd1498Szrj unsigned i;
264338fd1498Szrj tree base_binfo;
264438fd1498Szrj FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_BINFOS (TYPE_BINFO (type)), i, base_binfo)
264538fd1498Szrj if (BINFO_DEPENDENT_BASE_P (base_binfo))
264638fd1498Szrj return true;
264738fd1498Szrj
264838fd1498Szrj return false;
264938fd1498Szrj }
2650