138fd1498Szrj /* Functions related to building classes and their related objects.
238fd1498Szrj Copyright (C) 1987-2018 Free Software Foundation, Inc.
338fd1498Szrj Contributed by Michael Tiemann (tiemann@cygnus.com)
438fd1498Szrj
538fd1498Szrj This file is part of GCC.
638fd1498Szrj
738fd1498Szrj GCC is free software; you can redistribute it and/or modify
838fd1498Szrj it under the terms of the GNU General Public License as published by
938fd1498Szrj the Free Software Foundation; either version 3, or (at your option)
1038fd1498Szrj any later version.
1138fd1498Szrj
1238fd1498Szrj GCC is distributed in the hope that it will be useful,
1338fd1498Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
1438fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1538fd1498Szrj GNU General Public License for more details.
1638fd1498Szrj
1738fd1498Szrj You should have received a copy of the GNU General Public License
1838fd1498Szrj along with GCC; see the file COPYING3. If not see
1938fd1498Szrj <http://www.gnu.org/licenses/>. */
2038fd1498Szrj
2138fd1498Szrj
2238fd1498Szrj /* High-level class interface. */
2338fd1498Szrj
2438fd1498Szrj #include "config.h"
2538fd1498Szrj #include "system.h"
2638fd1498Szrj #include "coretypes.h"
2738fd1498Szrj #include "target.h"
2838fd1498Szrj #include "cp-tree.h"
2938fd1498Szrj #include "stringpool.h"
3038fd1498Szrj #include "cgraph.h"
3138fd1498Szrj #include "stor-layout.h"
3238fd1498Szrj #include "attribs.h"
3338fd1498Szrj #include "flags.h"
3438fd1498Szrj #include "toplev.h"
3538fd1498Szrj #include "convert.h"
3638fd1498Szrj #include "dumpfile.h"
3738fd1498Szrj #include "gimplify.h"
3838fd1498Szrj #include "intl.h"
3938fd1498Szrj #include "asan.h"
4038fd1498Szrj
4138fd1498Szrj /* Id for dumping the class hierarchy. */
4238fd1498Szrj int class_dump_id;
4338fd1498Szrj
4438fd1498Szrj /* The number of nested classes being processed. If we are not in the
4538fd1498Szrj scope of any class, this is zero. */
4638fd1498Szrj
4738fd1498Szrj int current_class_depth;
4838fd1498Szrj
4938fd1498Szrj /* In order to deal with nested classes, we keep a stack of classes.
5038fd1498Szrj The topmost entry is the innermost class, and is the entry at index
5138fd1498Szrj CURRENT_CLASS_DEPTH */
5238fd1498Szrj
5338fd1498Szrj typedef struct class_stack_node {
5438fd1498Szrj /* The name of the class. */
5538fd1498Szrj tree name;
5638fd1498Szrj
5738fd1498Szrj /* The _TYPE node for the class. */
5838fd1498Szrj tree type;
5938fd1498Szrj
6038fd1498Szrj /* The access specifier pending for new declarations in the scope of
6138fd1498Szrj this class. */
6238fd1498Szrj tree access;
6338fd1498Szrj
6438fd1498Szrj /* If were defining TYPE, the names used in this class. */
6538fd1498Szrj splay_tree names_used;
6638fd1498Szrj
6738fd1498Szrj /* Nonzero if this class is no longer open, because of a call to
6838fd1498Szrj push_to_top_level. */
6938fd1498Szrj size_t hidden;
7038fd1498Szrj }* class_stack_node_t;
7138fd1498Szrj
7238fd1498Szrj struct vtbl_init_data
7338fd1498Szrj {
7438fd1498Szrj /* The base for which we're building initializers. */
7538fd1498Szrj tree binfo;
7638fd1498Szrj /* The type of the most-derived type. */
7738fd1498Szrj tree derived;
7838fd1498Szrj /* The binfo for the dynamic type. This will be TYPE_BINFO (derived),
7938fd1498Szrj unless ctor_vtbl_p is true. */
8038fd1498Szrj tree rtti_binfo;
8138fd1498Szrj /* The negative-index vtable initializers built up so far. These
8238fd1498Szrj are in order from least negative index to most negative index. */
8338fd1498Szrj vec<constructor_elt, va_gc> *inits;
8438fd1498Szrj /* The binfo for the virtual base for which we're building
8538fd1498Szrj vcall offset initializers. */
8638fd1498Szrj tree vbase;
8738fd1498Szrj /* The functions in vbase for which we have already provided vcall
8838fd1498Szrj offsets. */
8938fd1498Szrj vec<tree, va_gc> *fns;
9038fd1498Szrj /* The vtable index of the next vcall or vbase offset. */
9138fd1498Szrj tree index;
9238fd1498Szrj /* Nonzero if we are building the initializer for the primary
9338fd1498Szrj vtable. */
9438fd1498Szrj int primary_vtbl_p;
9538fd1498Szrj /* Nonzero if we are building the initializer for a construction
9638fd1498Szrj vtable. */
9738fd1498Szrj int ctor_vtbl_p;
9838fd1498Szrj /* True when adding vcall offset entries to the vtable. False when
9938fd1498Szrj merely computing the indices. */
10038fd1498Szrj bool generate_vcall_entries;
10138fd1498Szrj };
10238fd1498Szrj
10338fd1498Szrj /* The type of a function passed to walk_subobject_offsets. */
10438fd1498Szrj typedef int (*subobject_offset_fn) (tree, tree, splay_tree);
10538fd1498Szrj
10638fd1498Szrj /* The stack itself. This is a dynamically resized array. The
10738fd1498Szrj number of elements allocated is CURRENT_CLASS_STACK_SIZE. */
10838fd1498Szrj static int current_class_stack_size;
10938fd1498Szrj static class_stack_node_t current_class_stack;
11038fd1498Szrj
11138fd1498Szrj /* The size of the largest empty class seen in this translation unit. */
11238fd1498Szrj static GTY (()) tree sizeof_biggest_empty_class;
11338fd1498Szrj
11438fd1498Szrj /* An array of all local classes present in this translation unit, in
11538fd1498Szrj declaration order. */
11638fd1498Szrj vec<tree, va_gc> *local_classes;
11738fd1498Szrj
11838fd1498Szrj static tree get_vfield_name (tree);
11938fd1498Szrj static void finish_struct_anon (tree);
12038fd1498Szrj static tree get_vtable_name (tree);
12138fd1498Szrj static void get_basefndecls (tree, tree, vec<tree> *);
12238fd1498Szrj static int build_primary_vtable (tree, tree);
12338fd1498Szrj static int build_secondary_vtable (tree);
12438fd1498Szrj static void finish_vtbls (tree);
12538fd1498Szrj static void modify_vtable_entry (tree, tree, tree, tree, tree *);
12638fd1498Szrj static void finish_struct_bits (tree);
12738fd1498Szrj static int alter_access (tree, tree, tree);
12838fd1498Szrj static void handle_using_decl (tree, tree);
12938fd1498Szrj static tree dfs_modify_vtables (tree, void *);
13038fd1498Szrj static tree modify_all_vtables (tree, tree);
13138fd1498Szrj static void determine_primary_bases (tree);
13238fd1498Szrj static void maybe_warn_about_overly_private_class (tree);
13338fd1498Szrj static void add_implicitly_declared_members (tree, tree*, int, int);
13438fd1498Szrj static tree fixed_type_or_null (tree, int *, int *);
13538fd1498Szrj static tree build_simple_base_path (tree expr, tree binfo);
13638fd1498Szrj static tree build_vtbl_ref_1 (tree, tree);
13738fd1498Szrj static void build_vtbl_initializer (tree, tree, tree, tree, int *,
13838fd1498Szrj vec<constructor_elt, va_gc> **);
13938fd1498Szrj static bool check_bitfield_decl (tree);
14038fd1498Szrj static bool check_field_decl (tree, tree, int *, int *);
14138fd1498Szrj static void check_field_decls (tree, tree *, int *, int *);
14238fd1498Szrj static tree *build_base_field (record_layout_info, tree, splay_tree, tree *);
14338fd1498Szrj static void build_base_fields (record_layout_info, splay_tree, tree *);
14438fd1498Szrj static void check_methods (tree);
14538fd1498Szrj static void remove_zero_width_bit_fields (tree);
14638fd1498Szrj static bool accessible_nvdtor_p (tree);
14738fd1498Szrj
14838fd1498Szrj /* Used by find_flexarrays and related functions. */
14938fd1498Szrj struct flexmems_t;
15038fd1498Szrj static void diagnose_flexarrays (tree, const flexmems_t *);
15138fd1498Szrj static void find_flexarrays (tree, flexmems_t *, bool = false,
15238fd1498Szrj tree = NULL_TREE, tree = NULL_TREE);
15338fd1498Szrj static void check_flexarrays (tree, flexmems_t * = NULL, bool = false);
15438fd1498Szrj static void check_bases (tree, int *, int *);
15538fd1498Szrj static void check_bases_and_members (tree);
15638fd1498Szrj static tree create_vtable_ptr (tree, tree *);
15738fd1498Szrj static void include_empty_classes (record_layout_info);
15838fd1498Szrj static void layout_class_type (tree, tree *);
15938fd1498Szrj static void propagate_binfo_offsets (tree, tree);
16038fd1498Szrj static void layout_virtual_bases (record_layout_info, splay_tree);
16138fd1498Szrj static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *);
16238fd1498Szrj static void add_vcall_offset_vtbl_entries_r (tree, vtbl_init_data *);
16338fd1498Szrj static void add_vcall_offset_vtbl_entries_1 (tree, vtbl_init_data *);
16438fd1498Szrj static void build_vcall_offset_vtbl_entries (tree, vtbl_init_data *);
16538fd1498Szrj static void add_vcall_offset (tree, tree, vtbl_init_data *);
16638fd1498Szrj static void layout_vtable_decl (tree, int);
16738fd1498Szrj static tree dfs_find_final_overrider_pre (tree, void *);
16838fd1498Szrj static tree dfs_find_final_overrider_post (tree, void *);
16938fd1498Szrj static tree find_final_overrider (tree, tree, tree);
17038fd1498Szrj static int make_new_vtable (tree, tree);
17138fd1498Szrj static tree get_primary_binfo (tree);
17238fd1498Szrj static int maybe_indent_hierarchy (FILE *, int, int);
17338fd1498Szrj static tree dump_class_hierarchy_r (FILE *, dump_flags_t, tree, tree, int);
17438fd1498Szrj static void dump_class_hierarchy (tree);
17538fd1498Szrj static void dump_class_hierarchy_1 (FILE *, dump_flags_t, tree);
17638fd1498Szrj static void dump_array (FILE *, tree);
17738fd1498Szrj static void dump_vtable (tree, tree, tree);
17838fd1498Szrj static void dump_vtt (tree, tree);
17938fd1498Szrj static void dump_thunk (FILE *, int, tree);
18038fd1498Szrj static tree build_vtable (tree, tree, tree);
18138fd1498Szrj static void initialize_vtable (tree, vec<constructor_elt, va_gc> *);
18238fd1498Szrj static void layout_nonempty_base_or_field (record_layout_info,
18338fd1498Szrj tree, tree, splay_tree);
18438fd1498Szrj static tree end_of_class (tree, int);
18538fd1498Szrj static bool layout_empty_base (record_layout_info, tree, tree, splay_tree);
18638fd1498Szrj static void accumulate_vtbl_inits (tree, tree, tree, tree, tree,
18738fd1498Szrj vec<constructor_elt, va_gc> **);
18838fd1498Szrj static void dfs_accumulate_vtbl_inits (tree, tree, tree, tree, tree,
18938fd1498Szrj vec<constructor_elt, va_gc> **);
19038fd1498Szrj static void build_rtti_vtbl_entries (tree, vtbl_init_data *);
19138fd1498Szrj static void build_vcall_and_vbase_vtbl_entries (tree, vtbl_init_data *);
19238fd1498Szrj static void clone_constructors_and_destructors (tree);
19338fd1498Szrj static tree build_clone (tree, tree);
19438fd1498Szrj static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned);
19538fd1498Szrj static void build_ctor_vtbl_group (tree, tree);
19638fd1498Szrj static void build_vtt (tree);
19738fd1498Szrj static tree binfo_ctor_vtable (tree);
19838fd1498Szrj static void build_vtt_inits (tree, tree, vec<constructor_elt, va_gc> **,
19938fd1498Szrj tree *);
20038fd1498Szrj static tree dfs_build_secondary_vptr_vtt_inits (tree, void *);
20138fd1498Szrj static tree dfs_fixup_binfo_vtbls (tree, void *);
20238fd1498Szrj static int record_subobject_offset (tree, tree, splay_tree);
20338fd1498Szrj static int check_subobject_offset (tree, tree, splay_tree);
20438fd1498Szrj static int walk_subobject_offsets (tree, subobject_offset_fn,
20538fd1498Szrj tree, splay_tree, tree, int);
20638fd1498Szrj static void record_subobject_offsets (tree, tree, splay_tree, bool);
20738fd1498Szrj static int layout_conflict_p (tree, tree, splay_tree, int);
20838fd1498Szrj static int splay_tree_compare_integer_csts (splay_tree_key k1,
20938fd1498Szrj splay_tree_key k2);
21038fd1498Szrj static void warn_about_ambiguous_bases (tree);
21138fd1498Szrj static bool type_requires_array_cookie (tree);
21238fd1498Szrj static bool base_derived_from (tree, tree);
21338fd1498Szrj static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree);
21438fd1498Szrj static tree end_of_base (tree);
21538fd1498Szrj static tree get_vcall_index (tree, tree);
21638fd1498Szrj static bool type_maybe_constexpr_default_constructor (tree);
21738fd1498Szrj
21838fd1498Szrj /* Return a COND_EXPR that executes TRUE_STMT if this execution of the
21938fd1498Szrj 'structor is in charge of 'structing virtual bases, or FALSE_STMT
22038fd1498Szrj otherwise. */
22138fd1498Szrj
22238fd1498Szrj tree
build_if_in_charge(tree true_stmt,tree false_stmt)22338fd1498Szrj build_if_in_charge (tree true_stmt, tree false_stmt)
22438fd1498Szrj {
22538fd1498Szrj gcc_assert (DECL_HAS_IN_CHARGE_PARM_P (current_function_decl));
22638fd1498Szrj tree cmp = build2 (NE_EXPR, boolean_type_node,
22738fd1498Szrj current_in_charge_parm, integer_zero_node);
22838fd1498Szrj tree type = unlowered_expr_type (true_stmt);
22938fd1498Szrj if (VOID_TYPE_P (type))
23038fd1498Szrj type = unlowered_expr_type (false_stmt);
23138fd1498Szrj tree cond = build3 (COND_EXPR, type,
23238fd1498Szrj cmp, true_stmt, false_stmt);
23338fd1498Szrj return cond;
23438fd1498Szrj }
23538fd1498Szrj
23638fd1498Szrj /* Convert to or from a base subobject. EXPR is an expression of type
23738fd1498Szrj `A' or `A*', an expression of type `B' or `B*' is returned. To
23838fd1498Szrj convert A to a base B, CODE is PLUS_EXPR and BINFO is the binfo for
23938fd1498Szrj the B base instance within A. To convert base A to derived B, CODE
24038fd1498Szrj is MINUS_EXPR and BINFO is the binfo for the A instance within B.
24138fd1498Szrj In this latter case, A must not be a morally virtual base of B.
24238fd1498Szrj NONNULL is true if EXPR is known to be non-NULL (this is only
24338fd1498Szrj needed when EXPR is of pointer type). CV qualifiers are preserved
24438fd1498Szrj from EXPR. */
24538fd1498Szrj
24638fd1498Szrj tree
build_base_path(enum tree_code code,tree expr,tree binfo,int nonnull,tsubst_flags_t complain)24738fd1498Szrj build_base_path (enum tree_code code,
24838fd1498Szrj tree expr,
24938fd1498Szrj tree binfo,
25038fd1498Szrj int nonnull,
25138fd1498Szrj tsubst_flags_t complain)
25238fd1498Szrj {
25338fd1498Szrj tree v_binfo = NULL_TREE;
25438fd1498Szrj tree d_binfo = NULL_TREE;
25538fd1498Szrj tree probe;
25638fd1498Szrj tree offset;
25738fd1498Szrj tree target_type;
25838fd1498Szrj tree null_test = NULL;
25938fd1498Szrj tree ptr_target_type;
26038fd1498Szrj int fixed_type_p;
26138fd1498Szrj int want_pointer = TYPE_PTR_P (TREE_TYPE (expr));
26238fd1498Szrj bool has_empty = false;
26338fd1498Szrj bool virtual_access;
26438fd1498Szrj bool rvalue = false;
26538fd1498Szrj
26638fd1498Szrj if (expr == error_mark_node || binfo == error_mark_node || !binfo)
26738fd1498Szrj return error_mark_node;
26838fd1498Szrj
26938fd1498Szrj for (probe = binfo; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
27038fd1498Szrj {
27138fd1498Szrj d_binfo = probe;
27238fd1498Szrj if (is_empty_class (BINFO_TYPE (probe)))
27338fd1498Szrj has_empty = true;
27438fd1498Szrj if (!v_binfo && BINFO_VIRTUAL_P (probe))
27538fd1498Szrj v_binfo = probe;
27638fd1498Szrj }
27738fd1498Szrj
27838fd1498Szrj probe = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
27938fd1498Szrj if (want_pointer)
28038fd1498Szrj probe = TYPE_MAIN_VARIANT (TREE_TYPE (probe));
28158e805e6Szrj if (dependent_type_p (probe))
28258e805e6Szrj if (tree open = currently_open_class (probe))
28358e805e6Szrj probe = open;
28438fd1498Szrj
28538fd1498Szrj if (code == PLUS_EXPR
28638fd1498Szrj && !SAME_BINFO_TYPE_P (BINFO_TYPE (d_binfo), probe))
28738fd1498Szrj {
28838fd1498Szrj /* This can happen when adjust_result_of_qualified_name_lookup can't
28938fd1498Szrj find a unique base binfo in a call to a member function. We
29038fd1498Szrj couldn't give the diagnostic then since we might have been calling
29138fd1498Szrj a static member function, so we do it now. In other cases, eg.
29238fd1498Szrj during error recovery (c++/71979), we may not have a base at all. */
29338fd1498Szrj if (complain & tf_error)
29438fd1498Szrj {
29538fd1498Szrj tree base = lookup_base (probe, BINFO_TYPE (d_binfo),
29638fd1498Szrj ba_unique, NULL, complain);
29738fd1498Szrj gcc_assert (base == error_mark_node || !base);
29838fd1498Szrj }
29938fd1498Szrj return error_mark_node;
30038fd1498Szrj }
30138fd1498Szrj
30238fd1498Szrj gcc_assert ((code == MINUS_EXPR
30338fd1498Szrj && SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), probe))
30438fd1498Szrj || code == PLUS_EXPR);
30538fd1498Szrj
30638fd1498Szrj if (binfo == d_binfo)
30738fd1498Szrj /* Nothing to do. */
30838fd1498Szrj return expr;
30938fd1498Szrj
31038fd1498Szrj if (code == MINUS_EXPR && v_binfo)
31138fd1498Szrj {
31238fd1498Szrj if (complain & tf_error)
31338fd1498Szrj {
31438fd1498Szrj if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), BINFO_TYPE (v_binfo)))
31538fd1498Szrj {
31638fd1498Szrj if (want_pointer)
31738fd1498Szrj error ("cannot convert from pointer to base class %qT to "
31838fd1498Szrj "pointer to derived class %qT because the base is "
31938fd1498Szrj "virtual", BINFO_TYPE (binfo), BINFO_TYPE (d_binfo));
32038fd1498Szrj else
32138fd1498Szrj error ("cannot convert from base class %qT to derived "
32238fd1498Szrj "class %qT because the base is virtual",
32338fd1498Szrj BINFO_TYPE (binfo), BINFO_TYPE (d_binfo));
32438fd1498Szrj }
32538fd1498Szrj else
32638fd1498Szrj {
32738fd1498Szrj if (want_pointer)
32838fd1498Szrj error ("cannot convert from pointer to base class %qT to "
32938fd1498Szrj "pointer to derived class %qT via virtual base %qT",
33038fd1498Szrj BINFO_TYPE (binfo), BINFO_TYPE (d_binfo),
33138fd1498Szrj BINFO_TYPE (v_binfo));
33238fd1498Szrj else
33338fd1498Szrj error ("cannot convert from base class %qT to derived "
33438fd1498Szrj "class %qT via virtual base %qT", BINFO_TYPE (binfo),
33538fd1498Szrj BINFO_TYPE (d_binfo), BINFO_TYPE (v_binfo));
33638fd1498Szrj }
33738fd1498Szrj }
33838fd1498Szrj return error_mark_node;
33938fd1498Szrj }
34038fd1498Szrj
34138fd1498Szrj if (!want_pointer)
34238fd1498Szrj {
34338fd1498Szrj rvalue = !lvalue_p (expr);
34438fd1498Szrj /* This must happen before the call to save_expr. */
34538fd1498Szrj expr = cp_build_addr_expr (expr, complain);
34638fd1498Szrj }
34738fd1498Szrj else
34838fd1498Szrj expr = mark_rvalue_use (expr);
34938fd1498Szrj
35038fd1498Szrj offset = BINFO_OFFSET (binfo);
35138fd1498Szrj fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
35238fd1498Szrj target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo);
35338fd1498Szrj /* TARGET_TYPE has been extracted from BINFO, and, is therefore always
35438fd1498Szrj cv-unqualified. Extract the cv-qualifiers from EXPR so that the
35538fd1498Szrj expression returned matches the input. */
35638fd1498Szrj target_type = cp_build_qualified_type
35738fd1498Szrj (target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr))));
35838fd1498Szrj ptr_target_type = build_pointer_type (target_type);
35938fd1498Szrj
36038fd1498Szrj /* Do we need to look in the vtable for the real offset? */
36138fd1498Szrj virtual_access = (v_binfo && fixed_type_p <= 0);
36238fd1498Szrj
36338fd1498Szrj /* Don't bother with the calculations inside sizeof; they'll ICE if the
36438fd1498Szrj source type is incomplete and the pointer value doesn't matter. In a
36538fd1498Szrj template (even in instantiate_non_dependent_expr), we don't have vtables
36638fd1498Szrj set up properly yet, and the value doesn't matter there either; we're
36738fd1498Szrj just interested in the result of overload resolution. */
36838fd1498Szrj if (cp_unevaluated_operand != 0
36938fd1498Szrj || processing_template_decl
37038fd1498Szrj || in_template_function ())
37138fd1498Szrj {
37238fd1498Szrj expr = build_nop (ptr_target_type, expr);
37338fd1498Szrj goto indout;
37438fd1498Szrj }
37538fd1498Szrj
37638fd1498Szrj /* If we're in an NSDMI, we don't have the full constructor context yet
37738fd1498Szrj that we need for converting to a virtual base, so just build a stub
37838fd1498Szrj CONVERT_EXPR and expand it later in bot_replace. */
37938fd1498Szrj if (virtual_access && fixed_type_p < 0
38038fd1498Szrj && current_scope () != current_function_decl)
38138fd1498Szrj {
38238fd1498Szrj expr = build1 (CONVERT_EXPR, ptr_target_type, expr);
38338fd1498Szrj CONVERT_EXPR_VBASE_PATH (expr) = true;
38438fd1498Szrj goto indout;
38538fd1498Szrj }
38638fd1498Szrj
38738fd1498Szrj /* Do we need to check for a null pointer? */
38838fd1498Szrj if (want_pointer && !nonnull)
38938fd1498Szrj {
39038fd1498Szrj /* If we know the conversion will not actually change the value
39138fd1498Szrj of EXPR, then we can avoid testing the expression for NULL.
39238fd1498Szrj We have to avoid generating a COMPONENT_REF for a base class
39338fd1498Szrj field, because other parts of the compiler know that such
39438fd1498Szrj expressions are always non-NULL. */
39538fd1498Szrj if (!virtual_access && integer_zerop (offset))
39638fd1498Szrj return build_nop (ptr_target_type, expr);
39738fd1498Szrj null_test = error_mark_node;
39838fd1498Szrj }
39938fd1498Szrj
40038fd1498Szrj /* Protect against multiple evaluation if necessary. */
40138fd1498Szrj if (TREE_SIDE_EFFECTS (expr) && (null_test || virtual_access))
40238fd1498Szrj expr = save_expr (expr);
40338fd1498Szrj
40438fd1498Szrj /* Now that we've saved expr, build the real null test. */
40538fd1498Szrj if (null_test)
40638fd1498Szrj {
40738fd1498Szrj tree zero = cp_convert (TREE_TYPE (expr), nullptr_node, complain);
40838fd1498Szrj null_test = build2_loc (input_location, NE_EXPR, boolean_type_node,
40938fd1498Szrj expr, zero);
41038fd1498Szrj /* This is a compiler generated comparison, don't emit
41138fd1498Szrj e.g. -Wnonnull-compare warning for it. */
41238fd1498Szrj TREE_NO_WARNING (null_test) = 1;
41338fd1498Szrj }
41438fd1498Szrj
41538fd1498Szrj /* If this is a simple base reference, express it as a COMPONENT_REF. */
41638fd1498Szrj if (code == PLUS_EXPR && !virtual_access
41738fd1498Szrj /* We don't build base fields for empty bases, and they aren't very
41838fd1498Szrj interesting to the optimizers anyway. */
41938fd1498Szrj && !has_empty)
42038fd1498Szrj {
42138fd1498Szrj expr = cp_build_fold_indirect_ref (expr);
42238fd1498Szrj expr = build_simple_base_path (expr, binfo);
42358e805e6Szrj if (rvalue && lvalue_p (expr))
42438fd1498Szrj expr = move (expr);
42538fd1498Szrj if (want_pointer)
42638fd1498Szrj expr = build_address (expr);
42738fd1498Szrj target_type = TREE_TYPE (expr);
42838fd1498Szrj goto out;
42938fd1498Szrj }
43038fd1498Szrj
43138fd1498Szrj if (virtual_access)
43238fd1498Szrj {
43338fd1498Szrj /* Going via virtual base V_BINFO. We need the static offset
43438fd1498Szrj from V_BINFO to BINFO, and the dynamic offset from D_BINFO to
43538fd1498Szrj V_BINFO. That offset is an entry in D_BINFO's vtable. */
43638fd1498Szrj tree v_offset;
43738fd1498Szrj
43838fd1498Szrj if (fixed_type_p < 0 && in_base_initializer)
43938fd1498Szrj {
44038fd1498Szrj /* In a base member initializer, we cannot rely on the
44138fd1498Szrj vtable being set up. We have to indirect via the
44238fd1498Szrj vtt_parm. */
44338fd1498Szrj tree t;
44438fd1498Szrj
44538fd1498Szrj t = TREE_TYPE (TYPE_VFIELD (current_class_type));
44638fd1498Szrj t = build_pointer_type (t);
44738fd1498Szrj v_offset = fold_convert (t, current_vtt_parm);
44838fd1498Szrj v_offset = cp_build_fold_indirect_ref (v_offset);
44938fd1498Szrj }
45038fd1498Szrj else
45138fd1498Szrj {
45238fd1498Szrj tree t = expr;
45338fd1498Szrj if (sanitize_flags_p (SANITIZE_VPTR)
45438fd1498Szrj && fixed_type_p == 0)
45538fd1498Szrj {
45638fd1498Szrj t = cp_ubsan_maybe_instrument_cast_to_vbase (input_location,
45738fd1498Szrj probe, expr);
45838fd1498Szrj if (t == NULL_TREE)
45938fd1498Szrj t = expr;
46038fd1498Szrj }
46138fd1498Szrj v_offset = build_vfield_ref (cp_build_fold_indirect_ref (t),
46238fd1498Szrj TREE_TYPE (TREE_TYPE (expr)));
46338fd1498Szrj }
46438fd1498Szrj
46538fd1498Szrj if (v_offset == error_mark_node)
46638fd1498Szrj return error_mark_node;
46738fd1498Szrj
46838fd1498Szrj v_offset = fold_build_pointer_plus (v_offset, BINFO_VPTR_FIELD (v_binfo));
46938fd1498Szrj v_offset = build1 (NOP_EXPR,
47038fd1498Szrj build_pointer_type (ptrdiff_type_node),
47138fd1498Szrj v_offset);
47238fd1498Szrj v_offset = cp_build_fold_indirect_ref (v_offset);
47338fd1498Szrj TREE_CONSTANT (v_offset) = 1;
47438fd1498Szrj
47538fd1498Szrj offset = convert_to_integer (ptrdiff_type_node,
47638fd1498Szrj size_diffop_loc (input_location, offset,
47738fd1498Szrj BINFO_OFFSET (v_binfo)));
47838fd1498Szrj
47938fd1498Szrj if (!integer_zerop (offset))
48038fd1498Szrj v_offset = build2 (code, ptrdiff_type_node, v_offset, offset);
48138fd1498Szrj
48238fd1498Szrj if (fixed_type_p < 0)
48338fd1498Szrj /* Negative fixed_type_p means this is a constructor or destructor;
48438fd1498Szrj virtual base layout is fixed in in-charge [cd]tors, but not in
48538fd1498Szrj base [cd]tors. */
48638fd1498Szrj offset = build_if_in_charge
48738fd1498Szrj (convert_to_integer (ptrdiff_type_node, BINFO_OFFSET (binfo)),
48838fd1498Szrj v_offset);
48938fd1498Szrj else
49038fd1498Szrj offset = v_offset;
49138fd1498Szrj }
49238fd1498Szrj
49338fd1498Szrj if (want_pointer)
49438fd1498Szrj target_type = ptr_target_type;
49538fd1498Szrj
49638fd1498Szrj expr = build1 (NOP_EXPR, ptr_target_type, expr);
49738fd1498Szrj
49838fd1498Szrj if (!integer_zerop (offset))
49938fd1498Szrj {
50038fd1498Szrj offset = fold_convert (sizetype, offset);
50138fd1498Szrj if (code == MINUS_EXPR)
50238fd1498Szrj offset = fold_build1_loc (input_location, NEGATE_EXPR, sizetype, offset);
50338fd1498Szrj expr = fold_build_pointer_plus (expr, offset);
50438fd1498Szrj }
50538fd1498Szrj else
50638fd1498Szrj null_test = NULL;
50738fd1498Szrj
50838fd1498Szrj indout:
50938fd1498Szrj if (!want_pointer)
51038fd1498Szrj {
51138fd1498Szrj expr = cp_build_fold_indirect_ref (expr);
51238fd1498Szrj if (rvalue)
51338fd1498Szrj expr = move (expr);
51438fd1498Szrj }
51538fd1498Szrj
51638fd1498Szrj out:
51738fd1498Szrj if (null_test)
51838fd1498Szrj expr = fold_build3_loc (input_location, COND_EXPR, target_type, null_test, expr,
51938fd1498Szrj build_zero_cst (target_type));
52038fd1498Szrj
52138fd1498Szrj return expr;
52238fd1498Szrj }
52338fd1498Szrj
52438fd1498Szrj /* Subroutine of build_base_path; EXPR and BINFO are as in that function.
52538fd1498Szrj Perform a derived-to-base conversion by recursively building up a
52638fd1498Szrj sequence of COMPONENT_REFs to the appropriate base fields. */
52738fd1498Szrj
52838fd1498Szrj static tree
build_simple_base_path(tree expr,tree binfo)52938fd1498Szrj build_simple_base_path (tree expr, tree binfo)
53038fd1498Szrj {
53138fd1498Szrj tree type = BINFO_TYPE (binfo);
53238fd1498Szrj tree d_binfo = BINFO_INHERITANCE_CHAIN (binfo);
53338fd1498Szrj tree field;
53438fd1498Szrj
53538fd1498Szrj if (d_binfo == NULL_TREE)
53638fd1498Szrj {
53738fd1498Szrj tree temp;
53838fd1498Szrj
53938fd1498Szrj gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type);
54038fd1498Szrj
54138fd1498Szrj /* Transform `(a, b).x' into `(*(a, &b)).x', `(a ? b : c).x'
54238fd1498Szrj into `(*(a ? &b : &c)).x', and so on. A COND_EXPR is only
54338fd1498Szrj an lvalue in the front end; only _DECLs and _REFs are lvalues
54438fd1498Szrj in the back end. */
54538fd1498Szrj temp = unary_complex_lvalue (ADDR_EXPR, expr);
54638fd1498Szrj if (temp)
54738fd1498Szrj expr = cp_build_fold_indirect_ref (temp);
54838fd1498Szrj
54938fd1498Szrj return expr;
55038fd1498Szrj }
55138fd1498Szrj
55238fd1498Szrj /* Recurse. */
55338fd1498Szrj expr = build_simple_base_path (expr, d_binfo);
55438fd1498Szrj
55538fd1498Szrj for (field = TYPE_FIELDS (BINFO_TYPE (d_binfo));
55638fd1498Szrj field; field = DECL_CHAIN (field))
55738fd1498Szrj /* Is this the base field created by build_base_field? */
55838fd1498Szrj if (TREE_CODE (field) == FIELD_DECL
55938fd1498Szrj && DECL_FIELD_IS_BASE (field)
56038fd1498Szrj && TREE_TYPE (field) == type
56138fd1498Szrj /* If we're looking for a field in the most-derived class,
56238fd1498Szrj also check the field offset; we can have two base fields
56338fd1498Szrj of the same type if one is an indirect virtual base and one
56438fd1498Szrj is a direct non-virtual base. */
56538fd1498Szrj && (BINFO_INHERITANCE_CHAIN (d_binfo)
56638fd1498Szrj || tree_int_cst_equal (byte_position (field),
56738fd1498Szrj BINFO_OFFSET (binfo))))
56838fd1498Szrj {
56938fd1498Szrj /* We don't use build_class_member_access_expr here, as that
57038fd1498Szrj has unnecessary checks, and more importantly results in
57138fd1498Szrj recursive calls to dfs_walk_once. */
57238fd1498Szrj int type_quals = cp_type_quals (TREE_TYPE (expr));
57338fd1498Szrj
57438fd1498Szrj expr = build3 (COMPONENT_REF,
57538fd1498Szrj cp_build_qualified_type (type, type_quals),
57638fd1498Szrj expr, field, NULL_TREE);
57738fd1498Szrj /* Mark the expression const or volatile, as appropriate.
57838fd1498Szrj Even though we've dealt with the type above, we still have
57938fd1498Szrj to mark the expression itself. */
58038fd1498Szrj if (type_quals & TYPE_QUAL_CONST)
58138fd1498Szrj TREE_READONLY (expr) = 1;
58238fd1498Szrj if (type_quals & TYPE_QUAL_VOLATILE)
58338fd1498Szrj TREE_THIS_VOLATILE (expr) = 1;
58438fd1498Szrj
58538fd1498Szrj return expr;
58638fd1498Szrj }
58738fd1498Szrj
58838fd1498Szrj /* Didn't find the base field?!? */
58938fd1498Szrj gcc_unreachable ();
59038fd1498Szrj }
59138fd1498Szrj
59238fd1498Szrj /* Convert OBJECT to the base TYPE. OBJECT is an expression whose
59338fd1498Szrj type is a class type or a pointer to a class type. In the former
59438fd1498Szrj case, TYPE is also a class type; in the latter it is another
59538fd1498Szrj pointer type. If CHECK_ACCESS is true, an error message is emitted
59638fd1498Szrj if TYPE is inaccessible. If OBJECT has pointer type, the value is
59738fd1498Szrj assumed to be non-NULL. */
59838fd1498Szrj
59938fd1498Szrj tree
convert_to_base(tree object,tree type,bool check_access,bool nonnull,tsubst_flags_t complain)60038fd1498Szrj convert_to_base (tree object, tree type, bool check_access, bool nonnull,
60138fd1498Szrj tsubst_flags_t complain)
60238fd1498Szrj {
60338fd1498Szrj tree binfo;
60438fd1498Szrj tree object_type;
60538fd1498Szrj
60638fd1498Szrj if (TYPE_PTR_P (TREE_TYPE (object)))
60738fd1498Szrj {
60838fd1498Szrj object_type = TREE_TYPE (TREE_TYPE (object));
60938fd1498Szrj type = TREE_TYPE (type);
61038fd1498Szrj }
61138fd1498Szrj else
61238fd1498Szrj object_type = TREE_TYPE (object);
61338fd1498Szrj
61438fd1498Szrj binfo = lookup_base (object_type, type, check_access ? ba_check : ba_unique,
61538fd1498Szrj NULL, complain);
61638fd1498Szrj if (!binfo || binfo == error_mark_node)
61738fd1498Szrj return error_mark_node;
61838fd1498Szrj
61938fd1498Szrj return build_base_path (PLUS_EXPR, object, binfo, nonnull, complain);
62038fd1498Szrj }
62138fd1498Szrj
62238fd1498Szrj /* EXPR is an expression with unqualified class type. BASE is a base
62338fd1498Szrj binfo of that class type. Returns EXPR, converted to the BASE
62438fd1498Szrj type. This function assumes that EXPR is the most derived class;
62538fd1498Szrj therefore virtual bases can be found at their static offsets. */
62638fd1498Szrj
62738fd1498Szrj tree
convert_to_base_statically(tree expr,tree base)62838fd1498Szrj convert_to_base_statically (tree expr, tree base)
62938fd1498Szrj {
63038fd1498Szrj tree expr_type;
63138fd1498Szrj
63238fd1498Szrj expr_type = TREE_TYPE (expr);
63338fd1498Szrj if (!SAME_BINFO_TYPE_P (BINFO_TYPE (base), expr_type))
63438fd1498Szrj {
63538fd1498Szrj /* If this is a non-empty base, use a COMPONENT_REF. */
63638fd1498Szrj if (!is_empty_class (BINFO_TYPE (base)))
63738fd1498Szrj return build_simple_base_path (expr, base);
63838fd1498Szrj
63938fd1498Szrj /* We use fold_build2 and fold_convert below to simplify the trees
64038fd1498Szrj provided to the optimizers. It is not safe to call these functions
64138fd1498Szrj when processing a template because they do not handle C++-specific
64238fd1498Szrj trees. */
64338fd1498Szrj gcc_assert (!processing_template_decl);
64438fd1498Szrj expr = cp_build_addr_expr (expr, tf_warning_or_error);
64538fd1498Szrj if (!integer_zerop (BINFO_OFFSET (base)))
64638fd1498Szrj expr = fold_build_pointer_plus_loc (input_location,
64738fd1498Szrj expr, BINFO_OFFSET (base));
64838fd1498Szrj expr = fold_convert (build_pointer_type (BINFO_TYPE (base)), expr);
64938fd1498Szrj expr = build_fold_indirect_ref_loc (input_location, expr);
65038fd1498Szrj }
65138fd1498Szrj
65238fd1498Szrj return expr;
65338fd1498Szrj }
65438fd1498Szrj
65538fd1498Szrj
65638fd1498Szrj tree
build_vfield_ref(tree datum,tree type)65738fd1498Szrj build_vfield_ref (tree datum, tree type)
65838fd1498Szrj {
65938fd1498Szrj tree vfield, vcontext;
66038fd1498Szrj
66138fd1498Szrj if (datum == error_mark_node
66238fd1498Szrj /* Can happen in case of duplicate base types (c++/59082). */
66338fd1498Szrj || !TYPE_VFIELD (type))
66438fd1498Szrj return error_mark_node;
66538fd1498Szrj
66638fd1498Szrj /* First, convert to the requested type. */
66738fd1498Szrj if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
66838fd1498Szrj datum = convert_to_base (datum, type, /*check_access=*/false,
66938fd1498Szrj /*nonnull=*/true, tf_warning_or_error);
67038fd1498Szrj
67138fd1498Szrj /* Second, the requested type may not be the owner of its own vptr.
67238fd1498Szrj If not, convert to the base class that owns it. We cannot use
67338fd1498Szrj convert_to_base here, because VCONTEXT may appear more than once
67438fd1498Szrj in the inheritance hierarchy of TYPE, and thus direct conversion
67538fd1498Szrj between the types may be ambiguous. Following the path back up
67638fd1498Szrj one step at a time via primary bases avoids the problem. */
67738fd1498Szrj vfield = TYPE_VFIELD (type);
67838fd1498Szrj vcontext = DECL_CONTEXT (vfield);
67938fd1498Szrj while (!same_type_ignoring_top_level_qualifiers_p (vcontext, type))
68038fd1498Szrj {
68138fd1498Szrj datum = build_simple_base_path (datum, CLASSTYPE_PRIMARY_BINFO (type));
68238fd1498Szrj type = TREE_TYPE (datum);
68338fd1498Szrj }
68438fd1498Szrj
68538fd1498Szrj return build3 (COMPONENT_REF, TREE_TYPE (vfield), datum, vfield, NULL_TREE);
68638fd1498Szrj }
68738fd1498Szrj
68838fd1498Szrj /* Given an object INSTANCE, return an expression which yields the
68938fd1498Szrj vtable element corresponding to INDEX. There are many special
69038fd1498Szrj cases for INSTANCE which we take care of here, mainly to avoid
69138fd1498Szrj creating extra tree nodes when we don't have to. */
69238fd1498Szrj
69338fd1498Szrj static tree
build_vtbl_ref_1(tree instance,tree idx)69438fd1498Szrj build_vtbl_ref_1 (tree instance, tree idx)
69538fd1498Szrj {
69638fd1498Szrj tree aref;
69738fd1498Szrj tree vtbl = NULL_TREE;
69838fd1498Szrj
69938fd1498Szrj /* Try to figure out what a reference refers to, and
70038fd1498Szrj access its virtual function table directly. */
70138fd1498Szrj
70238fd1498Szrj int cdtorp = 0;
70338fd1498Szrj tree fixed_type = fixed_type_or_null (instance, NULL, &cdtorp);
70438fd1498Szrj
70538fd1498Szrj tree basetype = non_reference (TREE_TYPE (instance));
70638fd1498Szrj
70738fd1498Szrj if (fixed_type && !cdtorp)
70838fd1498Szrj {
70938fd1498Szrj tree binfo = lookup_base (fixed_type, basetype,
71038fd1498Szrj ba_unique, NULL, tf_none);
71138fd1498Szrj if (binfo && binfo != error_mark_node)
71238fd1498Szrj vtbl = unshare_expr (BINFO_VTABLE (binfo));
71338fd1498Szrj }
71438fd1498Szrj
71538fd1498Szrj if (!vtbl)
71638fd1498Szrj vtbl = build_vfield_ref (instance, basetype);
71738fd1498Szrj
71838fd1498Szrj aref = build_array_ref (input_location, vtbl, idx);
71938fd1498Szrj TREE_CONSTANT (aref) |= TREE_CONSTANT (vtbl) && TREE_CONSTANT (idx);
72038fd1498Szrj
72138fd1498Szrj return aref;
72238fd1498Szrj }
72338fd1498Szrj
72438fd1498Szrj tree
build_vtbl_ref(tree instance,tree idx)72538fd1498Szrj build_vtbl_ref (tree instance, tree idx)
72638fd1498Szrj {
72738fd1498Szrj tree aref = build_vtbl_ref_1 (instance, idx);
72838fd1498Szrj
72938fd1498Szrj return aref;
73038fd1498Szrj }
73138fd1498Szrj
73238fd1498Szrj /* Given a stable object pointer INSTANCE_PTR, return an expression which
73338fd1498Szrj yields a function pointer corresponding to vtable element INDEX. */
73438fd1498Szrj
73538fd1498Szrj tree
build_vfn_ref(tree instance_ptr,tree idx)73638fd1498Szrj build_vfn_ref (tree instance_ptr, tree idx)
73738fd1498Szrj {
73838fd1498Szrj tree aref;
73938fd1498Szrj
74038fd1498Szrj aref = build_vtbl_ref_1 (cp_build_fold_indirect_ref (instance_ptr),
74138fd1498Szrj idx);
74238fd1498Szrj
74338fd1498Szrj /* When using function descriptors, the address of the
74438fd1498Szrj vtable entry is treated as a function pointer. */
74538fd1498Szrj if (TARGET_VTABLE_USES_DESCRIPTORS)
74638fd1498Szrj aref = build1 (NOP_EXPR, TREE_TYPE (aref),
74738fd1498Szrj cp_build_addr_expr (aref, tf_warning_or_error));
74838fd1498Szrj
74938fd1498Szrj /* Remember this as a method reference, for later devirtualization. */
75038fd1498Szrj aref = build3 (OBJ_TYPE_REF, TREE_TYPE (aref), aref, instance_ptr, idx);
75138fd1498Szrj
75238fd1498Szrj return aref;
75338fd1498Szrj }
75438fd1498Szrj
75538fd1498Szrj /* Return the name of the virtual function table (as an IDENTIFIER_NODE)
75638fd1498Szrj for the given TYPE. */
75738fd1498Szrj
75838fd1498Szrj static tree
get_vtable_name(tree type)75938fd1498Szrj get_vtable_name (tree type)
76038fd1498Szrj {
76138fd1498Szrj return mangle_vtbl_for_type (type);
76238fd1498Szrj }
76338fd1498Szrj
76438fd1498Szrj /* DECL is an entity associated with TYPE, like a virtual table or an
76538fd1498Szrj implicitly generated constructor. Determine whether or not DECL
76638fd1498Szrj should have external or internal linkage at the object file
76738fd1498Szrj level. This routine does not deal with COMDAT linkage and other
76838fd1498Szrj similar complexities; it simply sets TREE_PUBLIC if it possible for
76938fd1498Szrj entities in other translation units to contain copies of DECL, in
77038fd1498Szrj the abstract. */
77138fd1498Szrj
77238fd1498Szrj void
set_linkage_according_to_type(tree,tree decl)77338fd1498Szrj set_linkage_according_to_type (tree /*type*/, tree decl)
77438fd1498Szrj {
77538fd1498Szrj TREE_PUBLIC (decl) = 1;
77638fd1498Szrj determine_visibility (decl);
77738fd1498Szrj }
77838fd1498Szrj
77938fd1498Szrj /* Create a VAR_DECL for a primary or secondary vtable for CLASS_TYPE.
78038fd1498Szrj (For a secondary vtable for B-in-D, CLASS_TYPE should be D, not B.)
78138fd1498Szrj Use NAME for the name of the vtable, and VTABLE_TYPE for its type. */
78238fd1498Szrj
78338fd1498Szrj static tree
build_vtable(tree class_type,tree name,tree vtable_type)78438fd1498Szrj build_vtable (tree class_type, tree name, tree vtable_type)
78538fd1498Szrj {
78638fd1498Szrj tree decl;
78738fd1498Szrj
78838fd1498Szrj decl = build_lang_decl (VAR_DECL, name, vtable_type);
78938fd1498Szrj /* vtable names are already mangled; give them their DECL_ASSEMBLER_NAME
79038fd1498Szrj now to avoid confusion in mangle_decl. */
79138fd1498Szrj SET_DECL_ASSEMBLER_NAME (decl, name);
79238fd1498Szrj DECL_CONTEXT (decl) = class_type;
79338fd1498Szrj DECL_ARTIFICIAL (decl) = 1;
79438fd1498Szrj TREE_STATIC (decl) = 1;
79538fd1498Szrj TREE_READONLY (decl) = 1;
79638fd1498Szrj DECL_VIRTUAL_P (decl) = 1;
79738fd1498Szrj SET_DECL_ALIGN (decl, TARGET_VTABLE_ENTRY_ALIGN);
79838fd1498Szrj DECL_USER_ALIGN (decl) = true;
79938fd1498Szrj DECL_VTABLE_OR_VTT_P (decl) = 1;
80038fd1498Szrj set_linkage_according_to_type (class_type, decl);
80138fd1498Szrj /* The vtable has not been defined -- yet. */
80238fd1498Szrj DECL_EXTERNAL (decl) = 1;
80338fd1498Szrj DECL_NOT_REALLY_EXTERN (decl) = 1;
80438fd1498Szrj
80538fd1498Szrj /* Mark the VAR_DECL node representing the vtable itself as a
80638fd1498Szrj "gratuitous" one, thereby forcing dwarfout.c to ignore it. It
80738fd1498Szrj is rather important that such things be ignored because any
80838fd1498Szrj effort to actually generate DWARF for them will run into
80938fd1498Szrj trouble when/if we encounter code like:
81038fd1498Szrj
81138fd1498Szrj #pragma interface
81238fd1498Szrj struct S { virtual void member (); };
81338fd1498Szrj
81438fd1498Szrj because the artificial declaration of the vtable itself (as
81538fd1498Szrj manufactured by the g++ front end) will say that the vtable is
81638fd1498Szrj a static member of `S' but only *after* the debug output for
81738fd1498Szrj the definition of `S' has already been output. This causes
81838fd1498Szrj grief because the DWARF entry for the definition of the vtable
81938fd1498Szrj will try to refer back to an earlier *declaration* of the
82038fd1498Szrj vtable as a static member of `S' and there won't be one. We
82138fd1498Szrj might be able to arrange to have the "vtable static member"
82238fd1498Szrj attached to the member list for `S' before the debug info for
82338fd1498Szrj `S' get written (which would solve the problem) but that would
82438fd1498Szrj require more intrusive changes to the g++ front end. */
82538fd1498Szrj DECL_IGNORED_P (decl) = 1;
82638fd1498Szrj
82738fd1498Szrj return decl;
82838fd1498Szrj }
82938fd1498Szrj
83038fd1498Szrj /* Get the VAR_DECL of the vtable for TYPE. TYPE need not be polymorphic,
83138fd1498Szrj or even complete. If this does not exist, create it. If COMPLETE is
83238fd1498Szrj nonzero, then complete the definition of it -- that will render it
83338fd1498Szrj impossible to actually build the vtable, but is useful to get at those
83438fd1498Szrj which are known to exist in the runtime. */
83538fd1498Szrj
83638fd1498Szrj tree
get_vtable_decl(tree type,int complete)83738fd1498Szrj get_vtable_decl (tree type, int complete)
83838fd1498Szrj {
83938fd1498Szrj tree decl;
84038fd1498Szrj
84138fd1498Szrj if (CLASSTYPE_VTABLES (type))
84238fd1498Szrj return CLASSTYPE_VTABLES (type);
84338fd1498Szrj
84438fd1498Szrj decl = build_vtable (type, get_vtable_name (type), vtbl_type_node);
84538fd1498Szrj CLASSTYPE_VTABLES (type) = decl;
84638fd1498Szrj
84738fd1498Szrj if (complete)
84838fd1498Szrj {
84938fd1498Szrj DECL_EXTERNAL (decl) = 1;
85038fd1498Szrj cp_finish_decl (decl, NULL_TREE, false, NULL_TREE, 0);
85138fd1498Szrj }
85238fd1498Szrj
85338fd1498Szrj return decl;
85438fd1498Szrj }
85538fd1498Szrj
85638fd1498Szrj /* Build the primary virtual function table for TYPE. If BINFO is
85738fd1498Szrj non-NULL, build the vtable starting with the initial approximation
85838fd1498Szrj that it is the same as the one which is the head of the association
85938fd1498Szrj list. Returns a nonzero value if a new vtable is actually
86038fd1498Szrj created. */
86138fd1498Szrj
86238fd1498Szrj static int
build_primary_vtable(tree binfo,tree type)86338fd1498Szrj build_primary_vtable (tree binfo, tree type)
86438fd1498Szrj {
86538fd1498Szrj tree decl;
86638fd1498Szrj tree virtuals;
86738fd1498Szrj
86838fd1498Szrj decl = get_vtable_decl (type, /*complete=*/0);
86938fd1498Szrj
87038fd1498Szrj if (binfo)
87138fd1498Szrj {
87238fd1498Szrj if (BINFO_NEW_VTABLE_MARKED (binfo))
87338fd1498Szrj /* We have already created a vtable for this base, so there's
87438fd1498Szrj no need to do it again. */
87538fd1498Szrj return 0;
87638fd1498Szrj
87738fd1498Szrj virtuals = copy_list (BINFO_VIRTUALS (binfo));
87838fd1498Szrj TREE_TYPE (decl) = TREE_TYPE (get_vtbl_decl_for_binfo (binfo));
87938fd1498Szrj DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (decl));
88038fd1498Szrj DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
88138fd1498Szrj }
88238fd1498Szrj else
88338fd1498Szrj {
88438fd1498Szrj gcc_assert (TREE_TYPE (decl) == vtbl_type_node);
88538fd1498Szrj virtuals = NULL_TREE;
88638fd1498Szrj }
88738fd1498Szrj
88838fd1498Szrj /* Initialize the association list for this type, based
88938fd1498Szrj on our first approximation. */
89038fd1498Szrj BINFO_VTABLE (TYPE_BINFO (type)) = decl;
89138fd1498Szrj BINFO_VIRTUALS (TYPE_BINFO (type)) = virtuals;
89238fd1498Szrj SET_BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (type));
89338fd1498Szrj return 1;
89438fd1498Szrj }
89538fd1498Szrj
89638fd1498Szrj /* Give BINFO a new virtual function table which is initialized
89738fd1498Szrj with a skeleton-copy of its original initialization. The only
89838fd1498Szrj entry that changes is the `delta' entry, so we can really
89938fd1498Szrj share a lot of structure.
90038fd1498Szrj
90138fd1498Szrj FOR_TYPE is the most derived type which caused this table to
90238fd1498Szrj be needed.
90338fd1498Szrj
90438fd1498Szrj Returns nonzero if we haven't met BINFO before.
90538fd1498Szrj
90638fd1498Szrj The order in which vtables are built (by calling this function) for
90738fd1498Szrj an object must remain the same, otherwise a binary incompatibility
90838fd1498Szrj can result. */
90938fd1498Szrj
91038fd1498Szrj static int
build_secondary_vtable(tree binfo)91138fd1498Szrj build_secondary_vtable (tree binfo)
91238fd1498Szrj {
91338fd1498Szrj if (BINFO_NEW_VTABLE_MARKED (binfo))
91438fd1498Szrj /* We already created a vtable for this base. There's no need to
91538fd1498Szrj do it again. */
91638fd1498Szrj return 0;
91738fd1498Szrj
91838fd1498Szrj /* Remember that we've created a vtable for this BINFO, so that we
91938fd1498Szrj don't try to do so again. */
92038fd1498Szrj SET_BINFO_NEW_VTABLE_MARKED (binfo);
92138fd1498Szrj
92238fd1498Szrj /* Make fresh virtual list, so we can smash it later. */
92338fd1498Szrj BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));
92438fd1498Szrj
92538fd1498Szrj /* Secondary vtables are laid out as part of the same structure as
92638fd1498Szrj the primary vtable. */
92738fd1498Szrj BINFO_VTABLE (binfo) = NULL_TREE;
92838fd1498Szrj return 1;
92938fd1498Szrj }
93038fd1498Szrj
93138fd1498Szrj /* Create a new vtable for BINFO which is the hierarchy dominated by
93238fd1498Szrj T. Return nonzero if we actually created a new vtable. */
93338fd1498Szrj
93438fd1498Szrj static int
make_new_vtable(tree t,tree binfo)93538fd1498Szrj make_new_vtable (tree t, tree binfo)
93638fd1498Szrj {
93738fd1498Szrj if (binfo == TYPE_BINFO (t))
93838fd1498Szrj /* In this case, it is *type*'s vtable we are modifying. We start
93938fd1498Szrj with the approximation that its vtable is that of the
94038fd1498Szrj immediate base class. */
94138fd1498Szrj return build_primary_vtable (binfo, t);
94238fd1498Szrj else
94338fd1498Szrj /* This is our very own copy of `basetype' to play with. Later,
94438fd1498Szrj we will fill in all the virtual functions that override the
94538fd1498Szrj virtual functions in these base classes which are not defined
94638fd1498Szrj by the current type. */
94738fd1498Szrj return build_secondary_vtable (binfo);
94838fd1498Szrj }
94938fd1498Szrj
95038fd1498Szrj /* Make *VIRTUALS, an entry on the BINFO_VIRTUALS list for BINFO
95138fd1498Szrj (which is in the hierarchy dominated by T) list FNDECL as its
95238fd1498Szrj BV_FN. DELTA is the required constant adjustment from the `this'
95338fd1498Szrj pointer where the vtable entry appears to the `this' required when
95438fd1498Szrj the function is actually called. */
95538fd1498Szrj
95638fd1498Szrj static void
modify_vtable_entry(tree t,tree binfo,tree fndecl,tree delta,tree * virtuals)95738fd1498Szrj modify_vtable_entry (tree t,
95838fd1498Szrj tree binfo,
95938fd1498Szrj tree fndecl,
96038fd1498Szrj tree delta,
96138fd1498Szrj tree *virtuals)
96238fd1498Szrj {
96338fd1498Szrj tree v;
96438fd1498Szrj
96538fd1498Szrj v = *virtuals;
96638fd1498Szrj
96738fd1498Szrj if (fndecl != BV_FN (v)
96838fd1498Szrj || !tree_int_cst_equal (delta, BV_DELTA (v)))
96938fd1498Szrj {
97038fd1498Szrj /* We need a new vtable for BINFO. */
97138fd1498Szrj if (make_new_vtable (t, binfo))
97238fd1498Szrj {
97338fd1498Szrj /* If we really did make a new vtable, we also made a copy
97438fd1498Szrj of the BINFO_VIRTUALS list. Now, we have to find the
97538fd1498Szrj corresponding entry in that list. */
97638fd1498Szrj *virtuals = BINFO_VIRTUALS (binfo);
97738fd1498Szrj while (BV_FN (*virtuals) != BV_FN (v))
97838fd1498Szrj *virtuals = TREE_CHAIN (*virtuals);
97938fd1498Szrj v = *virtuals;
98038fd1498Szrj }
98138fd1498Szrj
98238fd1498Szrj BV_DELTA (v) = delta;
98338fd1498Szrj BV_VCALL_INDEX (v) = NULL_TREE;
98438fd1498Szrj BV_FN (v) = fndecl;
98538fd1498Szrj }
98638fd1498Szrj }
98738fd1498Szrj
98838fd1498Szrj
98938fd1498Szrj /* Add method METHOD to class TYPE. If VIA_USING indicates whether
99038fd1498Szrj METHOD is being injected via a using_decl. Returns true if the
99138fd1498Szrj method could be added to the method vec. */
99238fd1498Szrj
99338fd1498Szrj bool
add_method(tree type,tree method,bool via_using)99438fd1498Szrj add_method (tree type, tree method, bool via_using)
99538fd1498Szrj {
99638fd1498Szrj if (method == error_mark_node)
99738fd1498Szrj return false;
99838fd1498Szrj
99938fd1498Szrj gcc_assert (!DECL_EXTERN_C_P (method));
100038fd1498Szrj
100138fd1498Szrj tree *slot = find_member_slot (type, DECL_NAME (method));
100238fd1498Szrj tree current_fns = slot ? *slot : NULL_TREE;
100338fd1498Szrj
100438fd1498Szrj /* Check to see if we've already got this method. */
100538fd1498Szrj for (ovl_iterator iter (current_fns); iter; ++iter)
100638fd1498Szrj {
100738fd1498Szrj tree fn = *iter;
100838fd1498Szrj tree fn_type;
100938fd1498Szrj tree method_type;
101038fd1498Szrj tree parms1;
101138fd1498Szrj tree parms2;
101238fd1498Szrj
101338fd1498Szrj if (TREE_CODE (fn) != TREE_CODE (method))
101438fd1498Szrj continue;
101538fd1498Szrj
101638fd1498Szrj /* Two using-declarations can coexist, we'll complain about ambiguity in
101738fd1498Szrj overload resolution. */
101838fd1498Szrj if (via_using && iter.using_p ()
101938fd1498Szrj /* Except handle inherited constructors specially. */
102038fd1498Szrj && ! DECL_CONSTRUCTOR_P (fn))
102138fd1498Szrj continue;
102238fd1498Szrj
102338fd1498Szrj /* [over.load] Member function declarations with the
102438fd1498Szrj same name and the same parameter types cannot be
102538fd1498Szrj overloaded if any of them is a static member
102638fd1498Szrj function declaration.
102738fd1498Szrj
102838fd1498Szrj [over.load] Member function declarations with the same name and
102938fd1498Szrj the same parameter-type-list as well as member function template
103038fd1498Szrj declarations with the same name, the same parameter-type-list, and
103138fd1498Szrj the same template parameter lists cannot be overloaded if any of
103238fd1498Szrj them, but not all, have a ref-qualifier.
103338fd1498Szrj
103438fd1498Szrj [namespace.udecl] When a using-declaration brings names
103538fd1498Szrj from a base class into a derived class scope, member
103638fd1498Szrj functions in the derived class override and/or hide member
103738fd1498Szrj functions with the same name and parameter types in a base
103838fd1498Szrj class (rather than conflicting). */
103938fd1498Szrj fn_type = TREE_TYPE (fn);
104038fd1498Szrj method_type = TREE_TYPE (method);
104138fd1498Szrj parms1 = TYPE_ARG_TYPES (fn_type);
104238fd1498Szrj parms2 = TYPE_ARG_TYPES (method_type);
104338fd1498Szrj
104438fd1498Szrj /* Compare the quals on the 'this' parm. Don't compare
104538fd1498Szrj the whole types, as used functions are treated as
104638fd1498Szrj coming from the using class in overload resolution. */
104738fd1498Szrj if (! DECL_STATIC_FUNCTION_P (fn)
104838fd1498Szrj && ! DECL_STATIC_FUNCTION_P (method)
104938fd1498Szrj /* Either both or neither need to be ref-qualified for
105038fd1498Szrj differing quals to allow overloading. */
105138fd1498Szrj && (FUNCTION_REF_QUALIFIED (fn_type)
105238fd1498Szrj == FUNCTION_REF_QUALIFIED (method_type))
105338fd1498Szrj && (type_memfn_quals (fn_type) != type_memfn_quals (method_type)
105438fd1498Szrj || type_memfn_rqual (fn_type) != type_memfn_rqual (method_type)))
105538fd1498Szrj continue;
105638fd1498Szrj
105738fd1498Szrj /* For templates, the return type and template parameters
105838fd1498Szrj must be identical. */
105938fd1498Szrj if (TREE_CODE (fn) == TEMPLATE_DECL
106038fd1498Szrj && (!same_type_p (TREE_TYPE (fn_type),
106138fd1498Szrj TREE_TYPE (method_type))
106238fd1498Szrj || !comp_template_parms (DECL_TEMPLATE_PARMS (fn),
106338fd1498Szrj DECL_TEMPLATE_PARMS (method))))
106438fd1498Szrj continue;
106538fd1498Szrj
106638fd1498Szrj if (! DECL_STATIC_FUNCTION_P (fn))
106738fd1498Szrj parms1 = TREE_CHAIN (parms1);
106838fd1498Szrj if (! DECL_STATIC_FUNCTION_P (method))
106938fd1498Szrj parms2 = TREE_CHAIN (parms2);
107038fd1498Szrj
107138fd1498Szrj /* Bring back parameters omitted from an inherited ctor. */
107238fd1498Szrj if (ctor_omit_inherited_parms (fn))
107338fd1498Szrj parms1 = FUNCTION_FIRST_USER_PARMTYPE (DECL_ORIGIN (fn));
107438fd1498Szrj if (ctor_omit_inherited_parms (method))
107538fd1498Szrj parms2 = FUNCTION_FIRST_USER_PARMTYPE (DECL_ORIGIN (method));
107638fd1498Szrj
107738fd1498Szrj if (compparms (parms1, parms2)
107838fd1498Szrj && (!DECL_CONV_FN_P (fn)
107938fd1498Szrj || same_type_p (TREE_TYPE (fn_type),
108038fd1498Szrj TREE_TYPE (method_type)))
108138fd1498Szrj && equivalently_constrained (fn, method))
108238fd1498Szrj {
108338fd1498Szrj /* If these are versions of the same function, process and
108438fd1498Szrj move on. */
108538fd1498Szrj if (TREE_CODE (fn) == FUNCTION_DECL
108638fd1498Szrj && maybe_version_functions (method, fn, true))
108738fd1498Szrj continue;
108838fd1498Szrj
108938fd1498Szrj if (DECL_INHERITED_CTOR (method))
109038fd1498Szrj {
109138fd1498Szrj if (DECL_INHERITED_CTOR (fn))
109238fd1498Szrj {
109338fd1498Szrj tree basem = DECL_INHERITED_CTOR_BASE (method);
109438fd1498Szrj tree basef = DECL_INHERITED_CTOR_BASE (fn);
109538fd1498Szrj if (flag_new_inheriting_ctors)
109638fd1498Szrj {
109738fd1498Szrj if (basem == basef)
109838fd1498Szrj {
109938fd1498Szrj /* Inheriting the same constructor along different
110038fd1498Szrj paths, combine them. */
110138fd1498Szrj SET_DECL_INHERITED_CTOR
110238fd1498Szrj (fn, ovl_make (DECL_INHERITED_CTOR (method),
110338fd1498Szrj DECL_INHERITED_CTOR (fn)));
110438fd1498Szrj /* And discard the new one. */
110538fd1498Szrj return false;
110638fd1498Szrj }
110738fd1498Szrj else
110838fd1498Szrj /* Inherited ctors can coexist until overload
110938fd1498Szrj resolution. */
111038fd1498Szrj continue;
111138fd1498Szrj }
111238fd1498Szrj error_at (DECL_SOURCE_LOCATION (method),
111338fd1498Szrj "%q#D conflicts with version inherited from %qT",
111438fd1498Szrj method, basef);
111538fd1498Szrj inform (DECL_SOURCE_LOCATION (fn),
111638fd1498Szrj "version inherited from %qT declared here",
111738fd1498Szrj basef);
111838fd1498Szrj }
111938fd1498Szrj /* Otherwise defer to the other function. */
112038fd1498Szrj return false;
112138fd1498Szrj }
112238fd1498Szrj
112338fd1498Szrj if (via_using)
112438fd1498Szrj /* Defer to the local function. */
112538fd1498Szrj return false;
112638fd1498Szrj else if (flag_new_inheriting_ctors
112738fd1498Szrj && DECL_INHERITED_CTOR (fn))
112838fd1498Szrj {
112938fd1498Szrj /* Remove the inherited constructor. */
113038fd1498Szrj current_fns = iter.remove_node (current_fns);
113138fd1498Szrj continue;
113238fd1498Szrj }
113338fd1498Szrj else
113438fd1498Szrj {
113538fd1498Szrj error_at (DECL_SOURCE_LOCATION (method),
113638fd1498Szrj "%q#D cannot be overloaded with %q#D", method, fn);
113738fd1498Szrj inform (DECL_SOURCE_LOCATION (fn),
113838fd1498Szrj "previous declaration %q#D", fn);
113938fd1498Szrj return false;
114038fd1498Szrj }
114138fd1498Szrj }
114238fd1498Szrj }
114338fd1498Szrj
114438fd1498Szrj current_fns = ovl_insert (method, current_fns, via_using);
114538fd1498Szrj
114638fd1498Szrj if (!COMPLETE_TYPE_P (type) && !DECL_CONV_FN_P (method)
114738fd1498Szrj && !push_class_level_binding (DECL_NAME (method), current_fns))
114838fd1498Szrj return false;
114938fd1498Szrj
115038fd1498Szrj if (!slot)
115138fd1498Szrj slot = add_member_slot (type, DECL_NAME (method));
115238fd1498Szrj
115338fd1498Szrj /* Maintain TYPE_HAS_USER_CONSTRUCTOR, etc. */
115438fd1498Szrj grok_special_member_properties (method);
115538fd1498Szrj
115638fd1498Szrj *slot = current_fns;
115738fd1498Szrj
115838fd1498Szrj return true;
115938fd1498Szrj }
116038fd1498Szrj
116138fd1498Szrj /* Subroutines of finish_struct. */
116238fd1498Szrj
116338fd1498Szrj /* Change the access of FDECL to ACCESS in T. Return 1 if change was
116438fd1498Szrj legit, otherwise return 0. */
116538fd1498Szrj
116638fd1498Szrj static int
alter_access(tree t,tree fdecl,tree access)116738fd1498Szrj alter_access (tree t, tree fdecl, tree access)
116838fd1498Szrj {
116938fd1498Szrj tree elem;
117038fd1498Szrj
117138fd1498Szrj retrofit_lang_decl (fdecl);
117238fd1498Szrj
117338fd1498Szrj gcc_assert (!DECL_DISCRIMINATOR_P (fdecl));
117438fd1498Szrj
117538fd1498Szrj elem = purpose_member (t, DECL_ACCESS (fdecl));
117638fd1498Szrj if (elem)
117738fd1498Szrj {
117838fd1498Szrj if (TREE_VALUE (elem) != access)
117938fd1498Szrj {
118038fd1498Szrj if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)
118138fd1498Szrj error ("conflicting access specifications for method"
118238fd1498Szrj " %q+D, ignored", TREE_TYPE (fdecl));
118338fd1498Szrj else
118438fd1498Szrj error ("conflicting access specifications for field %qE, ignored",
118538fd1498Szrj DECL_NAME (fdecl));
118638fd1498Szrj }
118738fd1498Szrj else
118838fd1498Szrj {
118938fd1498Szrj /* They're changing the access to the same thing they changed
119038fd1498Szrj it to before. That's OK. */
119138fd1498Szrj ;
119238fd1498Szrj }
119338fd1498Szrj }
119438fd1498Szrj else
119538fd1498Szrj {
119638fd1498Szrj perform_or_defer_access_check (TYPE_BINFO (t), fdecl, fdecl,
119738fd1498Szrj tf_warning_or_error);
119838fd1498Szrj DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
119938fd1498Szrj return 1;
120038fd1498Szrj }
120138fd1498Szrj return 0;
120238fd1498Szrj }
120338fd1498Szrj
120438fd1498Szrj /* Return the access node for DECL's access in its enclosing class. */
120538fd1498Szrj
120638fd1498Szrj tree
declared_access(tree decl)120738fd1498Szrj declared_access (tree decl)
120838fd1498Szrj {
120938fd1498Szrj return (TREE_PRIVATE (decl) ? access_private_node
121038fd1498Szrj : TREE_PROTECTED (decl) ? access_protected_node
121138fd1498Szrj : access_public_node);
121238fd1498Szrj }
121338fd1498Szrj
121438fd1498Szrj /* Process the USING_DECL, which is a member of T. */
121538fd1498Szrj
121638fd1498Szrj static void
handle_using_decl(tree using_decl,tree t)121738fd1498Szrj handle_using_decl (tree using_decl, tree t)
121838fd1498Szrj {
121938fd1498Szrj tree decl = USING_DECL_DECLS (using_decl);
122038fd1498Szrj tree name = DECL_NAME (using_decl);
122138fd1498Szrj tree access = declared_access (using_decl);
122238fd1498Szrj tree flist = NULL_TREE;
122338fd1498Szrj tree old_value;
122438fd1498Szrj
122538fd1498Szrj gcc_assert (!processing_template_decl && decl);
122638fd1498Szrj
122738fd1498Szrj old_value = lookup_member (t, name, /*protect=*/0, /*want_type=*/false,
122838fd1498Szrj tf_warning_or_error);
122938fd1498Szrj if (old_value)
123038fd1498Szrj {
123138fd1498Szrj old_value = OVL_FIRST (old_value);
123238fd1498Szrj
123338fd1498Szrj if (DECL_P (old_value) && DECL_CONTEXT (old_value) == t)
123438fd1498Szrj /* OK */;
123538fd1498Szrj else
123638fd1498Szrj old_value = NULL_TREE;
123738fd1498Szrj }
123838fd1498Szrj
123938fd1498Szrj cp_emit_debug_info_for_using (decl, t);
124038fd1498Szrj
124138fd1498Szrj if (is_overloaded_fn (decl))
124238fd1498Szrj flist = decl;
124338fd1498Szrj
124438fd1498Szrj if (! old_value)
124538fd1498Szrj ;
124638fd1498Szrj else if (is_overloaded_fn (old_value))
124738fd1498Szrj {
124838fd1498Szrj if (flist)
124938fd1498Szrj /* It's OK to use functions from a base when there are functions with
125038fd1498Szrj the same name already present in the current class. */;
125138fd1498Szrj else
125238fd1498Szrj {
125338fd1498Szrj error_at (DECL_SOURCE_LOCATION (using_decl), "%qD invalid in %q#T "
125438fd1498Szrj "because of local method %q#D with same name",
125538fd1498Szrj using_decl, t, old_value);
125638fd1498Szrj inform (DECL_SOURCE_LOCATION (old_value),
125738fd1498Szrj "local method %q#D declared here", old_value);
125838fd1498Szrj return;
125938fd1498Szrj }
126038fd1498Szrj }
126138fd1498Szrj else if (!DECL_ARTIFICIAL (old_value))
126238fd1498Szrj {
126338fd1498Szrj error_at (DECL_SOURCE_LOCATION (using_decl), "%qD invalid in %q#T "
126438fd1498Szrj "because of local member %q#D with same name",
126538fd1498Szrj using_decl, t, old_value);
126638fd1498Szrj inform (DECL_SOURCE_LOCATION (old_value),
126738fd1498Szrj "local member %q#D declared here", old_value);
126838fd1498Szrj return;
126938fd1498Szrj }
127038fd1498Szrj
127138fd1498Szrj /* Make type T see field decl FDECL with access ACCESS. */
127238fd1498Szrj if (flist)
127338fd1498Szrj for (ovl_iterator iter (flist); iter; ++iter)
127438fd1498Szrj {
127538fd1498Szrj add_method (t, *iter, true);
127638fd1498Szrj alter_access (t, *iter, access);
127738fd1498Szrj }
127838fd1498Szrj else
127938fd1498Szrj alter_access (t, decl, access);
128038fd1498Szrj }
128138fd1498Szrj
128238fd1498Szrj /* Data structure for find_abi_tags_r, below. */
128338fd1498Szrj
128438fd1498Szrj struct abi_tag_data
128538fd1498Szrj {
128638fd1498Szrj tree t; // The type that we're checking for missing tags.
128738fd1498Szrj tree subob; // The subobject of T that we're getting tags from.
128838fd1498Szrj tree tags; // error_mark_node for diagnostics, or a list of missing tags.
128938fd1498Szrj };
129038fd1498Szrj
129138fd1498Szrj /* Subroutine of find_abi_tags_r. Handle a single TAG found on the class TP
129238fd1498Szrj in the context of P. TAG can be either an identifier (the DECL_NAME of
129338fd1498Szrj a tag NAMESPACE_DECL) or a STRING_CST (a tag attribute). */
129438fd1498Szrj
129538fd1498Szrj static void
check_tag(tree tag,tree id,tree * tp,abi_tag_data * p)129638fd1498Szrj check_tag (tree tag, tree id, tree *tp, abi_tag_data *p)
129738fd1498Szrj {
129838fd1498Szrj if (!IDENTIFIER_MARKED (id))
129938fd1498Szrj {
130038fd1498Szrj if (p->tags != error_mark_node)
130138fd1498Szrj {
130238fd1498Szrj /* We're collecting tags from template arguments or from
130338fd1498Szrj the type of a variable or function return type. */
130438fd1498Szrj p->tags = tree_cons (NULL_TREE, tag, p->tags);
130538fd1498Szrj
130638fd1498Szrj /* Don't inherit this tag multiple times. */
130738fd1498Szrj IDENTIFIER_MARKED (id) = true;
130838fd1498Szrj
130938fd1498Szrj if (TYPE_P (p->t))
131038fd1498Szrj {
131138fd1498Szrj /* Tags inherited from type template arguments are only used
131238fd1498Szrj to avoid warnings. */
131338fd1498Szrj ABI_TAG_IMPLICIT (p->tags) = true;
131438fd1498Szrj return;
131538fd1498Szrj }
131638fd1498Szrj /* For functions and variables we want to warn, too. */
131738fd1498Szrj }
131838fd1498Szrj
131938fd1498Szrj /* Otherwise we're diagnosing missing tags. */
132038fd1498Szrj if (TREE_CODE (p->t) == FUNCTION_DECL)
132138fd1498Szrj {
132238fd1498Szrj if (warning (OPT_Wabi_tag, "%qD inherits the %E ABI tag "
132338fd1498Szrj "that %qT (used in its return type) has",
132438fd1498Szrj p->t, tag, *tp))
132538fd1498Szrj inform (location_of (*tp), "%qT declared here", *tp);
132638fd1498Szrj }
132738fd1498Szrj else if (VAR_P (p->t))
132838fd1498Szrj {
132938fd1498Szrj if (warning (OPT_Wabi_tag, "%qD inherits the %E ABI tag "
133038fd1498Szrj "that %qT (used in its type) has", p->t, tag, *tp))
133138fd1498Szrj inform (location_of (*tp), "%qT declared here", *tp);
133238fd1498Szrj }
133338fd1498Szrj else if (TYPE_P (p->subob))
133438fd1498Szrj {
133538fd1498Szrj if (warning (OPT_Wabi_tag, "%qT does not have the %E ABI tag "
133638fd1498Szrj "that base %qT has", p->t, tag, p->subob))
133738fd1498Szrj inform (location_of (p->subob), "%qT declared here",
133838fd1498Szrj p->subob);
133938fd1498Szrj }
134038fd1498Szrj else
134138fd1498Szrj {
134238fd1498Szrj if (warning (OPT_Wabi_tag, "%qT does not have the %E ABI tag "
134338fd1498Szrj "that %qT (used in the type of %qD) has",
134438fd1498Szrj p->t, tag, *tp, p->subob))
134538fd1498Szrj {
134638fd1498Szrj inform (location_of (p->subob), "%qD declared here",
134738fd1498Szrj p->subob);
134838fd1498Szrj inform (location_of (*tp), "%qT declared here", *tp);
134938fd1498Szrj }
135038fd1498Szrj }
135138fd1498Szrj }
135238fd1498Szrj }
135338fd1498Szrj
135438fd1498Szrj /* Find all the ABI tags in the attribute list ATTR and either call
135538fd1498Szrj check_tag (if TP is non-null) or set IDENTIFIER_MARKED to val. */
135638fd1498Szrj
135738fd1498Szrj static void
mark_or_check_attr_tags(tree attr,tree * tp,abi_tag_data * p,bool val)135838fd1498Szrj mark_or_check_attr_tags (tree attr, tree *tp, abi_tag_data *p, bool val)
135938fd1498Szrj {
136038fd1498Szrj if (!attr)
136138fd1498Szrj return;
136238fd1498Szrj for (; (attr = lookup_attribute ("abi_tag", attr));
136338fd1498Szrj attr = TREE_CHAIN (attr))
136438fd1498Szrj for (tree list = TREE_VALUE (attr); list;
136538fd1498Szrj list = TREE_CHAIN (list))
136638fd1498Szrj {
136738fd1498Szrj tree tag = TREE_VALUE (list);
136838fd1498Szrj tree id = get_identifier (TREE_STRING_POINTER (tag));
136938fd1498Szrj if (tp)
137038fd1498Szrj check_tag (tag, id, tp, p);
137138fd1498Szrj else
137238fd1498Szrj IDENTIFIER_MARKED (id) = val;
137338fd1498Szrj }
137438fd1498Szrj }
137538fd1498Szrj
137638fd1498Szrj /* Find all the ABI tags on T and its enclosing scopes and either call
137738fd1498Szrj check_tag (if TP is non-null) or set IDENTIFIER_MARKED to val. */
137838fd1498Szrj
137938fd1498Szrj static void
mark_or_check_tags(tree t,tree * tp,abi_tag_data * p,bool val)138038fd1498Szrj mark_or_check_tags (tree t, tree *tp, abi_tag_data *p, bool val)
138138fd1498Szrj {
138238fd1498Szrj while (t != global_namespace)
138338fd1498Szrj {
138438fd1498Szrj tree attr;
138538fd1498Szrj if (TYPE_P (t))
138638fd1498Szrj {
138738fd1498Szrj attr = TYPE_ATTRIBUTES (t);
138838fd1498Szrj t = CP_TYPE_CONTEXT (t);
138938fd1498Szrj }
139038fd1498Szrj else
139138fd1498Szrj {
139238fd1498Szrj attr = DECL_ATTRIBUTES (t);
139338fd1498Szrj t = CP_DECL_CONTEXT (t);
139438fd1498Szrj }
139538fd1498Szrj mark_or_check_attr_tags (attr, tp, p, val);
139638fd1498Szrj }
139738fd1498Szrj }
139838fd1498Szrj
139938fd1498Szrj /* walk_tree callback for check_abi_tags: if the type at *TP involves any
140038fd1498Szrj types with ABI tags, add the corresponding identifiers to the VEC in
140138fd1498Szrj *DATA and set IDENTIFIER_MARKED. */
140238fd1498Szrj
140338fd1498Szrj static tree
find_abi_tags_r(tree * tp,int * walk_subtrees,void * data)140438fd1498Szrj find_abi_tags_r (tree *tp, int *walk_subtrees, void *data)
140538fd1498Szrj {
140638fd1498Szrj if (!OVERLOAD_TYPE_P (*tp))
140738fd1498Szrj return NULL_TREE;
140838fd1498Szrj
140938fd1498Szrj /* walk_tree shouldn't be walking into any subtrees of a RECORD_TYPE
141038fd1498Szrj anyway, but let's make sure of it. */
141138fd1498Szrj *walk_subtrees = false;
141238fd1498Szrj
141338fd1498Szrj abi_tag_data *p = static_cast<struct abi_tag_data*>(data);
141438fd1498Szrj
141538fd1498Szrj mark_or_check_tags (*tp, tp, p, false);
141638fd1498Szrj
141738fd1498Szrj return NULL_TREE;
141838fd1498Szrj }
141938fd1498Szrj
142038fd1498Szrj /* walk_tree callback for mark_abi_tags: if *TP is a class, set
142138fd1498Szrj IDENTIFIER_MARKED on its ABI tags. */
142238fd1498Szrj
142338fd1498Szrj static tree
mark_abi_tags_r(tree * tp,int * walk_subtrees,void * data)142438fd1498Szrj mark_abi_tags_r (tree *tp, int *walk_subtrees, void *data)
142538fd1498Szrj {
142638fd1498Szrj if (!OVERLOAD_TYPE_P (*tp))
142738fd1498Szrj return NULL_TREE;
142838fd1498Szrj
142938fd1498Szrj /* walk_tree shouldn't be walking into any subtrees of a RECORD_TYPE
143038fd1498Szrj anyway, but let's make sure of it. */
143138fd1498Szrj *walk_subtrees = false;
143238fd1498Szrj
143338fd1498Szrj bool *valp = static_cast<bool*>(data);
143438fd1498Szrj
143538fd1498Szrj mark_or_check_tags (*tp, NULL, NULL, *valp);
143638fd1498Szrj
143738fd1498Szrj return NULL_TREE;
143838fd1498Szrj }
143938fd1498Szrj
144038fd1498Szrj /* Set IDENTIFIER_MARKED on all the ABI tags on T and its enclosing
144138fd1498Szrj scopes. */
144238fd1498Szrj
144338fd1498Szrj static void
mark_abi_tags(tree t,bool val)144438fd1498Szrj mark_abi_tags (tree t, bool val)
144538fd1498Szrj {
144638fd1498Szrj mark_or_check_tags (t, NULL, NULL, val);
144738fd1498Szrj if (DECL_P (t))
144838fd1498Szrj {
144938fd1498Szrj if (DECL_LANG_SPECIFIC (t) && DECL_USE_TEMPLATE (t)
145038fd1498Szrj && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))
145138fd1498Szrj {
145238fd1498Szrj /* Template arguments are part of the signature. */
145338fd1498Szrj tree level = INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (t));
145438fd1498Szrj for (int j = 0; j < TREE_VEC_LENGTH (level); ++j)
145538fd1498Szrj {
145638fd1498Szrj tree arg = TREE_VEC_ELT (level, j);
145738fd1498Szrj cp_walk_tree_without_duplicates (&arg, mark_abi_tags_r, &val);
145838fd1498Szrj }
145938fd1498Szrj }
146038fd1498Szrj if (TREE_CODE (t) == FUNCTION_DECL)
146138fd1498Szrj /* A function's parameter types are part of the signature, so
146238fd1498Szrj we don't need to inherit any tags that are also in them. */
146338fd1498Szrj for (tree arg = FUNCTION_FIRST_USER_PARMTYPE (t); arg;
146438fd1498Szrj arg = TREE_CHAIN (arg))
146538fd1498Szrj cp_walk_tree_without_duplicates (&TREE_VALUE (arg),
146638fd1498Szrj mark_abi_tags_r, &val);
146738fd1498Szrj }
146838fd1498Szrj }
146938fd1498Szrj
147038fd1498Szrj /* Check that T has all the ABI tags that subobject SUBOB has, or
147138fd1498Szrj warn if not. If T is a (variable or function) declaration, also
147238fd1498Szrj return any missing tags, and add them to T if JUST_CHECKING is false. */
147338fd1498Szrj
147438fd1498Szrj static tree
147538fd1498Szrj check_abi_tags (tree t, tree subob, bool just_checking = false)
147638fd1498Szrj {
147738fd1498Szrj bool inherit = DECL_P (t);
147838fd1498Szrj
147938fd1498Szrj if (!inherit && !warn_abi_tag)
148038fd1498Szrj return NULL_TREE;
148138fd1498Szrj
148238fd1498Szrj tree decl = TYPE_P (t) ? TYPE_NAME (t) : t;
148338fd1498Szrj if (!TREE_PUBLIC (decl))
148438fd1498Szrj /* No need to worry about things local to this TU. */
148538fd1498Szrj return NULL_TREE;
148638fd1498Szrj
148738fd1498Szrj mark_abi_tags (t, true);
148838fd1498Szrj
148938fd1498Szrj tree subtype = TYPE_P (subob) ? subob : TREE_TYPE (subob);
149038fd1498Szrj struct abi_tag_data data = { t, subob, error_mark_node };
149138fd1498Szrj if (inherit)
149238fd1498Szrj data.tags = NULL_TREE;
149338fd1498Szrj
149438fd1498Szrj cp_walk_tree_without_duplicates (&subtype, find_abi_tags_r, &data);
149538fd1498Szrj
149638fd1498Szrj if (!(inherit && data.tags))
149738fd1498Szrj /* We don't need to do anything with data.tags. */;
149838fd1498Szrj else if (just_checking)
149938fd1498Szrj for (tree t = data.tags; t; t = TREE_CHAIN (t))
150038fd1498Szrj {
150138fd1498Szrj tree id = get_identifier (TREE_STRING_POINTER (TREE_VALUE (t)));
150238fd1498Szrj IDENTIFIER_MARKED (id) = false;
150338fd1498Szrj }
150438fd1498Szrj else
150538fd1498Szrj {
150638fd1498Szrj tree attr = lookup_attribute ("abi_tag", DECL_ATTRIBUTES (t));
150738fd1498Szrj if (attr)
150838fd1498Szrj TREE_VALUE (attr) = chainon (data.tags, TREE_VALUE (attr));
150938fd1498Szrj else
151038fd1498Szrj DECL_ATTRIBUTES (t)
151138fd1498Szrj = tree_cons (get_identifier ("abi_tag"), data.tags,
151238fd1498Szrj DECL_ATTRIBUTES (t));
151338fd1498Szrj }
151438fd1498Szrj
151538fd1498Szrj mark_abi_tags (t, false);
151638fd1498Szrj
151738fd1498Szrj return data.tags;
151838fd1498Szrj }
151938fd1498Szrj
152038fd1498Szrj /* Check that DECL has all the ABI tags that are used in parts of its type
152138fd1498Szrj that are not reflected in its mangled name. */
152238fd1498Szrj
152338fd1498Szrj void
check_abi_tags(tree decl)152438fd1498Szrj check_abi_tags (tree decl)
152538fd1498Szrj {
152638fd1498Szrj if (VAR_P (decl))
152738fd1498Szrj check_abi_tags (decl, TREE_TYPE (decl));
152838fd1498Szrj else if (TREE_CODE (decl) == FUNCTION_DECL
152938fd1498Szrj && !DECL_CONV_FN_P (decl)
153038fd1498Szrj && !mangle_return_type_p (decl))
153138fd1498Szrj check_abi_tags (decl, TREE_TYPE (TREE_TYPE (decl)));
153238fd1498Szrj }
153338fd1498Szrj
153438fd1498Szrj /* Return any ABI tags that are used in parts of the type of DECL
153538fd1498Szrj that are not reflected in its mangled name. This function is only
153638fd1498Szrj used in backward-compatible mangling for ABI <11. */
153738fd1498Szrj
153838fd1498Szrj tree
missing_abi_tags(tree decl)153938fd1498Szrj missing_abi_tags (tree decl)
154038fd1498Szrj {
154138fd1498Szrj if (VAR_P (decl))
154238fd1498Szrj return check_abi_tags (decl, TREE_TYPE (decl), true);
154338fd1498Szrj else if (TREE_CODE (decl) == FUNCTION_DECL
154438fd1498Szrj /* Don't check DECL_CONV_FN_P here like we do in check_abi_tags, so
154538fd1498Szrj that we can use this function for setting need_abi_warning
154638fd1498Szrj regardless of the current flag_abi_version. */
154738fd1498Szrj && !mangle_return_type_p (decl))
154838fd1498Szrj return check_abi_tags (decl, TREE_TYPE (TREE_TYPE (decl)), true);
154938fd1498Szrj else
155038fd1498Szrj return NULL_TREE;
155138fd1498Szrj }
155238fd1498Szrj
155338fd1498Szrj void
inherit_targ_abi_tags(tree t)155438fd1498Szrj inherit_targ_abi_tags (tree t)
155538fd1498Szrj {
155638fd1498Szrj if (!CLASS_TYPE_P (t)
155738fd1498Szrj || CLASSTYPE_TEMPLATE_INFO (t) == NULL_TREE)
155838fd1498Szrj return;
155938fd1498Szrj
156038fd1498Szrj mark_abi_tags (t, true);
156138fd1498Szrj
156238fd1498Szrj tree args = CLASSTYPE_TI_ARGS (t);
156338fd1498Szrj struct abi_tag_data data = { t, NULL_TREE, NULL_TREE };
156438fd1498Szrj for (int i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
156538fd1498Szrj {
156638fd1498Szrj tree level = TMPL_ARGS_LEVEL (args, i+1);
156738fd1498Szrj for (int j = 0; j < TREE_VEC_LENGTH (level); ++j)
156838fd1498Szrj {
156938fd1498Szrj tree arg = TREE_VEC_ELT (level, j);
157038fd1498Szrj data.subob = arg;
157138fd1498Szrj cp_walk_tree_without_duplicates (&arg, find_abi_tags_r, &data);
157238fd1498Szrj }
157338fd1498Szrj }
157438fd1498Szrj
157538fd1498Szrj // If we found some tags on our template arguments, add them to our
157638fd1498Szrj // abi_tag attribute.
157738fd1498Szrj if (data.tags)
157838fd1498Szrj {
157938fd1498Szrj tree attr = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (t));
158038fd1498Szrj if (attr)
158138fd1498Szrj TREE_VALUE (attr) = chainon (data.tags, TREE_VALUE (attr));
158238fd1498Szrj else
158338fd1498Szrj TYPE_ATTRIBUTES (t)
158438fd1498Szrj = tree_cons (get_identifier ("abi_tag"), data.tags,
158538fd1498Szrj TYPE_ATTRIBUTES (t));
158638fd1498Szrj }
158738fd1498Szrj
158838fd1498Szrj mark_abi_tags (t, false);
158938fd1498Szrj }
159038fd1498Szrj
159138fd1498Szrj /* Return true, iff class T has a non-virtual destructor that is
159238fd1498Szrj accessible from outside the class heirarchy (i.e. is public, or
159338fd1498Szrj there's a suitable friend. */
159438fd1498Szrj
159538fd1498Szrj static bool
accessible_nvdtor_p(tree t)159638fd1498Szrj accessible_nvdtor_p (tree t)
159738fd1498Szrj {
159838fd1498Szrj tree dtor = CLASSTYPE_DESTRUCTOR (t);
159938fd1498Szrj
160038fd1498Szrj /* An implicitly declared destructor is always public. And,
160138fd1498Szrj if it were virtual, we would have created it by now. */
160238fd1498Szrj if (!dtor)
160338fd1498Szrj return true;
160438fd1498Szrj
160538fd1498Szrj if (DECL_VINDEX (dtor))
160638fd1498Szrj return false; /* Virtual */
160738fd1498Szrj
160838fd1498Szrj if (!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor))
160938fd1498Szrj return true; /* Public */
161038fd1498Szrj
161138fd1498Szrj if (CLASSTYPE_FRIEND_CLASSES (t)
161238fd1498Szrj || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
161338fd1498Szrj return true; /* Has friends */
161438fd1498Szrj
161538fd1498Szrj return false;
161638fd1498Szrj }
161738fd1498Szrj
161838fd1498Szrj /* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P,
161938fd1498Szrj and NO_CONST_ASN_REF_P. Also set flag bits in T based on
162038fd1498Szrj properties of the bases. */
162138fd1498Szrj
162238fd1498Szrj static void
check_bases(tree t,int * cant_have_const_ctor_p,int * no_const_asn_ref_p)162338fd1498Szrj check_bases (tree t,
162438fd1498Szrj int* cant_have_const_ctor_p,
162538fd1498Szrj int* no_const_asn_ref_p)
162638fd1498Szrj {
162738fd1498Szrj int i;
162838fd1498Szrj bool seen_non_virtual_nearly_empty_base_p = 0;
162938fd1498Szrj int seen_tm_mask = 0;
163038fd1498Szrj tree base_binfo;
163138fd1498Szrj tree binfo;
163238fd1498Szrj tree field = NULL_TREE;
163338fd1498Szrj
163438fd1498Szrj if (!CLASSTYPE_NON_STD_LAYOUT (t))
163538fd1498Szrj for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
163638fd1498Szrj if (TREE_CODE (field) == FIELD_DECL)
163738fd1498Szrj break;
163838fd1498Szrj
163938fd1498Szrj for (binfo = TYPE_BINFO (t), i = 0;
164038fd1498Szrj BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
164138fd1498Szrj {
164238fd1498Szrj tree basetype = TREE_TYPE (base_binfo);
164338fd1498Szrj
164438fd1498Szrj gcc_assert (COMPLETE_TYPE_P (basetype));
164538fd1498Szrj
164638fd1498Szrj if (CLASSTYPE_FINAL (basetype))
164738fd1498Szrj error ("cannot derive from %<final%> base %qT in derived type %qT",
164838fd1498Szrj basetype, t);
164938fd1498Szrj
165038fd1498Szrj /* If any base class is non-literal, so is the derived class. */
165138fd1498Szrj if (!CLASSTYPE_LITERAL_P (basetype))
165238fd1498Szrj CLASSTYPE_LITERAL_P (t) = false;
165338fd1498Szrj
165438fd1498Szrj /* If the base class doesn't have copy constructors or
165538fd1498Szrj assignment operators that take const references, then the
165638fd1498Szrj derived class cannot have such a member automatically
165738fd1498Szrj generated. */
165838fd1498Szrj if (TYPE_HAS_COPY_CTOR (basetype)
165938fd1498Szrj && ! TYPE_HAS_CONST_COPY_CTOR (basetype))
166038fd1498Szrj *cant_have_const_ctor_p = 1;
166138fd1498Szrj if (TYPE_HAS_COPY_ASSIGN (basetype)
166238fd1498Szrj && !TYPE_HAS_CONST_COPY_ASSIGN (basetype))
166338fd1498Szrj *no_const_asn_ref_p = 1;
166438fd1498Szrj
166538fd1498Szrj if (BINFO_VIRTUAL_P (base_binfo))
166638fd1498Szrj /* A virtual base does not effect nearly emptiness. */
166738fd1498Szrj ;
166838fd1498Szrj else if (CLASSTYPE_NEARLY_EMPTY_P (basetype))
166938fd1498Szrj {
167038fd1498Szrj if (seen_non_virtual_nearly_empty_base_p)
167138fd1498Szrj /* And if there is more than one nearly empty base, then the
167238fd1498Szrj derived class is not nearly empty either. */
167338fd1498Szrj CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
167438fd1498Szrj else
167538fd1498Szrj /* Remember we've seen one. */
167638fd1498Szrj seen_non_virtual_nearly_empty_base_p = 1;
167738fd1498Szrj }
167838fd1498Szrj else if (!is_empty_class (basetype))
167938fd1498Szrj /* If the base class is not empty or nearly empty, then this
168038fd1498Szrj class cannot be nearly empty. */
168138fd1498Szrj CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
168238fd1498Szrj
168338fd1498Szrj /* A lot of properties from the bases also apply to the derived
168438fd1498Szrj class. */
168538fd1498Szrj TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
168638fd1498Szrj TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
168738fd1498Szrj |= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype);
168838fd1498Szrj TYPE_HAS_COMPLEX_COPY_ASSIGN (t)
168938fd1498Szrj |= (TYPE_HAS_COMPLEX_COPY_ASSIGN (basetype)
169038fd1498Szrj || !TYPE_HAS_COPY_ASSIGN (basetype));
169138fd1498Szrj TYPE_HAS_COMPLEX_COPY_CTOR (t) |= (TYPE_HAS_COMPLEX_COPY_CTOR (basetype)
169238fd1498Szrj || !TYPE_HAS_COPY_CTOR (basetype));
169338fd1498Szrj TYPE_HAS_COMPLEX_MOVE_ASSIGN (t)
169438fd1498Szrj |= TYPE_HAS_COMPLEX_MOVE_ASSIGN (basetype);
169538fd1498Szrj TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_HAS_COMPLEX_MOVE_CTOR (basetype);
169638fd1498Szrj TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
169738fd1498Szrj CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
169838fd1498Szrj |= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
169938fd1498Szrj TYPE_HAS_COMPLEX_DFLT (t) |= (!TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)
170038fd1498Szrj || TYPE_HAS_COMPLEX_DFLT (basetype));
170138fd1498Szrj SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT
170238fd1498Szrj (t, CLASSTYPE_READONLY_FIELDS_NEED_INIT (t)
170338fd1498Szrj | CLASSTYPE_READONLY_FIELDS_NEED_INIT (basetype));
170438fd1498Szrj SET_CLASSTYPE_REF_FIELDS_NEED_INIT
170538fd1498Szrj (t, CLASSTYPE_REF_FIELDS_NEED_INIT (t)
170638fd1498Szrj | CLASSTYPE_REF_FIELDS_NEED_INIT (basetype));
170738fd1498Szrj if (TYPE_HAS_MUTABLE_P (basetype))
170838fd1498Szrj CLASSTYPE_HAS_MUTABLE (t) = 1;
170938fd1498Szrj
171038fd1498Szrj /* A standard-layout class is a class that:
171138fd1498Szrj ...
171238fd1498Szrj * has no non-standard-layout base classes, */
171338fd1498Szrj CLASSTYPE_NON_STD_LAYOUT (t) |= CLASSTYPE_NON_STD_LAYOUT (basetype);
171438fd1498Szrj if (!CLASSTYPE_NON_STD_LAYOUT (t))
171538fd1498Szrj {
171638fd1498Szrj tree basefield;
171738fd1498Szrj /* ...has no base classes of the same type as the first non-static
171838fd1498Szrj data member... */
171938fd1498Szrj if (field && DECL_CONTEXT (field) == t
172038fd1498Szrj && (same_type_ignoring_top_level_qualifiers_p
172138fd1498Szrj (TREE_TYPE (field), basetype)))
172238fd1498Szrj CLASSTYPE_NON_STD_LAYOUT (t) = 1;
172338fd1498Szrj else
172438fd1498Szrj /* ...either has no non-static data members in the most-derived
172538fd1498Szrj class and at most one base class with non-static data
172638fd1498Szrj members, or has no base classes with non-static data
172738fd1498Szrj members */
172838fd1498Szrj for (basefield = TYPE_FIELDS (basetype); basefield;
172938fd1498Szrj basefield = DECL_CHAIN (basefield))
173038fd1498Szrj if (TREE_CODE (basefield) == FIELD_DECL
173138fd1498Szrj && !(DECL_FIELD_IS_BASE (basefield)
173238fd1498Szrj && integer_zerop (DECL_SIZE (basefield))))
173338fd1498Szrj {
173438fd1498Szrj if (field)
173538fd1498Szrj CLASSTYPE_NON_STD_LAYOUT (t) = 1;
173638fd1498Szrj else
173738fd1498Szrj field = basefield;
173838fd1498Szrj break;
173938fd1498Szrj }
174038fd1498Szrj }
174138fd1498Szrj
174238fd1498Szrj /* Don't bother collecting tm attributes if transactional memory
174338fd1498Szrj support is not enabled. */
174438fd1498Szrj if (flag_tm)
174538fd1498Szrj {
174638fd1498Szrj tree tm_attr = find_tm_attribute (TYPE_ATTRIBUTES (basetype));
174738fd1498Szrj if (tm_attr)
174838fd1498Szrj seen_tm_mask |= tm_attr_to_mask (tm_attr);
174938fd1498Szrj }
175038fd1498Szrj
175138fd1498Szrj check_abi_tags (t, basetype);
175238fd1498Szrj }
175338fd1498Szrj
175438fd1498Szrj /* If one of the base classes had TM attributes, and the current class
175538fd1498Szrj doesn't define its own, then the current class inherits one. */
175638fd1498Szrj if (seen_tm_mask && !find_tm_attribute (TYPE_ATTRIBUTES (t)))
175738fd1498Szrj {
175838fd1498Szrj tree tm_attr = tm_mask_to_attr (least_bit_hwi (seen_tm_mask));
175938fd1498Szrj TYPE_ATTRIBUTES (t) = tree_cons (tm_attr, NULL, TYPE_ATTRIBUTES (t));
176038fd1498Szrj }
176138fd1498Szrj }
176238fd1498Szrj
176338fd1498Szrj /* Determine all the primary bases within T. Sets BINFO_PRIMARY_BASE_P for
176438fd1498Szrj those that are primaries. Sets BINFO_LOST_PRIMARY_P for those
176538fd1498Szrj that have had a nearly-empty virtual primary base stolen by some
176638fd1498Szrj other base in the hierarchy. Determines CLASSTYPE_PRIMARY_BASE for
176738fd1498Szrj T. */
176838fd1498Szrj
176938fd1498Szrj static void
determine_primary_bases(tree t)177038fd1498Szrj determine_primary_bases (tree t)
177138fd1498Szrj {
177238fd1498Szrj unsigned i;
177338fd1498Szrj tree primary = NULL_TREE;
177438fd1498Szrj tree type_binfo = TYPE_BINFO (t);
177538fd1498Szrj tree base_binfo;
177638fd1498Szrj
177738fd1498Szrj /* Determine the primary bases of our bases. */
177838fd1498Szrj for (base_binfo = TREE_CHAIN (type_binfo); base_binfo;
177938fd1498Szrj base_binfo = TREE_CHAIN (base_binfo))
178038fd1498Szrj {
178138fd1498Szrj tree primary = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (base_binfo));
178238fd1498Szrj
178338fd1498Szrj /* See if we're the non-virtual primary of our inheritance
178438fd1498Szrj chain. */
178538fd1498Szrj if (!BINFO_VIRTUAL_P (base_binfo))
178638fd1498Szrj {
178738fd1498Szrj tree parent = BINFO_INHERITANCE_CHAIN (base_binfo);
178838fd1498Szrj tree parent_primary = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (parent));
178938fd1498Szrj
179038fd1498Szrj if (parent_primary
179138fd1498Szrj && SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo),
179238fd1498Szrj BINFO_TYPE (parent_primary)))
179338fd1498Szrj /* We are the primary binfo. */
179438fd1498Szrj BINFO_PRIMARY_P (base_binfo) = 1;
179538fd1498Szrj }
179638fd1498Szrj /* Determine if we have a virtual primary base, and mark it so.
179738fd1498Szrj */
179838fd1498Szrj if (primary && BINFO_VIRTUAL_P (primary))
179938fd1498Szrj {
180038fd1498Szrj tree this_primary = copied_binfo (primary, base_binfo);
180138fd1498Szrj
180238fd1498Szrj if (BINFO_PRIMARY_P (this_primary))
180338fd1498Szrj /* Someone already claimed this base. */
180438fd1498Szrj BINFO_LOST_PRIMARY_P (base_binfo) = 1;
180538fd1498Szrj else
180638fd1498Szrj {
180738fd1498Szrj tree delta;
180838fd1498Szrj
180938fd1498Szrj BINFO_PRIMARY_P (this_primary) = 1;
181038fd1498Szrj BINFO_INHERITANCE_CHAIN (this_primary) = base_binfo;
181138fd1498Szrj
181238fd1498Szrj /* A virtual binfo might have been copied from within
181338fd1498Szrj another hierarchy. As we're about to use it as a
181438fd1498Szrj primary base, make sure the offsets match. */
181538fd1498Szrj delta = size_diffop_loc (input_location,
181638fd1498Szrj fold_convert (ssizetype,
181738fd1498Szrj BINFO_OFFSET (base_binfo)),
181838fd1498Szrj fold_convert (ssizetype,
181938fd1498Szrj BINFO_OFFSET (this_primary)));
182038fd1498Szrj
182138fd1498Szrj propagate_binfo_offsets (this_primary, delta);
182238fd1498Szrj }
182338fd1498Szrj }
182438fd1498Szrj }
182538fd1498Szrj
182638fd1498Szrj /* First look for a dynamic direct non-virtual base. */
182738fd1498Szrj for (i = 0; BINFO_BASE_ITERATE (type_binfo, i, base_binfo); i++)
182838fd1498Szrj {
182938fd1498Szrj tree basetype = BINFO_TYPE (base_binfo);
183038fd1498Szrj
183138fd1498Szrj if (TYPE_CONTAINS_VPTR_P (basetype) && !BINFO_VIRTUAL_P (base_binfo))
183238fd1498Szrj {
183338fd1498Szrj primary = base_binfo;
183438fd1498Szrj goto found;
183538fd1498Szrj }
183638fd1498Szrj }
183738fd1498Szrj
183838fd1498Szrj /* A "nearly-empty" virtual base class can be the primary base
183938fd1498Szrj class, if no non-virtual polymorphic base can be found. Look for
184038fd1498Szrj a nearly-empty virtual dynamic base that is not already a primary
184138fd1498Szrj base of something in the hierarchy. If there is no such base,
184238fd1498Szrj just pick the first nearly-empty virtual base. */
184338fd1498Szrj
184438fd1498Szrj for (base_binfo = TREE_CHAIN (type_binfo); base_binfo;
184538fd1498Szrj base_binfo = TREE_CHAIN (base_binfo))
184638fd1498Szrj if (BINFO_VIRTUAL_P (base_binfo)
184738fd1498Szrj && CLASSTYPE_NEARLY_EMPTY_P (BINFO_TYPE (base_binfo)))
184838fd1498Szrj {
184938fd1498Szrj if (!BINFO_PRIMARY_P (base_binfo))
185038fd1498Szrj {
185138fd1498Szrj /* Found one that is not primary. */
185238fd1498Szrj primary = base_binfo;
185338fd1498Szrj goto found;
185438fd1498Szrj }
185538fd1498Szrj else if (!primary)
185638fd1498Szrj /* Remember the first candidate. */
185738fd1498Szrj primary = base_binfo;
185838fd1498Szrj }
185938fd1498Szrj
186038fd1498Szrj found:
186138fd1498Szrj /* If we've got a primary base, use it. */
186238fd1498Szrj if (primary)
186338fd1498Szrj {
186438fd1498Szrj tree basetype = BINFO_TYPE (primary);
186538fd1498Szrj
186638fd1498Szrj CLASSTYPE_PRIMARY_BINFO (t) = primary;
186738fd1498Szrj if (BINFO_PRIMARY_P (primary))
186838fd1498Szrj /* We are stealing a primary base. */
186938fd1498Szrj BINFO_LOST_PRIMARY_P (BINFO_INHERITANCE_CHAIN (primary)) = 1;
187038fd1498Szrj BINFO_PRIMARY_P (primary) = 1;
187138fd1498Szrj if (BINFO_VIRTUAL_P (primary))
187238fd1498Szrj {
187338fd1498Szrj tree delta;
187438fd1498Szrj
187538fd1498Szrj BINFO_INHERITANCE_CHAIN (primary) = type_binfo;
187638fd1498Szrj /* A virtual binfo might have been copied from within
187738fd1498Szrj another hierarchy. As we're about to use it as a primary
187838fd1498Szrj base, make sure the offsets match. */
187938fd1498Szrj delta = size_diffop_loc (input_location, ssize_int (0),
188038fd1498Szrj fold_convert (ssizetype, BINFO_OFFSET (primary)));
188138fd1498Szrj
188238fd1498Szrj propagate_binfo_offsets (primary, delta);
188338fd1498Szrj }
188438fd1498Szrj
188538fd1498Szrj primary = TYPE_BINFO (basetype);
188638fd1498Szrj
188738fd1498Szrj TYPE_VFIELD (t) = TYPE_VFIELD (basetype);
188838fd1498Szrj BINFO_VTABLE (type_binfo) = BINFO_VTABLE (primary);
188938fd1498Szrj BINFO_VIRTUALS (type_binfo) = BINFO_VIRTUALS (primary);
189038fd1498Szrj }
189138fd1498Szrj }
189238fd1498Szrj
189338fd1498Szrj /* Update the variant types of T. */
189438fd1498Szrj
189538fd1498Szrj void
fixup_type_variants(tree t)189638fd1498Szrj fixup_type_variants (tree t)
189738fd1498Szrj {
189838fd1498Szrj tree variants;
189938fd1498Szrj
190038fd1498Szrj if (!t)
190138fd1498Szrj return;
190238fd1498Szrj
190338fd1498Szrj for (variants = TYPE_NEXT_VARIANT (t);
190438fd1498Szrj variants;
190538fd1498Szrj variants = TYPE_NEXT_VARIANT (variants))
190638fd1498Szrj {
190738fd1498Szrj /* These fields are in the _TYPE part of the node, not in
190838fd1498Szrj the TYPE_LANG_SPECIFIC component, so they are not shared. */
190938fd1498Szrj TYPE_HAS_USER_CONSTRUCTOR (variants) = TYPE_HAS_USER_CONSTRUCTOR (t);
191038fd1498Szrj TYPE_NEEDS_CONSTRUCTING (variants) = TYPE_NEEDS_CONSTRUCTING (t);
191138fd1498Szrj TYPE_HAS_NONTRIVIAL_DESTRUCTOR (variants)
191238fd1498Szrj = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);
191338fd1498Szrj
191438fd1498Szrj TYPE_POLYMORPHIC_P (variants) = TYPE_POLYMORPHIC_P (t);
191538fd1498Szrj
191638fd1498Szrj TYPE_BINFO (variants) = TYPE_BINFO (t);
191738fd1498Szrj
191838fd1498Szrj /* Copy whatever these are holding today. */
191938fd1498Szrj TYPE_VFIELD (variants) = TYPE_VFIELD (t);
192038fd1498Szrj TYPE_FIELDS (variants) = TYPE_FIELDS (t);
192138fd1498Szrj }
192238fd1498Szrj }
192338fd1498Szrj
192438fd1498Szrj /* KLASS is a class that we're applying may_alias to after the body is
192538fd1498Szrj parsed. Fixup any POINTER_TO and REFERENCE_TO types. The
192638fd1498Szrj canonical type(s) will be implicitly updated. */
192738fd1498Szrj
192838fd1498Szrj static void
fixup_may_alias(tree klass)192938fd1498Szrj fixup_may_alias (tree klass)
193038fd1498Szrj {
193138fd1498Szrj tree t, v;
193238fd1498Szrj
193338fd1498Szrj for (t = TYPE_POINTER_TO (klass); t; t = TYPE_NEXT_PTR_TO (t))
193438fd1498Szrj for (v = TYPE_MAIN_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v))
193538fd1498Szrj TYPE_REF_CAN_ALIAS_ALL (v) = true;
193638fd1498Szrj for (t = TYPE_REFERENCE_TO (klass); t; t = TYPE_NEXT_REF_TO (t))
193738fd1498Szrj for (v = TYPE_MAIN_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v))
193838fd1498Szrj TYPE_REF_CAN_ALIAS_ALL (v) = true;
193938fd1498Szrj }
194038fd1498Szrj
194138fd1498Szrj /* Early variant fixups: we apply attributes at the beginning of the class
194238fd1498Szrj definition, and we need to fix up any variants that have already been
194338fd1498Szrj made via elaborated-type-specifier so that check_qualified_type works. */
194438fd1498Szrj
194538fd1498Szrj void
fixup_attribute_variants(tree t)194638fd1498Szrj fixup_attribute_variants (tree t)
194738fd1498Szrj {
194838fd1498Szrj tree variants;
194938fd1498Szrj
195038fd1498Szrj if (!t)
195138fd1498Szrj return;
195238fd1498Szrj
195338fd1498Szrj tree attrs = TYPE_ATTRIBUTES (t);
195438fd1498Szrj unsigned align = TYPE_ALIGN (t);
195538fd1498Szrj bool user_align = TYPE_USER_ALIGN (t);
195638fd1498Szrj bool may_alias = lookup_attribute ("may_alias", attrs);
195758e805e6Szrj bool packed = TYPE_PACKED (t);
195838fd1498Szrj
195938fd1498Szrj if (may_alias)
196038fd1498Szrj fixup_may_alias (t);
196138fd1498Szrj
196238fd1498Szrj for (variants = TYPE_NEXT_VARIANT (t);
196338fd1498Szrj variants;
196438fd1498Szrj variants = TYPE_NEXT_VARIANT (variants))
196538fd1498Szrj {
196638fd1498Szrj /* These are the two fields that check_qualified_type looks at and
196738fd1498Szrj are affected by attributes. */
196838fd1498Szrj TYPE_ATTRIBUTES (variants) = attrs;
196938fd1498Szrj unsigned valign = align;
197038fd1498Szrj if (TYPE_USER_ALIGN (variants))
197138fd1498Szrj valign = MAX (valign, TYPE_ALIGN (variants));
197238fd1498Szrj else
197338fd1498Szrj TYPE_USER_ALIGN (variants) = user_align;
197438fd1498Szrj SET_TYPE_ALIGN (variants, valign);
197558e805e6Szrj TYPE_PACKED (variants) = packed;
197638fd1498Szrj if (may_alias)
197738fd1498Szrj fixup_may_alias (variants);
197838fd1498Szrj }
197938fd1498Szrj }
198038fd1498Szrj
198138fd1498Szrj /* Set memoizing fields and bits of T (and its variants) for later
198238fd1498Szrj use. */
198338fd1498Szrj
198438fd1498Szrj static void
finish_struct_bits(tree t)198538fd1498Szrj finish_struct_bits (tree t)
198638fd1498Szrj {
198738fd1498Szrj /* Fix up variants (if any). */
198838fd1498Szrj fixup_type_variants (t);
198938fd1498Szrj
199038fd1498Szrj if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
199138fd1498Szrj /* For a class w/o baseclasses, 'finish_struct' has set
199238fd1498Szrj CLASSTYPE_PURE_VIRTUALS correctly (by definition).
199338fd1498Szrj Similarly for a class whose base classes do not have vtables.
199438fd1498Szrj When neither of these is true, we might have removed abstract
199538fd1498Szrj virtuals (by providing a definition), added some (by declaring
199638fd1498Szrj new ones), or redeclared ones from a base class. We need to
199738fd1498Szrj recalculate what's really an abstract virtual at this point (by
199838fd1498Szrj looking in the vtables). */
199938fd1498Szrj get_pure_virtuals (t);
200038fd1498Szrj
200138fd1498Szrj /* If this type has a copy constructor or a destructor, force its
200238fd1498Szrj mode to be BLKmode, and force its TREE_ADDRESSABLE bit to be
200338fd1498Szrj nonzero. This will cause it to be passed by invisible reference
200438fd1498Szrj and prevent it from being returned in a register. */
200538fd1498Szrj if (type_has_nontrivial_copy_init (t)
200638fd1498Szrj || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
200738fd1498Szrj {
200838fd1498Szrj tree variants;
200938fd1498Szrj SET_DECL_MODE (TYPE_MAIN_DECL (t), BLKmode);
201038fd1498Szrj for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants))
201138fd1498Szrj {
201238fd1498Szrj SET_TYPE_MODE (variants, BLKmode);
201338fd1498Szrj TREE_ADDRESSABLE (variants) = 1;
201438fd1498Szrj }
201538fd1498Szrj }
201638fd1498Szrj }
201738fd1498Szrj
201838fd1498Szrj /* Issue warnings about T having private constructors, but no friends,
201938fd1498Szrj and so forth.
202038fd1498Szrj
202138fd1498Szrj HAS_NONPRIVATE_METHOD is nonzero if T has any non-private methods or
202238fd1498Szrj static members. HAS_NONPRIVATE_STATIC_FN is nonzero if T has any
202338fd1498Szrj non-private static member functions. */
202438fd1498Szrj
202538fd1498Szrj static void
maybe_warn_about_overly_private_class(tree t)202638fd1498Szrj maybe_warn_about_overly_private_class (tree t)
202738fd1498Szrj {
202838fd1498Szrj int has_member_fn = 0;
202938fd1498Szrj int has_nonprivate_method = 0;
203058e805e6Szrj bool nonprivate_ctor = false;
203138fd1498Szrj
203238fd1498Szrj if (!warn_ctor_dtor_privacy
203338fd1498Szrj /* If the class has friends, those entities might create and
203438fd1498Szrj access instances, so we should not warn. */
203538fd1498Szrj || (CLASSTYPE_FRIEND_CLASSES (t)
203638fd1498Szrj || DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
203738fd1498Szrj /* We will have warned when the template was declared; there's
203838fd1498Szrj no need to warn on every instantiation. */
203938fd1498Szrj || CLASSTYPE_TEMPLATE_INSTANTIATION (t))
204038fd1498Szrj /* There's no reason to even consider warning about this
204138fd1498Szrj class. */
204238fd1498Szrj return;
204338fd1498Szrj
204438fd1498Szrj /* We only issue one warning, if more than one applies, because
204538fd1498Szrj otherwise, on code like:
204638fd1498Szrj
204738fd1498Szrj class A {
204838fd1498Szrj // Oops - forgot `public:'
204938fd1498Szrj A();
205038fd1498Szrj A(const A&);
205138fd1498Szrj ~A();
205238fd1498Szrj };
205338fd1498Szrj
205438fd1498Szrj we warn several times about essentially the same problem. */
205538fd1498Szrj
205638fd1498Szrj /* Check to see if all (non-constructor, non-destructor) member
205738fd1498Szrj functions are private. (Since there are no friends or
205838fd1498Szrj non-private statics, we can't ever call any of the private member
205938fd1498Szrj functions.) */
206038fd1498Szrj for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
206158e805e6Szrj if (TREE_CODE (fn) == USING_DECL
206258e805e6Szrj && DECL_NAME (fn) == ctor_identifier
206358e805e6Szrj && !TREE_PRIVATE (fn))
206458e805e6Szrj nonprivate_ctor = true;
206558e805e6Szrj else if (!DECL_DECLARES_FUNCTION_P (fn))
206638fd1498Szrj /* Not a function. */;
206738fd1498Szrj else if (DECL_ARTIFICIAL (fn))
206838fd1498Szrj /* We're not interested in compiler-generated methods; they don't
206938fd1498Szrj provide any way to call private members. */;
207038fd1498Szrj else if (!TREE_PRIVATE (fn))
207138fd1498Szrj {
207238fd1498Szrj if (DECL_STATIC_FUNCTION_P (fn))
207338fd1498Szrj /* A non-private static member function is just like a
207438fd1498Szrj friend; it can create and invoke private member
207538fd1498Szrj functions, and be accessed without a class
207638fd1498Szrj instance. */
207738fd1498Szrj return;
207838fd1498Szrj
207938fd1498Szrj has_nonprivate_method = 1;
208038fd1498Szrj /* Keep searching for a static member function. */
208138fd1498Szrj }
208238fd1498Szrj else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
208338fd1498Szrj has_member_fn = 1;
208438fd1498Szrj
208538fd1498Szrj if (!has_nonprivate_method && has_member_fn)
208638fd1498Szrj {
208738fd1498Szrj /* There are no non-private methods, and there's at least one
208838fd1498Szrj private member function that isn't a constructor or
208938fd1498Szrj destructor. (If all the private members are
209038fd1498Szrj constructors/destructors we want to use the code below that
209138fd1498Szrj issues error messages specifically referring to
209238fd1498Szrj constructors/destructors.) */
209338fd1498Szrj unsigned i;
209438fd1498Szrj tree binfo = TYPE_BINFO (t);
209538fd1498Szrj
209638fd1498Szrj for (i = 0; i != BINFO_N_BASE_BINFOS (binfo); i++)
209738fd1498Szrj if (BINFO_BASE_ACCESS (binfo, i) != access_private_node)
209838fd1498Szrj {
209938fd1498Szrj has_nonprivate_method = 1;
210038fd1498Szrj break;
210138fd1498Szrj }
210238fd1498Szrj if (!has_nonprivate_method)
210338fd1498Szrj {
210438fd1498Szrj warning (OPT_Wctor_dtor_privacy,
210538fd1498Szrj "all member functions in class %qT are private", t);
210638fd1498Szrj return;
210738fd1498Szrj }
210838fd1498Szrj }
210938fd1498Szrj
211038fd1498Szrj /* Even if some of the member functions are non-private, the class
211138fd1498Szrj won't be useful for much if all the constructors or destructors
211238fd1498Szrj are private: such an object can never be created or destroyed. */
211338fd1498Szrj if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
211438fd1498Szrj if (TREE_PRIVATE (dtor))
211538fd1498Szrj {
211638fd1498Szrj warning (OPT_Wctor_dtor_privacy,
211738fd1498Szrj "%q#T only defines a private destructor and has no friends",
211838fd1498Szrj t);
211938fd1498Szrj return;
212038fd1498Szrj }
212138fd1498Szrj
212238fd1498Szrj /* Warn about classes that have private constructors and no friends. */
212338fd1498Szrj if (TYPE_HAS_USER_CONSTRUCTOR (t)
212438fd1498Szrj /* Implicitly generated constructors are always public. */
212538fd1498Szrj && !CLASSTYPE_LAZY_DEFAULT_CTOR (t))
212638fd1498Szrj {
212738fd1498Szrj tree copy_or_move = NULL_TREE;
212838fd1498Szrj
212938fd1498Szrj /* If a non-template class does not define a copy
213038fd1498Szrj constructor, one is defined for it, enabling it to avoid
213138fd1498Szrj this warning. For a template class, this does not
213238fd1498Szrj happen, and so we would normally get a warning on:
213338fd1498Szrj
213438fd1498Szrj template <class T> class C { private: C(); };
213538fd1498Szrj
213638fd1498Szrj To avoid this asymmetry, we check TYPE_HAS_COPY_CTOR. All
213738fd1498Szrj complete non-template or fully instantiated classes have this
213838fd1498Szrj flag set. */
213938fd1498Szrj if (!TYPE_HAS_COPY_CTOR (t))
214038fd1498Szrj nonprivate_ctor = true;
214138fd1498Szrj else
214238fd1498Szrj for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t));
214338fd1498Szrj !nonprivate_ctor && iter; ++iter)
214438fd1498Szrj if (TREE_PRIVATE (*iter))
214538fd1498Szrj continue;
214638fd1498Szrj else if (copy_fn_p (*iter) || move_fn_p (*iter))
214738fd1498Szrj /* Ideally, we wouldn't count any constructor that takes
214838fd1498Szrj an argument of the class type as a parameter, because
214938fd1498Szrj such things cannot be used to construct an instance of
215038fd1498Szrj the class unless you already have one. */
215138fd1498Szrj copy_or_move = *iter;
215238fd1498Szrj else
215338fd1498Szrj nonprivate_ctor = true;
215438fd1498Szrj
215538fd1498Szrj if (!nonprivate_ctor)
215638fd1498Szrj {
215738fd1498Szrj warning (OPT_Wctor_dtor_privacy,
215838fd1498Szrj "%q#T only defines private constructors and has no friends",
215938fd1498Szrj t);
216038fd1498Szrj if (copy_or_move)
216138fd1498Szrj inform (DECL_SOURCE_LOCATION (copy_or_move),
216238fd1498Szrj "%q#D is public, but requires an existing %q#T object",
216338fd1498Szrj copy_or_move, t);
216438fd1498Szrj return;
216538fd1498Szrj }
216638fd1498Szrj }
216738fd1498Szrj }
216838fd1498Szrj
216938fd1498Szrj /* Make BINFO's vtable have N entries, including RTTI entries,
217038fd1498Szrj vbase and vcall offsets, etc. Set its type and call the back end
217138fd1498Szrj to lay it out. */
217238fd1498Szrj
217338fd1498Szrj static void
layout_vtable_decl(tree binfo,int n)217438fd1498Szrj layout_vtable_decl (tree binfo, int n)
217538fd1498Szrj {
217638fd1498Szrj tree atype;
217738fd1498Szrj tree vtable;
217838fd1498Szrj
217938fd1498Szrj atype = build_array_of_n_type (vtable_entry_type, n);
218038fd1498Szrj layout_type (atype);
218138fd1498Szrj
218238fd1498Szrj /* We may have to grow the vtable. */
218338fd1498Szrj vtable = get_vtbl_decl_for_binfo (binfo);
218438fd1498Szrj if (!same_type_p (TREE_TYPE (vtable), atype))
218538fd1498Szrj {
218638fd1498Szrj TREE_TYPE (vtable) = atype;
218738fd1498Szrj DECL_SIZE (vtable) = DECL_SIZE_UNIT (vtable) = NULL_TREE;
218838fd1498Szrj layout_decl (vtable, 0);
218938fd1498Szrj }
219038fd1498Szrj }
219138fd1498Szrj
219238fd1498Szrj /* True iff FNDECL and BASE_FNDECL (both non-static member functions)
219338fd1498Szrj have the same signature. */
219438fd1498Szrj
219538fd1498Szrj int
same_signature_p(const_tree fndecl,const_tree base_fndecl)219638fd1498Szrj same_signature_p (const_tree fndecl, const_tree base_fndecl)
219738fd1498Szrj {
219838fd1498Szrj /* One destructor overrides another if they are the same kind of
219938fd1498Szrj destructor. */
220038fd1498Szrj if (DECL_DESTRUCTOR_P (base_fndecl) && DECL_DESTRUCTOR_P (fndecl)
220138fd1498Szrj && special_function_p (base_fndecl) == special_function_p (fndecl))
220238fd1498Szrj return 1;
220338fd1498Szrj /* But a non-destructor never overrides a destructor, nor vice
220438fd1498Szrj versa, nor do different kinds of destructors override
220538fd1498Szrj one-another. For example, a complete object destructor does not
220638fd1498Szrj override a deleting destructor. */
220738fd1498Szrj if (DECL_DESTRUCTOR_P (base_fndecl) || DECL_DESTRUCTOR_P (fndecl))
220838fd1498Szrj return 0;
220938fd1498Szrj
221038fd1498Szrj if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl)
221138fd1498Szrj || (DECL_CONV_FN_P (fndecl)
221238fd1498Szrj && DECL_CONV_FN_P (base_fndecl)
221338fd1498Szrj && same_type_p (DECL_CONV_FN_TYPE (fndecl),
221438fd1498Szrj DECL_CONV_FN_TYPE (base_fndecl))))
221538fd1498Szrj {
221638fd1498Szrj tree fntype = TREE_TYPE (fndecl);
221738fd1498Szrj tree base_fntype = TREE_TYPE (base_fndecl);
221838fd1498Szrj if (type_memfn_quals (fntype) == type_memfn_quals (base_fntype)
221938fd1498Szrj && type_memfn_rqual (fntype) == type_memfn_rqual (base_fntype)
222038fd1498Szrj && compparms (FUNCTION_FIRST_USER_PARMTYPE (fndecl),
222138fd1498Szrj FUNCTION_FIRST_USER_PARMTYPE (base_fndecl)))
222238fd1498Szrj return 1;
222338fd1498Szrj }
222438fd1498Szrj return 0;
222538fd1498Szrj }
222638fd1498Szrj
222738fd1498Szrj /* Returns TRUE if DERIVED is a binfo containing the binfo BASE as a
222838fd1498Szrj subobject. */
222938fd1498Szrj
223038fd1498Szrj static bool
base_derived_from(tree derived,tree base)223138fd1498Szrj base_derived_from (tree derived, tree base)
223238fd1498Szrj {
223338fd1498Szrj tree probe;
223438fd1498Szrj
223538fd1498Szrj for (probe = base; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
223638fd1498Szrj {
223738fd1498Szrj if (probe == derived)
223838fd1498Szrj return true;
223938fd1498Szrj else if (BINFO_VIRTUAL_P (probe))
224038fd1498Szrj /* If we meet a virtual base, we can't follow the inheritance
224138fd1498Szrj any more. See if the complete type of DERIVED contains
224238fd1498Szrj such a virtual base. */
224338fd1498Szrj return (binfo_for_vbase (BINFO_TYPE (probe), BINFO_TYPE (derived))
224438fd1498Szrj != NULL_TREE);
224538fd1498Szrj }
224638fd1498Szrj return false;
224738fd1498Szrj }
224838fd1498Szrj
224938fd1498Szrj struct find_final_overrider_data {
225038fd1498Szrj /* The function for which we are trying to find a final overrider. */
225138fd1498Szrj tree fn;
225238fd1498Szrj /* The base class in which the function was declared. */
225338fd1498Szrj tree declaring_base;
225438fd1498Szrj /* The candidate overriders. */
225538fd1498Szrj tree candidates;
225638fd1498Szrj /* Path to most derived. */
225738fd1498Szrj vec<tree> path;
225838fd1498Szrj };
225938fd1498Szrj
226038fd1498Szrj /* Add the overrider along the current path to FFOD->CANDIDATES.
226138fd1498Szrj Returns true if an overrider was found; false otherwise. */
226238fd1498Szrj
226338fd1498Szrj static bool
dfs_find_final_overrider_1(tree binfo,find_final_overrider_data * ffod,unsigned depth)226438fd1498Szrj dfs_find_final_overrider_1 (tree binfo,
226538fd1498Szrj find_final_overrider_data *ffod,
226638fd1498Szrj unsigned depth)
226738fd1498Szrj {
226838fd1498Szrj tree method;
226938fd1498Szrj
227038fd1498Szrj /* If BINFO is not the most derived type, try a more derived class.
227138fd1498Szrj A definition there will overrider a definition here. */
227238fd1498Szrj if (depth)
227338fd1498Szrj {
227438fd1498Szrj depth--;
227538fd1498Szrj if (dfs_find_final_overrider_1
227638fd1498Szrj (ffod->path[depth], ffod, depth))
227738fd1498Szrj return true;
227838fd1498Szrj }
227938fd1498Szrj
228038fd1498Szrj method = look_for_overrides_here (BINFO_TYPE (binfo), ffod->fn);
228138fd1498Szrj if (method)
228238fd1498Szrj {
228338fd1498Szrj tree *candidate = &ffod->candidates;
228438fd1498Szrj
228538fd1498Szrj /* Remove any candidates overridden by this new function. */
228638fd1498Szrj while (*candidate)
228738fd1498Szrj {
228838fd1498Szrj /* If *CANDIDATE overrides METHOD, then METHOD
228938fd1498Szrj cannot override anything else on the list. */
229038fd1498Szrj if (base_derived_from (TREE_VALUE (*candidate), binfo))
229138fd1498Szrj return true;
229238fd1498Szrj /* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */
229338fd1498Szrj if (base_derived_from (binfo, TREE_VALUE (*candidate)))
229438fd1498Szrj *candidate = TREE_CHAIN (*candidate);
229538fd1498Szrj else
229638fd1498Szrj candidate = &TREE_CHAIN (*candidate);
229738fd1498Szrj }
229838fd1498Szrj
229938fd1498Szrj /* Add the new function. */
230038fd1498Szrj ffod->candidates = tree_cons (method, binfo, ffod->candidates);
230138fd1498Szrj return true;
230238fd1498Szrj }
230338fd1498Szrj
230438fd1498Szrj return false;
230538fd1498Szrj }
230638fd1498Szrj
230738fd1498Szrj /* Called from find_final_overrider via dfs_walk. */
230838fd1498Szrj
230938fd1498Szrj static tree
dfs_find_final_overrider_pre(tree binfo,void * data)231038fd1498Szrj dfs_find_final_overrider_pre (tree binfo, void *data)
231138fd1498Szrj {
231238fd1498Szrj find_final_overrider_data *ffod = (find_final_overrider_data *) data;
231338fd1498Szrj
231438fd1498Szrj if (binfo == ffod->declaring_base)
231538fd1498Szrj dfs_find_final_overrider_1 (binfo, ffod, ffod->path.length ());
231638fd1498Szrj ffod->path.safe_push (binfo);
231738fd1498Szrj
231838fd1498Szrj return NULL_TREE;
231938fd1498Szrj }
232038fd1498Szrj
232138fd1498Szrj static tree
dfs_find_final_overrider_post(tree,void * data)232238fd1498Szrj dfs_find_final_overrider_post (tree /*binfo*/, void *data)
232338fd1498Szrj {
232438fd1498Szrj find_final_overrider_data *ffod = (find_final_overrider_data *) data;
232538fd1498Szrj ffod->path.pop ();
232638fd1498Szrj
232738fd1498Szrj return NULL_TREE;
232838fd1498Szrj }
232938fd1498Szrj
233038fd1498Szrj /* Returns a TREE_LIST whose TREE_PURPOSE is the final overrider for
233138fd1498Szrj FN and whose TREE_VALUE is the binfo for the base where the
233238fd1498Szrj overriding occurs. BINFO (in the hierarchy dominated by the binfo
233338fd1498Szrj DERIVED) is the base object in which FN is declared. */
233438fd1498Szrj
233538fd1498Szrj static tree
find_final_overrider(tree derived,tree binfo,tree fn)233638fd1498Szrj find_final_overrider (tree derived, tree binfo, tree fn)
233738fd1498Szrj {
233838fd1498Szrj find_final_overrider_data ffod;
233938fd1498Szrj
234038fd1498Szrj /* Getting this right is a little tricky. This is valid:
234138fd1498Szrj
234238fd1498Szrj struct S { virtual void f (); };
234338fd1498Szrj struct T { virtual void f (); };
234438fd1498Szrj struct U : public S, public T { };
234538fd1498Szrj
234638fd1498Szrj even though calling `f' in `U' is ambiguous. But,
234738fd1498Szrj
234838fd1498Szrj struct R { virtual void f(); };
234938fd1498Szrj struct S : virtual public R { virtual void f (); };
235038fd1498Szrj struct T : virtual public R { virtual void f (); };
235138fd1498Szrj struct U : public S, public T { };
235238fd1498Szrj
235338fd1498Szrj is not -- there's no way to decide whether to put `S::f' or
235438fd1498Szrj `T::f' in the vtable for `R'.
235538fd1498Szrj
235638fd1498Szrj The solution is to look at all paths to BINFO. If we find
235738fd1498Szrj different overriders along any two, then there is a problem. */
235838fd1498Szrj if (DECL_THUNK_P (fn))
235938fd1498Szrj fn = THUNK_TARGET (fn);
236038fd1498Szrj
236138fd1498Szrj /* Determine the depth of the hierarchy. */
236238fd1498Szrj ffod.fn = fn;
236338fd1498Szrj ffod.declaring_base = binfo;
236438fd1498Szrj ffod.candidates = NULL_TREE;
236538fd1498Szrj ffod.path.create (30);
236638fd1498Szrj
236738fd1498Szrj dfs_walk_all (derived, dfs_find_final_overrider_pre,
236838fd1498Szrj dfs_find_final_overrider_post, &ffod);
236938fd1498Szrj
237038fd1498Szrj ffod.path.release ();
237138fd1498Szrj
237238fd1498Szrj /* If there was no winner, issue an error message. */
237338fd1498Szrj if (!ffod.candidates || TREE_CHAIN (ffod.candidates))
237438fd1498Szrj return error_mark_node;
237538fd1498Szrj
237638fd1498Szrj return ffod.candidates;
237738fd1498Szrj }
237838fd1498Szrj
237938fd1498Szrj /* Return the index of the vcall offset for FN when TYPE is used as a
238038fd1498Szrj virtual base. */
238138fd1498Szrj
238238fd1498Szrj static tree
get_vcall_index(tree fn,tree type)238338fd1498Szrj get_vcall_index (tree fn, tree type)
238438fd1498Szrj {
238538fd1498Szrj vec<tree_pair_s, va_gc> *indices = CLASSTYPE_VCALL_INDICES (type);
238638fd1498Szrj tree_pair_p p;
238738fd1498Szrj unsigned ix;
238838fd1498Szrj
238938fd1498Szrj FOR_EACH_VEC_SAFE_ELT (indices, ix, p)
239038fd1498Szrj if ((DECL_DESTRUCTOR_P (fn) && DECL_DESTRUCTOR_P (p->purpose))
239138fd1498Szrj || same_signature_p (fn, p->purpose))
239238fd1498Szrj return p->value;
239338fd1498Szrj
239438fd1498Szrj /* There should always be an appropriate index. */
239538fd1498Szrj gcc_unreachable ();
239638fd1498Szrj }
239738fd1498Szrj
239838fd1498Szrj /* Update an entry in the vtable for BINFO, which is in the hierarchy
239938fd1498Szrj dominated by T. FN is the old function; VIRTUALS points to the
240038fd1498Szrj corresponding position in the new BINFO_VIRTUALS list. IX is the index
240138fd1498Szrj of that entry in the list. */
240238fd1498Szrj
240338fd1498Szrj static void
update_vtable_entry_for_fn(tree t,tree binfo,tree fn,tree * virtuals,unsigned ix)240438fd1498Szrj update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
240538fd1498Szrj unsigned ix)
240638fd1498Szrj {
240738fd1498Szrj tree b;
240838fd1498Szrj tree overrider;
240938fd1498Szrj tree delta;
241038fd1498Szrj tree virtual_base;
241138fd1498Szrj tree first_defn;
241238fd1498Szrj tree overrider_fn, overrider_target;
241338fd1498Szrj tree target_fn = DECL_THUNK_P (fn) ? THUNK_TARGET (fn) : fn;
241438fd1498Szrj tree over_return, base_return;
241538fd1498Szrj bool lost = false;
241638fd1498Szrj
241738fd1498Szrj /* Find the nearest primary base (possibly binfo itself) which defines
241838fd1498Szrj this function; this is the class the caller will convert to when
241938fd1498Szrj calling FN through BINFO. */
242038fd1498Szrj for (b = binfo; ; b = get_primary_binfo (b))
242138fd1498Szrj {
242238fd1498Szrj gcc_assert (b);
242338fd1498Szrj if (look_for_overrides_here (BINFO_TYPE (b), target_fn))
242438fd1498Szrj break;
242538fd1498Szrj
242638fd1498Szrj /* The nearest definition is from a lost primary. */
242738fd1498Szrj if (BINFO_LOST_PRIMARY_P (b))
242838fd1498Szrj lost = true;
242938fd1498Szrj }
243038fd1498Szrj first_defn = b;
243138fd1498Szrj
243238fd1498Szrj /* Find the final overrider. */
243338fd1498Szrj overrider = find_final_overrider (TYPE_BINFO (t), b, target_fn);
243438fd1498Szrj if (overrider == error_mark_node)
243538fd1498Szrj {
243638fd1498Szrj error ("no unique final overrider for %qD in %qT", target_fn, t);
243738fd1498Szrj return;
243838fd1498Szrj }
243938fd1498Szrj overrider_target = overrider_fn = TREE_PURPOSE (overrider);
244038fd1498Szrj
244138fd1498Szrj /* Check for adjusting covariant return types. */
244238fd1498Szrj over_return = TREE_TYPE (TREE_TYPE (overrider_target));
244338fd1498Szrj base_return = TREE_TYPE (TREE_TYPE (target_fn));
244438fd1498Szrj
244538fd1498Szrj if (POINTER_TYPE_P (over_return)
244638fd1498Szrj && TREE_CODE (over_return) == TREE_CODE (base_return)
244738fd1498Szrj && CLASS_TYPE_P (TREE_TYPE (over_return))
244838fd1498Szrj && CLASS_TYPE_P (TREE_TYPE (base_return))
244938fd1498Szrj /* If the overrider is invalid, don't even try. */
245038fd1498Szrj && !DECL_INVALID_OVERRIDER_P (overrider_target))
245138fd1498Szrj {
245238fd1498Szrj /* If FN is a covariant thunk, we must figure out the adjustment
245338fd1498Szrj to the final base FN was converting to. As OVERRIDER_TARGET might
245438fd1498Szrj also be converting to the return type of FN, we have to
245538fd1498Szrj combine the two conversions here. */
245638fd1498Szrj tree fixed_offset, virtual_offset;
245738fd1498Szrj
245838fd1498Szrj over_return = TREE_TYPE (over_return);
245938fd1498Szrj base_return = TREE_TYPE (base_return);
246038fd1498Szrj
246138fd1498Szrj if (DECL_THUNK_P (fn))
246238fd1498Szrj {
246338fd1498Szrj gcc_assert (DECL_RESULT_THUNK_P (fn));
246438fd1498Szrj fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn));
246538fd1498Szrj virtual_offset = THUNK_VIRTUAL_OFFSET (fn);
246638fd1498Szrj }
246738fd1498Szrj else
246838fd1498Szrj fixed_offset = virtual_offset = NULL_TREE;
246938fd1498Szrj
247038fd1498Szrj if (virtual_offset)
247138fd1498Szrj /* Find the equivalent binfo within the return type of the
247238fd1498Szrj overriding function. We will want the vbase offset from
247338fd1498Szrj there. */
247438fd1498Szrj virtual_offset = binfo_for_vbase (BINFO_TYPE (virtual_offset),
247538fd1498Szrj over_return);
247638fd1498Szrj else if (!same_type_ignoring_top_level_qualifiers_p
247738fd1498Szrj (over_return, base_return))
247838fd1498Szrj {
247938fd1498Szrj /* There was no existing virtual thunk (which takes
248038fd1498Szrj precedence). So find the binfo of the base function's
248138fd1498Szrj return type within the overriding function's return type.
248238fd1498Szrj Fortunately we know the covariancy is valid (it
248338fd1498Szrj has already been checked), so we can just iterate along
248438fd1498Szrj the binfos, which have been chained in inheritance graph
248538fd1498Szrj order. Of course it is lame that we have to repeat the
248638fd1498Szrj search here anyway -- we should really be caching pieces
248738fd1498Szrj of the vtable and avoiding this repeated work. */
248838fd1498Szrj tree thunk_binfo = NULL_TREE;
248938fd1498Szrj tree base_binfo = TYPE_BINFO (base_return);
249038fd1498Szrj
249138fd1498Szrj /* Find the base binfo within the overriding function's
249238fd1498Szrj return type. We will always find a thunk_binfo, except
249338fd1498Szrj when the covariancy is invalid (which we will have
249438fd1498Szrj already diagnosed). */
249538fd1498Szrj if (base_binfo)
249638fd1498Szrj for (thunk_binfo = TYPE_BINFO (over_return); thunk_binfo;
249738fd1498Szrj thunk_binfo = TREE_CHAIN (thunk_binfo))
249838fd1498Szrj if (SAME_BINFO_TYPE_P (BINFO_TYPE (thunk_binfo),
249938fd1498Szrj BINFO_TYPE (base_binfo)))
250038fd1498Szrj break;
250138fd1498Szrj gcc_assert (thunk_binfo || errorcount);
250238fd1498Szrj
250338fd1498Szrj /* See if virtual inheritance is involved. */
250438fd1498Szrj for (virtual_offset = thunk_binfo;
250538fd1498Szrj virtual_offset;
250638fd1498Szrj virtual_offset = BINFO_INHERITANCE_CHAIN (virtual_offset))
250738fd1498Szrj if (BINFO_VIRTUAL_P (virtual_offset))
250838fd1498Szrj break;
250938fd1498Szrj
251038fd1498Szrj if (virtual_offset
251138fd1498Szrj || (thunk_binfo && !BINFO_OFFSET_ZEROP (thunk_binfo)))
251238fd1498Szrj {
251338fd1498Szrj tree offset = fold_convert (ssizetype, BINFO_OFFSET (thunk_binfo));
251438fd1498Szrj
251538fd1498Szrj if (virtual_offset)
251638fd1498Szrj {
251738fd1498Szrj /* We convert via virtual base. Adjust the fixed
251838fd1498Szrj offset to be from there. */
251938fd1498Szrj offset =
252038fd1498Szrj size_diffop (offset,
252138fd1498Szrj fold_convert (ssizetype,
252238fd1498Szrj BINFO_OFFSET (virtual_offset)));
252338fd1498Szrj }
252438fd1498Szrj if (fixed_offset)
252538fd1498Szrj /* There was an existing fixed offset, this must be
252638fd1498Szrj from the base just converted to, and the base the
252738fd1498Szrj FN was thunking to. */
252838fd1498Szrj fixed_offset = size_binop (PLUS_EXPR, fixed_offset, offset);
252938fd1498Szrj else
253038fd1498Szrj fixed_offset = offset;
253138fd1498Szrj }
253238fd1498Szrj }
253338fd1498Szrj
253438fd1498Szrj if (fixed_offset || virtual_offset)
253538fd1498Szrj /* Replace the overriding function with a covariant thunk. We
253638fd1498Szrj will emit the overriding function in its own slot as
253738fd1498Szrj well. */
253838fd1498Szrj overrider_fn = make_thunk (overrider_target, /*this_adjusting=*/0,
253938fd1498Szrj fixed_offset, virtual_offset);
254038fd1498Szrj }
254138fd1498Szrj else
254238fd1498Szrj gcc_assert (DECL_INVALID_OVERRIDER_P (overrider_target) ||
254338fd1498Szrj !DECL_THUNK_P (fn));
254438fd1498Szrj
254538fd1498Szrj /* If we need a covariant thunk, then we may need to adjust first_defn.
254638fd1498Szrj The ABI specifies that the thunks emitted with a function are
254738fd1498Szrj determined by which bases the function overrides, so we need to be
254838fd1498Szrj sure that we're using a thunk for some overridden base; even if we
254938fd1498Szrj know that the necessary this adjustment is zero, there may not be an
255038fd1498Szrj appropriate zero-this-adjustment thunk for us to use since thunks for
255138fd1498Szrj overriding virtual bases always use the vcall offset.
255238fd1498Szrj
255338fd1498Szrj Furthermore, just choosing any base that overrides this function isn't
255438fd1498Szrj quite right, as this slot won't be used for calls through a type that
255538fd1498Szrj puts a covariant thunk here. Calling the function through such a type
255638fd1498Szrj will use a different slot, and that slot is the one that determines
255738fd1498Szrj the thunk emitted for that base.
255838fd1498Szrj
255938fd1498Szrj So, keep looking until we find the base that we're really overriding
256038fd1498Szrj in this slot: the nearest primary base that doesn't use a covariant
256138fd1498Szrj thunk in this slot. */
256238fd1498Szrj if (overrider_target != overrider_fn)
256338fd1498Szrj {
256438fd1498Szrj if (BINFO_TYPE (b) == DECL_CONTEXT (overrider_target))
256538fd1498Szrj /* We already know that the overrider needs a covariant thunk. */
256638fd1498Szrj b = get_primary_binfo (b);
256738fd1498Szrj for (; ; b = get_primary_binfo (b))
256838fd1498Szrj {
256938fd1498Szrj tree main_binfo = TYPE_BINFO (BINFO_TYPE (b));
257038fd1498Szrj tree bv = chain_index (ix, BINFO_VIRTUALS (main_binfo));
257138fd1498Szrj if (!DECL_THUNK_P (TREE_VALUE (bv)))
257238fd1498Szrj break;
257338fd1498Szrj if (BINFO_LOST_PRIMARY_P (b))
257438fd1498Szrj lost = true;
257538fd1498Szrj }
257638fd1498Szrj first_defn = b;
257738fd1498Szrj }
257838fd1498Szrj
257938fd1498Szrj /* Assume that we will produce a thunk that convert all the way to
258038fd1498Szrj the final overrider, and not to an intermediate virtual base. */
258138fd1498Szrj virtual_base = NULL_TREE;
258238fd1498Szrj
258338fd1498Szrj /* See if we can convert to an intermediate virtual base first, and then
258438fd1498Szrj use the vcall offset located there to finish the conversion. */
258538fd1498Szrj for (; b; b = BINFO_INHERITANCE_CHAIN (b))
258638fd1498Szrj {
258738fd1498Szrj /* If we find the final overrider, then we can stop
258838fd1498Szrj walking. */
258938fd1498Szrj if (SAME_BINFO_TYPE_P (BINFO_TYPE (b),
259038fd1498Szrj BINFO_TYPE (TREE_VALUE (overrider))))
259138fd1498Szrj break;
259238fd1498Szrj
259338fd1498Szrj /* If we find a virtual base, and we haven't yet found the
259438fd1498Szrj overrider, then there is a virtual base between the
259538fd1498Szrj declaring base (first_defn) and the final overrider. */
259638fd1498Szrj if (BINFO_VIRTUAL_P (b))
259738fd1498Szrj {
259838fd1498Szrj virtual_base = b;
259938fd1498Szrj break;
260038fd1498Szrj }
260138fd1498Szrj }
260238fd1498Szrj
260338fd1498Szrj /* Compute the constant adjustment to the `this' pointer. The
260438fd1498Szrj `this' pointer, when this function is called, will point at BINFO
260538fd1498Szrj (or one of its primary bases, which are at the same offset). */
260638fd1498Szrj if (virtual_base)
260738fd1498Szrj /* The `this' pointer needs to be adjusted from the declaration to
260838fd1498Szrj the nearest virtual base. */
260938fd1498Szrj delta = size_diffop_loc (input_location,
261038fd1498Szrj fold_convert (ssizetype, BINFO_OFFSET (virtual_base)),
261138fd1498Szrj fold_convert (ssizetype, BINFO_OFFSET (first_defn)));
261238fd1498Szrj else if (lost)
261338fd1498Szrj /* If the nearest definition is in a lost primary, we don't need an
261438fd1498Szrj entry in our vtable. Except possibly in a constructor vtable,
261538fd1498Szrj if we happen to get our primary back. In that case, the offset
261638fd1498Szrj will be zero, as it will be a primary base. */
261738fd1498Szrj delta = size_zero_node;
261838fd1498Szrj else
261938fd1498Szrj /* The `this' pointer needs to be adjusted from pointing to
262038fd1498Szrj BINFO to pointing at the base where the final overrider
262138fd1498Szrj appears. */
262238fd1498Szrj delta = size_diffop_loc (input_location,
262338fd1498Szrj fold_convert (ssizetype,
262438fd1498Szrj BINFO_OFFSET (TREE_VALUE (overrider))),
262538fd1498Szrj fold_convert (ssizetype, BINFO_OFFSET (binfo)));
262638fd1498Szrj
262738fd1498Szrj modify_vtable_entry (t, binfo, overrider_fn, delta, virtuals);
262838fd1498Szrj
262938fd1498Szrj if (virtual_base)
263038fd1498Szrj BV_VCALL_INDEX (*virtuals)
263138fd1498Szrj = get_vcall_index (overrider_target, BINFO_TYPE (virtual_base));
263238fd1498Szrj else
263338fd1498Szrj BV_VCALL_INDEX (*virtuals) = NULL_TREE;
263438fd1498Szrj
263538fd1498Szrj BV_LOST_PRIMARY (*virtuals) = lost;
263638fd1498Szrj }
263738fd1498Szrj
263838fd1498Szrj /* Called from modify_all_vtables via dfs_walk. */
263938fd1498Szrj
264038fd1498Szrj static tree
dfs_modify_vtables(tree binfo,void * data)264138fd1498Szrj dfs_modify_vtables (tree binfo, void* data)
264238fd1498Szrj {
264338fd1498Szrj tree t = (tree) data;
264438fd1498Szrj tree virtuals;
264538fd1498Szrj tree old_virtuals;
264638fd1498Szrj unsigned ix;
264738fd1498Szrj
264838fd1498Szrj if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
264938fd1498Szrj /* A base without a vtable needs no modification, and its bases
265038fd1498Szrj are uninteresting. */
265138fd1498Szrj return dfs_skip_bases;
265238fd1498Szrj
265338fd1498Szrj if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t)
265438fd1498Szrj && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
265538fd1498Szrj /* Don't do the primary vtable, if it's new. */
265638fd1498Szrj return NULL_TREE;
265738fd1498Szrj
265838fd1498Szrj if (BINFO_PRIMARY_P (binfo) && !BINFO_VIRTUAL_P (binfo))
265938fd1498Szrj /* There's no need to modify the vtable for a non-virtual primary
266038fd1498Szrj base; we're not going to use that vtable anyhow. We do still
266138fd1498Szrj need to do this for virtual primary bases, as they could become
266238fd1498Szrj non-primary in a construction vtable. */
266338fd1498Szrj return NULL_TREE;
266438fd1498Szrj
266538fd1498Szrj make_new_vtable (t, binfo);
266638fd1498Szrj
266738fd1498Szrj /* Now, go through each of the virtual functions in the virtual
266838fd1498Szrj function table for BINFO. Find the final overrider, and update
266938fd1498Szrj the BINFO_VIRTUALS list appropriately. */
267038fd1498Szrj for (ix = 0, virtuals = BINFO_VIRTUALS (binfo),
267138fd1498Szrj old_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
267238fd1498Szrj virtuals;
267338fd1498Szrj ix++, virtuals = TREE_CHAIN (virtuals),
267438fd1498Szrj old_virtuals = TREE_CHAIN (old_virtuals))
267538fd1498Szrj update_vtable_entry_for_fn (t,
267638fd1498Szrj binfo,
267738fd1498Szrj BV_FN (old_virtuals),
267838fd1498Szrj &virtuals, ix);
267938fd1498Szrj
268038fd1498Szrj return NULL_TREE;
268138fd1498Szrj }
268238fd1498Szrj
268338fd1498Szrj /* Update all of the primary and secondary vtables for T. Create new
268438fd1498Szrj vtables as required, and initialize their RTTI information. Each
268538fd1498Szrj of the functions in VIRTUALS is declared in T and may override a
268638fd1498Szrj virtual function from a base class; find and modify the appropriate
268738fd1498Szrj entries to point to the overriding functions. Returns a list, in
268838fd1498Szrj declaration order, of the virtual functions that are declared in T,
268938fd1498Szrj but do not appear in the primary base class vtable, and which
269038fd1498Szrj should therefore be appended to the end of the vtable for T. */
269138fd1498Szrj
269238fd1498Szrj static tree
modify_all_vtables(tree t,tree virtuals)269338fd1498Szrj modify_all_vtables (tree t, tree virtuals)
269438fd1498Szrj {
269538fd1498Szrj tree binfo = TYPE_BINFO (t);
269638fd1498Szrj tree *fnsp;
269738fd1498Szrj
269838fd1498Szrj /* Mangle the vtable name before entering dfs_walk (c++/51884). */
269938fd1498Szrj if (TYPE_CONTAINS_VPTR_P (t))
270038fd1498Szrj get_vtable_decl (t, false);
270138fd1498Szrj
270238fd1498Szrj /* Update all of the vtables. */
270338fd1498Szrj dfs_walk_once (binfo, dfs_modify_vtables, NULL, t);
270438fd1498Szrj
270538fd1498Szrj /* Add virtual functions not already in our primary vtable. These
270638fd1498Szrj will be both those introduced by this class, and those overridden
270738fd1498Szrj from secondary bases. It does not include virtuals merely
270838fd1498Szrj inherited from secondary bases. */
270938fd1498Szrj for (fnsp = &virtuals; *fnsp; )
271038fd1498Szrj {
271138fd1498Szrj tree fn = TREE_VALUE (*fnsp);
271238fd1498Szrj
271338fd1498Szrj if (!value_member (fn, BINFO_VIRTUALS (binfo))
271438fd1498Szrj || DECL_VINDEX (fn) == error_mark_node)
271538fd1498Szrj {
271638fd1498Szrj /* We don't need to adjust the `this' pointer when
271738fd1498Szrj calling this function. */
271838fd1498Szrj BV_DELTA (*fnsp) = integer_zero_node;
271938fd1498Szrj BV_VCALL_INDEX (*fnsp) = NULL_TREE;
272038fd1498Szrj
272138fd1498Szrj /* This is a function not already in our vtable. Keep it. */
272238fd1498Szrj fnsp = &TREE_CHAIN (*fnsp);
272338fd1498Szrj }
272438fd1498Szrj else
272538fd1498Szrj /* We've already got an entry for this function. Skip it. */
272638fd1498Szrj *fnsp = TREE_CHAIN (*fnsp);
272738fd1498Szrj }
272838fd1498Szrj
272938fd1498Szrj return virtuals;
273038fd1498Szrj }
273138fd1498Szrj
273238fd1498Szrj /* Get the base virtual function declarations in T that have the
273338fd1498Szrj indicated NAME. */
273438fd1498Szrj
273538fd1498Szrj static void
get_basefndecls(tree name,tree t,vec<tree> * base_fndecls)273638fd1498Szrj get_basefndecls (tree name, tree t, vec<tree> *base_fndecls)
273738fd1498Szrj {
273838fd1498Szrj bool found_decls = false;
273938fd1498Szrj
274038fd1498Szrj /* Find virtual functions in T with the indicated NAME. */
274138fd1498Szrj for (ovl_iterator iter (get_class_binding (t, name)); iter; ++iter)
274238fd1498Szrj {
274338fd1498Szrj tree method = *iter;
274438fd1498Szrj
274538fd1498Szrj if (TREE_CODE (method) == FUNCTION_DECL && DECL_VINDEX (method))
274638fd1498Szrj {
274738fd1498Szrj base_fndecls->safe_push (method);
274838fd1498Szrj found_decls = true;
274938fd1498Szrj }
275038fd1498Szrj }
275138fd1498Szrj
275238fd1498Szrj if (found_decls)
275338fd1498Szrj return;
275438fd1498Szrj
275538fd1498Szrj int n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
275638fd1498Szrj for (int i = 0; i < n_baseclasses; i++)
275738fd1498Szrj {
275838fd1498Szrj tree basetype = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (t), i));
275938fd1498Szrj get_basefndecls (name, basetype, base_fndecls);
276038fd1498Szrj }
276138fd1498Szrj }
276238fd1498Szrj
276338fd1498Szrj /* If this declaration supersedes the declaration of
276438fd1498Szrj a method declared virtual in the base class, then
276538fd1498Szrj mark this field as being virtual as well. */
276638fd1498Szrj
276738fd1498Szrj void
check_for_override(tree decl,tree ctype)276838fd1498Szrj check_for_override (tree decl, tree ctype)
276938fd1498Szrj {
277038fd1498Szrj bool overrides_found = false;
277138fd1498Szrj if (TREE_CODE (decl) == TEMPLATE_DECL)
277238fd1498Szrj /* In [temp.mem] we have:
277338fd1498Szrj
277438fd1498Szrj A specialization of a member function template does not
277538fd1498Szrj override a virtual function from a base class. */
277638fd1498Szrj return;
277738fd1498Szrj if ((DECL_DESTRUCTOR_P (decl)
277838fd1498Szrj || IDENTIFIER_VIRTUAL_P (DECL_NAME (decl))
277938fd1498Szrj || DECL_CONV_FN_P (decl))
278038fd1498Szrj && look_for_overrides (ctype, decl)
278138fd1498Szrj && !DECL_STATIC_FUNCTION_P (decl))
278238fd1498Szrj /* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor
278338fd1498Szrj the error_mark_node so that we know it is an overriding
278438fd1498Szrj function. */
278538fd1498Szrj {
278638fd1498Szrj DECL_VINDEX (decl) = decl;
278738fd1498Szrj overrides_found = true;
278838fd1498Szrj if (warn_override && !DECL_OVERRIDE_P (decl)
278938fd1498Szrj && !DECL_DESTRUCTOR_P (decl))
279038fd1498Szrj warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wsuggest_override,
279138fd1498Szrj "%qD can be marked override", decl);
279238fd1498Szrj }
279338fd1498Szrj
279438fd1498Szrj if (DECL_VIRTUAL_P (decl))
279538fd1498Szrj {
279638fd1498Szrj if (!DECL_VINDEX (decl))
279738fd1498Szrj DECL_VINDEX (decl) = error_mark_node;
279838fd1498Szrj IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
279938fd1498Szrj if (DECL_DESTRUCTOR_P (decl))
280038fd1498Szrj TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
280138fd1498Szrj }
280238fd1498Szrj else if (DECL_FINAL_P (decl))
280338fd1498Szrj error ("%q+#D marked %<final%>, but is not virtual", decl);
280438fd1498Szrj if (DECL_OVERRIDE_P (decl) && !overrides_found)
280538fd1498Szrj error ("%q+#D marked %<override%>, but does not override", decl);
280638fd1498Szrj }
280738fd1498Szrj
280838fd1498Szrj /* Warn about hidden virtual functions that are not overridden in t.
280938fd1498Szrj We know that constructors and destructors don't apply. */
281038fd1498Szrj
281138fd1498Szrj static void
warn_hidden(tree t)281238fd1498Szrj warn_hidden (tree t)
281338fd1498Szrj {
281438fd1498Szrj if (vec<tree, va_gc> *member_vec = CLASSTYPE_MEMBER_VEC (t))
281538fd1498Szrj for (unsigned ix = member_vec->length (); ix--;)
281638fd1498Szrj {
281738fd1498Szrj tree fns = (*member_vec)[ix];
281838fd1498Szrj
281938fd1498Szrj if (!OVL_P (fns))
282038fd1498Szrj continue;
282138fd1498Szrj
282238fd1498Szrj tree name = OVL_NAME (fns);
282338fd1498Szrj auto_vec<tree, 20> base_fndecls;
282438fd1498Szrj tree base_binfo;
282538fd1498Szrj tree binfo;
282638fd1498Szrj unsigned j;
282738fd1498Szrj
282838fd1498Szrj /* Iterate through all of the base classes looking for possibly
282938fd1498Szrj hidden functions. */
283038fd1498Szrj for (binfo = TYPE_BINFO (t), j = 0;
283138fd1498Szrj BINFO_BASE_ITERATE (binfo, j, base_binfo); j++)
283238fd1498Szrj {
283338fd1498Szrj tree basetype = BINFO_TYPE (base_binfo);
283438fd1498Szrj get_basefndecls (name, basetype, &base_fndecls);
283538fd1498Szrj }
283638fd1498Szrj
283738fd1498Szrj /* If there are no functions to hide, continue. */
283838fd1498Szrj if (base_fndecls.is_empty ())
283938fd1498Szrj continue;
284038fd1498Szrj
284138fd1498Szrj /* Remove any overridden functions. */
284238fd1498Szrj for (ovl_iterator iter (fns); iter; ++iter)
284338fd1498Szrj {
284438fd1498Szrj tree fndecl = *iter;
284538fd1498Szrj if (TREE_CODE (fndecl) == FUNCTION_DECL
284638fd1498Szrj && DECL_VINDEX (fndecl))
284738fd1498Szrj {
284838fd1498Szrj /* If the method from the base class has the same
284938fd1498Szrj signature as the method from the derived class, it
285038fd1498Szrj has been overridden. */
285138fd1498Szrj for (size_t k = 0; k < base_fndecls.length (); k++)
285238fd1498Szrj if (base_fndecls[k]
285338fd1498Szrj && same_signature_p (fndecl, base_fndecls[k]))
285438fd1498Szrj base_fndecls[k] = NULL_TREE;
285538fd1498Szrj }
285638fd1498Szrj }
285738fd1498Szrj
285838fd1498Szrj /* Now give a warning for all base functions without overriders,
285938fd1498Szrj as they are hidden. */
286038fd1498Szrj tree base_fndecl;
286138fd1498Szrj FOR_EACH_VEC_ELT (base_fndecls, j, base_fndecl)
286238fd1498Szrj if (base_fndecl)
286338fd1498Szrj {
286438fd1498Szrj /* Here we know it is a hider, and no overrider exists. */
286538fd1498Szrj warning_at (location_of (base_fndecl),
286638fd1498Szrj OPT_Woverloaded_virtual,
286738fd1498Szrj "%qD was hidden", base_fndecl);
286838fd1498Szrj warning_at (location_of (fns),
286938fd1498Szrj OPT_Woverloaded_virtual, " by %qD", fns);
287038fd1498Szrj }
287138fd1498Szrj }
287238fd1498Szrj }
287338fd1498Szrj
287438fd1498Szrj /* Recursive helper for finish_struct_anon. */
287538fd1498Szrj
287638fd1498Szrj static void
finish_struct_anon_r(tree field,bool complain)287738fd1498Szrj finish_struct_anon_r (tree field, bool complain)
287838fd1498Szrj {
287938fd1498Szrj for (tree elt = TYPE_FIELDS (TREE_TYPE (field)); elt; elt = DECL_CHAIN (elt))
288038fd1498Szrj {
288138fd1498Szrj /* We're generally only interested in entities the user
288238fd1498Szrj declared, but we also find nested classes by noticing
288338fd1498Szrj the TYPE_DECL that we create implicitly. You're
288438fd1498Szrj allowed to put one anonymous union inside another,
288538fd1498Szrj though, so we explicitly tolerate that. We use
288638fd1498Szrj TYPE_UNNAMED_P rather than ANON_AGGR_TYPE_P so that
288738fd1498Szrj we also allow unnamed types used for defining fields. */
288838fd1498Szrj if (DECL_ARTIFICIAL (elt)
288938fd1498Szrj && (!DECL_IMPLICIT_TYPEDEF_P (elt)
289038fd1498Szrj || TYPE_UNNAMED_P (TREE_TYPE (elt))))
289138fd1498Szrj continue;
289238fd1498Szrj
289338fd1498Szrj if (complain
289438fd1498Szrj && (TREE_CODE (elt) != FIELD_DECL
289538fd1498Szrj || (TREE_PRIVATE (elt) || TREE_PROTECTED (elt))))
289638fd1498Szrj {
289738fd1498Szrj /* We already complained about static data members in
289838fd1498Szrj finish_static_data_member_decl. */
289938fd1498Szrj if (!VAR_P (elt)
290038fd1498Szrj && permerror (DECL_SOURCE_LOCATION (elt),
290138fd1498Szrj TREE_CODE (TREE_TYPE (field)) == UNION_TYPE
290238fd1498Szrj ? "%q#D invalid; an anonymous union may "
290338fd1498Szrj "only have public non-static data members"
290438fd1498Szrj : "%q#D invalid; an anonymous struct may "
290538fd1498Szrj "only have public non-static data members", elt))
290638fd1498Szrj {
290738fd1498Szrj static bool hint;
290838fd1498Szrj if (flag_permissive && !hint)
290938fd1498Szrj {
291038fd1498Szrj hint = true;
291138fd1498Szrj inform (DECL_SOURCE_LOCATION (elt),
291238fd1498Szrj "this flexibility is deprecated and will be removed");
291338fd1498Szrj }
291438fd1498Szrj }
291538fd1498Szrj }
291638fd1498Szrj
291738fd1498Szrj TREE_PRIVATE (elt) = TREE_PRIVATE (field);
291838fd1498Szrj TREE_PROTECTED (elt) = TREE_PROTECTED (field);
291938fd1498Szrj
292038fd1498Szrj /* Recurse into the anonymous aggregates to correctly handle
292138fd1498Szrj access control (c++/24926):
292238fd1498Szrj
292338fd1498Szrj class A {
292438fd1498Szrj union {
292538fd1498Szrj union {
292638fd1498Szrj int i;
292738fd1498Szrj };
292838fd1498Szrj };
292938fd1498Szrj };
293038fd1498Szrj
293138fd1498Szrj int j=A().i; */
293238fd1498Szrj if (DECL_NAME (elt) == NULL_TREE
293338fd1498Szrj && ANON_AGGR_TYPE_P (TREE_TYPE (elt)))
293438fd1498Szrj finish_struct_anon_r (elt, /*complain=*/false);
293538fd1498Szrj }
293638fd1498Szrj }
293738fd1498Szrj
293838fd1498Szrj /* Check for things that are invalid. There are probably plenty of other
293938fd1498Szrj things we should check for also. */
294038fd1498Szrj
294138fd1498Szrj static void
finish_struct_anon(tree t)294238fd1498Szrj finish_struct_anon (tree t)
294338fd1498Szrj {
294438fd1498Szrj for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
294538fd1498Szrj {
294638fd1498Szrj if (TREE_STATIC (field))
294738fd1498Szrj continue;
294838fd1498Szrj if (TREE_CODE (field) != FIELD_DECL)
294938fd1498Szrj continue;
295038fd1498Szrj
295138fd1498Szrj if (DECL_NAME (field) == NULL_TREE
295238fd1498Szrj && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
295338fd1498Szrj finish_struct_anon_r (field, /*complain=*/true);
295438fd1498Szrj }
295538fd1498Szrj }
295638fd1498Szrj
295738fd1498Szrj /* Add T to CLASSTYPE_DECL_LIST of current_class_type which
295838fd1498Szrj will be used later during class template instantiation.
295938fd1498Szrj When FRIEND_P is zero, T can be a static member data (VAR_DECL),
296038fd1498Szrj a non-static member data (FIELD_DECL), a member function
296138fd1498Szrj (FUNCTION_DECL), a nested type (RECORD_TYPE, ENUM_TYPE),
296238fd1498Szrj a typedef (TYPE_DECL) or a member class template (TEMPLATE_DECL)
296338fd1498Szrj When FRIEND_P is nonzero, T is either a friend class
296438fd1498Szrj (RECORD_TYPE, TEMPLATE_DECL) or a friend function
296538fd1498Szrj (FUNCTION_DECL, TEMPLATE_DECL). */
296638fd1498Szrj
296738fd1498Szrj void
maybe_add_class_template_decl_list(tree type,tree t,int friend_p)296838fd1498Szrj maybe_add_class_template_decl_list (tree type, tree t, int friend_p)
296938fd1498Szrj {
297038fd1498Szrj /* Save some memory by not creating TREE_LIST if TYPE is not template. */
297138fd1498Szrj if (CLASSTYPE_TEMPLATE_INFO (type))
297238fd1498Szrj CLASSTYPE_DECL_LIST (type)
297338fd1498Szrj = tree_cons (friend_p ? NULL_TREE : type,
297438fd1498Szrj t, CLASSTYPE_DECL_LIST (type));
297538fd1498Szrj }
297638fd1498Szrj
297738fd1498Szrj /* This function is called from declare_virt_assop_and_dtor via
297838fd1498Szrj dfs_walk_all.
297938fd1498Szrj
298038fd1498Szrj DATA is a type that direcly or indirectly inherits the base
298138fd1498Szrj represented by BINFO. If BINFO contains a virtual assignment [copy
298238fd1498Szrj assignment or move assigment] operator or a virtual constructor,
298338fd1498Szrj declare that function in DATA if it hasn't been already declared. */
298438fd1498Szrj
298538fd1498Szrj static tree
dfs_declare_virt_assop_and_dtor(tree binfo,void * data)298638fd1498Szrj dfs_declare_virt_assop_and_dtor (tree binfo, void *data)
298738fd1498Szrj {
298838fd1498Szrj tree bv, fn, t = (tree)data;
298938fd1498Szrj tree opname = assign_op_identifier;
299038fd1498Szrj
299138fd1498Szrj gcc_assert (t && CLASS_TYPE_P (t));
299238fd1498Szrj gcc_assert (binfo && TREE_CODE (binfo) == TREE_BINFO);
299338fd1498Szrj
299438fd1498Szrj if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
299538fd1498Szrj /* A base without a vtable needs no modification, and its bases
299638fd1498Szrj are uninteresting. */
299738fd1498Szrj return dfs_skip_bases;
299838fd1498Szrj
299938fd1498Szrj if (BINFO_PRIMARY_P (binfo))
300038fd1498Szrj /* If this is a primary base, then we have already looked at the
300138fd1498Szrj virtual functions of its vtable. */
300238fd1498Szrj return NULL_TREE;
300338fd1498Szrj
300438fd1498Szrj for (bv = BINFO_VIRTUALS (binfo); bv; bv = TREE_CHAIN (bv))
300538fd1498Szrj {
300638fd1498Szrj fn = BV_FN (bv);
300738fd1498Szrj
300838fd1498Szrj if (DECL_NAME (fn) == opname)
300938fd1498Szrj {
301038fd1498Szrj if (CLASSTYPE_LAZY_COPY_ASSIGN (t))
301138fd1498Szrj lazily_declare_fn (sfk_copy_assignment, t);
301238fd1498Szrj if (CLASSTYPE_LAZY_MOVE_ASSIGN (t))
301338fd1498Szrj lazily_declare_fn (sfk_move_assignment, t);
301438fd1498Szrj }
301538fd1498Szrj else if (DECL_DESTRUCTOR_P (fn)
301638fd1498Szrj && CLASSTYPE_LAZY_DESTRUCTOR (t))
301738fd1498Szrj lazily_declare_fn (sfk_destructor, t);
301838fd1498Szrj }
301938fd1498Szrj
302038fd1498Szrj return NULL_TREE;
302138fd1498Szrj }
302238fd1498Szrj
302338fd1498Szrj /* If the class type T has a direct or indirect base that contains a
302438fd1498Szrj virtual assignment operator or a virtual destructor, declare that
302538fd1498Szrj function in T if it hasn't been already declared. */
302638fd1498Szrj
302738fd1498Szrj static void
declare_virt_assop_and_dtor(tree t)302838fd1498Szrj declare_virt_assop_and_dtor (tree t)
302938fd1498Szrj {
303038fd1498Szrj if (!(TYPE_POLYMORPHIC_P (t)
303138fd1498Szrj && (CLASSTYPE_LAZY_COPY_ASSIGN (t)
303238fd1498Szrj || CLASSTYPE_LAZY_MOVE_ASSIGN (t)
303338fd1498Szrj || CLASSTYPE_LAZY_DESTRUCTOR (t))))
303438fd1498Szrj return;
303538fd1498Szrj
303638fd1498Szrj dfs_walk_all (TYPE_BINFO (t),
303738fd1498Szrj dfs_declare_virt_assop_and_dtor,
303838fd1498Szrj NULL, t);
303938fd1498Szrj }
304038fd1498Szrj
304138fd1498Szrj /* Declare the inheriting constructor for class T inherited from base
304238fd1498Szrj constructor CTOR with the parameter array PARMS of size NPARMS. */
304338fd1498Szrj
304438fd1498Szrj static void
one_inheriting_sig(tree t,tree ctor,tree * parms,int nparms)304538fd1498Szrj one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms)
304638fd1498Szrj {
304738fd1498Szrj gcc_assert (TYPE_MAIN_VARIANT (t) == t);
304838fd1498Szrj
304938fd1498Szrj /* We don't declare an inheriting ctor that would be a default,
305038fd1498Szrj copy or move ctor for derived or base. */
305138fd1498Szrj if (nparms == 0)
305238fd1498Szrj return;
305338fd1498Szrj if (nparms == 1
305438fd1498Szrj && TREE_CODE (parms[0]) == REFERENCE_TYPE)
305538fd1498Szrj {
305638fd1498Szrj tree parm = TYPE_MAIN_VARIANT (TREE_TYPE (parms[0]));
305738fd1498Szrj if (parm == t || parm == DECL_CONTEXT (ctor))
305838fd1498Szrj return;
305938fd1498Szrj }
306038fd1498Szrj
306138fd1498Szrj tree parmlist = void_list_node;
306238fd1498Szrj for (int i = nparms - 1; i >= 0; i--)
306338fd1498Szrj parmlist = tree_cons (NULL_TREE, parms[i], parmlist);
306438fd1498Szrj tree fn = implicitly_declare_fn (sfk_inheriting_constructor,
306538fd1498Szrj t, false, ctor, parmlist);
306638fd1498Szrj
306738fd1498Szrj if (add_method (t, fn, false))
306838fd1498Szrj {
306938fd1498Szrj DECL_CHAIN (fn) = TYPE_FIELDS (t);
307038fd1498Szrj TYPE_FIELDS (t) = fn;
307138fd1498Szrj }
307238fd1498Szrj }
307338fd1498Szrj
307438fd1498Szrj /* Declare all the inheriting constructors for class T inherited from base
307538fd1498Szrj constructor CTOR. */
307638fd1498Szrj
307738fd1498Szrj static void
one_inherited_ctor(tree ctor,tree t,tree using_decl)307838fd1498Szrj one_inherited_ctor (tree ctor, tree t, tree using_decl)
307938fd1498Szrj {
308038fd1498Szrj tree parms = FUNCTION_FIRST_USER_PARMTYPE (ctor);
308138fd1498Szrj
308238fd1498Szrj if (flag_new_inheriting_ctors)
308338fd1498Szrj {
308438fd1498Szrj ctor = implicitly_declare_fn (sfk_inheriting_constructor,
308538fd1498Szrj t, /*const*/false, ctor, parms);
308638fd1498Szrj add_method (t, ctor, using_decl != NULL_TREE);
308738fd1498Szrj TYPE_HAS_USER_CONSTRUCTOR (t) = true;
308838fd1498Szrj return;
308938fd1498Szrj }
309038fd1498Szrj
309138fd1498Szrj tree *new_parms = XALLOCAVEC (tree, list_length (parms));
309238fd1498Szrj int i = 0;
309338fd1498Szrj for (; parms && parms != void_list_node; parms = TREE_CHAIN (parms))
309438fd1498Szrj {
309538fd1498Szrj if (TREE_PURPOSE (parms))
309638fd1498Szrj one_inheriting_sig (t, ctor, new_parms, i);
309738fd1498Szrj new_parms[i++] = TREE_VALUE (parms);
309838fd1498Szrj }
309938fd1498Szrj one_inheriting_sig (t, ctor, new_parms, i);
310038fd1498Szrj if (parms == NULL_TREE)
310138fd1498Szrj {
310238fd1498Szrj if (warning (OPT_Winherited_variadic_ctor,
310338fd1498Szrj "the ellipsis in %qD is not inherited", ctor))
310438fd1498Szrj inform (DECL_SOURCE_LOCATION (ctor), "%qD declared here", ctor);
310538fd1498Szrj }
310638fd1498Szrj }
310738fd1498Szrj
310838fd1498Szrj /* Create default constructors, assignment operators, and so forth for
310938fd1498Szrj the type indicated by T, if they are needed. CANT_HAVE_CONST_CTOR,
311038fd1498Szrj and CANT_HAVE_CONST_ASSIGNMENT are nonzero if, for whatever reason,
311138fd1498Szrj the class cannot have a default constructor, copy constructor
311238fd1498Szrj taking a const reference argument, or an assignment operator taking
311338fd1498Szrj a const reference, respectively. */
311438fd1498Szrj
311538fd1498Szrj static void
add_implicitly_declared_members(tree t,tree * access_decls,int cant_have_const_cctor,int cant_have_const_assignment)311638fd1498Szrj add_implicitly_declared_members (tree t, tree* access_decls,
311738fd1498Szrj int cant_have_const_cctor,
311838fd1498Szrj int cant_have_const_assignment)
311938fd1498Szrj {
312038fd1498Szrj /* Destructor. */
312138fd1498Szrj if (!CLASSTYPE_DESTRUCTOR (t))
312238fd1498Szrj /* In general, we create destructors lazily. */
312338fd1498Szrj CLASSTYPE_LAZY_DESTRUCTOR (t) = 1;
312438fd1498Szrj
312538fd1498Szrj bool move_ok = false;
312638fd1498Szrj if (cxx_dialect >= cxx11 && CLASSTYPE_LAZY_DESTRUCTOR (t)
312738fd1498Szrj && !TYPE_HAS_COPY_CTOR (t) && !TYPE_HAS_COPY_ASSIGN (t)
312838fd1498Szrj && !classtype_has_move_assign_or_move_ctor_p (t, false))
312938fd1498Szrj move_ok = true;
313038fd1498Szrj
313138fd1498Szrj /* [class.ctor]
313238fd1498Szrj
313338fd1498Szrj If there is no user-declared constructor for a class, a default
313438fd1498Szrj constructor is implicitly declared. */
313538fd1498Szrj if (! TYPE_HAS_USER_CONSTRUCTOR (t))
313638fd1498Szrj {
313738fd1498Szrj TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 1;
313838fd1498Szrj CLASSTYPE_LAZY_DEFAULT_CTOR (t) = 1;
313938fd1498Szrj if (cxx_dialect >= cxx11)
314038fd1498Szrj TYPE_HAS_CONSTEXPR_CTOR (t)
314138fd1498Szrj /* Don't force the declaration to get a hard answer; if the
314238fd1498Szrj definition would have made the class non-literal, it will still be
314338fd1498Szrj non-literal because of the base or member in question, and that
314438fd1498Szrj gives a better diagnostic. */
314538fd1498Szrj = type_maybe_constexpr_default_constructor (t);
314638fd1498Szrj }
314738fd1498Szrj
314838fd1498Szrj /* [class.ctor]
314938fd1498Szrj
315038fd1498Szrj If a class definition does not explicitly declare a copy
315138fd1498Szrj constructor, one is declared implicitly. */
315238fd1498Szrj if (! TYPE_HAS_COPY_CTOR (t))
315338fd1498Szrj {
315438fd1498Szrj TYPE_HAS_COPY_CTOR (t) = 1;
315538fd1498Szrj TYPE_HAS_CONST_COPY_CTOR (t) = !cant_have_const_cctor;
315638fd1498Szrj CLASSTYPE_LAZY_COPY_CTOR (t) = 1;
315738fd1498Szrj if (move_ok)
315838fd1498Szrj CLASSTYPE_LAZY_MOVE_CTOR (t) = 1;
315938fd1498Szrj }
316038fd1498Szrj
316138fd1498Szrj /* If there is no assignment operator, one will be created if and
316238fd1498Szrj when it is needed. For now, just record whether or not the type
316338fd1498Szrj of the parameter to the assignment operator will be a const or
316438fd1498Szrj non-const reference. */
316538fd1498Szrj if (!TYPE_HAS_COPY_ASSIGN (t))
316638fd1498Szrj {
316738fd1498Szrj TYPE_HAS_COPY_ASSIGN (t) = 1;
316838fd1498Szrj TYPE_HAS_CONST_COPY_ASSIGN (t) = !cant_have_const_assignment;
316938fd1498Szrj CLASSTYPE_LAZY_COPY_ASSIGN (t) = 1;
317038fd1498Szrj if (move_ok && !LAMBDA_TYPE_P (t))
317138fd1498Szrj CLASSTYPE_LAZY_MOVE_ASSIGN (t) = 1;
317238fd1498Szrj }
317338fd1498Szrj
317438fd1498Szrj /* We can't be lazy about declaring functions that might override
317538fd1498Szrj a virtual function from a base class. */
317638fd1498Szrj declare_virt_assop_and_dtor (t);
317738fd1498Szrj
317838fd1498Szrj while (*access_decls)
317938fd1498Szrj {
318038fd1498Szrj tree using_decl = TREE_VALUE (*access_decls);
318138fd1498Szrj tree decl = USING_DECL_DECLS (using_decl);
318238fd1498Szrj if (DECL_NAME (using_decl) == ctor_identifier)
318338fd1498Szrj {
318438fd1498Szrj /* declare, then remove the decl */
318538fd1498Szrj tree ctor_list = decl;
318638fd1498Szrj location_t loc = input_location;
318738fd1498Szrj input_location = DECL_SOURCE_LOCATION (using_decl);
318838fd1498Szrj for (ovl_iterator iter (ctor_list); iter; ++iter)
318938fd1498Szrj one_inherited_ctor (*iter, t, using_decl);
319038fd1498Szrj *access_decls = TREE_CHAIN (*access_decls);
319138fd1498Szrj input_location = loc;
319238fd1498Szrj }
319338fd1498Szrj else
319438fd1498Szrj access_decls = &TREE_CHAIN (*access_decls);
319538fd1498Szrj }
319638fd1498Szrj }
319738fd1498Szrj
319838fd1498Szrj /* FIELD is a bit-field. We are finishing the processing for its
319938fd1498Szrj enclosing type. Issue any appropriate messages and set appropriate
320038fd1498Szrj flags. Returns false if an error has been diagnosed. */
320138fd1498Szrj
320238fd1498Szrj static bool
check_bitfield_decl(tree field)320338fd1498Szrj check_bitfield_decl (tree field)
320438fd1498Szrj {
320538fd1498Szrj tree type = TREE_TYPE (field);
320638fd1498Szrj tree w;
320738fd1498Szrj
320838fd1498Szrj /* Extract the declared width of the bitfield, which has been
320938fd1498Szrj temporarily stashed in DECL_BIT_FIELD_REPRESENTATIVE by grokbitfield. */
321038fd1498Szrj w = DECL_BIT_FIELD_REPRESENTATIVE (field);
321138fd1498Szrj gcc_assert (w != NULL_TREE);
321238fd1498Szrj /* Remove the bit-field width indicator so that the rest of the
321338fd1498Szrj compiler does not treat that value as a qualifier. */
321438fd1498Szrj DECL_BIT_FIELD_REPRESENTATIVE (field) = NULL_TREE;
321538fd1498Szrj
321638fd1498Szrj /* Detect invalid bit-field type. */
321738fd1498Szrj if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type))
321838fd1498Szrj {
321938fd1498Szrj error ("bit-field %q+#D with non-integral type", field);
322038fd1498Szrj w = error_mark_node;
322138fd1498Szrj }
322238fd1498Szrj else
322338fd1498Szrj {
322438fd1498Szrj location_t loc = input_location;
322538fd1498Szrj /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs. */
322638fd1498Szrj STRIP_NOPS (w);
322738fd1498Szrj
322838fd1498Szrj /* detect invalid field size. */
322938fd1498Szrj input_location = DECL_SOURCE_LOCATION (field);
323038fd1498Szrj w = cxx_constant_value (w);
323138fd1498Szrj input_location = loc;
323238fd1498Szrj
323338fd1498Szrj if (TREE_CODE (w) != INTEGER_CST)
323438fd1498Szrj {
323538fd1498Szrj error ("bit-field %q+D width not an integer constant", field);
323638fd1498Szrj w = error_mark_node;
323738fd1498Szrj }
323838fd1498Szrj else if (tree_int_cst_sgn (w) < 0)
323938fd1498Szrj {
324038fd1498Szrj error ("negative width in bit-field %q+D", field);
324138fd1498Szrj w = error_mark_node;
324238fd1498Szrj }
324338fd1498Szrj else if (integer_zerop (w) && DECL_NAME (field) != 0)
324438fd1498Szrj {
324538fd1498Szrj error ("zero width for bit-field %q+D", field);
324638fd1498Szrj w = error_mark_node;
324738fd1498Szrj }
324838fd1498Szrj else if ((TREE_CODE (type) != ENUMERAL_TYPE
324938fd1498Szrj && TREE_CODE (type) != BOOLEAN_TYPE
325038fd1498Szrj && compare_tree_int (w, TYPE_PRECISION (type)) > 0)
325138fd1498Szrj || ((TREE_CODE (type) == ENUMERAL_TYPE
325238fd1498Szrj || TREE_CODE (type) == BOOLEAN_TYPE)
325338fd1498Szrj && tree_int_cst_lt (TYPE_SIZE (type), w)))
325438fd1498Szrj warning_at (DECL_SOURCE_LOCATION (field), 0,
325538fd1498Szrj "width of %qD exceeds its type", field);
325638fd1498Szrj else if (TREE_CODE (type) == ENUMERAL_TYPE)
325738fd1498Szrj {
325838fd1498Szrj int prec = TYPE_PRECISION (ENUM_UNDERLYING_TYPE (type));
325938fd1498Szrj if (compare_tree_int (w, prec) < 0)
326038fd1498Szrj warning_at (DECL_SOURCE_LOCATION (field), 0,
326138fd1498Szrj "%qD is too small to hold all values of %q#T",
326238fd1498Szrj field, type);
326338fd1498Szrj }
326438fd1498Szrj }
326538fd1498Szrj
326638fd1498Szrj if (w != error_mark_node)
326738fd1498Szrj {
326838fd1498Szrj DECL_SIZE (field) = fold_convert (bitsizetype, w);
326938fd1498Szrj DECL_BIT_FIELD (field) = 1;
327038fd1498Szrj return true;
327138fd1498Szrj }
327238fd1498Szrj else
327338fd1498Szrj {
327438fd1498Szrj /* Non-bit-fields are aligned for their type. */
327538fd1498Szrj DECL_BIT_FIELD (field) = 0;
327638fd1498Szrj CLEAR_DECL_C_BIT_FIELD (field);
327738fd1498Szrj return false;
327838fd1498Szrj }
327938fd1498Szrj }
328038fd1498Szrj
328138fd1498Szrj /* FIELD is a non bit-field. We are finishing the processing for its
328238fd1498Szrj enclosing type T. Issue any appropriate messages and set appropriate
328338fd1498Szrj flags. */
328438fd1498Szrj
328538fd1498Szrj static bool
check_field_decl(tree field,tree t,int * cant_have_const_ctor,int * no_const_asn_ref)328638fd1498Szrj check_field_decl (tree field,
328738fd1498Szrj tree t,
328838fd1498Szrj int* cant_have_const_ctor,
328938fd1498Szrj int* no_const_asn_ref)
329038fd1498Szrj {
329138fd1498Szrj tree type = strip_array_types (TREE_TYPE (field));
329238fd1498Szrj bool any_default_members = false;
329338fd1498Szrj
329438fd1498Szrj /* In C++98 an anonymous union cannot contain any fields which would change
329538fd1498Szrj the settings of CANT_HAVE_CONST_CTOR and friends. */
329638fd1498Szrj if (ANON_UNION_TYPE_P (type) && cxx_dialect < cxx11)
329738fd1498Szrj ;
329838fd1498Szrj /* And, we don't set TYPE_HAS_CONST_COPY_CTOR, etc., for anonymous
329938fd1498Szrj structs. So, we recurse through their fields here. */
330038fd1498Szrj else if (ANON_AGGR_TYPE_P (type))
330138fd1498Szrj {
330238fd1498Szrj for (tree fields = TYPE_FIELDS (type); fields;
330338fd1498Szrj fields = DECL_CHAIN (fields))
330438fd1498Szrj if (TREE_CODE (fields) == FIELD_DECL)
330538fd1498Szrj any_default_members |= check_field_decl (fields, t,
330638fd1498Szrj cant_have_const_ctor,
330738fd1498Szrj no_const_asn_ref);
330838fd1498Szrj }
330938fd1498Szrj /* Check members with class type for constructors, destructors,
331038fd1498Szrj etc. */
331138fd1498Szrj else if (CLASS_TYPE_P (type))
331238fd1498Szrj {
331338fd1498Szrj /* Never let anything with uninheritable virtuals
331438fd1498Szrj make it through without complaint. */
331538fd1498Szrj abstract_virtuals_error (field, type);
331638fd1498Szrj
331738fd1498Szrj if (TREE_CODE (t) == UNION_TYPE && cxx_dialect < cxx11)
331838fd1498Szrj {
331938fd1498Szrj static bool warned;
332038fd1498Szrj int oldcount = errorcount;
332138fd1498Szrj if (TYPE_NEEDS_CONSTRUCTING (type))
332238fd1498Szrj error ("member %q+#D with constructor not allowed in union",
332338fd1498Szrj field);
332438fd1498Szrj if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
332538fd1498Szrj error ("member %q+#D with destructor not allowed in union", field);
332638fd1498Szrj if (TYPE_HAS_COMPLEX_COPY_ASSIGN (type))
332738fd1498Szrj error ("member %q+#D with copy assignment operator not allowed in union",
332838fd1498Szrj field);
332938fd1498Szrj if (!warned && errorcount > oldcount)
333038fd1498Szrj {
333138fd1498Szrj inform (DECL_SOURCE_LOCATION (field), "unrestricted unions "
333238fd1498Szrj "only available with -std=c++11 or -std=gnu++11");
333338fd1498Szrj warned = true;
333438fd1498Szrj }
333538fd1498Szrj }
333638fd1498Szrj else
333738fd1498Szrj {
333838fd1498Szrj TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (type);
333938fd1498Szrj TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
334038fd1498Szrj |= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type);
334138fd1498Szrj TYPE_HAS_COMPLEX_COPY_ASSIGN (t)
334238fd1498Szrj |= (TYPE_HAS_COMPLEX_COPY_ASSIGN (type)
334338fd1498Szrj || !TYPE_HAS_COPY_ASSIGN (type));
334438fd1498Szrj TYPE_HAS_COMPLEX_COPY_CTOR (t) |= (TYPE_HAS_COMPLEX_COPY_CTOR (type)
334538fd1498Szrj || !TYPE_HAS_COPY_CTOR (type));
334638fd1498Szrj TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_HAS_COMPLEX_MOVE_ASSIGN (type);
334738fd1498Szrj TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_HAS_COMPLEX_MOVE_CTOR (type);
334838fd1498Szrj TYPE_HAS_COMPLEX_DFLT (t) |= (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type)
334938fd1498Szrj || TYPE_HAS_COMPLEX_DFLT (type));
335038fd1498Szrj }
335138fd1498Szrj
335238fd1498Szrj if (TYPE_HAS_COPY_CTOR (type)
335338fd1498Szrj && !TYPE_HAS_CONST_COPY_CTOR (type))
335438fd1498Szrj *cant_have_const_ctor = 1;
335538fd1498Szrj
335638fd1498Szrj if (TYPE_HAS_COPY_ASSIGN (type)
335738fd1498Szrj && !TYPE_HAS_CONST_COPY_ASSIGN (type))
335838fd1498Szrj *no_const_asn_ref = 1;
335938fd1498Szrj }
336038fd1498Szrj
336138fd1498Szrj check_abi_tags (t, field);
336238fd1498Szrj
336338fd1498Szrj if (DECL_INITIAL (field) != NULL_TREE)
336438fd1498Szrj /* `build_class_init_list' does not recognize
336538fd1498Szrj non-FIELD_DECLs. */
336638fd1498Szrj any_default_members = true;
336738fd1498Szrj
336838fd1498Szrj return any_default_members;
336938fd1498Szrj }
337038fd1498Szrj
337138fd1498Szrj /* Check the data members (both static and non-static), class-scoped
337238fd1498Szrj typedefs, etc., appearing in the declaration of T. Issue
337338fd1498Szrj appropriate diagnostics. Sets ACCESS_DECLS to a list (in
337438fd1498Szrj declaration order) of access declarations; each TREE_VALUE in this
337538fd1498Szrj list is a USING_DECL.
337638fd1498Szrj
337738fd1498Szrj In addition, set the following flags:
337838fd1498Szrj
337938fd1498Szrj EMPTY_P
338038fd1498Szrj The class is empty, i.e., contains no non-static data members.
338138fd1498Szrj
338238fd1498Szrj CANT_HAVE_CONST_CTOR_P
338338fd1498Szrj This class cannot have an implicitly generated copy constructor
338438fd1498Szrj taking a const reference.
338538fd1498Szrj
338638fd1498Szrj CANT_HAVE_CONST_ASN_REF
338738fd1498Szrj This class cannot have an implicitly generated assignment
338838fd1498Szrj operator taking a const reference.
338938fd1498Szrj
339038fd1498Szrj All of these flags should be initialized before calling this
339138fd1498Szrj function.
339238fd1498Szrj
339338fd1498Szrj Returns a pointer to the end of the TYPE_FIELDs chain; additional
339438fd1498Szrj fields can be added by adding to this chain. */
339538fd1498Szrj
339638fd1498Szrj static void
check_field_decls(tree t,tree * access_decls,int * cant_have_const_ctor_p,int * no_const_asn_ref_p)339738fd1498Szrj check_field_decls (tree t, tree *access_decls,
339838fd1498Szrj int *cant_have_const_ctor_p,
339938fd1498Szrj int *no_const_asn_ref_p)
340038fd1498Szrj {
340138fd1498Szrj tree *field;
340238fd1498Szrj tree *next;
340338fd1498Szrj bool has_pointers;
340438fd1498Szrj bool any_default_members;
340538fd1498Szrj int cant_pack = 0;
340638fd1498Szrj int field_access = -1;
340738fd1498Szrj
340838fd1498Szrj /* Assume there are no access declarations. */
340938fd1498Szrj *access_decls = NULL_TREE;
341038fd1498Szrj /* Assume this class has no pointer members. */
341138fd1498Szrj has_pointers = false;
341238fd1498Szrj /* Assume none of the members of this class have default
341338fd1498Szrj initializations. */
341438fd1498Szrj any_default_members = false;
341538fd1498Szrj
341638fd1498Szrj for (field = &TYPE_FIELDS (t); *field; field = next)
341738fd1498Szrj {
341838fd1498Szrj tree x = *field;
341938fd1498Szrj tree type = TREE_TYPE (x);
342038fd1498Szrj int this_field_access;
342138fd1498Szrj
342238fd1498Szrj next = &DECL_CHAIN (x);
342338fd1498Szrj
342438fd1498Szrj if (TREE_CODE (x) == USING_DECL)
342538fd1498Szrj {
342638fd1498Szrj /* Save the access declarations for our caller. */
342738fd1498Szrj *access_decls = tree_cons (NULL_TREE, x, *access_decls);
342838fd1498Szrj continue;
342938fd1498Szrj }
343038fd1498Szrj
343138fd1498Szrj if (TREE_CODE (x) == TYPE_DECL
343238fd1498Szrj || TREE_CODE (x) == TEMPLATE_DECL)
343338fd1498Szrj continue;
343438fd1498Szrj
343538fd1498Szrj if (TREE_CODE (x) == FUNCTION_DECL)
343638fd1498Szrj /* FIXME: We should fold in the checking from check_methods. */
343738fd1498Szrj continue;
343838fd1498Szrj
343938fd1498Szrj /* If we've gotten this far, it's a data member, possibly static,
344038fd1498Szrj or an enumerator. */
344138fd1498Szrj if (TREE_CODE (x) != CONST_DECL)
344238fd1498Szrj DECL_CONTEXT (x) = t;
344338fd1498Szrj
344438fd1498Szrj /* When this goes into scope, it will be a non-local reference. */
344538fd1498Szrj DECL_NONLOCAL (x) = 1;
344638fd1498Szrj
344738fd1498Szrj if (TREE_CODE (t) == UNION_TYPE)
344838fd1498Szrj {
344938fd1498Szrj /* [class.union] (C++98)
345038fd1498Szrj
345138fd1498Szrj If a union contains a static data member, or a member of
345238fd1498Szrj reference type, the program is ill-formed.
345338fd1498Szrj
345438fd1498Szrj In C++11 [class.union] says:
345538fd1498Szrj If a union contains a non-static data member of reference type
345638fd1498Szrj the program is ill-formed. */
345738fd1498Szrj if (VAR_P (x) && cxx_dialect < cxx11)
345838fd1498Szrj {
345938fd1498Szrj error ("in C++98 %q+D may not be static because it is "
346038fd1498Szrj "a member of a union", x);
346138fd1498Szrj continue;
346238fd1498Szrj }
346338fd1498Szrj if (TREE_CODE (type) == REFERENCE_TYPE
346438fd1498Szrj && TREE_CODE (x) == FIELD_DECL)
346538fd1498Szrj {
346638fd1498Szrj error ("non-static data member %q+D in a union may not "
346738fd1498Szrj "have reference type %qT", x, type);
346838fd1498Szrj continue;
346938fd1498Szrj }
347038fd1498Szrj }
347138fd1498Szrj
347238fd1498Szrj /* Perform error checking that did not get done in
347338fd1498Szrj grokdeclarator. */
347438fd1498Szrj if (TREE_CODE (type) == FUNCTION_TYPE)
347538fd1498Szrj {
347638fd1498Szrj error ("field %q+D invalidly declared function type", x);
347738fd1498Szrj type = build_pointer_type (type);
347838fd1498Szrj TREE_TYPE (x) = type;
347938fd1498Szrj }
348038fd1498Szrj else if (TREE_CODE (type) == METHOD_TYPE)
348138fd1498Szrj {
348238fd1498Szrj error ("field %q+D invalidly declared method type", x);
348338fd1498Szrj type = build_pointer_type (type);
348438fd1498Szrj TREE_TYPE (x) = type;
348538fd1498Szrj }
348638fd1498Szrj
348738fd1498Szrj if (type == error_mark_node)
348838fd1498Szrj continue;
348938fd1498Szrj
349038fd1498Szrj if (TREE_CODE (x) == CONST_DECL || VAR_P (x))
349138fd1498Szrj continue;
349238fd1498Szrj
349338fd1498Szrj /* Now it can only be a FIELD_DECL. */
349438fd1498Szrj
349538fd1498Szrj if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
349638fd1498Szrj CLASSTYPE_NON_AGGREGATE (t) = 1;
349738fd1498Szrj
349838fd1498Szrj /* If at least one non-static data member is non-literal, the whole
349938fd1498Szrj class becomes non-literal. Per Core/1453, volatile non-static
350038fd1498Szrj data members and base classes are also not allowed.
350138fd1498Szrj Note: if the type is incomplete we will complain later on. */
350238fd1498Szrj if (COMPLETE_TYPE_P (type)
350338fd1498Szrj && (!literal_type_p (type) || CP_TYPE_VOLATILE_P (type)))
350438fd1498Szrj CLASSTYPE_LITERAL_P (t) = false;
350538fd1498Szrj
350638fd1498Szrj /* A standard-layout class is a class that:
350738fd1498Szrj ...
350838fd1498Szrj has the same access control (Clause 11) for all non-static data members,
350938fd1498Szrj ... */
351038fd1498Szrj this_field_access = TREE_PROTECTED (x) ? 1 : TREE_PRIVATE (x) ? 2 : 0;
351138fd1498Szrj if (field_access == -1)
351238fd1498Szrj field_access = this_field_access;
351338fd1498Szrj else if (this_field_access != field_access)
351438fd1498Szrj CLASSTYPE_NON_STD_LAYOUT (t) = 1;
351538fd1498Szrj
351638fd1498Szrj /* If this is of reference type, check if it needs an init. */
351738fd1498Szrj if (TREE_CODE (type) == REFERENCE_TYPE)
351838fd1498Szrj {
351938fd1498Szrj CLASSTYPE_NON_LAYOUT_POD_P (t) = 1;
352038fd1498Szrj CLASSTYPE_NON_STD_LAYOUT (t) = 1;
352138fd1498Szrj if (DECL_INITIAL (x) == NULL_TREE)
352238fd1498Szrj SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
352338fd1498Szrj if (cxx_dialect < cxx11)
352438fd1498Szrj {
352538fd1498Szrj /* ARM $12.6.2: [A member initializer list] (or, for an
352638fd1498Szrj aggregate, initialization by a brace-enclosed list) is the
352738fd1498Szrj only way to initialize nonstatic const and reference
352838fd1498Szrj members. */
352938fd1498Szrj TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
353038fd1498Szrj TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
353138fd1498Szrj }
353238fd1498Szrj }
353338fd1498Szrj
353438fd1498Szrj type = strip_array_types (type);
353538fd1498Szrj
353638fd1498Szrj if (TYPE_PACKED (t))
353738fd1498Szrj {
353838fd1498Szrj if (!layout_pod_type_p (type) && !TYPE_PACKED (type))
353938fd1498Szrj {
354038fd1498Szrj warning_at
354138fd1498Szrj (DECL_SOURCE_LOCATION (x), 0,
354238fd1498Szrj "ignoring packed attribute because of unpacked non-POD field %q#D",
354338fd1498Szrj x);
354438fd1498Szrj cant_pack = 1;
354538fd1498Szrj }
354638fd1498Szrj else if (DECL_C_BIT_FIELD (x)
354738fd1498Szrj || TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
354838fd1498Szrj DECL_PACKED (x) = 1;
354938fd1498Szrj }
355038fd1498Szrj
355138fd1498Szrj if (DECL_C_BIT_FIELD (x)
355238fd1498Szrj && integer_zerop (DECL_BIT_FIELD_REPRESENTATIVE (x)))
355338fd1498Szrj /* We don't treat zero-width bitfields as making a class
355438fd1498Szrj non-empty. */
355538fd1498Szrj ;
355638fd1498Szrj else
355738fd1498Szrj {
355838fd1498Szrj /* The class is non-empty. */
355938fd1498Szrj CLASSTYPE_EMPTY_P (t) = 0;
356038fd1498Szrj /* The class is not even nearly empty. */
356138fd1498Szrj CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
356238fd1498Szrj /* If one of the data members contains an empty class,
356338fd1498Szrj so does T. */
356438fd1498Szrj if (CLASS_TYPE_P (type)
356538fd1498Szrj && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
356638fd1498Szrj CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
356738fd1498Szrj }
356838fd1498Szrj
356938fd1498Szrj /* This is used by -Weffc++ (see below). Warn only for pointers
357038fd1498Szrj to members which might hold dynamic memory. So do not warn
357138fd1498Szrj for pointers to functions or pointers to members. */
357238fd1498Szrj if (TYPE_PTR_P (type)
357338fd1498Szrj && !TYPE_PTRFN_P (type))
357438fd1498Szrj has_pointers = true;
357538fd1498Szrj
357638fd1498Szrj if (CLASS_TYPE_P (type))
357738fd1498Szrj {
357838fd1498Szrj if (CLASSTYPE_REF_FIELDS_NEED_INIT (type))
357938fd1498Szrj SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
358038fd1498Szrj if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (type))
358138fd1498Szrj SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
358238fd1498Szrj }
358338fd1498Szrj
358438fd1498Szrj if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
358538fd1498Szrj CLASSTYPE_HAS_MUTABLE (t) = 1;
358638fd1498Szrj
358738fd1498Szrj if (DECL_MUTABLE_P (x))
358838fd1498Szrj {
358938fd1498Szrj if (CP_TYPE_CONST_P (type))
359038fd1498Szrj {
359138fd1498Szrj error ("member %q+D cannot be declared both %<const%> "
359238fd1498Szrj "and %<mutable%>", x);
359338fd1498Szrj continue;
359438fd1498Szrj }
359538fd1498Szrj if (TREE_CODE (type) == REFERENCE_TYPE)
359638fd1498Szrj {
359738fd1498Szrj error ("member %q+D cannot be declared as a %<mutable%> "
359838fd1498Szrj "reference", x);
359938fd1498Szrj continue;
360038fd1498Szrj }
360138fd1498Szrj }
360238fd1498Szrj
360338fd1498Szrj if (! layout_pod_type_p (type))
360438fd1498Szrj /* DR 148 now allows pointers to members (which are POD themselves),
360538fd1498Szrj to be allowed in POD structs. */
360638fd1498Szrj CLASSTYPE_NON_LAYOUT_POD_P (t) = 1;
360738fd1498Szrj
360838fd1498Szrj if (!std_layout_type_p (type))
360938fd1498Szrj CLASSTYPE_NON_STD_LAYOUT (t) = 1;
361038fd1498Szrj
361138fd1498Szrj if (! zero_init_p (type))
361238fd1498Szrj CLASSTYPE_NON_ZERO_INIT_P (t) = 1;
361338fd1498Szrj
361438fd1498Szrj /* We set DECL_C_BIT_FIELD in grokbitfield.
361538fd1498Szrj If the type and width are valid, we'll also set DECL_BIT_FIELD. */
361638fd1498Szrj if (DECL_C_BIT_FIELD (x))
361738fd1498Szrj check_bitfield_decl (x);
361838fd1498Szrj
361938fd1498Szrj if (check_field_decl (x, t, cant_have_const_ctor_p, no_const_asn_ref_p))
362038fd1498Szrj {
362138fd1498Szrj if (any_default_members
362238fd1498Szrj && TREE_CODE (t) == UNION_TYPE)
362338fd1498Szrj error ("multiple fields in union %qT initialized", t);
362438fd1498Szrj any_default_members = true;
362538fd1498Szrj }
362638fd1498Szrj
362738fd1498Szrj /* Now that we've removed bit-field widths from DECL_INITIAL,
362838fd1498Szrj anything left in DECL_INITIAL is an NSDMI that makes the class
362938fd1498Szrj non-aggregate in C++11. */
363038fd1498Szrj if (DECL_INITIAL (x) && cxx_dialect < cxx14)
363138fd1498Szrj CLASSTYPE_NON_AGGREGATE (t) = true;
363238fd1498Szrj
363338fd1498Szrj /* If any field is const, the structure type is pseudo-const. */
363438fd1498Szrj if (CP_TYPE_CONST_P (type))
363538fd1498Szrj {
363638fd1498Szrj C_TYPE_FIELDS_READONLY (t) = 1;
363738fd1498Szrj if (DECL_INITIAL (x) == NULL_TREE)
363838fd1498Szrj SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
363938fd1498Szrj if (cxx_dialect < cxx11)
364038fd1498Szrj {
364138fd1498Szrj /* ARM $12.6.2: [A member initializer list] (or, for an
364238fd1498Szrj aggregate, initialization by a brace-enclosed list) is the
364338fd1498Szrj only way to initialize nonstatic const and reference
364438fd1498Szrj members. */
364538fd1498Szrj TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
364638fd1498Szrj TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
364738fd1498Szrj }
364838fd1498Szrj }
364938fd1498Szrj /* A field that is pseudo-const makes the structure likewise. */
365038fd1498Szrj else if (CLASS_TYPE_P (type))
365138fd1498Szrj {
365238fd1498Szrj C_TYPE_FIELDS_READONLY (t) |= C_TYPE_FIELDS_READONLY (type);
365338fd1498Szrj SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t,
365438fd1498Szrj CLASSTYPE_READONLY_FIELDS_NEED_INIT (t)
365538fd1498Szrj | CLASSTYPE_READONLY_FIELDS_NEED_INIT (type));
365638fd1498Szrj }
365738fd1498Szrj
365838fd1498Szrj /* Core issue 80: A nonstatic data member is required to have a
365938fd1498Szrj different name from the class iff the class has a
366038fd1498Szrj user-declared constructor. */
366138fd1498Szrj if (constructor_name_p (DECL_NAME (x), t)
366238fd1498Szrj && TYPE_HAS_USER_CONSTRUCTOR (t))
366338fd1498Szrj permerror (DECL_SOURCE_LOCATION (x),
366438fd1498Szrj "field %q#D with same name as class", x);
366538fd1498Szrj }
366638fd1498Szrj
366738fd1498Szrj /* Effective C++ rule 11: if a class has dynamic memory held by pointers,
366838fd1498Szrj it should also define a copy constructor and an assignment operator to
366938fd1498Szrj implement the correct copy semantic (deep vs shallow, etc.). As it is
367038fd1498Szrj not feasible to check whether the constructors do allocate dynamic memory
367138fd1498Szrj and store it within members, we approximate the warning like this:
367238fd1498Szrj
367338fd1498Szrj -- Warn only if there are members which are pointers
367438fd1498Szrj -- Warn only if there is a non-trivial constructor (otherwise,
367538fd1498Szrj there cannot be memory allocated).
367638fd1498Szrj -- Warn only if there is a non-trivial destructor. We assume that the
367738fd1498Szrj user at least implemented the cleanup correctly, and a destructor
367838fd1498Szrj is needed to free dynamic memory.
367938fd1498Szrj
368038fd1498Szrj This seems enough for practical purposes. */
368138fd1498Szrj if (warn_ecpp
368238fd1498Szrj && has_pointers
368338fd1498Szrj && TYPE_HAS_USER_CONSTRUCTOR (t)
368438fd1498Szrj && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
368538fd1498Szrj && !(TYPE_HAS_COPY_CTOR (t) && TYPE_HAS_COPY_ASSIGN (t)))
368638fd1498Szrj {
368738fd1498Szrj warning (OPT_Weffc__, "%q#T has pointer data members", t);
368838fd1498Szrj
368938fd1498Szrj if (! TYPE_HAS_COPY_CTOR (t))
369038fd1498Szrj {
369138fd1498Szrj warning (OPT_Weffc__,
369238fd1498Szrj " but does not override %<%T(const %T&)%>", t, t);
369338fd1498Szrj if (!TYPE_HAS_COPY_ASSIGN (t))
369438fd1498Szrj warning (OPT_Weffc__, " or %<operator=(const %T&)%>", t);
369538fd1498Szrj }
369638fd1498Szrj else if (! TYPE_HAS_COPY_ASSIGN (t))
369738fd1498Szrj warning (OPT_Weffc__,
369838fd1498Szrj " but does not override %<operator=(const %T&)%>", t);
369938fd1498Szrj }
370038fd1498Szrj
370138fd1498Szrj /* Non-static data member initializers make the default constructor
370238fd1498Szrj non-trivial. */
370338fd1498Szrj if (any_default_members)
370438fd1498Szrj {
370538fd1498Szrj TYPE_NEEDS_CONSTRUCTING (t) = true;
370638fd1498Szrj TYPE_HAS_COMPLEX_DFLT (t) = true;
370738fd1498Szrj }
370838fd1498Szrj
370938fd1498Szrj /* If any of the fields couldn't be packed, unset TYPE_PACKED. */
371038fd1498Szrj if (cant_pack)
371138fd1498Szrj TYPE_PACKED (t) = 0;
371238fd1498Szrj
371338fd1498Szrj /* Check anonymous struct/anonymous union fields. */
371438fd1498Szrj finish_struct_anon (t);
371538fd1498Szrj
371638fd1498Szrj /* We've built up the list of access declarations in reverse order.
371738fd1498Szrj Fix that now. */
371838fd1498Szrj *access_decls = nreverse (*access_decls);
371938fd1498Szrj }
372038fd1498Szrj
372138fd1498Szrj /* If TYPE is an empty class type, records its OFFSET in the table of
372238fd1498Szrj OFFSETS. */
372338fd1498Szrj
372438fd1498Szrj static int
record_subobject_offset(tree type,tree offset,splay_tree offsets)372538fd1498Szrj record_subobject_offset (tree type, tree offset, splay_tree offsets)
372638fd1498Szrj {
372738fd1498Szrj splay_tree_node n;
372838fd1498Szrj
372938fd1498Szrj if (!is_empty_class (type))
373038fd1498Szrj return 0;
373138fd1498Szrj
373238fd1498Szrj /* Record the location of this empty object in OFFSETS. */
373338fd1498Szrj n = splay_tree_lookup (offsets, (splay_tree_key) offset);
373438fd1498Szrj if (!n)
373538fd1498Szrj n = splay_tree_insert (offsets,
373638fd1498Szrj (splay_tree_key) offset,
373738fd1498Szrj (splay_tree_value) NULL_TREE);
373838fd1498Szrj n->value = ((splay_tree_value)
373938fd1498Szrj tree_cons (NULL_TREE,
374038fd1498Szrj type,
374138fd1498Szrj (tree) n->value));
374238fd1498Szrj
374338fd1498Szrj return 0;
374438fd1498Szrj }
374538fd1498Szrj
374638fd1498Szrj /* Returns nonzero if TYPE is an empty class type and there is
374738fd1498Szrj already an entry in OFFSETS for the same TYPE as the same OFFSET. */
374838fd1498Szrj
374938fd1498Szrj static int
check_subobject_offset(tree type,tree offset,splay_tree offsets)375038fd1498Szrj check_subobject_offset (tree type, tree offset, splay_tree offsets)
375138fd1498Szrj {
375238fd1498Szrj splay_tree_node n;
375338fd1498Szrj tree t;
375438fd1498Szrj
375538fd1498Szrj if (!is_empty_class (type))
375638fd1498Szrj return 0;
375738fd1498Szrj
375838fd1498Szrj /* Record the location of this empty object in OFFSETS. */
375938fd1498Szrj n = splay_tree_lookup (offsets, (splay_tree_key) offset);
376038fd1498Szrj if (!n)
376138fd1498Szrj return 0;
376238fd1498Szrj
376338fd1498Szrj for (t = (tree) n->value; t; t = TREE_CHAIN (t))
376438fd1498Szrj if (same_type_p (TREE_VALUE (t), type))
376538fd1498Szrj return 1;
376638fd1498Szrj
376738fd1498Szrj return 0;
376838fd1498Szrj }
376938fd1498Szrj
377038fd1498Szrj /* Walk through all the subobjects of TYPE (located at OFFSET). Call
377138fd1498Szrj F for every subobject, passing it the type, offset, and table of
377238fd1498Szrj OFFSETS. If VBASES_P is one, then virtual non-primary bases should
377338fd1498Szrj be traversed.
377438fd1498Szrj
377538fd1498Szrj If MAX_OFFSET is non-NULL, then subobjects with an offset greater
377638fd1498Szrj than MAX_OFFSET will not be walked.
377738fd1498Szrj
377838fd1498Szrj If F returns a nonzero value, the traversal ceases, and that value
377938fd1498Szrj is returned. Otherwise, returns zero. */
378038fd1498Szrj
378138fd1498Szrj static int
walk_subobject_offsets(tree type,subobject_offset_fn f,tree offset,splay_tree offsets,tree max_offset,int vbases_p)378238fd1498Szrj walk_subobject_offsets (tree type,
378338fd1498Szrj subobject_offset_fn f,
378438fd1498Szrj tree offset,
378538fd1498Szrj splay_tree offsets,
378638fd1498Szrj tree max_offset,
378738fd1498Szrj int vbases_p)
378838fd1498Szrj {
378938fd1498Szrj int r = 0;
379038fd1498Szrj tree type_binfo = NULL_TREE;
379138fd1498Szrj
379238fd1498Szrj /* If this OFFSET is bigger than the MAX_OFFSET, then we should
379338fd1498Szrj stop. */
379438fd1498Szrj if (max_offset && tree_int_cst_lt (max_offset, offset))
379538fd1498Szrj return 0;
379638fd1498Szrj
379738fd1498Szrj if (type == error_mark_node)
379838fd1498Szrj return 0;
379938fd1498Szrj
380038fd1498Szrj if (!TYPE_P (type))
380138fd1498Szrj {
380238fd1498Szrj type_binfo = type;
380338fd1498Szrj type = BINFO_TYPE (type);
380438fd1498Szrj }
380538fd1498Szrj
380638fd1498Szrj if (CLASS_TYPE_P (type))
380738fd1498Szrj {
380838fd1498Szrj tree field;
380938fd1498Szrj tree binfo;
381038fd1498Szrj int i;
381138fd1498Szrj
381238fd1498Szrj /* Avoid recursing into objects that are not interesting. */
381338fd1498Szrj if (!CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
381438fd1498Szrj return 0;
381538fd1498Szrj
381638fd1498Szrj /* Record the location of TYPE. */
381738fd1498Szrj r = (*f) (type, offset, offsets);
381838fd1498Szrj if (r)
381938fd1498Szrj return r;
382038fd1498Szrj
382138fd1498Szrj /* Iterate through the direct base classes of TYPE. */
382238fd1498Szrj if (!type_binfo)
382338fd1498Szrj type_binfo = TYPE_BINFO (type);
382438fd1498Szrj for (i = 0; BINFO_BASE_ITERATE (type_binfo, i, binfo); i++)
382538fd1498Szrj {
382638fd1498Szrj tree binfo_offset;
382738fd1498Szrj
382838fd1498Szrj if (BINFO_VIRTUAL_P (binfo))
382938fd1498Szrj continue;
383038fd1498Szrj
383138fd1498Szrj tree orig_binfo;
383238fd1498Szrj /* We cannot rely on BINFO_OFFSET being set for the base
383338fd1498Szrj class yet, but the offsets for direct non-virtual
383438fd1498Szrj bases can be calculated by going back to the TYPE. */
383538fd1498Szrj orig_binfo = BINFO_BASE_BINFO (TYPE_BINFO (type), i);
383638fd1498Szrj binfo_offset = size_binop (PLUS_EXPR,
383738fd1498Szrj offset,
383838fd1498Szrj BINFO_OFFSET (orig_binfo));
383938fd1498Szrj
384038fd1498Szrj r = walk_subobject_offsets (binfo,
384138fd1498Szrj f,
384238fd1498Szrj binfo_offset,
384338fd1498Szrj offsets,
384438fd1498Szrj max_offset,
384538fd1498Szrj /*vbases_p=*/0);
384638fd1498Szrj if (r)
384738fd1498Szrj return r;
384838fd1498Szrj }
384938fd1498Szrj
385038fd1498Szrj if (CLASSTYPE_VBASECLASSES (type))
385138fd1498Szrj {
385238fd1498Szrj unsigned ix;
385338fd1498Szrj vec<tree, va_gc> *vbases;
385438fd1498Szrj
385538fd1498Szrj /* Iterate through the virtual base classes of TYPE. In G++
385638fd1498Szrj 3.2, we included virtual bases in the direct base class
385738fd1498Szrj loop above, which results in incorrect results; the
385838fd1498Szrj correct offsets for virtual bases are only known when
385938fd1498Szrj working with the most derived type. */
386038fd1498Szrj if (vbases_p)
386138fd1498Szrj for (vbases = CLASSTYPE_VBASECLASSES (type), ix = 0;
386238fd1498Szrj vec_safe_iterate (vbases, ix, &binfo); ix++)
386338fd1498Szrj {
386438fd1498Szrj r = walk_subobject_offsets (binfo,
386538fd1498Szrj f,
386638fd1498Szrj size_binop (PLUS_EXPR,
386738fd1498Szrj offset,
386838fd1498Szrj BINFO_OFFSET (binfo)),
386938fd1498Szrj offsets,
387038fd1498Szrj max_offset,
387138fd1498Szrj /*vbases_p=*/0);
387238fd1498Szrj if (r)
387338fd1498Szrj return r;
387438fd1498Szrj }
387538fd1498Szrj else
387638fd1498Szrj {
387738fd1498Szrj /* We still have to walk the primary base, if it is
387838fd1498Szrj virtual. (If it is non-virtual, then it was walked
387938fd1498Szrj above.) */
388038fd1498Szrj tree vbase = get_primary_binfo (type_binfo);
388138fd1498Szrj
388238fd1498Szrj if (vbase && BINFO_VIRTUAL_P (vbase)
388338fd1498Szrj && BINFO_PRIMARY_P (vbase)
388438fd1498Szrj && BINFO_INHERITANCE_CHAIN (vbase) == type_binfo)
388538fd1498Szrj {
388638fd1498Szrj r = (walk_subobject_offsets
388738fd1498Szrj (vbase, f, offset,
388838fd1498Szrj offsets, max_offset, /*vbases_p=*/0));
388938fd1498Szrj if (r)
389038fd1498Szrj return r;
389138fd1498Szrj }
389238fd1498Szrj }
389338fd1498Szrj }
389438fd1498Szrj
389538fd1498Szrj /* Iterate through the fields of TYPE. */
389638fd1498Szrj for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
389738fd1498Szrj if (TREE_CODE (field) == FIELD_DECL
389838fd1498Szrj && TREE_TYPE (field) != error_mark_node
389938fd1498Szrj && !DECL_ARTIFICIAL (field))
390038fd1498Szrj {
390138fd1498Szrj tree field_offset;
390238fd1498Szrj
390338fd1498Szrj field_offset = byte_position (field);
390438fd1498Szrj
390538fd1498Szrj r = walk_subobject_offsets (TREE_TYPE (field),
390638fd1498Szrj f,
390738fd1498Szrj size_binop (PLUS_EXPR,
390838fd1498Szrj offset,
390938fd1498Szrj field_offset),
391038fd1498Szrj offsets,
391138fd1498Szrj max_offset,
391238fd1498Szrj /*vbases_p=*/1);
391338fd1498Szrj if (r)
391438fd1498Szrj return r;
391538fd1498Szrj }
391638fd1498Szrj }
391738fd1498Szrj else if (TREE_CODE (type) == ARRAY_TYPE)
391838fd1498Szrj {
391938fd1498Szrj tree element_type = strip_array_types (type);
392038fd1498Szrj tree domain = TYPE_DOMAIN (type);
392138fd1498Szrj tree index;
392238fd1498Szrj
392338fd1498Szrj /* Avoid recursing into objects that are not interesting. */
392438fd1498Szrj if (!CLASS_TYPE_P (element_type)
392538fd1498Szrj || !CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type)
392638fd1498Szrj || !domain
392738fd1498Szrj || integer_minus_onep (TYPE_MAX_VALUE (domain)))
392838fd1498Szrj return 0;
392938fd1498Szrj
393038fd1498Szrj /* Step through each of the elements in the array. */
393138fd1498Szrj for (index = size_zero_node;
393238fd1498Szrj !tree_int_cst_lt (TYPE_MAX_VALUE (domain), index);
393338fd1498Szrj index = size_binop (PLUS_EXPR, index, size_one_node))
393438fd1498Szrj {
393538fd1498Szrj r = walk_subobject_offsets (TREE_TYPE (type),
393638fd1498Szrj f,
393738fd1498Szrj offset,
393838fd1498Szrj offsets,
393938fd1498Szrj max_offset,
394038fd1498Szrj /*vbases_p=*/1);
394138fd1498Szrj if (r)
394238fd1498Szrj return r;
394338fd1498Szrj offset = size_binop (PLUS_EXPR, offset,
394438fd1498Szrj TYPE_SIZE_UNIT (TREE_TYPE (type)));
394538fd1498Szrj /* If this new OFFSET is bigger than the MAX_OFFSET, then
394638fd1498Szrj there's no point in iterating through the remaining
394738fd1498Szrj elements of the array. */
394838fd1498Szrj if (max_offset && tree_int_cst_lt (max_offset, offset))
394938fd1498Szrj break;
395038fd1498Szrj }
395138fd1498Szrj }
395238fd1498Szrj
395338fd1498Szrj return 0;
395438fd1498Szrj }
395538fd1498Szrj
395638fd1498Szrj /* Record all of the empty subobjects of TYPE (either a type or a
395738fd1498Szrj binfo). If IS_DATA_MEMBER is true, then a non-static data member
395838fd1498Szrj is being placed at OFFSET; otherwise, it is a base class that is
395938fd1498Szrj being placed at OFFSET. */
396038fd1498Szrj
396138fd1498Szrj static void
record_subobject_offsets(tree type,tree offset,splay_tree offsets,bool is_data_member)396238fd1498Szrj record_subobject_offsets (tree type,
396338fd1498Szrj tree offset,
396438fd1498Szrj splay_tree offsets,
396538fd1498Szrj bool is_data_member)
396638fd1498Szrj {
396738fd1498Szrj tree max_offset;
396838fd1498Szrj /* If recording subobjects for a non-static data member or a
396938fd1498Szrj non-empty base class , we do not need to record offsets beyond
397038fd1498Szrj the size of the biggest empty class. Additional data members
397138fd1498Szrj will go at the end of the class. Additional base classes will go
397238fd1498Szrj either at offset zero (if empty, in which case they cannot
397338fd1498Szrj overlap with offsets past the size of the biggest empty class) or
397438fd1498Szrj at the end of the class.
397538fd1498Szrj
397638fd1498Szrj However, if we are placing an empty base class, then we must record
397738fd1498Szrj all offsets, as either the empty class is at offset zero (where
397838fd1498Szrj other empty classes might later be placed) or at the end of the
397938fd1498Szrj class (where other objects might then be placed, so other empty
398038fd1498Szrj subobjects might later overlap). */
398138fd1498Szrj if (is_data_member
398238fd1498Szrj || !is_empty_class (BINFO_TYPE (type)))
398338fd1498Szrj max_offset = sizeof_biggest_empty_class;
398438fd1498Szrj else
398538fd1498Szrj max_offset = NULL_TREE;
398638fd1498Szrj walk_subobject_offsets (type, record_subobject_offset, offset,
398738fd1498Szrj offsets, max_offset, is_data_member);
398838fd1498Szrj }
398938fd1498Szrj
399038fd1498Szrj /* Returns nonzero if any of the empty subobjects of TYPE (located at
399138fd1498Szrj OFFSET) conflict with entries in OFFSETS. If VBASES_P is nonzero,
399238fd1498Szrj virtual bases of TYPE are examined. */
399338fd1498Szrj
399438fd1498Szrj static int
layout_conflict_p(tree type,tree offset,splay_tree offsets,int vbases_p)399538fd1498Szrj layout_conflict_p (tree type,
399638fd1498Szrj tree offset,
399738fd1498Szrj splay_tree offsets,
399838fd1498Szrj int vbases_p)
399938fd1498Szrj {
400038fd1498Szrj splay_tree_node max_node;
400138fd1498Szrj
400238fd1498Szrj /* Get the node in OFFSETS that indicates the maximum offset where
400338fd1498Szrj an empty subobject is located. */
400438fd1498Szrj max_node = splay_tree_max (offsets);
400538fd1498Szrj /* If there aren't any empty subobjects, then there's no point in
400638fd1498Szrj performing this check. */
400738fd1498Szrj if (!max_node)
400838fd1498Szrj return 0;
400938fd1498Szrj
401038fd1498Szrj return walk_subobject_offsets (type, check_subobject_offset, offset,
401138fd1498Szrj offsets, (tree) (max_node->key),
401238fd1498Szrj vbases_p);
401338fd1498Szrj }
401438fd1498Szrj
401538fd1498Szrj /* DECL is a FIELD_DECL corresponding either to a base subobject of a
401638fd1498Szrj non-static data member of the type indicated by RLI. BINFO is the
401738fd1498Szrj binfo corresponding to the base subobject, OFFSETS maps offsets to
401838fd1498Szrj types already located at those offsets. This function determines
401938fd1498Szrj the position of the DECL. */
402038fd1498Szrj
402138fd1498Szrj static void
layout_nonempty_base_or_field(record_layout_info rli,tree decl,tree binfo,splay_tree offsets)402238fd1498Szrj layout_nonempty_base_or_field (record_layout_info rli,
402338fd1498Szrj tree decl,
402438fd1498Szrj tree binfo,
402538fd1498Szrj splay_tree offsets)
402638fd1498Szrj {
402738fd1498Szrj tree offset = NULL_TREE;
402838fd1498Szrj bool field_p;
402938fd1498Szrj tree type;
403038fd1498Szrj
403138fd1498Szrj if (binfo)
403238fd1498Szrj {
403338fd1498Szrj /* For the purposes of determining layout conflicts, we want to
403438fd1498Szrj use the class type of BINFO; TREE_TYPE (DECL) will be the
403538fd1498Szrj CLASSTYPE_AS_BASE version, which does not contain entries for
403638fd1498Szrj zero-sized bases. */
403738fd1498Szrj type = TREE_TYPE (binfo);
403838fd1498Szrj field_p = false;
403938fd1498Szrj }
404038fd1498Szrj else
404138fd1498Szrj {
404238fd1498Szrj type = TREE_TYPE (decl);
404338fd1498Szrj field_p = true;
404438fd1498Szrj }
404538fd1498Szrj
404638fd1498Szrj /* Try to place the field. It may take more than one try if we have
404738fd1498Szrj a hard time placing the field without putting two objects of the
404838fd1498Szrj same type at the same address. */
404938fd1498Szrj while (1)
405038fd1498Szrj {
405138fd1498Szrj struct record_layout_info_s old_rli = *rli;
405238fd1498Szrj
405338fd1498Szrj /* Place this field. */
405438fd1498Szrj place_field (rli, decl);
405538fd1498Szrj offset = byte_position (decl);
405638fd1498Szrj
405738fd1498Szrj /* We have to check to see whether or not there is already
405838fd1498Szrj something of the same type at the offset we're about to use.
405938fd1498Szrj For example, consider:
406038fd1498Szrj
406138fd1498Szrj struct S {};
406238fd1498Szrj struct T : public S { int i; };
406338fd1498Szrj struct U : public S, public T {};
406438fd1498Szrj
406538fd1498Szrj Here, we put S at offset zero in U. Then, we can't put T at
406638fd1498Szrj offset zero -- its S component would be at the same address
406738fd1498Szrj as the S we already allocated. So, we have to skip ahead.
406838fd1498Szrj Since all data members, including those whose type is an
406938fd1498Szrj empty class, have nonzero size, any overlap can happen only
407038fd1498Szrj with a direct or indirect base-class -- it can't happen with
407138fd1498Szrj a data member. */
407238fd1498Szrj /* In a union, overlap is permitted; all members are placed at
407338fd1498Szrj offset zero. */
407438fd1498Szrj if (TREE_CODE (rli->t) == UNION_TYPE)
407538fd1498Szrj break;
407638fd1498Szrj if (layout_conflict_p (field_p ? type : binfo, offset,
407738fd1498Szrj offsets, field_p))
407838fd1498Szrj {
407938fd1498Szrj /* Strip off the size allocated to this field. That puts us
408038fd1498Szrj at the first place we could have put the field with
408138fd1498Szrj proper alignment. */
408238fd1498Szrj *rli = old_rli;
408338fd1498Szrj
408438fd1498Szrj /* Bump up by the alignment required for the type. */
408538fd1498Szrj rli->bitpos
408638fd1498Szrj = size_binop (PLUS_EXPR, rli->bitpos,
408738fd1498Szrj bitsize_int (binfo
408838fd1498Szrj ? CLASSTYPE_ALIGN (type)
408938fd1498Szrj : TYPE_ALIGN (type)));
409038fd1498Szrj normalize_rli (rli);
409138fd1498Szrj }
409238fd1498Szrj else if (TREE_CODE (type) == NULLPTR_TYPE
409338fd1498Szrj && warn_abi && abi_version_crosses (9))
409438fd1498Szrj {
409538fd1498Szrj /* Before ABI v9, we were giving nullptr_t alignment of 1; if
409638fd1498Szrj the offset wasn't aligned like a pointer when we started to
409738fd1498Szrj layout this field, that affects its position. */
409838fd1498Szrj tree pos = rli_size_unit_so_far (&old_rli);
409938fd1498Szrj if (int_cst_value (pos) % TYPE_ALIGN_UNIT (ptr_type_node) != 0)
410038fd1498Szrj {
410138fd1498Szrj if (abi_version_at_least (9))
410238fd1498Szrj warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wabi,
410338fd1498Szrj "alignment of %qD increased in -fabi-version=9 "
410438fd1498Szrj "(GCC 5.2)", decl);
410538fd1498Szrj else
410638fd1498Szrj warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wabi, "alignment "
410738fd1498Szrj "of %qD will increase in -fabi-version=9", decl);
410838fd1498Szrj }
410938fd1498Szrj break;
411038fd1498Szrj }
411138fd1498Szrj else
411238fd1498Szrj /* There was no conflict. We're done laying out this field. */
411338fd1498Szrj break;
411438fd1498Szrj }
411538fd1498Szrj
411638fd1498Szrj /* Now that we know where it will be placed, update its
411738fd1498Szrj BINFO_OFFSET. */
411838fd1498Szrj if (binfo && CLASS_TYPE_P (BINFO_TYPE (binfo)))
411938fd1498Szrj /* Indirect virtual bases may have a nonzero BINFO_OFFSET at
412038fd1498Szrj this point because their BINFO_OFFSET is copied from another
412138fd1498Szrj hierarchy. Therefore, we may not need to add the entire
412238fd1498Szrj OFFSET. */
412338fd1498Szrj propagate_binfo_offsets (binfo,
412438fd1498Szrj size_diffop_loc (input_location,
412538fd1498Szrj fold_convert (ssizetype, offset),
412638fd1498Szrj fold_convert (ssizetype,
412738fd1498Szrj BINFO_OFFSET (binfo))));
412838fd1498Szrj }
412938fd1498Szrj
413038fd1498Szrj /* Returns true if TYPE is empty and OFFSET is nonzero. */
413138fd1498Szrj
413238fd1498Szrj static int
empty_base_at_nonzero_offset_p(tree type,tree offset,splay_tree)413338fd1498Szrj empty_base_at_nonzero_offset_p (tree type,
413438fd1498Szrj tree offset,
413538fd1498Szrj splay_tree /*offsets*/)
413638fd1498Szrj {
413738fd1498Szrj return is_empty_class (type) && !integer_zerop (offset);
413838fd1498Szrj }
413938fd1498Szrj
414038fd1498Szrj /* Layout the empty base BINFO. EOC indicates the byte currently just
414138fd1498Szrj past the end of the class, and should be correctly aligned for a
414238fd1498Szrj class of the type indicated by BINFO; OFFSETS gives the offsets of
414338fd1498Szrj the empty bases allocated so far. T is the most derived
414438fd1498Szrj type. Return nonzero iff we added it at the end. */
414538fd1498Szrj
414638fd1498Szrj static bool
layout_empty_base(record_layout_info rli,tree binfo,tree eoc,splay_tree offsets)414738fd1498Szrj layout_empty_base (record_layout_info rli, tree binfo,
414838fd1498Szrj tree eoc, splay_tree offsets)
414938fd1498Szrj {
415038fd1498Szrj tree alignment;
415138fd1498Szrj tree basetype = BINFO_TYPE (binfo);
415238fd1498Szrj bool atend = false;
415338fd1498Szrj
415438fd1498Szrj /* This routine should only be used for empty classes. */
415538fd1498Szrj gcc_assert (is_empty_class (basetype));
415638fd1498Szrj alignment = ssize_int (CLASSTYPE_ALIGN_UNIT (basetype));
415738fd1498Szrj
415838fd1498Szrj if (!integer_zerop (BINFO_OFFSET (binfo)))
415938fd1498Szrj propagate_binfo_offsets
416038fd1498Szrj (binfo, size_diffop_loc (input_location,
416138fd1498Szrj size_zero_node, BINFO_OFFSET (binfo)));
416238fd1498Szrj
416338fd1498Szrj /* This is an empty base class. We first try to put it at offset
416438fd1498Szrj zero. */
416538fd1498Szrj if (layout_conflict_p (binfo,
416638fd1498Szrj BINFO_OFFSET (binfo),
416738fd1498Szrj offsets,
416838fd1498Szrj /*vbases_p=*/0))
416938fd1498Szrj {
417038fd1498Szrj /* That didn't work. Now, we move forward from the next
417138fd1498Szrj available spot in the class. */
417238fd1498Szrj atend = true;
417338fd1498Szrj propagate_binfo_offsets (binfo, fold_convert (ssizetype, eoc));
417438fd1498Szrj while (1)
417538fd1498Szrj {
417638fd1498Szrj if (!layout_conflict_p (binfo,
417738fd1498Szrj BINFO_OFFSET (binfo),
417838fd1498Szrj offsets,
417938fd1498Szrj /*vbases_p=*/0))
418038fd1498Szrj /* We finally found a spot where there's no overlap. */
418138fd1498Szrj break;
418238fd1498Szrj
418338fd1498Szrj /* There's overlap here, too. Bump along to the next spot. */
418438fd1498Szrj propagate_binfo_offsets (binfo, alignment);
418538fd1498Szrj }
418638fd1498Szrj }
418738fd1498Szrj
418838fd1498Szrj if (CLASSTYPE_USER_ALIGN (basetype))
418938fd1498Szrj {
419038fd1498Szrj rli->record_align = MAX (rli->record_align, CLASSTYPE_ALIGN (basetype));
419138fd1498Szrj if (warn_packed)
419238fd1498Szrj rli->unpacked_align = MAX (rli->unpacked_align, CLASSTYPE_ALIGN (basetype));
419338fd1498Szrj TYPE_USER_ALIGN (rli->t) = 1;
419438fd1498Szrj }
419538fd1498Szrj
419638fd1498Szrj return atend;
419738fd1498Szrj }
419838fd1498Szrj
419938fd1498Szrj /* Build the FIELD_DECL for BASETYPE as a base of T, add it to the chain of
420038fd1498Szrj fields at NEXT_FIELD, and return it. */
420138fd1498Szrj
420238fd1498Szrj static tree
build_base_field_1(tree t,tree basetype,tree * & next_field)420338fd1498Szrj build_base_field_1 (tree t, tree basetype, tree *&next_field)
420438fd1498Szrj {
420538fd1498Szrj /* Create the FIELD_DECL. */
420638fd1498Szrj gcc_assert (CLASSTYPE_AS_BASE (basetype));
420738fd1498Szrj tree decl = build_decl (input_location,
420838fd1498Szrj FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype));
420938fd1498Szrj DECL_ARTIFICIAL (decl) = 1;
421038fd1498Szrj DECL_IGNORED_P (decl) = 1;
421138fd1498Szrj DECL_FIELD_CONTEXT (decl) = t;
421238fd1498Szrj if (is_empty_class (basetype))
421338fd1498Szrj /* CLASSTYPE_SIZE is one byte, but the field needs to have size zero. */
421438fd1498Szrj DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = size_zero_node;
421538fd1498Szrj else
421638fd1498Szrj {
421738fd1498Szrj DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
421838fd1498Szrj DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
421938fd1498Szrj }
422038fd1498Szrj SET_DECL_ALIGN (decl, CLASSTYPE_ALIGN (basetype));
422138fd1498Szrj DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
422238fd1498Szrj SET_DECL_MODE (decl, TYPE_MODE (basetype));
422338fd1498Szrj DECL_FIELD_IS_BASE (decl) = 1;
422438fd1498Szrj
422538fd1498Szrj /* Add the new FIELD_DECL to the list of fields for T. */
422638fd1498Szrj DECL_CHAIN (decl) = *next_field;
422738fd1498Szrj *next_field = decl;
422838fd1498Szrj next_field = &DECL_CHAIN (decl);
422938fd1498Szrj
423038fd1498Szrj return decl;
423138fd1498Szrj }
423238fd1498Szrj
423338fd1498Szrj /* Layout the base given by BINFO in the class indicated by RLI.
423438fd1498Szrj *BASE_ALIGN is a running maximum of the alignments of
423538fd1498Szrj any base class. OFFSETS gives the location of empty base
423638fd1498Szrj subobjects. T is the most derived type. Return nonzero if the new
423738fd1498Szrj object cannot be nearly-empty. A new FIELD_DECL is inserted at
423838fd1498Szrj *NEXT_FIELD, unless BINFO is for an empty base class.
423938fd1498Szrj
424038fd1498Szrj Returns the location at which the next field should be inserted. */
424138fd1498Szrj
424238fd1498Szrj static tree *
build_base_field(record_layout_info rli,tree binfo,splay_tree offsets,tree * next_field)424338fd1498Szrj build_base_field (record_layout_info rli, tree binfo,
424438fd1498Szrj splay_tree offsets, tree *next_field)
424538fd1498Szrj {
424638fd1498Szrj tree t = rli->t;
424738fd1498Szrj tree basetype = BINFO_TYPE (binfo);
424838fd1498Szrj
424938fd1498Szrj if (!COMPLETE_TYPE_P (basetype))
425038fd1498Szrj /* This error is now reported in xref_tag, thus giving better
425138fd1498Szrj location information. */
425238fd1498Szrj return next_field;
425338fd1498Szrj
425438fd1498Szrj /* Place the base class. */
425538fd1498Szrj if (!is_empty_class (basetype))
425638fd1498Szrj {
425738fd1498Szrj tree decl;
425838fd1498Szrj
425938fd1498Szrj /* The containing class is non-empty because it has a non-empty
426038fd1498Szrj base class. */
426138fd1498Szrj CLASSTYPE_EMPTY_P (t) = 0;
426238fd1498Szrj
426338fd1498Szrj /* Create the FIELD_DECL. */
426438fd1498Szrj decl = build_base_field_1 (t, basetype, next_field);
426538fd1498Szrj
426638fd1498Szrj /* Try to place the field. It may take more than one try if we
426738fd1498Szrj have a hard time placing the field without putting two
426838fd1498Szrj objects of the same type at the same address. */
426938fd1498Szrj layout_nonempty_base_or_field (rli, decl, binfo, offsets);
427038fd1498Szrj }
427138fd1498Szrj else
427238fd1498Szrj {
427338fd1498Szrj tree eoc;
427438fd1498Szrj bool atend;
427538fd1498Szrj
427638fd1498Szrj /* On some platforms (ARM), even empty classes will not be
427738fd1498Szrj byte-aligned. */
427838fd1498Szrj eoc = round_up_loc (input_location,
427938fd1498Szrj rli_size_unit_so_far (rli),
428038fd1498Szrj CLASSTYPE_ALIGN_UNIT (basetype));
428138fd1498Szrj atend = layout_empty_base (rli, binfo, eoc, offsets);
428238fd1498Szrj /* A nearly-empty class "has no proper base class that is empty,
428338fd1498Szrj not morally virtual, and at an offset other than zero." */
428438fd1498Szrj if (!BINFO_VIRTUAL_P (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t))
428538fd1498Szrj {
428638fd1498Szrj if (atend)
428738fd1498Szrj CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
428838fd1498Szrj /* The check above (used in G++ 3.2) is insufficient because
428938fd1498Szrj an empty class placed at offset zero might itself have an
429038fd1498Szrj empty base at a nonzero offset. */
429138fd1498Szrj else if (walk_subobject_offsets (basetype,
429238fd1498Szrj empty_base_at_nonzero_offset_p,
429338fd1498Szrj size_zero_node,
429438fd1498Szrj /*offsets=*/NULL,
429538fd1498Szrj /*max_offset=*/NULL_TREE,
429638fd1498Szrj /*vbases_p=*/true))
429738fd1498Szrj CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
429838fd1498Szrj }
429938fd1498Szrj
430038fd1498Szrj /* We used to not create a FIELD_DECL for empty base classes because of
430138fd1498Szrj back end issues with overlapping FIELD_DECLs, but that doesn't seem to
430238fd1498Szrj be a problem anymore. We need them to handle initialization of C++17
430338fd1498Szrj aggregate bases. */
430438fd1498Szrj if (cxx_dialect >= cxx17 && !BINFO_VIRTUAL_P (binfo))
430538fd1498Szrj {
430638fd1498Szrj tree decl = build_base_field_1 (t, basetype, next_field);
430738fd1498Szrj DECL_FIELD_OFFSET (decl) = BINFO_OFFSET (binfo);
430838fd1498Szrj DECL_FIELD_BIT_OFFSET (decl) = bitsize_zero_node;
430938fd1498Szrj SET_DECL_OFFSET_ALIGN (decl, BITS_PER_UNIT);
431038fd1498Szrj }
431138fd1498Szrj
431238fd1498Szrj /* An empty virtual base causes a class to be non-empty
431338fd1498Szrj -- but in that case we do not need to clear CLASSTYPE_EMPTY_P
431438fd1498Szrj here because that was already done when the virtual table
431538fd1498Szrj pointer was created. */
431638fd1498Szrj }
431738fd1498Szrj
431838fd1498Szrj /* Record the offsets of BINFO and its base subobjects. */
431938fd1498Szrj record_subobject_offsets (binfo,
432038fd1498Szrj BINFO_OFFSET (binfo),
432138fd1498Szrj offsets,
432238fd1498Szrj /*is_data_member=*/false);
432338fd1498Szrj
432438fd1498Szrj return next_field;
432538fd1498Szrj }
432638fd1498Szrj
432738fd1498Szrj /* Layout all of the non-virtual base classes. Record empty
432838fd1498Szrj subobjects in OFFSETS. T is the most derived type. Return nonzero
432938fd1498Szrj if the type cannot be nearly empty. The fields created
433038fd1498Szrj corresponding to the base classes will be inserted at
433138fd1498Szrj *NEXT_FIELD. */
433238fd1498Szrj
433338fd1498Szrj static void
build_base_fields(record_layout_info rli,splay_tree offsets,tree * next_field)433438fd1498Szrj build_base_fields (record_layout_info rli,
433538fd1498Szrj splay_tree offsets, tree *next_field)
433638fd1498Szrj {
433738fd1498Szrj /* Chain to hold all the new FIELD_DECLs which stand in for base class
433838fd1498Szrj subobjects. */
433938fd1498Szrj tree t = rli->t;
434038fd1498Szrj int n_baseclasses = BINFO_N_BASE_BINFOS (TYPE_BINFO (t));
434138fd1498Szrj int i;
434238fd1498Szrj
434338fd1498Szrj /* The primary base class is always allocated first. */
434438fd1498Szrj if (CLASSTYPE_HAS_PRIMARY_BASE_P (t))
434538fd1498Szrj next_field = build_base_field (rli, CLASSTYPE_PRIMARY_BINFO (t),
434638fd1498Szrj offsets, next_field);
434738fd1498Szrj
434838fd1498Szrj /* Now allocate the rest of the bases. */
434938fd1498Szrj for (i = 0; i < n_baseclasses; ++i)
435038fd1498Szrj {
435138fd1498Szrj tree base_binfo;
435238fd1498Szrj
435338fd1498Szrj base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (t), i);
435438fd1498Szrj
435538fd1498Szrj /* The primary base was already allocated above, so we don't
435638fd1498Szrj need to allocate it again here. */
435738fd1498Szrj if (base_binfo == CLASSTYPE_PRIMARY_BINFO (t))
435838fd1498Szrj continue;
435938fd1498Szrj
436038fd1498Szrj /* Virtual bases are added at the end (a primary virtual base
436138fd1498Szrj will have already been added). */
436238fd1498Szrj if (BINFO_VIRTUAL_P (base_binfo))
436338fd1498Szrj continue;
436438fd1498Szrj
436538fd1498Szrj next_field = build_base_field (rli, base_binfo,
436638fd1498Szrj offsets, next_field);
436738fd1498Szrj }
436838fd1498Szrj }
436938fd1498Szrj
437038fd1498Szrj /* Go through the TYPE_FIELDS of T issuing any appropriate
437138fd1498Szrj diagnostics, figuring out which methods override which other
437238fd1498Szrj methods, and so forth. */
437338fd1498Szrj
437438fd1498Szrj static void
check_methods(tree t)437538fd1498Szrj check_methods (tree t)
437638fd1498Szrj {
437738fd1498Szrj for (tree x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
437838fd1498Szrj if (DECL_DECLARES_FUNCTION_P (x))
437938fd1498Szrj {
438038fd1498Szrj check_for_override (x, t);
438138fd1498Szrj
438238fd1498Szrj if (DECL_PURE_VIRTUAL_P (x)
438338fd1498Szrj && (TREE_CODE (x) != FUNCTION_DECL || ! DECL_VINDEX (x)))
438438fd1498Szrj error ("initializer specified for non-virtual method %q+D", x);
438538fd1498Szrj /* The name of the field is the original field name
438638fd1498Szrj Save this in auxiliary field for later overloading. */
438738fd1498Szrj if (TREE_CODE (x) == FUNCTION_DECL && DECL_VINDEX (x))
438838fd1498Szrj {
438938fd1498Szrj TYPE_POLYMORPHIC_P (t) = 1;
439038fd1498Szrj if (DECL_PURE_VIRTUAL_P (x))
439138fd1498Szrj vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
439238fd1498Szrj }
439338fd1498Szrj
439438fd1498Szrj /* All user-provided destructors are non-trivial.
439538fd1498Szrj Constructors and assignment ops are handled in
439638fd1498Szrj grok_special_member_properties. */
439738fd1498Szrj if (DECL_DESTRUCTOR_P (x) && user_provided_p (x))
439838fd1498Szrj TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1;
439938fd1498Szrj if (!DECL_VIRTUAL_P (x)
440038fd1498Szrj && lookup_attribute ("transaction_safe_dynamic",
440138fd1498Szrj DECL_ATTRIBUTES (x)))
440238fd1498Szrj error_at (DECL_SOURCE_LOCATION (x),
440338fd1498Szrj "%<transaction_safe_dynamic%> may only be specified for "
440438fd1498Szrj "a virtual function");
440538fd1498Szrj }
440638fd1498Szrj }
440738fd1498Szrj
440838fd1498Szrj /* FN is a constructor or destructor. Clone the declaration to create
440938fd1498Szrj a specialized in-charge or not-in-charge version, as indicated by
441038fd1498Szrj NAME. */
441138fd1498Szrj
441238fd1498Szrj static tree
build_clone(tree fn,tree name)441338fd1498Szrj build_clone (tree fn, tree name)
441438fd1498Szrj {
441538fd1498Szrj tree parms;
441638fd1498Szrj tree clone;
441738fd1498Szrj
441838fd1498Szrj /* Copy the function. */
441938fd1498Szrj clone = copy_decl (fn);
442038fd1498Szrj /* Reset the function name. */
442138fd1498Szrj DECL_NAME (clone) = name;
442238fd1498Szrj /* Remember where this function came from. */
442338fd1498Szrj DECL_ABSTRACT_ORIGIN (clone) = fn;
442438fd1498Szrj /* Make it easy to find the CLONE given the FN. */
442538fd1498Szrj DECL_CHAIN (clone) = DECL_CHAIN (fn);
442638fd1498Szrj DECL_CHAIN (fn) = clone;
442738fd1498Szrj
442838fd1498Szrj /* If this is a template, do the rest on the DECL_TEMPLATE_RESULT. */
442938fd1498Szrj if (TREE_CODE (clone) == TEMPLATE_DECL)
443038fd1498Szrj {
443138fd1498Szrj tree result = build_clone (DECL_TEMPLATE_RESULT (clone), name);
443238fd1498Szrj DECL_TEMPLATE_RESULT (clone) = result;
443338fd1498Szrj DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result));
443438fd1498Szrj DECL_TI_TEMPLATE (result) = clone;
443538fd1498Szrj TREE_TYPE (clone) = TREE_TYPE (result);
443638fd1498Szrj return clone;
443738fd1498Szrj }
443838fd1498Szrj else
443938fd1498Szrj {
444038fd1498Szrj // Clone constraints.
444138fd1498Szrj if (flag_concepts)
444238fd1498Szrj if (tree ci = get_constraints (fn))
444338fd1498Szrj set_constraints (clone, copy_node (ci));
444438fd1498Szrj }
444538fd1498Szrj
444638fd1498Szrj
444738fd1498Szrj SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE);
444838fd1498Szrj DECL_CLONED_FUNCTION (clone) = fn;
444938fd1498Szrj /* There's no pending inline data for this function. */
445038fd1498Szrj DECL_PENDING_INLINE_INFO (clone) = NULL;
445138fd1498Szrj DECL_PENDING_INLINE_P (clone) = 0;
445238fd1498Szrj
445338fd1498Szrj /* The base-class destructor is not virtual. */
445438fd1498Szrj if (name == base_dtor_identifier)
445538fd1498Szrj {
445638fd1498Szrj DECL_VIRTUAL_P (clone) = 0;
445738fd1498Szrj if (TREE_CODE (clone) != TEMPLATE_DECL)
445838fd1498Szrj DECL_VINDEX (clone) = NULL_TREE;
445938fd1498Szrj }
446038fd1498Szrj
446138fd1498Szrj bool ctor_omit_inherited_parms_p = ctor_omit_inherited_parms (clone);
446238fd1498Szrj if (ctor_omit_inherited_parms_p)
446338fd1498Szrj gcc_assert (DECL_HAS_IN_CHARGE_PARM_P (clone));
446438fd1498Szrj
446538fd1498Szrj /* If there was an in-charge parameter, drop it from the function
446638fd1498Szrj type. */
446738fd1498Szrj if (DECL_HAS_IN_CHARGE_PARM_P (clone))
446838fd1498Szrj {
446938fd1498Szrj tree basetype;
447038fd1498Szrj tree parmtypes;
447138fd1498Szrj tree exceptions;
447238fd1498Szrj
447338fd1498Szrj exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone));
447438fd1498Szrj basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
447538fd1498Szrj parmtypes = TYPE_ARG_TYPES (TREE_TYPE (clone));
447638fd1498Szrj /* Skip the `this' parameter. */
447738fd1498Szrj parmtypes = TREE_CHAIN (parmtypes);
447838fd1498Szrj /* Skip the in-charge parameter. */
447938fd1498Szrj parmtypes = TREE_CHAIN (parmtypes);
448038fd1498Szrj /* And the VTT parm, in a complete [cd]tor. */
448138fd1498Szrj if (DECL_HAS_VTT_PARM_P (fn)
448238fd1498Szrj && ! DECL_NEEDS_VTT_PARM_P (clone))
448338fd1498Szrj parmtypes = TREE_CHAIN (parmtypes);
448438fd1498Szrj if (ctor_omit_inherited_parms_p)
448538fd1498Szrj {
448638fd1498Szrj /* If we're omitting inherited parms, that just leaves the VTT. */
448738fd1498Szrj gcc_assert (DECL_NEEDS_VTT_PARM_P (clone));
448838fd1498Szrj parmtypes = tree_cons (NULL_TREE, vtt_parm_type, void_list_node);
448938fd1498Szrj }
449038fd1498Szrj TREE_TYPE (clone)
449138fd1498Szrj = build_method_type_directly (basetype,
449238fd1498Szrj TREE_TYPE (TREE_TYPE (clone)),
449338fd1498Szrj parmtypes);
449438fd1498Szrj if (exceptions)
449538fd1498Szrj TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone),
449638fd1498Szrj exceptions);
449738fd1498Szrj TREE_TYPE (clone)
449838fd1498Szrj = cp_build_type_attribute_variant (TREE_TYPE (clone),
449938fd1498Szrj TYPE_ATTRIBUTES (TREE_TYPE (fn)));
450038fd1498Szrj }
450138fd1498Szrj
450238fd1498Szrj /* Copy the function parameters. */
450338fd1498Szrj DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
450438fd1498Szrj /* Remove the in-charge parameter. */
450538fd1498Szrj if (DECL_HAS_IN_CHARGE_PARM_P (clone))
450638fd1498Szrj {
450738fd1498Szrj DECL_CHAIN (DECL_ARGUMENTS (clone))
450838fd1498Szrj = DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone)));
450938fd1498Szrj DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
451038fd1498Szrj }
451138fd1498Szrj /* And the VTT parm, in a complete [cd]tor. */
451238fd1498Szrj if (DECL_HAS_VTT_PARM_P (fn))
451338fd1498Szrj {
451438fd1498Szrj if (DECL_NEEDS_VTT_PARM_P (clone))
451538fd1498Szrj DECL_HAS_VTT_PARM_P (clone) = 1;
451638fd1498Szrj else
451738fd1498Szrj {
451838fd1498Szrj DECL_CHAIN (DECL_ARGUMENTS (clone))
451938fd1498Szrj = DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone)));
452038fd1498Szrj DECL_HAS_VTT_PARM_P (clone) = 0;
452138fd1498Szrj }
452238fd1498Szrj }
452338fd1498Szrj
452438fd1498Szrj /* A base constructor inheriting from a virtual base doesn't get the
452538fd1498Szrj arguments. */
452638fd1498Szrj if (ctor_omit_inherited_parms_p)
452738fd1498Szrj DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))) = NULL_TREE;
452838fd1498Szrj
452938fd1498Szrj for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms))
453038fd1498Szrj {
453138fd1498Szrj DECL_CONTEXT (parms) = clone;
453238fd1498Szrj cxx_dup_lang_specific_decl (parms);
453338fd1498Szrj }
453438fd1498Szrj
453538fd1498Szrj /* Create the RTL for this function. */
453638fd1498Szrj SET_DECL_RTL (clone, NULL);
453738fd1498Szrj rest_of_decl_compilation (clone, /*top_level=*/1, at_eof);
453838fd1498Szrj
453938fd1498Szrj return clone;
454038fd1498Szrj }
454138fd1498Szrj
454238fd1498Szrj /* Implementation of DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P, do
454338fd1498Szrj not invoke this function directly.
454438fd1498Szrj
454538fd1498Szrj For a non-thunk function, returns the address of the slot for storing
454638fd1498Szrj the function it is a clone of. Otherwise returns NULL_TREE.
454738fd1498Szrj
454838fd1498Szrj If JUST_TESTING, looks through TEMPLATE_DECL and returns NULL if
454938fd1498Szrj cloned_function is unset. This is to support the separate
455038fd1498Szrj DECL_CLONED_FUNCTION and DECL_CLONED_FUNCTION_P modes; using the latter
455138fd1498Szrj on a template makes sense, but not the former. */
455238fd1498Szrj
455338fd1498Szrj tree *
decl_cloned_function_p(const_tree decl,bool just_testing)455438fd1498Szrj decl_cloned_function_p (const_tree decl, bool just_testing)
455538fd1498Szrj {
455638fd1498Szrj tree *ptr;
455738fd1498Szrj if (just_testing)
455838fd1498Szrj decl = STRIP_TEMPLATE (decl);
455938fd1498Szrj
456038fd1498Szrj if (TREE_CODE (decl) != FUNCTION_DECL
456138fd1498Szrj || !DECL_LANG_SPECIFIC (decl)
456238fd1498Szrj || DECL_LANG_SPECIFIC (decl)->u.fn.thunk_p)
456338fd1498Szrj {
456438fd1498Szrj #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
456538fd1498Szrj if (!just_testing)
456638fd1498Szrj lang_check_failed (__FILE__, __LINE__, __FUNCTION__);
456738fd1498Szrj else
456838fd1498Szrj #endif
456938fd1498Szrj return NULL;
457038fd1498Szrj }
457138fd1498Szrj
457238fd1498Szrj ptr = &DECL_LANG_SPECIFIC (decl)->u.fn.u5.cloned_function;
457338fd1498Szrj if (just_testing && *ptr == NULL_TREE)
457438fd1498Szrj return NULL;
457538fd1498Szrj else
457638fd1498Szrj return ptr;
457738fd1498Szrj }
457838fd1498Szrj
457938fd1498Szrj /* Produce declarations for all appropriate clones of FN. If
458038fd1498Szrj UPDATE_METHODS is true, the clones are added to the
458138fd1498Szrj CLASSTYPE_MEMBER_VEC. */
458238fd1498Szrj
458338fd1498Szrj void
clone_function_decl(tree fn,bool update_methods)458438fd1498Szrj clone_function_decl (tree fn, bool update_methods)
458538fd1498Szrj {
458638fd1498Szrj tree clone;
458738fd1498Szrj
458838fd1498Szrj /* Avoid inappropriate cloning. */
458938fd1498Szrj if (DECL_CHAIN (fn)
459038fd1498Szrj && DECL_CLONED_FUNCTION_P (DECL_CHAIN (fn)))
459138fd1498Szrj return;
459238fd1498Szrj
459338fd1498Szrj if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
459438fd1498Szrj {
459538fd1498Szrj /* For each constructor, we need two variants: an in-charge version
459638fd1498Szrj and a not-in-charge version. */
459738fd1498Szrj clone = build_clone (fn, complete_ctor_identifier);
459838fd1498Szrj if (update_methods)
459938fd1498Szrj add_method (DECL_CONTEXT (clone), clone, false);
460038fd1498Szrj clone = build_clone (fn, base_ctor_identifier);
460138fd1498Szrj if (update_methods)
460238fd1498Szrj add_method (DECL_CONTEXT (clone), clone, false);
460338fd1498Szrj }
460438fd1498Szrj else
460538fd1498Szrj {
460638fd1498Szrj gcc_assert (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn));
460738fd1498Szrj
460838fd1498Szrj /* For each destructor, we need three variants: an in-charge
460938fd1498Szrj version, a not-in-charge version, and an in-charge deleting
461038fd1498Szrj version. We clone the deleting version first because that
461138fd1498Szrj means it will go second on the TYPE_FIELDS list -- and that
461238fd1498Szrj corresponds to the correct layout order in the virtual
461338fd1498Szrj function table.
461438fd1498Szrj
461538fd1498Szrj For a non-virtual destructor, we do not build a deleting
461638fd1498Szrj destructor. */
461738fd1498Szrj if (DECL_VIRTUAL_P (fn))
461838fd1498Szrj {
461938fd1498Szrj clone = build_clone (fn, deleting_dtor_identifier);
462038fd1498Szrj if (update_methods)
462138fd1498Szrj add_method (DECL_CONTEXT (clone), clone, false);
462238fd1498Szrj }
462338fd1498Szrj clone = build_clone (fn, complete_dtor_identifier);
462438fd1498Szrj if (update_methods)
462538fd1498Szrj add_method (DECL_CONTEXT (clone), clone, false);
462638fd1498Szrj clone = build_clone (fn, base_dtor_identifier);
462738fd1498Szrj if (update_methods)
462838fd1498Szrj add_method (DECL_CONTEXT (clone), clone, false);
462938fd1498Szrj }
463038fd1498Szrj
463138fd1498Szrj /* Note that this is an abstract function that is never emitted. */
463238fd1498Szrj DECL_ABSTRACT_P (fn) = true;
463338fd1498Szrj }
463438fd1498Szrj
463538fd1498Szrj /* DECL is an in charge constructor, which is being defined. This will
463638fd1498Szrj have had an in class declaration, from whence clones were
463738fd1498Szrj declared. An out-of-class definition can specify additional default
463838fd1498Szrj arguments. As it is the clones that are involved in overload
463938fd1498Szrj resolution, we must propagate the information from the DECL to its
464038fd1498Szrj clones. */
464138fd1498Szrj
464238fd1498Szrj void
adjust_clone_args(tree decl)464338fd1498Szrj adjust_clone_args (tree decl)
464438fd1498Szrj {
464538fd1498Szrj tree clone;
464638fd1498Szrj
464738fd1498Szrj for (clone = DECL_CHAIN (decl); clone && DECL_CLONED_FUNCTION_P (clone);
464838fd1498Szrj clone = DECL_CHAIN (clone))
464938fd1498Szrj {
465038fd1498Szrj tree orig_clone_parms = TYPE_ARG_TYPES (TREE_TYPE (clone));
465138fd1498Szrj tree orig_decl_parms = TYPE_ARG_TYPES (TREE_TYPE (decl));
465238fd1498Szrj tree decl_parms, clone_parms;
465338fd1498Szrj
465438fd1498Szrj clone_parms = orig_clone_parms;
465538fd1498Szrj
465638fd1498Szrj /* Skip the 'this' parameter. */
465738fd1498Szrj orig_clone_parms = TREE_CHAIN (orig_clone_parms);
465838fd1498Szrj orig_decl_parms = TREE_CHAIN (orig_decl_parms);
465938fd1498Szrj
466038fd1498Szrj if (DECL_HAS_IN_CHARGE_PARM_P (decl))
466138fd1498Szrj orig_decl_parms = TREE_CHAIN (orig_decl_parms);
466238fd1498Szrj if (DECL_HAS_VTT_PARM_P (decl))
466338fd1498Szrj orig_decl_parms = TREE_CHAIN (orig_decl_parms);
466438fd1498Szrj
466538fd1498Szrj clone_parms = orig_clone_parms;
466638fd1498Szrj if (DECL_HAS_VTT_PARM_P (clone))
466738fd1498Szrj clone_parms = TREE_CHAIN (clone_parms);
466838fd1498Szrj
466938fd1498Szrj for (decl_parms = orig_decl_parms; decl_parms;
467038fd1498Szrj decl_parms = TREE_CHAIN (decl_parms),
467138fd1498Szrj clone_parms = TREE_CHAIN (clone_parms))
467238fd1498Szrj {
467338fd1498Szrj if (clone_parms == void_list_node)
467438fd1498Szrj {
467538fd1498Szrj gcc_assert (decl_parms == clone_parms
467638fd1498Szrj || ctor_omit_inherited_parms (clone));
467738fd1498Szrj break;
467838fd1498Szrj }
467938fd1498Szrj
468038fd1498Szrj gcc_assert (same_type_p (TREE_TYPE (decl_parms),
468138fd1498Szrj TREE_TYPE (clone_parms)));
468238fd1498Szrj
468338fd1498Szrj if (TREE_PURPOSE (decl_parms) && !TREE_PURPOSE (clone_parms))
468438fd1498Szrj {
468538fd1498Szrj /* A default parameter has been added. Adjust the
468638fd1498Szrj clone's parameters. */
468738fd1498Szrj tree exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone));
468838fd1498Szrj tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (clone));
468938fd1498Szrj tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
469038fd1498Szrj tree type;
469138fd1498Szrj
469238fd1498Szrj clone_parms = orig_decl_parms;
469338fd1498Szrj
469438fd1498Szrj if (DECL_HAS_VTT_PARM_P (clone))
469538fd1498Szrj {
469638fd1498Szrj clone_parms = tree_cons (TREE_PURPOSE (orig_clone_parms),
469738fd1498Szrj TREE_VALUE (orig_clone_parms),
469838fd1498Szrj clone_parms);
469938fd1498Szrj TREE_TYPE (clone_parms) = TREE_TYPE (orig_clone_parms);
470038fd1498Szrj }
470138fd1498Szrj type = build_method_type_directly (basetype,
470238fd1498Szrj TREE_TYPE (TREE_TYPE (clone)),
470338fd1498Szrj clone_parms);
470438fd1498Szrj if (exceptions)
470538fd1498Szrj type = build_exception_variant (type, exceptions);
470638fd1498Szrj if (attrs)
470738fd1498Szrj type = cp_build_type_attribute_variant (type, attrs);
470838fd1498Szrj TREE_TYPE (clone) = type;
470938fd1498Szrj
471038fd1498Szrj clone_parms = NULL_TREE;
471138fd1498Szrj break;
471238fd1498Szrj }
471338fd1498Szrj }
471438fd1498Szrj gcc_assert (!clone_parms || clone_parms == void_list_node);
471538fd1498Szrj }
471638fd1498Szrj }
471738fd1498Szrj
471838fd1498Szrj /* For each of the constructors and destructors in T, create an
471938fd1498Szrj in-charge and not-in-charge variant. */
472038fd1498Szrj
472138fd1498Szrj static void
clone_constructors_and_destructors(tree t)472238fd1498Szrj clone_constructors_and_destructors (tree t)
472338fd1498Szrj {
472438fd1498Szrj /* While constructors can be via a using declaration, at this point
472538fd1498Szrj we no longer need to know that. */
472638fd1498Szrj for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
472738fd1498Szrj clone_function_decl (*iter, /*update_methods=*/true);
472838fd1498Szrj
472938fd1498Szrj if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
473038fd1498Szrj clone_function_decl (dtor, /*update_methods=*/true);
473138fd1498Szrj }
473238fd1498Szrj
473338fd1498Szrj /* Deduce noexcept for a destructor DTOR. */
473438fd1498Szrj
473538fd1498Szrj void
deduce_noexcept_on_destructor(tree dtor)473638fd1498Szrj deduce_noexcept_on_destructor (tree dtor)
473738fd1498Szrj {
473838fd1498Szrj if (!TYPE_RAISES_EXCEPTIONS (TREE_TYPE (dtor)))
473938fd1498Szrj TREE_TYPE (dtor) = build_exception_variant (TREE_TYPE (dtor),
474038fd1498Szrj noexcept_deferred_spec);
474138fd1498Szrj }
474238fd1498Szrj
474338fd1498Szrj /* Subroutine of set_one_vmethod_tm_attributes. Search base classes
474438fd1498Szrj of TYPE for virtual functions which FNDECL overrides. Return a
474538fd1498Szrj mask of the tm attributes found therein. */
474638fd1498Szrj
474738fd1498Szrj static int
look_for_tm_attr_overrides(tree type,tree fndecl)474838fd1498Szrj look_for_tm_attr_overrides (tree type, tree fndecl)
474938fd1498Szrj {
475038fd1498Szrj tree binfo = TYPE_BINFO (type);
475138fd1498Szrj tree base_binfo;
475238fd1498Szrj int ix, found = 0;
475338fd1498Szrj
475438fd1498Szrj for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ++ix)
475538fd1498Szrj {
475638fd1498Szrj tree o, basetype = BINFO_TYPE (base_binfo);
475738fd1498Szrj
475838fd1498Szrj if (!TYPE_POLYMORPHIC_P (basetype))
475938fd1498Szrj continue;
476038fd1498Szrj
476138fd1498Szrj o = look_for_overrides_here (basetype, fndecl);
476238fd1498Szrj if (o)
476338fd1498Szrj {
476438fd1498Szrj if (lookup_attribute ("transaction_safe_dynamic",
476538fd1498Szrj DECL_ATTRIBUTES (o)))
476638fd1498Szrj /* transaction_safe_dynamic is not inherited. */;
476738fd1498Szrj else
476838fd1498Szrj found |= tm_attr_to_mask (find_tm_attribute
476938fd1498Szrj (TYPE_ATTRIBUTES (TREE_TYPE (o))));
477038fd1498Szrj }
477138fd1498Szrj else
477238fd1498Szrj found |= look_for_tm_attr_overrides (basetype, fndecl);
477338fd1498Szrj }
477438fd1498Szrj
477538fd1498Szrj return found;
477638fd1498Szrj }
477738fd1498Szrj
477838fd1498Szrj /* Subroutine of set_method_tm_attributes. Handle the checks and
477938fd1498Szrj inheritance for one virtual method FNDECL. */
478038fd1498Szrj
478138fd1498Szrj static void
set_one_vmethod_tm_attributes(tree type,tree fndecl)478238fd1498Szrj set_one_vmethod_tm_attributes (tree type, tree fndecl)
478338fd1498Szrj {
478438fd1498Szrj tree tm_attr;
478538fd1498Szrj int found, have;
478638fd1498Szrj
478738fd1498Szrj found = look_for_tm_attr_overrides (type, fndecl);
478838fd1498Szrj
478938fd1498Szrj /* If FNDECL doesn't actually override anything (i.e. T is the
479038fd1498Szrj class that first declares FNDECL virtual), then we're done. */
479138fd1498Szrj if (found == 0)
479238fd1498Szrj return;
479338fd1498Szrj
479438fd1498Szrj tm_attr = find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl)));
479538fd1498Szrj have = tm_attr_to_mask (tm_attr);
479638fd1498Szrj
479738fd1498Szrj /* Intel STM Language Extension 3.0, Section 4.2 table 4:
479838fd1498Szrj tm_pure must match exactly, otherwise no weakening of
479938fd1498Szrj tm_safe > tm_callable > nothing. */
480038fd1498Szrj /* ??? The tm_pure attribute didn't make the transition to the
480138fd1498Szrj multivendor language spec. */
480238fd1498Szrj if (have == TM_ATTR_PURE)
480338fd1498Szrj {
480438fd1498Szrj if (found != TM_ATTR_PURE)
480538fd1498Szrj {
480638fd1498Szrj found &= -found;
480738fd1498Szrj goto err_override;
480838fd1498Szrj }
480938fd1498Szrj }
481038fd1498Szrj /* If the overridden function is tm_pure, then FNDECL must be. */
481138fd1498Szrj else if (found == TM_ATTR_PURE && tm_attr)
481238fd1498Szrj goto err_override;
481338fd1498Szrj /* Look for base class combinations that cannot be satisfied. */
481438fd1498Szrj else if (found != TM_ATTR_PURE && (found & TM_ATTR_PURE))
481538fd1498Szrj {
481638fd1498Szrj found &= ~TM_ATTR_PURE;
481738fd1498Szrj found &= -found;
481838fd1498Szrj error_at (DECL_SOURCE_LOCATION (fndecl),
481938fd1498Szrj "method overrides both %<transaction_pure%> and %qE methods",
482038fd1498Szrj tm_mask_to_attr (found));
482138fd1498Szrj }
482238fd1498Szrj /* If FNDECL did not declare an attribute, then inherit the most
482338fd1498Szrj restrictive one. */
482438fd1498Szrj else if (tm_attr == NULL)
482538fd1498Szrj {
482638fd1498Szrj apply_tm_attr (fndecl, tm_mask_to_attr (least_bit_hwi (found)));
482738fd1498Szrj }
482838fd1498Szrj /* Otherwise validate that we're not weaker than a function
482938fd1498Szrj that is being overridden. */
483038fd1498Szrj else
483138fd1498Szrj {
483238fd1498Szrj found &= -found;
483338fd1498Szrj if (found <= TM_ATTR_CALLABLE && have > found)
483438fd1498Szrj goto err_override;
483538fd1498Szrj }
483638fd1498Szrj return;
483738fd1498Szrj
483838fd1498Szrj err_override:
483938fd1498Szrj error_at (DECL_SOURCE_LOCATION (fndecl),
484038fd1498Szrj "method declared %qE overriding %qE method",
484138fd1498Szrj tm_attr, tm_mask_to_attr (found));
484238fd1498Szrj }
484338fd1498Szrj
484438fd1498Szrj /* For each of the methods in T, propagate a class-level tm attribute. */
484538fd1498Szrj
484638fd1498Szrj static void
set_method_tm_attributes(tree t)484738fd1498Szrj set_method_tm_attributes (tree t)
484838fd1498Szrj {
484938fd1498Szrj tree class_tm_attr, fndecl;
485038fd1498Szrj
485138fd1498Szrj /* Don't bother collecting tm attributes if transactional memory
485238fd1498Szrj support is not enabled. */
485338fd1498Szrj if (!flag_tm)
485438fd1498Szrj return;
485538fd1498Szrj
485638fd1498Szrj /* Process virtual methods first, as they inherit directly from the
485738fd1498Szrj base virtual function and also require validation of new attributes. */
485838fd1498Szrj if (TYPE_CONTAINS_VPTR_P (t))
485938fd1498Szrj {
486038fd1498Szrj tree vchain;
486138fd1498Szrj for (vchain = BINFO_VIRTUALS (TYPE_BINFO (t)); vchain;
486238fd1498Szrj vchain = TREE_CHAIN (vchain))
486338fd1498Szrj {
486438fd1498Szrj fndecl = BV_FN (vchain);
486538fd1498Szrj if (DECL_THUNK_P (fndecl))
486638fd1498Szrj fndecl = THUNK_TARGET (fndecl);
486738fd1498Szrj set_one_vmethod_tm_attributes (t, fndecl);
486838fd1498Szrj }
486938fd1498Szrj }
487038fd1498Szrj
487138fd1498Szrj /* If the class doesn't have an attribute, nothing more to do. */
487238fd1498Szrj class_tm_attr = find_tm_attribute (TYPE_ATTRIBUTES (t));
487338fd1498Szrj if (class_tm_attr == NULL)
487438fd1498Szrj return;
487538fd1498Szrj
487638fd1498Szrj /* Any method that does not yet have a tm attribute inherits
487738fd1498Szrj the one from the class. */
487838fd1498Szrj for (fndecl = TYPE_FIELDS (t); fndecl; fndecl = DECL_CHAIN (fndecl))
487938fd1498Szrj if (DECL_DECLARES_FUNCTION_P (fndecl)
488038fd1498Szrj && !find_tm_attribute (TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
488138fd1498Szrj apply_tm_attr (fndecl, class_tm_attr);
488238fd1498Szrj }
488338fd1498Szrj
488438fd1498Szrj /* Returns true if FN is a default constructor. */
488538fd1498Szrj
488638fd1498Szrj bool
default_ctor_p(tree fn)488738fd1498Szrj default_ctor_p (tree fn)
488838fd1498Szrj {
488938fd1498Szrj return (DECL_CONSTRUCTOR_P (fn)
489038fd1498Szrj && sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)));
489138fd1498Szrj }
489238fd1498Szrj
489338fd1498Szrj /* Returns true iff class T has a user-defined constructor that can be called
489438fd1498Szrj with more than zero arguments. */
489538fd1498Szrj
489638fd1498Szrj bool
type_has_user_nondefault_constructor(tree t)489738fd1498Szrj type_has_user_nondefault_constructor (tree t)
489838fd1498Szrj {
489938fd1498Szrj if (!TYPE_HAS_USER_CONSTRUCTOR (t))
490038fd1498Szrj return false;
490138fd1498Szrj
490238fd1498Szrj for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
490338fd1498Szrj {
490438fd1498Szrj tree fn = *iter;
490538fd1498Szrj if (!DECL_ARTIFICIAL (fn)
490638fd1498Szrj && (TREE_CODE (fn) == TEMPLATE_DECL
490738fd1498Szrj || (skip_artificial_parms_for (fn, DECL_ARGUMENTS (fn))
490838fd1498Szrj != NULL_TREE)))
490938fd1498Szrj return true;
491038fd1498Szrj }
491138fd1498Szrj
491238fd1498Szrj return false;
491338fd1498Szrj }
491438fd1498Szrj
491538fd1498Szrj /* Returns the defaulted constructor if T has one. Otherwise, returns
491638fd1498Szrj NULL_TREE. */
491738fd1498Szrj
491838fd1498Szrj tree
in_class_defaulted_default_constructor(tree t)491938fd1498Szrj in_class_defaulted_default_constructor (tree t)
492038fd1498Szrj {
492138fd1498Szrj if (!TYPE_HAS_USER_CONSTRUCTOR (t))
492238fd1498Szrj return NULL_TREE;
492338fd1498Szrj
492438fd1498Szrj for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
492538fd1498Szrj {
492638fd1498Szrj tree fn = *iter;
492738fd1498Szrj
492838fd1498Szrj if (DECL_DEFAULTED_IN_CLASS_P (fn)
492938fd1498Szrj && default_ctor_p (fn))
493038fd1498Szrj return fn;
493138fd1498Szrj }
493238fd1498Szrj
493338fd1498Szrj return NULL_TREE;
493438fd1498Szrj }
493538fd1498Szrj
493638fd1498Szrj /* Returns true iff FN is a user-provided function, i.e. user-declared
493738fd1498Szrj and not defaulted at its first declaration. */
493838fd1498Szrj
493938fd1498Szrj bool
user_provided_p(tree fn)494038fd1498Szrj user_provided_p (tree fn)
494138fd1498Szrj {
494238fd1498Szrj if (TREE_CODE (fn) == TEMPLATE_DECL)
494338fd1498Szrj return true;
494438fd1498Szrj else
494538fd1498Szrj return (!DECL_ARTIFICIAL (fn)
494638fd1498Szrj && !(DECL_INITIALIZED_IN_CLASS_P (fn)
494738fd1498Szrj && (DECL_DEFAULTED_FN (fn) || DECL_DELETED_FN (fn))));
494838fd1498Szrj }
494938fd1498Szrj
495038fd1498Szrj /* Returns true iff class T has a user-provided constructor. */
495138fd1498Szrj
495238fd1498Szrj bool
type_has_user_provided_constructor(tree t)495338fd1498Szrj type_has_user_provided_constructor (tree t)
495438fd1498Szrj {
495538fd1498Szrj if (!CLASS_TYPE_P (t))
495638fd1498Szrj return false;
495738fd1498Szrj
495838fd1498Szrj if (!TYPE_HAS_USER_CONSTRUCTOR (t))
495938fd1498Szrj return false;
496038fd1498Szrj
496138fd1498Szrj for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
496238fd1498Szrj if (user_provided_p (*iter))
496338fd1498Szrj return true;
496438fd1498Szrj
496538fd1498Szrj return false;
496638fd1498Szrj }
496738fd1498Szrj
496838fd1498Szrj /* Returns true iff class T has a user-provided or explicit constructor. */
496938fd1498Szrj
497038fd1498Szrj bool
type_has_user_provided_or_explicit_constructor(tree t)497138fd1498Szrj type_has_user_provided_or_explicit_constructor (tree t)
497238fd1498Szrj {
497338fd1498Szrj if (!CLASS_TYPE_P (t))
497438fd1498Szrj return false;
497538fd1498Szrj
497638fd1498Szrj if (!TYPE_HAS_USER_CONSTRUCTOR (t))
497738fd1498Szrj return false;
497838fd1498Szrj
497938fd1498Szrj for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
498038fd1498Szrj {
498138fd1498Szrj tree fn = *iter;
498238fd1498Szrj if (user_provided_p (fn) || DECL_NONCONVERTING_P (fn))
498338fd1498Szrj return true;
498438fd1498Szrj }
498538fd1498Szrj
498638fd1498Szrj return false;
498738fd1498Szrj }
498838fd1498Szrj
498938fd1498Szrj /* Returns true iff class T has a non-user-provided (i.e. implicitly
499038fd1498Szrj declared or explicitly defaulted in the class body) default
499138fd1498Szrj constructor. */
499238fd1498Szrj
499338fd1498Szrj bool
type_has_non_user_provided_default_constructor(tree t)499438fd1498Szrj type_has_non_user_provided_default_constructor (tree t)
499538fd1498Szrj {
499638fd1498Szrj if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (t))
499738fd1498Szrj return false;
499838fd1498Szrj if (CLASSTYPE_LAZY_DEFAULT_CTOR (t))
499938fd1498Szrj return true;
500038fd1498Szrj
500138fd1498Szrj for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
500238fd1498Szrj {
500338fd1498Szrj tree fn = *iter;
500438fd1498Szrj if (TREE_CODE (fn) == FUNCTION_DECL
500538fd1498Szrj && default_ctor_p (fn)
500638fd1498Szrj && !user_provided_p (fn))
500738fd1498Szrj return true;
500838fd1498Szrj }
500938fd1498Szrj
501038fd1498Szrj return false;
501138fd1498Szrj }
501238fd1498Szrj
501338fd1498Szrj /* TYPE is being used as a virtual base, and has a non-trivial move
501438fd1498Szrj assignment. Return true if this is due to there being a user-provided
501538fd1498Szrj move assignment in TYPE or one of its subobjects; if there isn't, then
501638fd1498Szrj multiple move assignment can't cause any harm. */
501738fd1498Szrj
501838fd1498Szrj bool
vbase_has_user_provided_move_assign(tree type)501938fd1498Szrj vbase_has_user_provided_move_assign (tree type)
502038fd1498Szrj {
502138fd1498Szrj /* Does the type itself have a user-provided move assignment operator? */
502238fd1498Szrj if (!CLASSTYPE_LAZY_MOVE_ASSIGN (type))
502338fd1498Szrj for (ovl_iterator iter (get_class_binding_direct
502438fd1498Szrj (type, assign_op_identifier));
502538fd1498Szrj iter; ++iter)
502638fd1498Szrj if (!DECL_ARTIFICIAL (*iter) && move_fn_p (*iter))
502738fd1498Szrj return true;
502838fd1498Szrj
502938fd1498Szrj /* Do any of its bases? */
503038fd1498Szrj tree binfo = TYPE_BINFO (type);
503138fd1498Szrj tree base_binfo;
503238fd1498Szrj for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
503338fd1498Szrj if (vbase_has_user_provided_move_assign (BINFO_TYPE (base_binfo)))
503438fd1498Szrj return true;
503538fd1498Szrj
503638fd1498Szrj /* Or non-static data members? */
503738fd1498Szrj for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
503838fd1498Szrj {
503938fd1498Szrj if (TREE_CODE (field) == FIELD_DECL
504038fd1498Szrj && CLASS_TYPE_P (TREE_TYPE (field))
504138fd1498Szrj && vbase_has_user_provided_move_assign (TREE_TYPE (field)))
504238fd1498Szrj return true;
504338fd1498Szrj }
504438fd1498Szrj
504538fd1498Szrj /* Seems not. */
504638fd1498Szrj return false;
504738fd1498Szrj }
504838fd1498Szrj
504938fd1498Szrj /* If default-initialization leaves part of TYPE uninitialized, returns
505038fd1498Szrj a DECL for the field or TYPE itself (DR 253). */
505138fd1498Szrj
505238fd1498Szrj tree
default_init_uninitialized_part(tree type)505338fd1498Szrj default_init_uninitialized_part (tree type)
505438fd1498Szrj {
505538fd1498Szrj tree t, r, binfo;
505638fd1498Szrj int i;
505738fd1498Szrj
505838fd1498Szrj type = strip_array_types (type);
505938fd1498Szrj if (!CLASS_TYPE_P (type))
506038fd1498Szrj return type;
506138fd1498Szrj if (!type_has_non_user_provided_default_constructor (type))
506238fd1498Szrj return NULL_TREE;
506338fd1498Szrj for (binfo = TYPE_BINFO (type), i = 0;
506438fd1498Szrj BINFO_BASE_ITERATE (binfo, i, t); ++i)
506538fd1498Szrj {
506638fd1498Szrj r = default_init_uninitialized_part (BINFO_TYPE (t));
506738fd1498Szrj if (r)
506838fd1498Szrj return r;
506938fd1498Szrj }
507038fd1498Szrj for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t))
507138fd1498Szrj if (TREE_CODE (t) == FIELD_DECL
507238fd1498Szrj && !DECL_ARTIFICIAL (t)
507338fd1498Szrj && !DECL_INITIAL (t))
507438fd1498Szrj {
507538fd1498Szrj r = default_init_uninitialized_part (TREE_TYPE (t));
507638fd1498Szrj if (r)
507738fd1498Szrj return DECL_P (r) ? r : t;
507838fd1498Szrj }
507938fd1498Szrj
508038fd1498Szrj return NULL_TREE;
508138fd1498Szrj }
508238fd1498Szrj
508338fd1498Szrj /* Returns true iff for class T, a trivial synthesized default constructor
508438fd1498Szrj would be constexpr. */
508538fd1498Szrj
508638fd1498Szrj bool
trivial_default_constructor_is_constexpr(tree t)508738fd1498Szrj trivial_default_constructor_is_constexpr (tree t)
508838fd1498Szrj {
508938fd1498Szrj /* A defaulted trivial default constructor is constexpr
509038fd1498Szrj if there is nothing to initialize. */
509138fd1498Szrj gcc_assert (!TYPE_HAS_COMPLEX_DFLT (t));
509238fd1498Szrj return is_really_empty_class (t);
509338fd1498Szrj }
509438fd1498Szrj
509538fd1498Szrj /* Returns true iff class T has a constexpr default constructor. */
509638fd1498Szrj
509738fd1498Szrj bool
type_has_constexpr_default_constructor(tree t)509838fd1498Szrj type_has_constexpr_default_constructor (tree t)
509938fd1498Szrj {
510038fd1498Szrj tree fns;
510138fd1498Szrj
510238fd1498Szrj if (!CLASS_TYPE_P (t))
510338fd1498Szrj {
510438fd1498Szrj /* The caller should have stripped an enclosing array. */
510538fd1498Szrj gcc_assert (TREE_CODE (t) != ARRAY_TYPE);
510638fd1498Szrj return false;
510738fd1498Szrj }
510838fd1498Szrj if (CLASSTYPE_LAZY_DEFAULT_CTOR (t))
510938fd1498Szrj {
511038fd1498Szrj if (!TYPE_HAS_COMPLEX_DFLT (t))
511138fd1498Szrj return trivial_default_constructor_is_constexpr (t);
511238fd1498Szrj /* Non-trivial, we need to check subobject constructors. */
511338fd1498Szrj lazily_declare_fn (sfk_constructor, t);
511438fd1498Szrj }
511538fd1498Szrj fns = locate_ctor (t);
511638fd1498Szrj return (fns && DECL_DECLARED_CONSTEXPR_P (fns));
511738fd1498Szrj }
511838fd1498Szrj
511938fd1498Szrj /* Returns true iff class T has a constexpr default constructor or has an
512038fd1498Szrj implicitly declared default constructor that we can't tell if it's constexpr
512138fd1498Szrj without forcing a lazy declaration (which might cause undesired
512238fd1498Szrj instantiations). */
512338fd1498Szrj
512438fd1498Szrj bool
type_maybe_constexpr_default_constructor(tree t)512538fd1498Szrj type_maybe_constexpr_default_constructor (tree t)
512638fd1498Szrj {
512738fd1498Szrj if (CLASS_TYPE_P (t) && CLASSTYPE_LAZY_DEFAULT_CTOR (t)
512838fd1498Szrj && TYPE_HAS_COMPLEX_DFLT (t))
512938fd1498Szrj /* Assume it's constexpr. */
513038fd1498Szrj return true;
513138fd1498Szrj return type_has_constexpr_default_constructor (t);
513238fd1498Szrj }
513338fd1498Szrj
513438fd1498Szrj /* Returns true iff class TYPE has a virtual destructor. */
513538fd1498Szrj
513638fd1498Szrj bool
type_has_virtual_destructor(tree type)513738fd1498Szrj type_has_virtual_destructor (tree type)
513838fd1498Szrj {
513938fd1498Szrj tree dtor;
514038fd1498Szrj
514138fd1498Szrj if (!CLASS_TYPE_P (type))
514238fd1498Szrj return false;
514338fd1498Szrj
514438fd1498Szrj gcc_assert (COMPLETE_TYPE_P (type));
514538fd1498Szrj dtor = CLASSTYPE_DESTRUCTOR (type);
514638fd1498Szrj return (dtor && DECL_VIRTUAL_P (dtor));
514738fd1498Szrj }
514838fd1498Szrj
514938fd1498Szrj /* Returns true iff T, a class, has a move-assignment or
515038fd1498Szrj move-constructor. Does not lazily declare either.
515138fd1498Szrj If USER_P is false, any move function will do. If it is true, the
515238fd1498Szrj move function must be user-declared.
515338fd1498Szrj
515438fd1498Szrj Note that user-declared here is different from "user-provided",
515538fd1498Szrj which doesn't include functions that are defaulted in the
515638fd1498Szrj class. */
515738fd1498Szrj
515838fd1498Szrj bool
classtype_has_move_assign_or_move_ctor_p(tree t,bool user_p)515938fd1498Szrj classtype_has_move_assign_or_move_ctor_p (tree t, bool user_p)
516038fd1498Szrj {
516138fd1498Szrj gcc_assert (user_p
516238fd1498Szrj || (!CLASSTYPE_LAZY_MOVE_CTOR (t)
516338fd1498Szrj && !CLASSTYPE_LAZY_MOVE_ASSIGN (t)));
516438fd1498Szrj
516538fd1498Szrj if (!CLASSTYPE_LAZY_MOVE_CTOR (t))
516638fd1498Szrj for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
516738fd1498Szrj if ((!user_p || !DECL_ARTIFICIAL (*iter)) && move_fn_p (*iter))
516838fd1498Szrj return true;
516938fd1498Szrj
517038fd1498Szrj if (!CLASSTYPE_LAZY_MOVE_ASSIGN (t))
517138fd1498Szrj for (ovl_iterator iter (get_class_binding_direct
517238fd1498Szrj (t, assign_op_identifier));
517338fd1498Szrj iter; ++iter)
5174*e215fc28Szrj if ((!user_p || !DECL_ARTIFICIAL (*iter))
5175*e215fc28Szrj && DECL_CONTEXT (*iter) == t
5176*e215fc28Szrj && move_fn_p (*iter))
517738fd1498Szrj return true;
517838fd1498Szrj
517938fd1498Szrj return false;
518038fd1498Szrj }
518138fd1498Szrj
518258e805e6Szrj /* True iff T has a move constructor that is not deleted. */
518358e805e6Szrj
518458e805e6Szrj bool
classtype_has_non_deleted_move_ctor(tree t)518558e805e6Szrj classtype_has_non_deleted_move_ctor (tree t)
518658e805e6Szrj {
518758e805e6Szrj if (CLASSTYPE_LAZY_MOVE_CTOR (t))
518858e805e6Szrj lazily_declare_fn (sfk_move_constructor, t);
518958e805e6Szrj for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
519058e805e6Szrj if (move_fn_p (*iter) && !DECL_DELETED_FN (*iter))
519158e805e6Szrj return true;
519258e805e6Szrj return false;
519358e805e6Szrj }
519458e805e6Szrj
519538fd1498Szrj /* Nonzero if we need to build up a constructor call when initializing an
519638fd1498Szrj object of this class, either because it has a user-declared constructor
519738fd1498Szrj or because it doesn't have a default constructor (so we need to give an
519838fd1498Szrj error if no initializer is provided). Use TYPE_NEEDS_CONSTRUCTING when
519938fd1498Szrj what you care about is whether or not an object can be produced by a
520038fd1498Szrj constructor (e.g. so we don't set TREE_READONLY on const variables of
520138fd1498Szrj such type); use this function when what you care about is whether or not
520238fd1498Szrj to try to call a constructor to create an object. The latter case is
520338fd1498Szrj the former plus some cases of constructors that cannot be called. */
520438fd1498Szrj
520538fd1498Szrj bool
type_build_ctor_call(tree t)520638fd1498Szrj type_build_ctor_call (tree t)
520738fd1498Szrj {
520838fd1498Szrj tree inner;
520938fd1498Szrj if (TYPE_NEEDS_CONSTRUCTING (t))
521038fd1498Szrj return true;
521138fd1498Szrj inner = strip_array_types (t);
521238fd1498Szrj if (!CLASS_TYPE_P (inner) || ANON_AGGR_TYPE_P (inner))
521338fd1498Szrj return false;
521438fd1498Szrj if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (inner))
521538fd1498Szrj return true;
521638fd1498Szrj if (cxx_dialect < cxx11)
521738fd1498Szrj return false;
521838fd1498Szrj /* A user-declared constructor might be private, and a constructor might
521938fd1498Szrj be trivial but deleted. */
522038fd1498Szrj for (ovl_iterator iter (get_class_binding (inner, complete_ctor_identifier));
522138fd1498Szrj iter; ++iter)
522238fd1498Szrj {
522338fd1498Szrj tree fn = *iter;
522438fd1498Szrj if (!DECL_ARTIFICIAL (fn)
522538fd1498Szrj || DECL_DELETED_FN (fn))
522638fd1498Szrj return true;
522738fd1498Szrj }
522838fd1498Szrj return false;
522938fd1498Szrj }
523038fd1498Szrj
523138fd1498Szrj /* Like type_build_ctor_call, but for destructors. */
523238fd1498Szrj
523338fd1498Szrj bool
type_build_dtor_call(tree t)523438fd1498Szrj type_build_dtor_call (tree t)
523538fd1498Szrj {
523638fd1498Szrj tree inner;
523738fd1498Szrj if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
523838fd1498Szrj return true;
523938fd1498Szrj inner = strip_array_types (t);
524038fd1498Szrj if (!CLASS_TYPE_P (inner) || ANON_AGGR_TYPE_P (inner)
524138fd1498Szrj || !COMPLETE_TYPE_P (inner))
524238fd1498Szrj return false;
524338fd1498Szrj if (cxx_dialect < cxx11)
524438fd1498Szrj return false;
524538fd1498Szrj /* A user-declared destructor might be private, and a destructor might
524638fd1498Szrj be trivial but deleted. */
524738fd1498Szrj for (ovl_iterator iter (get_class_binding (inner, complete_dtor_identifier));
524838fd1498Szrj iter; ++iter)
524938fd1498Szrj {
525038fd1498Szrj tree fn = *iter;
525138fd1498Szrj if (!DECL_ARTIFICIAL (fn)
525238fd1498Szrj || DECL_DELETED_FN (fn))
525338fd1498Szrj return true;
525438fd1498Szrj }
525538fd1498Szrj return false;
525638fd1498Szrj }
525738fd1498Szrj
525838fd1498Szrj /* Remove all zero-width bit-fields from T. */
525938fd1498Szrj
526038fd1498Szrj static void
remove_zero_width_bit_fields(tree t)526138fd1498Szrj remove_zero_width_bit_fields (tree t)
526238fd1498Szrj {
526338fd1498Szrj tree *fieldsp;
526438fd1498Szrj
526538fd1498Szrj fieldsp = &TYPE_FIELDS (t);
526638fd1498Szrj while (*fieldsp)
526738fd1498Szrj {
526838fd1498Szrj if (TREE_CODE (*fieldsp) == FIELD_DECL
526938fd1498Szrj && DECL_C_BIT_FIELD (*fieldsp)
527038fd1498Szrj /* We should not be confused by the fact that grokbitfield
527138fd1498Szrj temporarily sets the width of the bit field into
527238fd1498Szrj DECL_BIT_FIELD_REPRESENTATIVE (*fieldsp).
527338fd1498Szrj check_bitfield_decl eventually sets DECL_SIZE (*fieldsp)
527438fd1498Szrj to that width. */
527538fd1498Szrj && (DECL_SIZE (*fieldsp) == NULL_TREE
527638fd1498Szrj || integer_zerop (DECL_SIZE (*fieldsp))))
527738fd1498Szrj *fieldsp = DECL_CHAIN (*fieldsp);
527838fd1498Szrj else
527938fd1498Szrj fieldsp = &DECL_CHAIN (*fieldsp);
528038fd1498Szrj }
528138fd1498Szrj }
528238fd1498Szrj
528338fd1498Szrj /* Returns TRUE iff we need a cookie when dynamically allocating an
528438fd1498Szrj array whose elements have the indicated class TYPE. */
528538fd1498Szrj
528638fd1498Szrj static bool
type_requires_array_cookie(tree type)528738fd1498Szrj type_requires_array_cookie (tree type)
528838fd1498Szrj {
528938fd1498Szrj tree fns;
529038fd1498Szrj bool has_two_argument_delete_p = false;
529138fd1498Szrj
529238fd1498Szrj gcc_assert (CLASS_TYPE_P (type));
529338fd1498Szrj
529438fd1498Szrj /* If there's a non-trivial destructor, we need a cookie. In order
529538fd1498Szrj to iterate through the array calling the destructor for each
529638fd1498Szrj element, we'll have to know how many elements there are. */
529738fd1498Szrj if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
529838fd1498Szrj return true;
529938fd1498Szrj
530038fd1498Szrj /* If the usual deallocation function is a two-argument whose second
530138fd1498Szrj argument is of type `size_t', then we have to pass the size of
530238fd1498Szrj the array to the deallocation function, so we will need to store
530338fd1498Szrj a cookie. */
530438fd1498Szrj fns = lookup_fnfields (TYPE_BINFO (type),
530538fd1498Szrj ovl_op_identifier (false, VEC_DELETE_EXPR),
530638fd1498Szrj /*protect=*/0);
530738fd1498Szrj /* If there are no `operator []' members, or the lookup is
530838fd1498Szrj ambiguous, then we don't need a cookie. */
530938fd1498Szrj if (!fns || fns == error_mark_node)
531038fd1498Szrj return false;
531138fd1498Szrj /* Loop through all of the functions. */
531238fd1498Szrj for (lkp_iterator iter (BASELINK_FUNCTIONS (fns)); iter; ++iter)
531338fd1498Szrj {
531438fd1498Szrj tree fn = *iter;
531538fd1498Szrj
531638fd1498Szrj /* See if this function is a one-argument delete function. If
531738fd1498Szrj it is, then it will be the usual deallocation function. */
531838fd1498Szrj tree second_parm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
531938fd1498Szrj if (second_parm == void_list_node)
532038fd1498Szrj return false;
532138fd1498Szrj /* Do not consider this function if its second argument is an
532238fd1498Szrj ellipsis. */
532338fd1498Szrj if (!second_parm)
532438fd1498Szrj continue;
532538fd1498Szrj /* Otherwise, if we have a two-argument function and the second
532638fd1498Szrj argument is `size_t', it will be the usual deallocation
532738fd1498Szrj function -- unless there is one-argument function, too. */
532838fd1498Szrj if (TREE_CHAIN (second_parm) == void_list_node
532938fd1498Szrj && same_type_p (TREE_VALUE (second_parm), size_type_node))
533038fd1498Szrj has_two_argument_delete_p = true;
533138fd1498Szrj }
533238fd1498Szrj
533338fd1498Szrj return has_two_argument_delete_p;
533438fd1498Szrj }
533538fd1498Szrj
533638fd1498Szrj /* Finish computing the `literal type' property of class type T.
533738fd1498Szrj
533838fd1498Szrj At this point, we have already processed base classes and
533938fd1498Szrj non-static data members. We need to check whether the copy
534038fd1498Szrj constructor is trivial, the destructor is trivial, and there
534138fd1498Szrj is a trivial default constructor or at least one constexpr
534238fd1498Szrj constructor other than the copy constructor. */
534338fd1498Szrj
534438fd1498Szrj static void
finalize_literal_type_property(tree t)534538fd1498Szrj finalize_literal_type_property (tree t)
534638fd1498Szrj {
534738fd1498Szrj tree fn;
534838fd1498Szrj
534938fd1498Szrj if (cxx_dialect < cxx11
535038fd1498Szrj || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
535138fd1498Szrj CLASSTYPE_LITERAL_P (t) = false;
535238fd1498Szrj else if (CLASSTYPE_LITERAL_P (t) && LAMBDA_TYPE_P (t))
535338fd1498Szrj CLASSTYPE_LITERAL_P (t) = (cxx_dialect >= cxx17);
535438fd1498Szrj else if (CLASSTYPE_LITERAL_P (t) && !TYPE_HAS_TRIVIAL_DFLT (t)
535538fd1498Szrj && CLASSTYPE_NON_AGGREGATE (t)
535638fd1498Szrj && !TYPE_HAS_CONSTEXPR_CTOR (t))
535738fd1498Szrj CLASSTYPE_LITERAL_P (t) = false;
535838fd1498Szrj
535938fd1498Szrj /* C++14 DR 1684 removed this restriction. */
536038fd1498Szrj if (cxx_dialect < cxx14
536138fd1498Szrj && !CLASSTYPE_LITERAL_P (t) && !LAMBDA_TYPE_P (t))
536238fd1498Szrj for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
536338fd1498Szrj if (TREE_CODE (fn) == FUNCTION_DECL
536438fd1498Szrj && DECL_DECLARED_CONSTEXPR_P (fn)
536538fd1498Szrj && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
536638fd1498Szrj && !DECL_CONSTRUCTOR_P (fn))
536738fd1498Szrj {
536838fd1498Szrj DECL_DECLARED_CONSTEXPR_P (fn) = false;
536938fd1498Szrj if (!DECL_GENERATED_P (fn)
537038fd1498Szrj && pedwarn (DECL_SOURCE_LOCATION (fn), OPT_Wpedantic,
537138fd1498Szrj "enclosing class of %<constexpr%> non-static member "
537238fd1498Szrj "function %q+#D is not a literal type", fn))
537338fd1498Szrj explain_non_literal_class (t);
537438fd1498Szrj }
537538fd1498Szrj }
537638fd1498Szrj
537738fd1498Szrj /* T is a non-literal type used in a context which requires a constant
537838fd1498Szrj expression. Explain why it isn't literal. */
537938fd1498Szrj
538038fd1498Szrj void
explain_non_literal_class(tree t)538138fd1498Szrj explain_non_literal_class (tree t)
538238fd1498Szrj {
538338fd1498Szrj static hash_set<tree> *diagnosed;
538438fd1498Szrj
538538fd1498Szrj if (!CLASS_TYPE_P (t))
538638fd1498Szrj return;
538738fd1498Szrj t = TYPE_MAIN_VARIANT (t);
538838fd1498Szrj
538938fd1498Szrj if (diagnosed == NULL)
539038fd1498Szrj diagnosed = new hash_set<tree>;
539138fd1498Szrj if (diagnosed->add (t))
539238fd1498Szrj /* Already explained. */
539338fd1498Szrj return;
539438fd1498Szrj
539538fd1498Szrj inform (UNKNOWN_LOCATION, "%q+T is not literal because:", t);
539638fd1498Szrj if (cxx_dialect < cxx17 && LAMBDA_TYPE_P (t))
539738fd1498Szrj inform (UNKNOWN_LOCATION,
539838fd1498Szrj " %qT is a closure type, which is only literal in "
539938fd1498Szrj "C++17 and later", t);
540038fd1498Szrj else if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
540138fd1498Szrj inform (UNKNOWN_LOCATION, " %q+T has a non-trivial destructor", t);
540238fd1498Szrj else if (CLASSTYPE_NON_AGGREGATE (t)
540338fd1498Szrj && !TYPE_HAS_TRIVIAL_DFLT (t)
540438fd1498Szrj && !LAMBDA_TYPE_P (t)
540538fd1498Szrj && !TYPE_HAS_CONSTEXPR_CTOR (t))
540638fd1498Szrj {
540738fd1498Szrj inform (UNKNOWN_LOCATION,
540838fd1498Szrj " %q+T is not an aggregate, does not have a trivial "
540938fd1498Szrj "default constructor, and has no %<constexpr%> constructor that "
541038fd1498Szrj "is not a copy or move constructor", t);
541138fd1498Szrj if (type_has_non_user_provided_default_constructor (t))
541238fd1498Szrj /* Note that we can't simply call locate_ctor because when the
541338fd1498Szrj constructor is deleted it just returns NULL_TREE. */
541438fd1498Szrj for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
541538fd1498Szrj {
541638fd1498Szrj tree fn = *iter;
541738fd1498Szrj tree parms = TYPE_ARG_TYPES (TREE_TYPE (fn));
541838fd1498Szrj
541938fd1498Szrj parms = skip_artificial_parms_for (fn, parms);
542038fd1498Szrj
542138fd1498Szrj if (sufficient_parms_p (parms))
542238fd1498Szrj {
542338fd1498Szrj if (DECL_DELETED_FN (fn))
542438fd1498Szrj maybe_explain_implicit_delete (fn);
542538fd1498Szrj else
542638fd1498Szrj explain_invalid_constexpr_fn (fn);
542738fd1498Szrj break;
542838fd1498Szrj }
542938fd1498Szrj }
543038fd1498Szrj }
543138fd1498Szrj else
543238fd1498Szrj {
543338fd1498Szrj tree binfo, base_binfo, field; int i;
543438fd1498Szrj for (binfo = TYPE_BINFO (t), i = 0;
543538fd1498Szrj BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
543638fd1498Szrj {
543738fd1498Szrj tree basetype = TREE_TYPE (base_binfo);
543838fd1498Szrj if (!CLASSTYPE_LITERAL_P (basetype))
543938fd1498Szrj {
544038fd1498Szrj inform (UNKNOWN_LOCATION,
544138fd1498Szrj " base class %qT of %q+T is non-literal",
544238fd1498Szrj basetype, t);
544338fd1498Szrj explain_non_literal_class (basetype);
544438fd1498Szrj return;
544538fd1498Szrj }
544638fd1498Szrj }
544738fd1498Szrj for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
544838fd1498Szrj {
544938fd1498Szrj tree ftype;
545038fd1498Szrj if (TREE_CODE (field) != FIELD_DECL)
545138fd1498Szrj continue;
545238fd1498Szrj ftype = TREE_TYPE (field);
545338fd1498Szrj if (!literal_type_p (ftype))
545438fd1498Szrj {
545538fd1498Szrj inform (DECL_SOURCE_LOCATION (field),
545638fd1498Szrj " non-static data member %qD has non-literal type",
545738fd1498Szrj field);
545838fd1498Szrj if (CLASS_TYPE_P (ftype))
545938fd1498Szrj explain_non_literal_class (ftype);
546038fd1498Szrj }
546138fd1498Szrj if (CP_TYPE_VOLATILE_P (ftype))
546238fd1498Szrj inform (DECL_SOURCE_LOCATION (field),
546338fd1498Szrj " non-static data member %qD has volatile type", field);
546438fd1498Szrj }
546538fd1498Szrj }
546638fd1498Szrj }
546738fd1498Szrj
546838fd1498Szrj /* Check the validity of the bases and members declared in T. Add any
546938fd1498Szrj implicitly-generated functions (like copy-constructors and
547038fd1498Szrj assignment operators). Compute various flag bits (like
547138fd1498Szrj CLASSTYPE_NON_LAYOUT_POD_T) for T. This routine works purely at the C++
547238fd1498Szrj level: i.e., independently of the ABI in use. */
547338fd1498Szrj
547438fd1498Szrj static void
check_bases_and_members(tree t)547538fd1498Szrj check_bases_and_members (tree t)
547638fd1498Szrj {
547738fd1498Szrj /* Nonzero if the implicitly generated copy constructor should take
547838fd1498Szrj a non-const reference argument. */
547938fd1498Szrj int cant_have_const_ctor;
548038fd1498Szrj /* Nonzero if the implicitly generated assignment operator
548138fd1498Szrj should take a non-const reference argument. */
548238fd1498Szrj int no_const_asn_ref;
548338fd1498Szrj tree access_decls;
548438fd1498Szrj bool saved_complex_asn_ref;
548538fd1498Szrj bool saved_nontrivial_dtor;
548638fd1498Szrj tree fn;
548738fd1498Szrj
548838fd1498Szrj /* By default, we use const reference arguments and generate default
548938fd1498Szrj constructors. */
549038fd1498Szrj cant_have_const_ctor = 0;
549138fd1498Szrj no_const_asn_ref = 0;
549238fd1498Szrj
549338fd1498Szrj /* Check all the base-classes and set FMEM members to point to arrays
549438fd1498Szrj of potential interest. */
549538fd1498Szrj check_bases (t, &cant_have_const_ctor, &no_const_asn_ref);
549638fd1498Szrj
549738fd1498Szrj /* Deduce noexcept on destructor. This needs to happen after we've set
549838fd1498Szrj triviality flags appropriately for our bases. */
549938fd1498Szrj if (cxx_dialect >= cxx11)
550038fd1498Szrj if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
550138fd1498Szrj deduce_noexcept_on_destructor (dtor);
550238fd1498Szrj
550338fd1498Szrj /* Check all the method declarations. */
550438fd1498Szrj check_methods (t);
550538fd1498Szrj
550638fd1498Szrj /* Save the initial values of these flags which only indicate whether
550738fd1498Szrj or not the class has user-provided functions. As we analyze the
550838fd1498Szrj bases and members we can set these flags for other reasons. */
550938fd1498Szrj saved_complex_asn_ref = TYPE_HAS_COMPLEX_COPY_ASSIGN (t);
551038fd1498Szrj saved_nontrivial_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);
551138fd1498Szrj
551238fd1498Szrj /* Check all the data member declarations. We cannot call
551338fd1498Szrj check_field_decls until we have called check_bases check_methods,
551438fd1498Szrj as check_field_decls depends on TYPE_HAS_NONTRIVIAL_DESTRUCTOR
551538fd1498Szrj being set appropriately. */
551638fd1498Szrj check_field_decls (t, &access_decls,
551738fd1498Szrj &cant_have_const_ctor,
551838fd1498Szrj &no_const_asn_ref);
551938fd1498Szrj
552038fd1498Szrj /* A nearly-empty class has to be vptr-containing; a nearly empty
552138fd1498Szrj class contains just a vptr. */
552238fd1498Szrj if (!TYPE_CONTAINS_VPTR_P (t))
552338fd1498Szrj CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
552438fd1498Szrj
552538fd1498Szrj /* Do some bookkeeping that will guide the generation of implicitly
552638fd1498Szrj declared member functions. */
552738fd1498Szrj TYPE_HAS_COMPLEX_COPY_CTOR (t) |= TYPE_CONTAINS_VPTR_P (t);
552838fd1498Szrj TYPE_HAS_COMPLEX_MOVE_CTOR (t) |= TYPE_CONTAINS_VPTR_P (t);
552938fd1498Szrj /* We need to call a constructor for this class if it has a
553038fd1498Szrj user-provided constructor, or if the default constructor is going
553138fd1498Szrj to initialize the vptr. (This is not an if-and-only-if;
553238fd1498Szrj TYPE_NEEDS_CONSTRUCTING is set elsewhere if bases or members
553338fd1498Szrj themselves need constructing.) */
553438fd1498Szrj TYPE_NEEDS_CONSTRUCTING (t)
553538fd1498Szrj |= (type_has_user_provided_constructor (t) || TYPE_CONTAINS_VPTR_P (t));
553638fd1498Szrj /* [dcl.init.aggr]
553738fd1498Szrj
553838fd1498Szrj An aggregate is an array or a class with no user-provided
553938fd1498Szrj constructors ... and no virtual functions.
554038fd1498Szrj
554138fd1498Szrj Again, other conditions for being an aggregate are checked
554238fd1498Szrj elsewhere. */
554338fd1498Szrj CLASSTYPE_NON_AGGREGATE (t)
554438fd1498Szrj |= (type_has_user_provided_or_explicit_constructor (t)
554538fd1498Szrj || TYPE_POLYMORPHIC_P (t));
554638fd1498Szrj /* This is the C++98/03 definition of POD; it changed in C++0x, but we
554738fd1498Szrj retain the old definition internally for ABI reasons. */
554838fd1498Szrj CLASSTYPE_NON_LAYOUT_POD_P (t)
554938fd1498Szrj |= (CLASSTYPE_NON_AGGREGATE (t)
555038fd1498Szrj || saved_nontrivial_dtor || saved_complex_asn_ref);
555138fd1498Szrj CLASSTYPE_NON_STD_LAYOUT (t) |= TYPE_CONTAINS_VPTR_P (t);
555238fd1498Szrj TYPE_HAS_COMPLEX_COPY_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t);
555338fd1498Szrj TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t);
555438fd1498Szrj TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t);
555538fd1498Szrj
555638fd1498Szrj /* If the only explicitly declared default constructor is user-provided,
555738fd1498Szrj set TYPE_HAS_COMPLEX_DFLT. */
555838fd1498Szrj if (!TYPE_HAS_COMPLEX_DFLT (t)
555938fd1498Szrj && TYPE_HAS_DEFAULT_CONSTRUCTOR (t)
556038fd1498Szrj && !type_has_non_user_provided_default_constructor (t))
556138fd1498Szrj TYPE_HAS_COMPLEX_DFLT (t) = true;
556238fd1498Szrj
556338fd1498Szrj /* Warn if a public base of a polymorphic type has an accessible
556438fd1498Szrj non-virtual destructor. It is only now that we know the class is
556538fd1498Szrj polymorphic. Although a polymorphic base will have a already
556638fd1498Szrj been diagnosed during its definition, we warn on use too. */
556738fd1498Szrj if (TYPE_POLYMORPHIC_P (t) && warn_nonvdtor)
556838fd1498Szrj {
556938fd1498Szrj tree binfo = TYPE_BINFO (t);
557038fd1498Szrj vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (binfo);
557138fd1498Szrj tree base_binfo;
557238fd1498Szrj unsigned i;
557338fd1498Szrj
557438fd1498Szrj for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
557538fd1498Szrj {
557638fd1498Szrj tree basetype = TREE_TYPE (base_binfo);
557738fd1498Szrj
557838fd1498Szrj if ((*accesses)[i] == access_public_node
557938fd1498Szrj && (TYPE_POLYMORPHIC_P (basetype) || warn_ecpp)
558038fd1498Szrj && accessible_nvdtor_p (basetype))
558138fd1498Szrj warning (OPT_Wnon_virtual_dtor,
558238fd1498Szrj "base class %q#T has accessible non-virtual destructor",
558338fd1498Szrj basetype);
558438fd1498Szrj }
558538fd1498Szrj }
558638fd1498Szrj
558738fd1498Szrj /* If the class has no user-declared constructor, but does have
558838fd1498Szrj non-static const or reference data members that can never be
558938fd1498Szrj initialized, issue a warning. */
559038fd1498Szrj if (warn_uninitialized
559138fd1498Szrj /* Classes with user-declared constructors are presumed to
559238fd1498Szrj initialize these members. */
559338fd1498Szrj && !TYPE_HAS_USER_CONSTRUCTOR (t)
559438fd1498Szrj /* Aggregates can be initialized with brace-enclosed
559538fd1498Szrj initializers. */
559638fd1498Szrj && CLASSTYPE_NON_AGGREGATE (t))
559738fd1498Szrj {
559838fd1498Szrj tree field;
559938fd1498Szrj
560038fd1498Szrj for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
560138fd1498Szrj {
560238fd1498Szrj tree type;
560338fd1498Szrj
560438fd1498Szrj if (TREE_CODE (field) != FIELD_DECL
560538fd1498Szrj || DECL_INITIAL (field) != NULL_TREE)
560638fd1498Szrj continue;
560738fd1498Szrj
560838fd1498Szrj type = TREE_TYPE (field);
560938fd1498Szrj if (TREE_CODE (type) == REFERENCE_TYPE)
561038fd1498Szrj warning_at (DECL_SOURCE_LOCATION (field),
561138fd1498Szrj OPT_Wuninitialized, "non-static reference %q#D "
561238fd1498Szrj "in class without a constructor", field);
561338fd1498Szrj else if (CP_TYPE_CONST_P (type)
561438fd1498Szrj && (!CLASS_TYPE_P (type)
561538fd1498Szrj || !TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
561638fd1498Szrj warning_at (DECL_SOURCE_LOCATION (field),
561738fd1498Szrj OPT_Wuninitialized, "non-static const member %q#D "
561838fd1498Szrj "in class without a constructor", field);
561938fd1498Szrj }
562038fd1498Szrj }
562138fd1498Szrj
562238fd1498Szrj /* Synthesize any needed methods. */
562338fd1498Szrj add_implicitly_declared_members (t, &access_decls,
562438fd1498Szrj cant_have_const_ctor,
562538fd1498Szrj no_const_asn_ref);
562638fd1498Szrj
562738fd1498Szrj /* Check defaulted declarations here so we have cant_have_const_ctor
562838fd1498Szrj and don't need to worry about clones. */
562938fd1498Szrj for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
563038fd1498Szrj if (DECL_DECLARES_FUNCTION_P (fn)
563138fd1498Szrj && !DECL_ARTIFICIAL (fn)
563238fd1498Szrj && DECL_DEFAULTED_IN_CLASS_P (fn))
563338fd1498Szrj {
563438fd1498Szrj int copy = copy_fn_p (fn);
563538fd1498Szrj if (copy > 0)
563638fd1498Szrj {
563738fd1498Szrj bool imp_const_p
563838fd1498Szrj = (DECL_CONSTRUCTOR_P (fn) ? !cant_have_const_ctor
563938fd1498Szrj : !no_const_asn_ref);
564038fd1498Szrj bool fn_const_p = (copy == 2);
564138fd1498Szrj
564238fd1498Szrj if (fn_const_p && !imp_const_p)
564338fd1498Szrj /* If the function is defaulted outside the class, we just
564438fd1498Szrj give the synthesis error. */
564538fd1498Szrj error ("%q+D declared to take const reference, but implicit "
564638fd1498Szrj "declaration would take non-const", fn);
564738fd1498Szrj }
564838fd1498Szrj defaulted_late_check (fn);
564938fd1498Szrj }
565038fd1498Szrj
565138fd1498Szrj if (LAMBDA_TYPE_P (t))
565238fd1498Szrj {
565338fd1498Szrj /* "This class type is not an aggregate." */
565438fd1498Szrj CLASSTYPE_NON_AGGREGATE (t) = 1;
565538fd1498Szrj }
565638fd1498Szrj
565738fd1498Szrj /* Compute the 'literal type' property before we
565838fd1498Szrj do anything with non-static member functions. */
565938fd1498Szrj finalize_literal_type_property (t);
566038fd1498Szrj
566138fd1498Szrj /* Create the in-charge and not-in-charge variants of constructors
566238fd1498Szrj and destructors. */
566338fd1498Szrj clone_constructors_and_destructors (t);
566438fd1498Szrj
566538fd1498Szrj /* Process the using-declarations. */
566638fd1498Szrj for (; access_decls; access_decls = TREE_CHAIN (access_decls))
566738fd1498Szrj handle_using_decl (TREE_VALUE (access_decls), t);
566838fd1498Szrj
566938fd1498Szrj /* Figure out whether or not we will need a cookie when dynamically
567038fd1498Szrj allocating an array of this type. */
567138fd1498Szrj LANG_TYPE_CLASS_CHECK (t)->vec_new_uses_cookie
567238fd1498Szrj = type_requires_array_cookie (t);
567338fd1498Szrj }
567438fd1498Szrj
567538fd1498Szrj /* If T needs a pointer to its virtual function table, set TYPE_VFIELD
567638fd1498Szrj accordingly. If a new vfield was created (because T doesn't have a
567738fd1498Szrj primary base class), then the newly created field is returned. It
567838fd1498Szrj is not added to the TYPE_FIELDS list; it is the caller's
567938fd1498Szrj responsibility to do that. Accumulate declared virtual functions
568038fd1498Szrj on VIRTUALS_P. */
568138fd1498Szrj
568238fd1498Szrj static tree
create_vtable_ptr(tree t,tree * virtuals_p)568338fd1498Szrj create_vtable_ptr (tree t, tree* virtuals_p)
568438fd1498Szrj {
568538fd1498Szrj tree fn;
568638fd1498Szrj
568738fd1498Szrj /* Collect the virtual functions declared in T. */
568838fd1498Szrj for (fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))
568938fd1498Szrj if (TREE_CODE (fn) == FUNCTION_DECL
569038fd1498Szrj && DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
569138fd1498Szrj && TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
569238fd1498Szrj {
569338fd1498Szrj tree new_virtual = make_node (TREE_LIST);
569438fd1498Szrj
569538fd1498Szrj BV_FN (new_virtual) = fn;
569638fd1498Szrj BV_DELTA (new_virtual) = integer_zero_node;
569738fd1498Szrj BV_VCALL_INDEX (new_virtual) = NULL_TREE;
569838fd1498Szrj
569938fd1498Szrj TREE_CHAIN (new_virtual) = *virtuals_p;
570038fd1498Szrj *virtuals_p = new_virtual;
570138fd1498Szrj }
570238fd1498Szrj
570338fd1498Szrj /* If we couldn't find an appropriate base class, create a new field
570438fd1498Szrj here. Even if there weren't any new virtual functions, we might need a
570538fd1498Szrj new virtual function table if we're supposed to include vptrs in
570638fd1498Szrj all classes that need them. */
570738fd1498Szrj if (!TYPE_VFIELD (t) && (*virtuals_p || TYPE_CONTAINS_VPTR_P (t)))
570838fd1498Szrj {
570938fd1498Szrj /* We build this decl with vtbl_ptr_type_node, which is a
571038fd1498Szrj `vtable_entry_type*'. It might seem more precise to use
571138fd1498Szrj `vtable_entry_type (*)[N]' where N is the number of virtual
571238fd1498Szrj functions. However, that would require the vtable pointer in
571338fd1498Szrj base classes to have a different type than the vtable pointer
571438fd1498Szrj in derived classes. We could make that happen, but that
571538fd1498Szrj still wouldn't solve all the problems. In particular, the
571638fd1498Szrj type-based alias analysis code would decide that assignments
571738fd1498Szrj to the base class vtable pointer can't alias assignments to
571838fd1498Szrj the derived class vtable pointer, since they have different
571938fd1498Szrj types. Thus, in a derived class destructor, where the base
572038fd1498Szrj class constructor was inlined, we could generate bad code for
572138fd1498Szrj setting up the vtable pointer.
572238fd1498Szrj
572338fd1498Szrj Therefore, we use one type for all vtable pointers. We still
572438fd1498Szrj use a type-correct type; it's just doesn't indicate the array
572538fd1498Szrj bounds. That's better than using `void*' or some such; it's
572638fd1498Szrj cleaner, and it let's the alias analysis code know that these
572738fd1498Szrj stores cannot alias stores to void*! */
572838fd1498Szrj tree field;
572938fd1498Szrj
573038fd1498Szrj field = build_decl (input_location,
573138fd1498Szrj FIELD_DECL, get_vfield_name (t), vtbl_ptr_type_node);
573238fd1498Szrj DECL_VIRTUAL_P (field) = 1;
573338fd1498Szrj DECL_ARTIFICIAL (field) = 1;
573438fd1498Szrj DECL_FIELD_CONTEXT (field) = t;
573538fd1498Szrj DECL_FCONTEXT (field) = t;
573638fd1498Szrj if (TYPE_PACKED (t))
573738fd1498Szrj DECL_PACKED (field) = 1;
573838fd1498Szrj
573938fd1498Szrj TYPE_VFIELD (t) = field;
574038fd1498Szrj
574138fd1498Szrj /* This class is non-empty. */
574238fd1498Szrj CLASSTYPE_EMPTY_P (t) = 0;
574338fd1498Szrj
574438fd1498Szrj return field;
574538fd1498Szrj }
574638fd1498Szrj
574738fd1498Szrj return NULL_TREE;
574838fd1498Szrj }
574938fd1498Szrj
575038fd1498Szrj /* Add OFFSET to all base types of BINFO which is a base in the
575138fd1498Szrj hierarchy dominated by T.
575238fd1498Szrj
575338fd1498Szrj OFFSET, which is a type offset, is number of bytes. */
575438fd1498Szrj
575538fd1498Szrj static void
propagate_binfo_offsets(tree binfo,tree offset)575638fd1498Szrj propagate_binfo_offsets (tree binfo, tree offset)
575738fd1498Szrj {
575838fd1498Szrj int i;
575938fd1498Szrj tree primary_binfo;
576038fd1498Szrj tree base_binfo;
576138fd1498Szrj
576238fd1498Szrj /* Update BINFO's offset. */
576338fd1498Szrj BINFO_OFFSET (binfo)
576438fd1498Szrj = fold_convert (sizetype,
576538fd1498Szrj size_binop (PLUS_EXPR,
576638fd1498Szrj fold_convert (ssizetype, BINFO_OFFSET (binfo)),
576738fd1498Szrj offset));
576838fd1498Szrj
576938fd1498Szrj /* Find the primary base class. */
577038fd1498Szrj primary_binfo = get_primary_binfo (binfo);
577138fd1498Szrj
577238fd1498Szrj if (primary_binfo && BINFO_INHERITANCE_CHAIN (primary_binfo) == binfo)
577338fd1498Szrj propagate_binfo_offsets (primary_binfo, offset);
577438fd1498Szrj
577538fd1498Szrj /* Scan all of the bases, pushing the BINFO_OFFSET adjust
577638fd1498Szrj downwards. */
577738fd1498Szrj for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
577838fd1498Szrj {
577938fd1498Szrj /* Don't do the primary base twice. */
578038fd1498Szrj if (base_binfo == primary_binfo)
578138fd1498Szrj continue;
578238fd1498Szrj
578338fd1498Szrj if (BINFO_VIRTUAL_P (base_binfo))
578438fd1498Szrj continue;
578538fd1498Szrj
578638fd1498Szrj propagate_binfo_offsets (base_binfo, offset);
578738fd1498Szrj }
578838fd1498Szrj }
578938fd1498Szrj
579038fd1498Szrj /* Set BINFO_OFFSET for all of the virtual bases for RLI->T. Update
579138fd1498Szrj TYPE_ALIGN and TYPE_SIZE for T. OFFSETS gives the location of
579238fd1498Szrj empty subobjects of T. */
579338fd1498Szrj
579438fd1498Szrj static void
layout_virtual_bases(record_layout_info rli,splay_tree offsets)579538fd1498Szrj layout_virtual_bases (record_layout_info rli, splay_tree offsets)
579638fd1498Szrj {
579738fd1498Szrj tree vbase;
579838fd1498Szrj tree t = rli->t;
579938fd1498Szrj tree *next_field;
580038fd1498Szrj
580138fd1498Szrj if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) == 0)
580238fd1498Szrj return;
580338fd1498Szrj
580438fd1498Szrj /* Find the last field. The artificial fields created for virtual
580538fd1498Szrj bases will go after the last extant field to date. */
580638fd1498Szrj next_field = &TYPE_FIELDS (t);
580738fd1498Szrj while (*next_field)
580838fd1498Szrj next_field = &DECL_CHAIN (*next_field);
580938fd1498Szrj
581038fd1498Szrj /* Go through the virtual bases, allocating space for each virtual
581138fd1498Szrj base that is not already a primary base class. These are
581238fd1498Szrj allocated in inheritance graph order. */
581338fd1498Szrj for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
581438fd1498Szrj {
581538fd1498Szrj if (!BINFO_VIRTUAL_P (vbase))
581638fd1498Szrj continue;
581738fd1498Szrj
581838fd1498Szrj if (!BINFO_PRIMARY_P (vbase))
581938fd1498Szrj {
582038fd1498Szrj /* This virtual base is not a primary base of any class in the
582138fd1498Szrj hierarchy, so we have to add space for it. */
582238fd1498Szrj next_field = build_base_field (rli, vbase,
582338fd1498Szrj offsets, next_field);
582438fd1498Szrj }
582538fd1498Szrj }
582638fd1498Szrj }
582738fd1498Szrj
582838fd1498Szrj /* Returns the offset of the byte just past the end of the base class
582938fd1498Szrj BINFO. */
583038fd1498Szrj
583138fd1498Szrj static tree
end_of_base(tree binfo)583238fd1498Szrj end_of_base (tree binfo)
583338fd1498Szrj {
583438fd1498Szrj tree size;
583538fd1498Szrj
583638fd1498Szrj if (!CLASSTYPE_AS_BASE (BINFO_TYPE (binfo)))
583738fd1498Szrj size = TYPE_SIZE_UNIT (char_type_node);
583838fd1498Szrj else if (is_empty_class (BINFO_TYPE (binfo)))
583938fd1498Szrj /* An empty class has zero CLASSTYPE_SIZE_UNIT, but we need to
584038fd1498Szrj allocate some space for it. It cannot have virtual bases, so
584138fd1498Szrj TYPE_SIZE_UNIT is fine. */
584238fd1498Szrj size = TYPE_SIZE_UNIT (BINFO_TYPE (binfo));
584338fd1498Szrj else
584438fd1498Szrj size = CLASSTYPE_SIZE_UNIT (BINFO_TYPE (binfo));
584538fd1498Szrj
584638fd1498Szrj return size_binop (PLUS_EXPR, BINFO_OFFSET (binfo), size);
584738fd1498Szrj }
584838fd1498Szrj
584938fd1498Szrj /* Returns the offset of the byte just past the end of the base class
585038fd1498Szrj with the highest offset in T. If INCLUDE_VIRTUALS_P is zero, then
585138fd1498Szrj only non-virtual bases are included. */
585238fd1498Szrj
585338fd1498Szrj static tree
end_of_class(tree t,int include_virtuals_p)585438fd1498Szrj end_of_class (tree t, int include_virtuals_p)
585538fd1498Szrj {
585638fd1498Szrj tree result = size_zero_node;
585738fd1498Szrj vec<tree, va_gc> *vbases;
585838fd1498Szrj tree binfo;
585938fd1498Szrj tree base_binfo;
586038fd1498Szrj tree offset;
586138fd1498Szrj int i;
586238fd1498Szrj
586338fd1498Szrj for (binfo = TYPE_BINFO (t), i = 0;
586438fd1498Szrj BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
586538fd1498Szrj {
586638fd1498Szrj if (!include_virtuals_p
586738fd1498Szrj && BINFO_VIRTUAL_P (base_binfo)
586838fd1498Szrj && (!BINFO_PRIMARY_P (base_binfo)
586938fd1498Szrj || BINFO_INHERITANCE_CHAIN (base_binfo) != TYPE_BINFO (t)))
587038fd1498Szrj continue;
587138fd1498Szrj
587238fd1498Szrj offset = end_of_base (base_binfo);
587338fd1498Szrj if (tree_int_cst_lt (result, offset))
587438fd1498Szrj result = offset;
587538fd1498Szrj }
587638fd1498Szrj
587738fd1498Szrj if (include_virtuals_p)
587838fd1498Szrj for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
587938fd1498Szrj vec_safe_iterate (vbases, i, &base_binfo); i++)
588038fd1498Szrj {
588138fd1498Szrj offset = end_of_base (base_binfo);
588238fd1498Szrj if (tree_int_cst_lt (result, offset))
588338fd1498Szrj result = offset;
588438fd1498Szrj }
588538fd1498Szrj
588638fd1498Szrj return result;
588738fd1498Szrj }
588838fd1498Szrj
588938fd1498Szrj /* Warn about bases of T that are inaccessible because they are
589038fd1498Szrj ambiguous. For example:
589138fd1498Szrj
589238fd1498Szrj struct S {};
589338fd1498Szrj struct T : public S {};
589438fd1498Szrj struct U : public S, public T {};
589538fd1498Szrj
589638fd1498Szrj Here, `(S*) new U' is not allowed because there are two `S'
589738fd1498Szrj subobjects of U. */
589838fd1498Szrj
589938fd1498Szrj static void
warn_about_ambiguous_bases(tree t)590038fd1498Szrj warn_about_ambiguous_bases (tree t)
590138fd1498Szrj {
590238fd1498Szrj int i;
590338fd1498Szrj vec<tree, va_gc> *vbases;
590438fd1498Szrj tree basetype;
590538fd1498Szrj tree binfo;
590638fd1498Szrj tree base_binfo;
590738fd1498Szrj
590838fd1498Szrj /* If there are no repeated bases, nothing can be ambiguous. */
590938fd1498Szrj if (!CLASSTYPE_REPEATED_BASE_P (t))
591038fd1498Szrj return;
591138fd1498Szrj
591238fd1498Szrj /* Check direct bases. */
591338fd1498Szrj for (binfo = TYPE_BINFO (t), i = 0;
591438fd1498Szrj BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
591538fd1498Szrj {
591638fd1498Szrj basetype = BINFO_TYPE (base_binfo);
591738fd1498Szrj
591838fd1498Szrj if (!uniquely_derived_from_p (basetype, t))
591938fd1498Szrj warning (0, "direct base %qT inaccessible in %qT due to ambiguity",
592038fd1498Szrj basetype, t);
592138fd1498Szrj }
592238fd1498Szrj
592338fd1498Szrj /* Check for ambiguous virtual bases. */
592438fd1498Szrj if (extra_warnings)
592538fd1498Szrj for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
592638fd1498Szrj vec_safe_iterate (vbases, i, &binfo); i++)
592738fd1498Szrj {
592838fd1498Szrj basetype = BINFO_TYPE (binfo);
592938fd1498Szrj
593038fd1498Szrj if (!uniquely_derived_from_p (basetype, t))
593138fd1498Szrj warning (OPT_Wextra, "virtual base %qT inaccessible in %qT due "
593238fd1498Szrj "to ambiguity", basetype, t);
593338fd1498Szrj }
593438fd1498Szrj }
593538fd1498Szrj
593638fd1498Szrj /* Compare two INTEGER_CSTs K1 and K2. */
593738fd1498Szrj
593838fd1498Szrj static int
splay_tree_compare_integer_csts(splay_tree_key k1,splay_tree_key k2)593938fd1498Szrj splay_tree_compare_integer_csts (splay_tree_key k1, splay_tree_key k2)
594038fd1498Szrj {
594138fd1498Szrj return tree_int_cst_compare ((tree) k1, (tree) k2);
594238fd1498Szrj }
594338fd1498Szrj
594438fd1498Szrj /* Increase the size indicated in RLI to account for empty classes
594538fd1498Szrj that are "off the end" of the class. */
594638fd1498Szrj
594738fd1498Szrj static void
include_empty_classes(record_layout_info rli)594838fd1498Szrj include_empty_classes (record_layout_info rli)
594938fd1498Szrj {
595038fd1498Szrj tree eoc;
595138fd1498Szrj tree rli_size;
595238fd1498Szrj
595338fd1498Szrj /* It might be the case that we grew the class to allocate a
595438fd1498Szrj zero-sized base class. That won't be reflected in RLI, yet,
595538fd1498Szrj because we are willing to overlay multiple bases at the same
595638fd1498Szrj offset. However, now we need to make sure that RLI is big enough
595738fd1498Szrj to reflect the entire class. */
595838fd1498Szrj eoc = end_of_class (rli->t, CLASSTYPE_AS_BASE (rli->t) != NULL_TREE);
595938fd1498Szrj rli_size = rli_size_unit_so_far (rli);
596038fd1498Szrj if (TREE_CODE (rli_size) == INTEGER_CST
596138fd1498Szrj && tree_int_cst_lt (rli_size, eoc))
596238fd1498Szrj {
596338fd1498Szrj /* The size should have been rounded to a whole byte. */
596438fd1498Szrj gcc_assert (tree_int_cst_equal
596538fd1498Szrj (rli->bitpos, round_down (rli->bitpos, BITS_PER_UNIT)));
596638fd1498Szrj rli->bitpos
596738fd1498Szrj = size_binop (PLUS_EXPR,
596838fd1498Szrj rli->bitpos,
596938fd1498Szrj size_binop (MULT_EXPR,
597038fd1498Szrj fold_convert (bitsizetype,
597138fd1498Szrj size_binop (MINUS_EXPR,
597238fd1498Szrj eoc, rli_size)),
597338fd1498Szrj bitsize_int (BITS_PER_UNIT)));
597438fd1498Szrj normalize_rli (rli);
597538fd1498Szrj }
597638fd1498Szrj }
597738fd1498Szrj
597838fd1498Szrj /* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T. Calculate
597938fd1498Szrj BINFO_OFFSETs for all of the base-classes. Position the vtable
598038fd1498Szrj pointer. Accumulate declared virtual functions on VIRTUALS_P. */
598138fd1498Szrj
598238fd1498Szrj static void
layout_class_type(tree t,tree * virtuals_p)598338fd1498Szrj layout_class_type (tree t, tree *virtuals_p)
598438fd1498Szrj {
598538fd1498Szrj tree non_static_data_members;
598638fd1498Szrj tree field;
598738fd1498Szrj tree vptr;
598838fd1498Szrj record_layout_info rli;
598938fd1498Szrj /* Maps offsets (represented as INTEGER_CSTs) to a TREE_LIST of
599038fd1498Szrj types that appear at that offset. */
599138fd1498Szrj splay_tree empty_base_offsets;
599238fd1498Szrj /* True if the last field laid out was a bit-field. */
599338fd1498Szrj bool last_field_was_bitfield = false;
599438fd1498Szrj /* The location at which the next field should be inserted. */
599538fd1498Szrj tree *next_field;
599638fd1498Szrj
599738fd1498Szrj /* Keep track of the first non-static data member. */
599838fd1498Szrj non_static_data_members = TYPE_FIELDS (t);
599938fd1498Szrj
600038fd1498Szrj /* Start laying out the record. */
600138fd1498Szrj rli = start_record_layout (t);
600238fd1498Szrj
600338fd1498Szrj /* Mark all the primary bases in the hierarchy. */
600438fd1498Szrj determine_primary_bases (t);
600538fd1498Szrj
600638fd1498Szrj /* Create a pointer to our virtual function table. */
600738fd1498Szrj vptr = create_vtable_ptr (t, virtuals_p);
600838fd1498Szrj
600938fd1498Szrj /* The vptr is always the first thing in the class. */
601038fd1498Szrj if (vptr)
601138fd1498Szrj {
601238fd1498Szrj DECL_CHAIN (vptr) = TYPE_FIELDS (t);
601338fd1498Szrj TYPE_FIELDS (t) = vptr;
601438fd1498Szrj next_field = &DECL_CHAIN (vptr);
601538fd1498Szrj place_field (rli, vptr);
601638fd1498Szrj }
601738fd1498Szrj else
601838fd1498Szrj next_field = &TYPE_FIELDS (t);
601938fd1498Szrj
602038fd1498Szrj /* Build FIELD_DECLs for all of the non-virtual base-types. */
602138fd1498Szrj empty_base_offsets = splay_tree_new (splay_tree_compare_integer_csts,
602238fd1498Szrj NULL, NULL);
602338fd1498Szrj build_base_fields (rli, empty_base_offsets, next_field);
602438fd1498Szrj
602538fd1498Szrj /* Layout the non-static data members. */
602638fd1498Szrj for (field = non_static_data_members; field; field = DECL_CHAIN (field))
602738fd1498Szrj {
602838fd1498Szrj tree type;
602938fd1498Szrj tree padding;
603038fd1498Szrj
603138fd1498Szrj /* We still pass things that aren't non-static data members to
603238fd1498Szrj the back end, in case it wants to do something with them. */
603338fd1498Szrj if (TREE_CODE (field) != FIELD_DECL)
603438fd1498Szrj {
603538fd1498Szrj place_field (rli, field);
603638fd1498Szrj /* If the static data member has incomplete type, keep track
603738fd1498Szrj of it so that it can be completed later. (The handling
603838fd1498Szrj of pending statics in finish_record_layout is
603938fd1498Szrj insufficient; consider:
604038fd1498Szrj
604138fd1498Szrj struct S1;
604238fd1498Szrj struct S2 { static S1 s1; };
604338fd1498Szrj
604438fd1498Szrj At this point, finish_record_layout will be called, but
604538fd1498Szrj S1 is still incomplete.) */
604638fd1498Szrj if (VAR_P (field))
604738fd1498Szrj {
604838fd1498Szrj maybe_register_incomplete_var (field);
604938fd1498Szrj /* The visibility of static data members is determined
605038fd1498Szrj at their point of declaration, not their point of
605138fd1498Szrj definition. */
605238fd1498Szrj determine_visibility (field);
605338fd1498Szrj }
605438fd1498Szrj continue;
605538fd1498Szrj }
605638fd1498Szrj
605738fd1498Szrj type = TREE_TYPE (field);
605838fd1498Szrj if (type == error_mark_node)
605938fd1498Szrj continue;
606038fd1498Szrj
606138fd1498Szrj padding = NULL_TREE;
606238fd1498Szrj
606338fd1498Szrj /* If this field is a bit-field whose width is greater than its
606438fd1498Szrj type, then there are some special rules for allocating
606538fd1498Szrj it. */
606638fd1498Szrj if (DECL_C_BIT_FIELD (field)
606738fd1498Szrj && tree_int_cst_lt (TYPE_SIZE (type), DECL_SIZE (field)))
606838fd1498Szrj {
606938fd1498Szrj bool was_unnamed_p = false;
607038fd1498Szrj /* We must allocate the bits as if suitably aligned for the
607138fd1498Szrj longest integer type that fits in this many bits. Then,
607238fd1498Szrj we are supposed to use the left over bits as additional
607338fd1498Szrj padding. */
607438fd1498Szrj
607538fd1498Szrj /* Do not pick a type bigger than MAX_FIXED_MODE_SIZE. */
607638fd1498Szrj tree limit = size_int (MAX_FIXED_MODE_SIZE);
607738fd1498Szrj if (tree_int_cst_lt (DECL_SIZE (field), limit))
607838fd1498Szrj limit = DECL_SIZE (field);
607938fd1498Szrj
608038fd1498Szrj tree integer_type = integer_types[itk_char];
608138fd1498Szrj for (unsigned itk = itk_char; itk != itk_none; itk++)
608238fd1498Szrj if (tree next = integer_types[itk])
608338fd1498Szrj {
608438fd1498Szrj if (tree_int_cst_lt (limit, TYPE_SIZE (next)))
608538fd1498Szrj /* Too big, so our current guess is what we want. */
608638fd1498Szrj break;
608738fd1498Szrj /* Not bigger than limit, ok */
608838fd1498Szrj integer_type = next;
608938fd1498Szrj }
609038fd1498Szrj
609138fd1498Szrj /* Figure out how much additional padding is required. */
609238fd1498Szrj if (TREE_CODE (t) == UNION_TYPE)
609338fd1498Szrj /* In a union, the padding field must have the full width
609438fd1498Szrj of the bit-field; all fields start at offset zero. */
609538fd1498Szrj padding = DECL_SIZE (field);
609638fd1498Szrj else
609738fd1498Szrj padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
609838fd1498Szrj TYPE_SIZE (integer_type));
609938fd1498Szrj
610038fd1498Szrj if (integer_zerop (padding))
610138fd1498Szrj padding = NULL_TREE;
610238fd1498Szrj
610338fd1498Szrj /* An unnamed bitfield does not normally affect the
610438fd1498Szrj alignment of the containing class on a target where
610538fd1498Szrj PCC_BITFIELD_TYPE_MATTERS. But, the C++ ABI does not
610638fd1498Szrj make any exceptions for unnamed bitfields when the
610738fd1498Szrj bitfields are longer than their types. Therefore, we
610838fd1498Szrj temporarily give the field a name. */
610938fd1498Szrj if (PCC_BITFIELD_TYPE_MATTERS && !DECL_NAME (field))
611038fd1498Szrj {
611138fd1498Szrj was_unnamed_p = true;
611238fd1498Szrj DECL_NAME (field) = make_anon_name ();
611338fd1498Szrj }
611438fd1498Szrj
611538fd1498Szrj DECL_SIZE (field) = TYPE_SIZE (integer_type);
611638fd1498Szrj SET_DECL_ALIGN (field, TYPE_ALIGN (integer_type));
611738fd1498Szrj DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
611838fd1498Szrj layout_nonempty_base_or_field (rli, field, NULL_TREE,
611938fd1498Szrj empty_base_offsets);
612038fd1498Szrj if (was_unnamed_p)
612138fd1498Szrj DECL_NAME (field) = NULL_TREE;
612238fd1498Szrj /* Now that layout has been performed, set the size of the
612338fd1498Szrj field to the size of its declared type; the rest of the
612438fd1498Szrj field is effectively invisible. */
612538fd1498Szrj DECL_SIZE (field) = TYPE_SIZE (type);
612638fd1498Szrj /* We must also reset the DECL_MODE of the field. */
612738fd1498Szrj SET_DECL_MODE (field, TYPE_MODE (type));
612838fd1498Szrj }
612938fd1498Szrj else
613038fd1498Szrj layout_nonempty_base_or_field (rli, field, NULL_TREE,
613138fd1498Szrj empty_base_offsets);
613238fd1498Szrj
613338fd1498Szrj /* Remember the location of any empty classes in FIELD. */
613438fd1498Szrj record_subobject_offsets (TREE_TYPE (field),
613538fd1498Szrj byte_position(field),
613638fd1498Szrj empty_base_offsets,
613738fd1498Szrj /*is_data_member=*/true);
613838fd1498Szrj
613938fd1498Szrj /* If a bit-field does not immediately follow another bit-field,
614038fd1498Szrj and yet it starts in the middle of a byte, we have failed to
614138fd1498Szrj comply with the ABI. */
614238fd1498Szrj if (warn_abi
614338fd1498Szrj && DECL_C_BIT_FIELD (field)
614438fd1498Szrj /* The TREE_NO_WARNING flag gets set by Objective-C when
614538fd1498Szrj laying out an Objective-C class. The ObjC ABI differs
614638fd1498Szrj from the C++ ABI, and so we do not want a warning
614738fd1498Szrj here. */
614838fd1498Szrj && !TREE_NO_WARNING (field)
614938fd1498Szrj && !last_field_was_bitfield
615038fd1498Szrj && !integer_zerop (size_binop (TRUNC_MOD_EXPR,
615138fd1498Szrj DECL_FIELD_BIT_OFFSET (field),
615238fd1498Szrj bitsize_unit_node)))
615338fd1498Szrj warning_at (DECL_SOURCE_LOCATION (field), OPT_Wabi,
615438fd1498Szrj "offset of %qD is not ABI-compliant and may "
615538fd1498Szrj "change in a future version of GCC", field);
615638fd1498Szrj
615738fd1498Szrj /* The middle end uses the type of expressions to determine the
615838fd1498Szrj possible range of expression values. In order to optimize
615938fd1498Szrj "x.i > 7" to "false" for a 2-bit bitfield "i", the middle end
616038fd1498Szrj must be made aware of the width of "i", via its type.
616138fd1498Szrj
616238fd1498Szrj Because C++ does not have integer types of arbitrary width,
616338fd1498Szrj we must (for the purposes of the front end) convert from the
616438fd1498Szrj type assigned here to the declared type of the bitfield
616538fd1498Szrj whenever a bitfield expression is used as an rvalue.
616638fd1498Szrj Similarly, when assigning a value to a bitfield, the value
616738fd1498Szrj must be converted to the type given the bitfield here. */
616838fd1498Szrj if (DECL_C_BIT_FIELD (field))
616938fd1498Szrj {
617038fd1498Szrj unsigned HOST_WIDE_INT width;
617138fd1498Szrj tree ftype = TREE_TYPE (field);
617238fd1498Szrj width = tree_to_uhwi (DECL_SIZE (field));
617338fd1498Szrj if (width != TYPE_PRECISION (ftype))
617438fd1498Szrj {
617538fd1498Szrj TREE_TYPE (field)
617638fd1498Szrj = c_build_bitfield_integer_type (width,
617738fd1498Szrj TYPE_UNSIGNED (ftype));
617838fd1498Szrj TREE_TYPE (field)
617938fd1498Szrj = cp_build_qualified_type (TREE_TYPE (field),
618038fd1498Szrj cp_type_quals (ftype));
618138fd1498Szrj }
618238fd1498Szrj }
618338fd1498Szrj
618438fd1498Szrj /* If we needed additional padding after this field, add it
618538fd1498Szrj now. */
618638fd1498Szrj if (padding)
618738fd1498Szrj {
618838fd1498Szrj tree padding_field;
618938fd1498Szrj
619038fd1498Szrj padding_field = build_decl (input_location,
619138fd1498Szrj FIELD_DECL,
619238fd1498Szrj NULL_TREE,
619338fd1498Szrj char_type_node);
619438fd1498Szrj DECL_BIT_FIELD (padding_field) = 1;
619538fd1498Szrj DECL_SIZE (padding_field) = padding;
619638fd1498Szrj DECL_CONTEXT (padding_field) = t;
619738fd1498Szrj DECL_ARTIFICIAL (padding_field) = 1;
619838fd1498Szrj DECL_IGNORED_P (padding_field) = 1;
619938fd1498Szrj DECL_PADDING_P (padding_field) = 1;
620038fd1498Szrj layout_nonempty_base_or_field (rli, padding_field,
620138fd1498Szrj NULL_TREE,
620238fd1498Szrj empty_base_offsets);
620338fd1498Szrj }
620438fd1498Szrj
620538fd1498Szrj last_field_was_bitfield = DECL_C_BIT_FIELD (field);
620638fd1498Szrj }
620738fd1498Szrj
620838fd1498Szrj if (!integer_zerop (rli->bitpos))
620938fd1498Szrj {
621038fd1498Szrj /* Make sure that we are on a byte boundary so that the size of
621138fd1498Szrj the class without virtual bases will always be a round number
621238fd1498Szrj of bytes. */
621338fd1498Szrj rli->bitpos = round_up_loc (input_location, rli->bitpos, BITS_PER_UNIT);
621438fd1498Szrj normalize_rli (rli);
621538fd1498Szrj }
621638fd1498Szrj
621738fd1498Szrj /* Delete all zero-width bit-fields from the list of fields. Now
621838fd1498Szrj that the type is laid out they are no longer important. */
621938fd1498Szrj remove_zero_width_bit_fields (t);
622038fd1498Szrj
622138fd1498Szrj if (CLASSTYPE_NON_LAYOUT_POD_P (t) || CLASSTYPE_EMPTY_P (t))
622238fd1498Szrj {
622338fd1498Szrj /* T needs a different layout as a base (eliding virtual bases
622438fd1498Szrj or whatever). Create that version. */
622538fd1498Szrj tree base_t = make_node (TREE_CODE (t));
622638fd1498Szrj
622738fd1498Szrj /* If the ABI version is not at least two, and the last
622838fd1498Szrj field was a bit-field, RLI may not be on a byte
622938fd1498Szrj boundary. In particular, rli_size_unit_so_far might
623038fd1498Szrj indicate the last complete byte, while rli_size_so_far
623138fd1498Szrj indicates the total number of bits used. Therefore,
623238fd1498Szrj rli_size_so_far, rather than rli_size_unit_so_far, is
623338fd1498Szrj used to compute TYPE_SIZE_UNIT. */
623438fd1498Szrj tree eoc = end_of_class (t, /*include_virtuals_p=*/0);
623538fd1498Szrj TYPE_SIZE_UNIT (base_t)
623638fd1498Szrj = size_binop (MAX_EXPR,
623738fd1498Szrj fold_convert (sizetype,
623838fd1498Szrj size_binop (CEIL_DIV_EXPR,
623938fd1498Szrj rli_size_so_far (rli),
624038fd1498Szrj bitsize_int (BITS_PER_UNIT))),
624138fd1498Szrj eoc);
624238fd1498Szrj TYPE_SIZE (base_t)
624338fd1498Szrj = size_binop (MAX_EXPR,
624438fd1498Szrj rli_size_so_far (rli),
624538fd1498Szrj size_binop (MULT_EXPR,
624638fd1498Szrj fold_convert (bitsizetype, eoc),
624738fd1498Szrj bitsize_int (BITS_PER_UNIT)));
624838fd1498Szrj SET_TYPE_ALIGN (base_t, rli->record_align);
624938fd1498Szrj TYPE_USER_ALIGN (base_t) = TYPE_USER_ALIGN (t);
625058e805e6Szrj TYPE_TYPELESS_STORAGE (base_t) = TYPE_TYPELESS_STORAGE (t);
625138fd1498Szrj
625238fd1498Szrj /* Copy the non-static data members of T. This will include its
625338fd1498Szrj direct non-virtual bases & vtable. */
625438fd1498Szrj next_field = &TYPE_FIELDS (base_t);
625538fd1498Szrj for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
625638fd1498Szrj if (TREE_CODE (field) == FIELD_DECL)
625738fd1498Szrj {
625838fd1498Szrj *next_field = copy_node (field);
625938fd1498Szrj DECL_CONTEXT (*next_field) = base_t;
626038fd1498Szrj next_field = &DECL_CHAIN (*next_field);
626138fd1498Szrj }
626238fd1498Szrj *next_field = NULL_TREE;
626338fd1498Szrj
626438fd1498Szrj /* We use the base type for trivial assignments, and hence it
626538fd1498Szrj needs a mode. */
626638fd1498Szrj compute_record_mode (base_t);
626738fd1498Szrj
626838fd1498Szrj TYPE_CONTEXT (base_t) = t;
626938fd1498Szrj
627038fd1498Szrj /* Record the base version of the type. */
627138fd1498Szrj CLASSTYPE_AS_BASE (t) = base_t;
627238fd1498Szrj }
627338fd1498Szrj else
627438fd1498Szrj CLASSTYPE_AS_BASE (t) = t;
627538fd1498Szrj
627638fd1498Szrj /* Every empty class contains an empty class. */
627738fd1498Szrj if (CLASSTYPE_EMPTY_P (t))
627838fd1498Szrj CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
627938fd1498Szrj
628038fd1498Szrj /* Set the TYPE_DECL for this type to contain the right
628138fd1498Szrj value for DECL_OFFSET, so that we can use it as part
628238fd1498Szrj of a COMPONENT_REF for multiple inheritance. */
628338fd1498Szrj layout_decl (TYPE_MAIN_DECL (t), 0);
628438fd1498Szrj
628538fd1498Szrj /* Now fix up any virtual base class types that we left lying
628638fd1498Szrj around. We must get these done before we try to lay out the
628738fd1498Szrj virtual function table. As a side-effect, this will remove the
628838fd1498Szrj base subobject fields. */
628938fd1498Szrj layout_virtual_bases (rli, empty_base_offsets);
629038fd1498Szrj
629138fd1498Szrj /* Make sure that empty classes are reflected in RLI at this
629238fd1498Szrj point. */
629338fd1498Szrj include_empty_classes (rli);
629438fd1498Szrj
629538fd1498Szrj /* Make sure not to create any structures with zero size. */
629638fd1498Szrj if (integer_zerop (rli_size_unit_so_far (rli)) && CLASSTYPE_EMPTY_P (t))
629738fd1498Szrj place_field (rli,
629838fd1498Szrj build_decl (input_location,
629938fd1498Szrj FIELD_DECL, NULL_TREE, char_type_node));
630038fd1498Szrj
630138fd1498Szrj /* If this is a non-POD, declaring it packed makes a difference to how it
630238fd1498Szrj can be used as a field; don't let finalize_record_size undo it. */
630338fd1498Szrj if (TYPE_PACKED (t) && !layout_pod_type_p (t))
630438fd1498Szrj rli->packed_maybe_necessary = true;
630538fd1498Szrj
630638fd1498Szrj /* Let the back end lay out the type. */
630738fd1498Szrj finish_record_layout (rli, /*free_p=*/true);
630838fd1498Szrj
630938fd1498Szrj if (TYPE_SIZE_UNIT (t)
631038fd1498Szrj && TREE_CODE (TYPE_SIZE_UNIT (t)) == INTEGER_CST
631138fd1498Szrj && !TREE_OVERFLOW (TYPE_SIZE_UNIT (t))
631238fd1498Szrj && !valid_constant_size_p (TYPE_SIZE_UNIT (t)))
631338fd1498Szrj error ("size of type %qT is too large (%qE bytes)", t, TYPE_SIZE_UNIT (t));
631438fd1498Szrj
631538fd1498Szrj /* Warn about bases that can't be talked about due to ambiguity. */
631638fd1498Szrj warn_about_ambiguous_bases (t);
631738fd1498Szrj
631838fd1498Szrj /* Now that we're done with layout, give the base fields the real types. */
631938fd1498Szrj for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
632038fd1498Szrj if (DECL_ARTIFICIAL (field) && IS_FAKE_BASE_TYPE (TREE_TYPE (field)))
632138fd1498Szrj TREE_TYPE (field) = TYPE_CONTEXT (TREE_TYPE (field));
632238fd1498Szrj
632338fd1498Szrj /* Clean up. */
632438fd1498Szrj splay_tree_delete (empty_base_offsets);
632538fd1498Szrj
632638fd1498Szrj if (CLASSTYPE_EMPTY_P (t)
632738fd1498Szrj && tree_int_cst_lt (sizeof_biggest_empty_class,
632838fd1498Szrj TYPE_SIZE_UNIT (t)))
632938fd1498Szrj sizeof_biggest_empty_class = TYPE_SIZE_UNIT (t);
633038fd1498Szrj }
633138fd1498Szrj
633238fd1498Szrj /* Determine the "key method" for the class type indicated by TYPE,
633338fd1498Szrj and set CLASSTYPE_KEY_METHOD accordingly. */
633438fd1498Szrj
633538fd1498Szrj void
determine_key_method(tree type)633638fd1498Szrj determine_key_method (tree type)
633738fd1498Szrj {
633838fd1498Szrj tree method;
633938fd1498Szrj
634038fd1498Szrj if (processing_template_decl
634138fd1498Szrj || CLASSTYPE_TEMPLATE_INSTANTIATION (type)
634238fd1498Szrj || CLASSTYPE_INTERFACE_KNOWN (type))
634338fd1498Szrj return;
634438fd1498Szrj
634538fd1498Szrj /* The key method is the first non-pure virtual function that is not
634638fd1498Szrj inline at the point of class definition. On some targets the
634738fd1498Szrj key function may not be inline; those targets should not call
634838fd1498Szrj this function until the end of the translation unit. */
634938fd1498Szrj for (method = TYPE_FIELDS (type); method; method = DECL_CHAIN (method))
635038fd1498Szrj if (TREE_CODE (method) == FUNCTION_DECL
635138fd1498Szrj && DECL_VINDEX (method) != NULL_TREE
635238fd1498Szrj && ! DECL_DECLARED_INLINE_P (method)
635338fd1498Szrj && ! DECL_PURE_VIRTUAL_P (method))
635438fd1498Szrj {
635538fd1498Szrj CLASSTYPE_KEY_METHOD (type) = method;
635638fd1498Szrj break;
635738fd1498Szrj }
635838fd1498Szrj
635938fd1498Szrj return;
636038fd1498Szrj }
636138fd1498Szrj
636238fd1498Szrj /* Helper of find_flexarrays. Return true when FLD refers to a non-static
636338fd1498Szrj class data member of non-zero size, otherwise false. */
636438fd1498Szrj
636538fd1498Szrj static inline bool
field_nonempty_p(const_tree fld)636638fd1498Szrj field_nonempty_p (const_tree fld)
636738fd1498Szrj {
636838fd1498Szrj if (TREE_CODE (fld) == ERROR_MARK)
636938fd1498Szrj return false;
637038fd1498Szrj
637138fd1498Szrj tree type = TREE_TYPE (fld);
637238fd1498Szrj if (TREE_CODE (fld) == FIELD_DECL
637338fd1498Szrj && TREE_CODE (type) != ERROR_MARK
637438fd1498Szrj && (DECL_NAME (fld) || RECORD_OR_UNION_TYPE_P (type)))
637538fd1498Szrj {
637638fd1498Szrj return TYPE_SIZE (type)
637738fd1498Szrj && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
637838fd1498Szrj || !tree_int_cst_equal (size_zero_node, TYPE_SIZE (type)));
637938fd1498Szrj }
638038fd1498Szrj
638138fd1498Szrj return false;
638238fd1498Szrj }
638338fd1498Szrj
638438fd1498Szrj /* Used by find_flexarrays and related functions. */
638538fd1498Szrj
638638fd1498Szrj struct flexmems_t
638738fd1498Szrj {
638838fd1498Szrj /* The first flexible array member or non-zero array member found
638938fd1498Szrj in the order of layout. */
639038fd1498Szrj tree array;
639138fd1498Szrj /* First non-static non-empty data member in the class or its bases. */
639238fd1498Szrj tree first;
639338fd1498Szrj /* The first non-static non-empty data member following either
639438fd1498Szrj the flexible array member, if found, or the zero-length array member
639538fd1498Szrj otherwise. AFTER[1] refers to the first such data member of a union
639638fd1498Szrj of which the struct containing the flexible array member or zero-length
639738fd1498Szrj array is a member, or NULL when no such union exists. This element is
639838fd1498Szrj only used during searching, not for diagnosing problems. AFTER[0]
639938fd1498Szrj refers to the first such data member that is not a member of such
640038fd1498Szrj a union. */
640138fd1498Szrj tree after[2];
640238fd1498Szrj
640338fd1498Szrj /* Refers to a struct (not union) in which the struct of which the flexible
640438fd1498Szrj array is member is defined. Used to diagnose strictly (according to C)
640538fd1498Szrj invalid uses of the latter structs. */
640638fd1498Szrj tree enclosing;
640738fd1498Szrj };
640838fd1498Szrj
640938fd1498Szrj /* Find either the first flexible array member or the first zero-length
641038fd1498Szrj array, in that order of preference, among members of class T (but not
641138fd1498Szrj its base classes), and set members of FMEM accordingly.
641238fd1498Szrj BASE_P is true if T is a base class of another class.
641338fd1498Szrj PUN is set to the outermost union in which the flexible array member
641438fd1498Szrj (or zero-length array) is defined if one such union exists, otherwise
641538fd1498Szrj to NULL.
641638fd1498Szrj Similarly, PSTR is set to a data member of the outermost struct of
641738fd1498Szrj which the flexible array is a member if one such struct exists,
641838fd1498Szrj otherwise to NULL. */
641938fd1498Szrj
642038fd1498Szrj static void
find_flexarrays(tree t,flexmems_t * fmem,bool base_p,tree pun,tree pstr)642138fd1498Szrj find_flexarrays (tree t, flexmems_t *fmem, bool base_p,
642238fd1498Szrj tree pun /* = NULL_TREE */,
642338fd1498Szrj tree pstr /* = NULL_TREE */)
642438fd1498Szrj {
642538fd1498Szrj /* Set the "pointer" to the outermost enclosing union if not set
642638fd1498Szrj yet and maintain it for the remainder of the recursion. */
642738fd1498Szrj if (!pun && TREE_CODE (t) == UNION_TYPE)
642838fd1498Szrj pun = t;
642938fd1498Szrj
643038fd1498Szrj for (tree fld = TYPE_FIELDS (t); fld; fld = DECL_CHAIN (fld))
643138fd1498Szrj {
643238fd1498Szrj if (fld == error_mark_node)
643338fd1498Szrj return;
643438fd1498Szrj
643538fd1498Szrj /* Is FLD a typedef for an anonymous struct? */
643638fd1498Szrj
643738fd1498Szrj /* FIXME: Note that typedefs (as well as arrays) need to be fully
643838fd1498Szrj handled elsewhere so that errors like the following are detected
643938fd1498Szrj as well:
644038fd1498Szrj typedef struct { int i, a[], j; } S; // bug c++/72753
644138fd1498Szrj S s [2]; // bug c++/68489
644238fd1498Szrj */
644338fd1498Szrj if (TREE_CODE (fld) == TYPE_DECL
644438fd1498Szrj && DECL_IMPLICIT_TYPEDEF_P (fld)
644538fd1498Szrj && CLASS_TYPE_P (TREE_TYPE (fld))
644638fd1498Szrj && anon_aggrname_p (DECL_NAME (fld)))
644738fd1498Szrj {
644838fd1498Szrj /* Check the nested unnamed type referenced via a typedef
644938fd1498Szrj independently of FMEM (since it's not a data member of
645038fd1498Szrj the enclosing class). */
645138fd1498Szrj check_flexarrays (TREE_TYPE (fld));
645238fd1498Szrj continue;
645338fd1498Szrj }
645438fd1498Szrj
645538fd1498Szrj /* Skip anything that's GCC-generated or not a (non-static) data
645638fd1498Szrj member. */
645738fd1498Szrj if (DECL_ARTIFICIAL (fld) || TREE_CODE (fld) != FIELD_DECL)
645838fd1498Szrj continue;
645938fd1498Szrj
646038fd1498Szrj /* Type of the member. */
646138fd1498Szrj tree fldtype = TREE_TYPE (fld);
646238fd1498Szrj if (fldtype == error_mark_node)
646338fd1498Szrj return;
646438fd1498Szrj
646538fd1498Szrj /* Determine the type of the array element or object referenced
646638fd1498Szrj by the member so that it can be checked for flexible array
646738fd1498Szrj members if it hasn't been yet. */
646838fd1498Szrj tree eltype = fldtype;
646938fd1498Szrj while (TREE_CODE (eltype) == ARRAY_TYPE
647038fd1498Szrj || TREE_CODE (eltype) == POINTER_TYPE
647138fd1498Szrj || TREE_CODE (eltype) == REFERENCE_TYPE)
647238fd1498Szrj eltype = TREE_TYPE (eltype);
647338fd1498Szrj
647438fd1498Szrj if (RECORD_OR_UNION_TYPE_P (eltype))
647538fd1498Szrj {
647638fd1498Szrj if (fmem->array && !fmem->after[bool (pun)])
647738fd1498Szrj {
647838fd1498Szrj /* Once the member after the flexible array has been found
647938fd1498Szrj we're done. */
648038fd1498Szrj fmem->after[bool (pun)] = fld;
648138fd1498Szrj break;
648238fd1498Szrj }
648338fd1498Szrj
648438fd1498Szrj if (eltype == fldtype || TYPE_UNNAMED_P (eltype))
648538fd1498Szrj {
648638fd1498Szrj /* Descend into the non-static member struct or union and try
648738fd1498Szrj to find a flexible array member or zero-length array among
648838fd1498Szrj its members. This is only necessary for anonymous types
648938fd1498Szrj and types in whose context the current type T has not been
649038fd1498Szrj defined (the latter must not be checked again because they
649138fd1498Szrj are already in the process of being checked by one of the
649238fd1498Szrj recursive calls). */
649338fd1498Szrj
649438fd1498Szrj tree first = fmem->first;
649538fd1498Szrj tree array = fmem->array;
649638fd1498Szrj
649738fd1498Szrj /* If this member isn't anonymous and a prior non-flexible array
649838fd1498Szrj member has been seen in one of the enclosing structs, clear
649938fd1498Szrj the FIRST member since it doesn't contribute to the flexible
650038fd1498Szrj array struct's members. */
650138fd1498Szrj if (first && !array && !ANON_AGGR_TYPE_P (eltype))
650238fd1498Szrj fmem->first = NULL_TREE;
650338fd1498Szrj
650438fd1498Szrj find_flexarrays (eltype, fmem, false, pun,
650538fd1498Szrj !pstr && TREE_CODE (t) == RECORD_TYPE ? fld : pstr);
650638fd1498Szrj
650738fd1498Szrj if (fmem->array != array)
650838fd1498Szrj continue;
650938fd1498Szrj
651038fd1498Szrj if (first && !array && !ANON_AGGR_TYPE_P (eltype))
651138fd1498Szrj {
651238fd1498Szrj /* Restore the FIRST member reset above if no flexible
651338fd1498Szrj array member has been found in this member's struct. */
651438fd1498Szrj fmem->first = first;
651538fd1498Szrj }
651638fd1498Szrj
651738fd1498Szrj /* If the member struct contains the first flexible array
651838fd1498Szrj member, or if this member is a base class, continue to
651938fd1498Szrj the next member and avoid setting the FMEM->NEXT pointer
652038fd1498Szrj to point to it. */
652138fd1498Szrj if (base_p)
652238fd1498Szrj continue;
652338fd1498Szrj }
652438fd1498Szrj }
652538fd1498Szrj
652638fd1498Szrj if (field_nonempty_p (fld))
652738fd1498Szrj {
652838fd1498Szrj /* Remember the first non-static data member. */
652938fd1498Szrj if (!fmem->first)
653038fd1498Szrj fmem->first = fld;
653138fd1498Szrj
653238fd1498Szrj /* Remember the first non-static data member after the flexible
653338fd1498Szrj array member, if one has been found, or the zero-length array
653438fd1498Szrj if it has been found. */
653538fd1498Szrj if (fmem->array && !fmem->after[bool (pun)])
653638fd1498Szrj fmem->after[bool (pun)] = fld;
653738fd1498Szrj }
653838fd1498Szrj
653938fd1498Szrj /* Skip non-arrays. */
654038fd1498Szrj if (TREE_CODE (fldtype) != ARRAY_TYPE)
654138fd1498Szrj continue;
654238fd1498Szrj
654338fd1498Szrj /* Determine the upper bound of the array if it has one. */
654438fd1498Szrj if (TYPE_DOMAIN (fldtype))
654538fd1498Szrj {
654638fd1498Szrj if (fmem->array)
654738fd1498Szrj {
654838fd1498Szrj /* Make a record of the zero-length array if either one
654938fd1498Szrj such field or a flexible array member has been seen to
655038fd1498Szrj handle the pathological and unlikely case of multiple
655138fd1498Szrj such members. */
655238fd1498Szrj if (!fmem->after[bool (pun)])
655338fd1498Szrj fmem->after[bool (pun)] = fld;
655438fd1498Szrj }
655538fd1498Szrj else if (integer_all_onesp (TYPE_MAX_VALUE (TYPE_DOMAIN (fldtype))))
655638fd1498Szrj {
655738fd1498Szrj /* Remember the first zero-length array unless a flexible array
655838fd1498Szrj member has already been seen. */
655938fd1498Szrj fmem->array = fld;
656038fd1498Szrj fmem->enclosing = pstr;
656138fd1498Szrj }
656238fd1498Szrj }
656338fd1498Szrj else
656438fd1498Szrj {
656538fd1498Szrj /* Flexible array members have no upper bound. */
656638fd1498Szrj if (fmem->array)
656738fd1498Szrj {
656838fd1498Szrj if (TYPE_DOMAIN (TREE_TYPE (fmem->array)))
656938fd1498Szrj {
657038fd1498Szrj /* Replace the zero-length array if it's been stored and
657138fd1498Szrj reset the after pointer. */
657238fd1498Szrj fmem->after[bool (pun)] = NULL_TREE;
657338fd1498Szrj fmem->array = fld;
657438fd1498Szrj fmem->enclosing = pstr;
657538fd1498Szrj }
657638fd1498Szrj else if (!fmem->after[bool (pun)])
657738fd1498Szrj /* Make a record of another flexible array member. */
657838fd1498Szrj fmem->after[bool (pun)] = fld;
657938fd1498Szrj }
658038fd1498Szrj else
658138fd1498Szrj {
658238fd1498Szrj fmem->array = fld;
658338fd1498Szrj fmem->enclosing = pstr;
658438fd1498Szrj }
658538fd1498Szrj }
658638fd1498Szrj }
658738fd1498Szrj }
658838fd1498Szrj
658938fd1498Szrj /* Diagnose a strictly (by the C standard) invalid use of a struct with
659038fd1498Szrj a flexible array member (or the zero-length array extension). */
659138fd1498Szrj
659238fd1498Szrj static void
diagnose_invalid_flexarray(const flexmems_t * fmem)659338fd1498Szrj diagnose_invalid_flexarray (const flexmems_t *fmem)
659438fd1498Szrj {
659538fd1498Szrj if (fmem->array && fmem->enclosing
659638fd1498Szrj && pedwarn (location_of (fmem->enclosing), OPT_Wpedantic,
659738fd1498Szrj TYPE_DOMAIN (TREE_TYPE (fmem->array))
659838fd1498Szrj ? G_("invalid use of %q#T with a zero-size array "
659938fd1498Szrj "in %q#D")
660038fd1498Szrj : G_("invalid use of %q#T with a flexible array member "
660138fd1498Szrj "in %q#T"),
660238fd1498Szrj DECL_CONTEXT (fmem->array),
660338fd1498Szrj DECL_CONTEXT (fmem->enclosing)))
660438fd1498Szrj inform (DECL_SOURCE_LOCATION (fmem->array),
660538fd1498Szrj "array member %q#D declared here", fmem->array);
660638fd1498Szrj }
660738fd1498Szrj
660838fd1498Szrj /* Issue diagnostics for invalid flexible array members or zero-length
660938fd1498Szrj arrays that are not the last elements of the containing class or its
661038fd1498Szrj base classes or that are its sole members. */
661138fd1498Szrj
661238fd1498Szrj static void
diagnose_flexarrays(tree t,const flexmems_t * fmem)661338fd1498Szrj diagnose_flexarrays (tree t, const flexmems_t *fmem)
661438fd1498Szrj {
661538fd1498Szrj if (!fmem->array)
661638fd1498Szrj return;
661738fd1498Szrj
661838fd1498Szrj if (fmem->first && !fmem->after[0])
661938fd1498Szrj {
662038fd1498Szrj diagnose_invalid_flexarray (fmem);
662138fd1498Szrj return;
662238fd1498Szrj }
662338fd1498Szrj
662438fd1498Szrj /* Has a diagnostic been issued? */
662538fd1498Szrj bool diagd = false;
662638fd1498Szrj
662738fd1498Szrj const char *msg = 0;
662838fd1498Szrj
662938fd1498Szrj if (TYPE_DOMAIN (TREE_TYPE (fmem->array)))
663038fd1498Szrj {
663138fd1498Szrj if (fmem->after[0])
663238fd1498Szrj msg = G_("zero-size array member %qD not at end of %q#T");
663338fd1498Szrj else if (!fmem->first)
663438fd1498Szrj msg = G_("zero-size array member %qD in an otherwise empty %q#T");
663538fd1498Szrj
663638fd1498Szrj if (msg)
663738fd1498Szrj {
663838fd1498Szrj location_t loc = DECL_SOURCE_LOCATION (fmem->array);
663938fd1498Szrj
664038fd1498Szrj if (pedwarn (loc, OPT_Wpedantic, msg, fmem->array, t))
664138fd1498Szrj {
664238fd1498Szrj inform (location_of (t), "in the definition of %q#T", t);
664338fd1498Szrj diagd = true;
664438fd1498Szrj }
664538fd1498Szrj }
664638fd1498Szrj }
664738fd1498Szrj else
664838fd1498Szrj {
664938fd1498Szrj if (fmem->after[0])
665038fd1498Szrj msg = G_("flexible array member %qD not at end of %q#T");
665138fd1498Szrj else if (!fmem->first)
665238fd1498Szrj msg = G_("flexible array member %qD in an otherwise empty %q#T");
665338fd1498Szrj
665438fd1498Szrj if (msg)
665538fd1498Szrj {
665638fd1498Szrj location_t loc = DECL_SOURCE_LOCATION (fmem->array);
665738fd1498Szrj diagd = true;
665838fd1498Szrj
665938fd1498Szrj error_at (loc, msg, fmem->array, t);
666038fd1498Szrj
666138fd1498Szrj /* In the unlikely event that the member following the flexible
666238fd1498Szrj array member is declared in a different class, or the member
666338fd1498Szrj overlaps another member of a common union, point to it.
666438fd1498Szrj Otherwise it should be obvious. */
666538fd1498Szrj if (fmem->after[0]
666638fd1498Szrj && ((DECL_CONTEXT (fmem->after[0])
666738fd1498Szrj != DECL_CONTEXT (fmem->array))))
666838fd1498Szrj {
666938fd1498Szrj inform (DECL_SOURCE_LOCATION (fmem->after[0]),
667038fd1498Szrj "next member %q#D declared here",
667138fd1498Szrj fmem->after[0]);
667238fd1498Szrj inform (location_of (t), "in the definition of %q#T", t);
667338fd1498Szrj }
667438fd1498Szrj }
667538fd1498Szrj }
667638fd1498Szrj
667738fd1498Szrj if (!diagd && fmem->array && fmem->enclosing)
667838fd1498Szrj diagnose_invalid_flexarray (fmem);
667938fd1498Szrj }
668038fd1498Szrj
668138fd1498Szrj
668238fd1498Szrj /* Recursively check to make sure that any flexible array or zero-length
668338fd1498Szrj array members of class T or its bases are valid (i.e., not the sole
668438fd1498Szrj non-static data member of T and, if one exists, that it is the last
668538fd1498Szrj non-static data member of T and its base classes. FMEM is expected
668638fd1498Szrj to be initially null and is used internally by recursive calls to
668738fd1498Szrj the function. Issue the appropriate diagnostics for the array member
668838fd1498Szrj that fails the checks. */
668938fd1498Szrj
669038fd1498Szrj static void
check_flexarrays(tree t,flexmems_t * fmem,bool base_p)669138fd1498Szrj check_flexarrays (tree t, flexmems_t *fmem /* = NULL */,
669238fd1498Szrj bool base_p /* = false */)
669338fd1498Szrj {
669438fd1498Szrj /* Initialize the result of a search for flexible array and zero-length
669538fd1498Szrj array members. Avoid doing any work if the most interesting FMEM data
669638fd1498Szrj have already been populated. */
669738fd1498Szrj flexmems_t flexmems = flexmems_t ();
669838fd1498Szrj if (!fmem)
669938fd1498Szrj fmem = &flexmems;
670038fd1498Szrj else if (fmem->array && fmem->first && fmem->after[0])
670138fd1498Szrj return;
670238fd1498Szrj
670338fd1498Szrj tree fam = fmem->array;
670438fd1498Szrj
670538fd1498Szrj /* Recursively check the primary base class first. */
670638fd1498Szrj if (CLASSTYPE_HAS_PRIMARY_BASE_P (t))
670738fd1498Szrj {
670838fd1498Szrj tree basetype = BINFO_TYPE (CLASSTYPE_PRIMARY_BINFO (t));
670938fd1498Szrj check_flexarrays (basetype, fmem, true);
671038fd1498Szrj }
671138fd1498Szrj
671238fd1498Szrj /* Recursively check the base classes. */
671338fd1498Szrj int nbases = TYPE_BINFO (t) ? BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) : 0;
671438fd1498Szrj for (int i = 0; i < nbases; ++i)
671538fd1498Szrj {
671638fd1498Szrj tree base_binfo = BINFO_BASE_BINFO (TYPE_BINFO (t), i);
671738fd1498Szrj
671838fd1498Szrj /* The primary base class was already checked above. */
671938fd1498Szrj if (base_binfo == CLASSTYPE_PRIMARY_BINFO (t))
672038fd1498Szrj continue;
672138fd1498Szrj
672238fd1498Szrj /* Virtual base classes are at the end. */
672338fd1498Szrj if (BINFO_VIRTUAL_P (base_binfo))
672438fd1498Szrj continue;
672538fd1498Szrj
672638fd1498Szrj /* Check the base class. */
672738fd1498Szrj check_flexarrays (BINFO_TYPE (base_binfo), fmem, /*base_p=*/true);
672838fd1498Szrj }
672938fd1498Szrj
673038fd1498Szrj if (fmem == &flexmems)
673138fd1498Szrj {
673238fd1498Szrj /* Check virtual base classes only once per derived class.
673338fd1498Szrj I.e., this check is not performed recursively for base
673438fd1498Szrj classes. */
673538fd1498Szrj int i;
673638fd1498Szrj tree base_binfo;
673738fd1498Szrj vec<tree, va_gc> *vbases;
673838fd1498Szrj for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
673938fd1498Szrj vec_safe_iterate (vbases, i, &base_binfo); i++)
674038fd1498Szrj {
674138fd1498Szrj /* Check the virtual base class. */
674238fd1498Szrj tree basetype = TREE_TYPE (base_binfo);
674338fd1498Szrj
674438fd1498Szrj check_flexarrays (basetype, fmem, /*base_p=*/true);
674538fd1498Szrj }
674638fd1498Szrj }
674738fd1498Szrj
674838fd1498Szrj /* Is the type unnamed (and therefore a member of it potentially
674938fd1498Szrj an anonymous struct or union)? */
675038fd1498Szrj bool maybe_anon_p = TYPE_UNNAMED_P (t);
675138fd1498Szrj
675238fd1498Szrj /* Search the members of the current (possibly derived) class, skipping
675338fd1498Szrj unnamed structs and unions since those could be anonymous. */
675438fd1498Szrj if (fmem != &flexmems || !maybe_anon_p)
675538fd1498Szrj find_flexarrays (t, fmem, base_p || fam != fmem->array);
675638fd1498Szrj
675738fd1498Szrj if (fmem == &flexmems && !maybe_anon_p)
675838fd1498Szrj {
675938fd1498Szrj /* Issue diagnostics for invalid flexible and zero-length array
676038fd1498Szrj members found in base classes or among the members of the current
676138fd1498Szrj class. Ignore anonymous structs and unions whose members are
676238fd1498Szrj considered to be members of the enclosing class and thus will
676338fd1498Szrj be diagnosed when checking it. */
676438fd1498Szrj diagnose_flexarrays (t, fmem);
676538fd1498Szrj }
676638fd1498Szrj }
676738fd1498Szrj
676838fd1498Szrj /* Perform processing required when the definition of T (a class type)
676938fd1498Szrj is complete. Diagnose invalid definitions of flexible array members
677038fd1498Szrj and zero-size arrays. */
677138fd1498Szrj
677238fd1498Szrj void
finish_struct_1(tree t)677338fd1498Szrj finish_struct_1 (tree t)
677438fd1498Szrj {
677538fd1498Szrj tree x;
677638fd1498Szrj /* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */
677738fd1498Szrj tree virtuals = NULL_TREE;
677838fd1498Szrj
677938fd1498Szrj if (COMPLETE_TYPE_P (t))
678038fd1498Szrj {
678138fd1498Szrj gcc_assert (MAYBE_CLASS_TYPE_P (t));
678238fd1498Szrj error ("redefinition of %q#T", t);
678338fd1498Szrj popclass ();
678438fd1498Szrj return;
678538fd1498Szrj }
678638fd1498Szrj
678738fd1498Szrj /* If this type was previously laid out as a forward reference,
678838fd1498Szrj make sure we lay it out again. */
678938fd1498Szrj TYPE_SIZE (t) = NULL_TREE;
679038fd1498Szrj CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
679138fd1498Szrj
679238fd1498Szrj /* Make assumptions about the class; we'll reset the flags if
679338fd1498Szrj necessary. */
679438fd1498Szrj CLASSTYPE_EMPTY_P (t) = 1;
679538fd1498Szrj CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
679638fd1498Szrj CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0;
679738fd1498Szrj CLASSTYPE_LITERAL_P (t) = true;
679838fd1498Szrj
679938fd1498Szrj /* Do end-of-class semantic processing: checking the validity of the
680038fd1498Szrj bases and members and add implicitly generated methods. */
680138fd1498Szrj check_bases_and_members (t);
680238fd1498Szrj
680338fd1498Szrj /* Find the key method. */
680438fd1498Szrj if (TYPE_CONTAINS_VPTR_P (t))
680538fd1498Szrj {
680638fd1498Szrj /* The Itanium C++ ABI permits the key method to be chosen when
680738fd1498Szrj the class is defined -- even though the key method so
680838fd1498Szrj selected may later turn out to be an inline function. On
680938fd1498Szrj some systems (such as ARM Symbian OS) the key method cannot
681038fd1498Szrj be determined until the end of the translation unit. On such
681138fd1498Szrj systems, we leave CLASSTYPE_KEY_METHOD set to NULL, which
681238fd1498Szrj will cause the class to be added to KEYED_CLASSES. Then, in
681338fd1498Szrj finish_file we will determine the key method. */
681438fd1498Szrj if (targetm.cxx.key_method_may_be_inline ())
681538fd1498Szrj determine_key_method (t);
681638fd1498Szrj
681738fd1498Szrj /* If a polymorphic class has no key method, we may emit the vtable
681838fd1498Szrj in every translation unit where the class definition appears. If
681938fd1498Szrj we're devirtualizing, we can look into the vtable even if we
682038fd1498Szrj aren't emitting it. */
682138fd1498Szrj if (!CLASSTYPE_KEY_METHOD (t))
682238fd1498Szrj vec_safe_push (keyed_classes, t);
682338fd1498Szrj }
682438fd1498Szrj
682538fd1498Szrj /* Layout the class itself. */
682638fd1498Szrj layout_class_type (t, &virtuals);
682738fd1498Szrj /* COMPLETE_TYPE_P is now true. */
682838fd1498Szrj
682938fd1498Szrj set_class_bindings (t);
683038fd1498Szrj
683138fd1498Szrj /* With the layout complete, check for flexible array members and
683238fd1498Szrj zero-length arrays that might overlap other members in the final
683338fd1498Szrj layout. */
683438fd1498Szrj check_flexarrays (t);
683538fd1498Szrj
683638fd1498Szrj virtuals = modify_all_vtables (t, nreverse (virtuals));
683738fd1498Szrj
683838fd1498Szrj /* If necessary, create the primary vtable for this class. */
683938fd1498Szrj if (virtuals || TYPE_CONTAINS_VPTR_P (t))
684038fd1498Szrj {
684138fd1498Szrj /* We must enter these virtuals into the table. */
684238fd1498Szrj if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
684338fd1498Szrj build_primary_vtable (NULL_TREE, t);
684438fd1498Szrj else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
684538fd1498Szrj /* Here we know enough to change the type of our virtual
684638fd1498Szrj function table, but we will wait until later this function. */
684738fd1498Szrj build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
684838fd1498Szrj
684938fd1498Szrj /* If we're warning about ABI tags, check the types of the new
685038fd1498Szrj virtual functions. */
685138fd1498Szrj if (warn_abi_tag)
685238fd1498Szrj for (tree v = virtuals; v; v = TREE_CHAIN (v))
685338fd1498Szrj check_abi_tags (t, TREE_VALUE (v));
685438fd1498Szrj }
685538fd1498Szrj
685638fd1498Szrj if (TYPE_CONTAINS_VPTR_P (t))
685738fd1498Szrj {
685838fd1498Szrj int vindex;
685938fd1498Szrj tree fn;
686038fd1498Szrj
686138fd1498Szrj if (BINFO_VTABLE (TYPE_BINFO (t)))
686238fd1498Szrj gcc_assert (DECL_VIRTUAL_P (BINFO_VTABLE (TYPE_BINFO (t))));
686338fd1498Szrj if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
686438fd1498Szrj gcc_assert (BINFO_VIRTUALS (TYPE_BINFO (t)) == NULL_TREE);
686538fd1498Szrj
686638fd1498Szrj /* Add entries for virtual functions introduced by this class. */
686738fd1498Szrj BINFO_VIRTUALS (TYPE_BINFO (t))
686838fd1498Szrj = chainon (BINFO_VIRTUALS (TYPE_BINFO (t)), virtuals);
686938fd1498Szrj
687038fd1498Szrj /* Set DECL_VINDEX for all functions declared in this class. */
687138fd1498Szrj for (vindex = 0, fn = BINFO_VIRTUALS (TYPE_BINFO (t));
687238fd1498Szrj fn;
687338fd1498Szrj fn = TREE_CHAIN (fn),
687438fd1498Szrj vindex += (TARGET_VTABLE_USES_DESCRIPTORS
687538fd1498Szrj ? TARGET_VTABLE_USES_DESCRIPTORS : 1))
687638fd1498Szrj {
687738fd1498Szrj tree fndecl = BV_FN (fn);
687838fd1498Szrj
687938fd1498Szrj if (DECL_THUNK_P (fndecl))
688038fd1498Szrj /* A thunk. We should never be calling this entry directly
688138fd1498Szrj from this vtable -- we'd use the entry for the non
688238fd1498Szrj thunk base function. */
688338fd1498Szrj DECL_VINDEX (fndecl) = NULL_TREE;
688438fd1498Szrj else if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)
688538fd1498Szrj DECL_VINDEX (fndecl) = build_int_cst (NULL_TREE, vindex);
688638fd1498Szrj }
688738fd1498Szrj }
688838fd1498Szrj
688938fd1498Szrj finish_struct_bits (t);
689038fd1498Szrj
689138fd1498Szrj set_method_tm_attributes (t);
689238fd1498Szrj if (flag_openmp || flag_openmp_simd)
689338fd1498Szrj finish_omp_declare_simd_methods (t);
689438fd1498Szrj
689538fd1498Szrj /* Clear DECL_IN_AGGR_P for all member functions. Complete the rtl
689638fd1498Szrj for any static member objects of the type we're working on. */
689738fd1498Szrj for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
689838fd1498Szrj if (DECL_DECLARES_FUNCTION_P (x))
689938fd1498Szrj DECL_IN_AGGR_P (x) = false;
690038fd1498Szrj else if (VAR_P (x) && TREE_STATIC (x)
690138fd1498Szrj && TREE_TYPE (x) != error_mark_node
690238fd1498Szrj && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t))
690338fd1498Szrj SET_DECL_MODE (x, TYPE_MODE (t));
690438fd1498Szrj
690538fd1498Szrj /* Complain if one of the field types requires lower visibility. */
690638fd1498Szrj constrain_class_visibility (t);
690738fd1498Szrj
690838fd1498Szrj /* Make the rtl for any new vtables we have created, and unmark
690938fd1498Szrj the base types we marked. */
691038fd1498Szrj finish_vtbls (t);
691138fd1498Szrj
691238fd1498Szrj /* Build the VTT for T. */
691338fd1498Szrj build_vtt (t);
691438fd1498Szrj
691538fd1498Szrj if (warn_nonvdtor
691638fd1498Szrj && TYPE_POLYMORPHIC_P (t) && accessible_nvdtor_p (t)
691738fd1498Szrj && !CLASSTYPE_FINAL (t))
691838fd1498Szrj warning (OPT_Wnon_virtual_dtor,
691938fd1498Szrj "%q#T has virtual functions and accessible"
692038fd1498Szrj " non-virtual destructor", t);
692138fd1498Szrj
692238fd1498Szrj complete_vars (t);
692338fd1498Szrj
692438fd1498Szrj if (warn_overloaded_virtual)
692538fd1498Szrj warn_hidden (t);
692638fd1498Szrj
692738fd1498Szrj /* Class layout, assignment of virtual table slots, etc., is now
692838fd1498Szrj complete. Give the back end a chance to tweak the visibility of
692938fd1498Szrj the class or perform any other required target modifications. */
693038fd1498Szrj targetm.cxx.adjust_class_at_definition (t);
693138fd1498Szrj
693238fd1498Szrj maybe_suppress_debug_info (t);
693338fd1498Szrj
693438fd1498Szrj if (flag_vtable_verify)
693538fd1498Szrj vtv_save_class_info (t);
693638fd1498Szrj
693738fd1498Szrj dump_class_hierarchy (t);
693838fd1498Szrj
693938fd1498Szrj /* Finish debugging output for this type. */
694038fd1498Szrj rest_of_type_compilation (t, ! LOCAL_CLASS_P (t));
694138fd1498Szrj
694238fd1498Szrj if (TYPE_TRANSPARENT_AGGR (t))
694338fd1498Szrj {
694438fd1498Szrj tree field = first_field (t);
694538fd1498Szrj if (field == NULL_TREE || error_operand_p (field))
694638fd1498Szrj {
694738fd1498Szrj error ("type transparent %q#T does not have any fields", t);
694838fd1498Szrj TYPE_TRANSPARENT_AGGR (t) = 0;
694938fd1498Szrj }
695038fd1498Szrj else if (DECL_ARTIFICIAL (field))
695138fd1498Szrj {
695238fd1498Szrj if (DECL_FIELD_IS_BASE (field))
695338fd1498Szrj error ("type transparent class %qT has base classes", t);
695438fd1498Szrj else
695538fd1498Szrj {
695638fd1498Szrj gcc_checking_assert (DECL_VIRTUAL_P (field));
695738fd1498Szrj error ("type transparent class %qT has virtual functions", t);
695838fd1498Szrj }
695938fd1498Szrj TYPE_TRANSPARENT_AGGR (t) = 0;
696038fd1498Szrj }
696138fd1498Szrj else if (TYPE_MODE (t) != DECL_MODE (field))
696238fd1498Szrj {
696338fd1498Szrj error ("type transparent %q#T cannot be made transparent because "
696438fd1498Szrj "the type of the first field has a different ABI from the "
696538fd1498Szrj "class overall", t);
696638fd1498Szrj TYPE_TRANSPARENT_AGGR (t) = 0;
696738fd1498Szrj }
696838fd1498Szrj }
696938fd1498Szrj }
697038fd1498Szrj
697138fd1498Szrj /* When T was built up, the member declarations were added in reverse
697238fd1498Szrj order. Rearrange them to declaration order. */
697338fd1498Szrj
697438fd1498Szrj void
unreverse_member_declarations(tree t)697538fd1498Szrj unreverse_member_declarations (tree t)
697638fd1498Szrj {
697738fd1498Szrj tree next;
697838fd1498Szrj tree prev;
697938fd1498Szrj tree x;
698038fd1498Szrj
698138fd1498Szrj /* The following lists are all in reverse order. Put them in
698238fd1498Szrj declaration order now. */
698338fd1498Szrj CLASSTYPE_DECL_LIST (t) = nreverse (CLASSTYPE_DECL_LIST (t));
698438fd1498Szrj
698538fd1498Szrj /* For the TYPE_FIELDS, only the non TYPE_DECLs are in reverse
698638fd1498Szrj order, so we can't just use nreverse. Due to stat_hack
698738fd1498Szrj chicanery in finish_member_declaration. */
698838fd1498Szrj prev = NULL_TREE;
698938fd1498Szrj for (x = TYPE_FIELDS (t);
699038fd1498Szrj x && TREE_CODE (x) != TYPE_DECL;
699138fd1498Szrj x = next)
699238fd1498Szrj {
699338fd1498Szrj next = DECL_CHAIN (x);
699438fd1498Szrj DECL_CHAIN (x) = prev;
699538fd1498Szrj prev = x;
699638fd1498Szrj }
699738fd1498Szrj
699838fd1498Szrj if (prev)
699938fd1498Szrj {
700038fd1498Szrj DECL_CHAIN (TYPE_FIELDS (t)) = x;
700138fd1498Szrj TYPE_FIELDS (t) = prev;
700238fd1498Szrj }
700338fd1498Szrj }
700438fd1498Szrj
700538fd1498Szrj tree
finish_struct(tree t,tree attributes)700638fd1498Szrj finish_struct (tree t, tree attributes)
700738fd1498Szrj {
700838fd1498Szrj location_t saved_loc = input_location;
700938fd1498Szrj
701038fd1498Szrj /* Now that we've got all the field declarations, reverse everything
701138fd1498Szrj as necessary. */
701238fd1498Szrj unreverse_member_declarations (t);
701338fd1498Szrj
701438fd1498Szrj cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
701538fd1498Szrj fixup_attribute_variants (t);
701638fd1498Szrj
701738fd1498Szrj /* Nadger the current location so that diagnostics point to the start of
701838fd1498Szrj the struct, not the end. */
701938fd1498Szrj input_location = DECL_SOURCE_LOCATION (TYPE_NAME (t));
702038fd1498Szrj
702138fd1498Szrj if (processing_template_decl)
702238fd1498Szrj {
702338fd1498Szrj tree x;
702438fd1498Szrj
702538fd1498Szrj /* We need to add the target functions of USING_DECLS, so that
702638fd1498Szrj they can be found when the using declaration is not
702738fd1498Szrj instantiated yet. */
702838fd1498Szrj for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
702938fd1498Szrj if (TREE_CODE (x) == USING_DECL)
703038fd1498Szrj {
703138fd1498Szrj tree fn = strip_using_decl (x);
703238fd1498Szrj if (OVL_P (fn))
703338fd1498Szrj for (lkp_iterator iter (fn); iter; ++iter)
703438fd1498Szrj add_method (t, *iter, true);
703538fd1498Szrj }
703638fd1498Szrj else if (DECL_DECLARES_FUNCTION_P (x))
703738fd1498Szrj DECL_IN_AGGR_P (x) = false;
703838fd1498Szrj
703958e805e6Szrj /* Also add a USING_DECL for operator=. We know there'll be (at
704058e805e6Szrj least) one, but we don't know the signature(s). We want name
704158e805e6Szrj lookup not to fail or recurse into bases. This isn't added
704258e805e6Szrj to the template decl list so we drop this at instantiation
704358e805e6Szrj time. */
704458e805e6Szrj tree ass_op = build_lang_decl (USING_DECL, assign_op_identifier,
704558e805e6Szrj NULL_TREE);
704658e805e6Szrj DECL_CONTEXT (ass_op) = t;
704758e805e6Szrj USING_DECL_SCOPE (ass_op) = t;
704858e805e6Szrj DECL_DEPENDENT_P (ass_op) = true;
704958e805e6Szrj DECL_ARTIFICIAL (ass_op) = true;
705058e805e6Szrj DECL_CHAIN (ass_op) = TYPE_FIELDS (t);
705158e805e6Szrj TYPE_FIELDS (t) = ass_op;
705258e805e6Szrj
705338fd1498Szrj TYPE_SIZE (t) = bitsize_zero_node;
705438fd1498Szrj TYPE_SIZE_UNIT (t) = size_zero_node;
705538fd1498Szrj /* COMPLETE_TYPE_P is now true. */
705638fd1498Szrj
705738fd1498Szrj set_class_bindings (t);
705838fd1498Szrj
705938fd1498Szrj /* We need to emit an error message if this type was used as a parameter
706038fd1498Szrj and it is an abstract type, even if it is a template. We construct
706138fd1498Szrj a simple CLASSTYPE_PURE_VIRTUALS list without taking bases into
706238fd1498Szrj account and we call complete_vars with this type, which will check
706338fd1498Szrj the PARM_DECLS. Note that while the type is being defined,
706438fd1498Szrj CLASSTYPE_PURE_VIRTUALS contains the list of the inline friends
706538fd1498Szrj (see CLASSTYPE_INLINE_FRIENDS) so we need to clear it. */
706638fd1498Szrj CLASSTYPE_PURE_VIRTUALS (t) = NULL;
706738fd1498Szrj for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
706838fd1498Szrj if (TREE_CODE (x) == FUNCTION_DECL && DECL_PURE_VIRTUAL_P (x))
706938fd1498Szrj vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
707038fd1498Szrj complete_vars (t);
707138fd1498Szrj
707238fd1498Szrj /* Remember current #pragma pack value. */
707338fd1498Szrj TYPE_PRECISION (t) = maximum_field_alignment;
707438fd1498Szrj
707538fd1498Szrj /* Fix up any variants we've already built. */
707638fd1498Szrj for (x = TYPE_NEXT_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
707738fd1498Szrj {
707838fd1498Szrj TYPE_SIZE (x) = TYPE_SIZE (t);
707938fd1498Szrj TYPE_SIZE_UNIT (x) = TYPE_SIZE_UNIT (t);
708038fd1498Szrj TYPE_FIELDS (x) = TYPE_FIELDS (t);
708138fd1498Szrj }
708238fd1498Szrj }
708338fd1498Szrj else
708438fd1498Szrj finish_struct_1 (t);
708538fd1498Szrj /* COMPLETE_TYPE_P is now true. */
708638fd1498Szrj
708738fd1498Szrj maybe_warn_about_overly_private_class (t);
708838fd1498Szrj
708938fd1498Szrj if (is_std_init_list (t))
709038fd1498Szrj {
709138fd1498Szrj /* People keep complaining that the compiler crashes on an invalid
709238fd1498Szrj definition of initializer_list, so I guess we should explicitly
709338fd1498Szrj reject it. What the compiler internals care about is that it's a
709438fd1498Szrj template and has a pointer field followed by size_type field. */
709538fd1498Szrj bool ok = false;
709638fd1498Szrj if (processing_template_decl)
709738fd1498Szrj {
709838fd1498Szrj tree f = next_initializable_field (TYPE_FIELDS (t));
709938fd1498Szrj if (f && TREE_CODE (TREE_TYPE (f)) == POINTER_TYPE)
710038fd1498Szrj {
710138fd1498Szrj f = next_initializable_field (DECL_CHAIN (f));
710238fd1498Szrj if (f && same_type_p (TREE_TYPE (f), size_type_node))
710338fd1498Szrj ok = true;
710438fd1498Szrj }
710538fd1498Szrj }
710638fd1498Szrj if (!ok)
710738fd1498Szrj fatal_error (input_location, "definition of %qD does not match "
710838fd1498Szrj "%<#include <initializer_list>%>", TYPE_NAME (t));
710938fd1498Szrj }
711038fd1498Szrj
711138fd1498Szrj input_location = saved_loc;
711238fd1498Szrj
711338fd1498Szrj TYPE_BEING_DEFINED (t) = 0;
711438fd1498Szrj
711538fd1498Szrj if (current_class_type)
711638fd1498Szrj popclass ();
711738fd1498Szrj else
711838fd1498Szrj error ("trying to finish struct, but kicked out due to previous parse errors");
711938fd1498Szrj
712038fd1498Szrj if (processing_template_decl && at_function_scope_p ()
712138fd1498Szrj /* Lambdas are defined by the LAMBDA_EXPR. */
712238fd1498Szrj && !LAMBDA_TYPE_P (t))
712338fd1498Szrj add_stmt (build_min (TAG_DEFN, t));
712438fd1498Szrj
712538fd1498Szrj return t;
712638fd1498Szrj }
712738fd1498Szrj
712838fd1498Szrj /* Hash table to avoid endless recursion when handling references. */
712938fd1498Szrj static hash_table<nofree_ptr_hash<tree_node> > *fixed_type_or_null_ref_ht;
713038fd1498Szrj
713138fd1498Szrj /* Return the dynamic type of INSTANCE, if known.
713238fd1498Szrj Used to determine whether the virtual function table is needed
713338fd1498Szrj or not.
713438fd1498Szrj
713538fd1498Szrj *NONNULL is set iff INSTANCE can be known to be nonnull, regardless
713638fd1498Szrj of our knowledge of its type. *NONNULL should be initialized
713738fd1498Szrj before this function is called. */
713838fd1498Szrj
713938fd1498Szrj static tree
fixed_type_or_null(tree instance,int * nonnull,int * cdtorp)714038fd1498Szrj fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
714138fd1498Szrj {
714238fd1498Szrj #define RECUR(T) fixed_type_or_null((T), nonnull, cdtorp)
714338fd1498Szrj
714438fd1498Szrj switch (TREE_CODE (instance))
714538fd1498Szrj {
714638fd1498Szrj case INDIRECT_REF:
714738fd1498Szrj if (POINTER_TYPE_P (TREE_TYPE (instance)))
714838fd1498Szrj return NULL_TREE;
714938fd1498Szrj else
715038fd1498Szrj return RECUR (TREE_OPERAND (instance, 0));
715138fd1498Szrj
715238fd1498Szrj case CALL_EXPR:
715338fd1498Szrj /* This is a call to a constructor, hence it's never zero. */
715438fd1498Szrj if (CALL_EXPR_FN (instance)
715538fd1498Szrj && TREE_HAS_CONSTRUCTOR (instance))
715638fd1498Szrj {
715738fd1498Szrj if (nonnull)
715838fd1498Szrj *nonnull = 1;
715938fd1498Szrj return TREE_TYPE (instance);
716038fd1498Szrj }
716138fd1498Szrj return NULL_TREE;
716238fd1498Szrj
716338fd1498Szrj case SAVE_EXPR:
716438fd1498Szrj /* This is a call to a constructor, hence it's never zero. */
716538fd1498Szrj if (TREE_HAS_CONSTRUCTOR (instance))
716638fd1498Szrj {
716738fd1498Szrj if (nonnull)
716838fd1498Szrj *nonnull = 1;
716938fd1498Szrj return TREE_TYPE (instance);
717038fd1498Szrj }
717138fd1498Szrj return RECUR (TREE_OPERAND (instance, 0));
717238fd1498Szrj
717338fd1498Szrj case POINTER_PLUS_EXPR:
717438fd1498Szrj case PLUS_EXPR:
717538fd1498Szrj case MINUS_EXPR:
717638fd1498Szrj if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
717738fd1498Szrj return RECUR (TREE_OPERAND (instance, 0));
717838fd1498Szrj if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
717938fd1498Szrj /* Propagate nonnull. */
718038fd1498Szrj return RECUR (TREE_OPERAND (instance, 0));
718138fd1498Szrj
718238fd1498Szrj return NULL_TREE;
718338fd1498Szrj
718438fd1498Szrj CASE_CONVERT:
718538fd1498Szrj return RECUR (TREE_OPERAND (instance, 0));
718638fd1498Szrj
718738fd1498Szrj case ADDR_EXPR:
718838fd1498Szrj instance = TREE_OPERAND (instance, 0);
718938fd1498Szrj if (nonnull)
719038fd1498Szrj {
719138fd1498Szrj /* Just because we see an ADDR_EXPR doesn't mean we're dealing
719238fd1498Szrj with a real object -- given &p->f, p can still be null. */
719338fd1498Szrj tree t = get_base_address (instance);
719438fd1498Szrj /* ??? Probably should check DECL_WEAK here. */
719538fd1498Szrj if (t && DECL_P (t))
719638fd1498Szrj *nonnull = 1;
719738fd1498Szrj }
719838fd1498Szrj return RECUR (instance);
719938fd1498Szrj
720038fd1498Szrj case COMPONENT_REF:
720138fd1498Szrj /* If this component is really a base class reference, then the field
720238fd1498Szrj itself isn't definitive. */
720338fd1498Szrj if (DECL_FIELD_IS_BASE (TREE_OPERAND (instance, 1)))
720438fd1498Szrj return RECUR (TREE_OPERAND (instance, 0));
720538fd1498Szrj return RECUR (TREE_OPERAND (instance, 1));
720638fd1498Szrj
720738fd1498Szrj case VAR_DECL:
720838fd1498Szrj case FIELD_DECL:
720938fd1498Szrj if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE
721038fd1498Szrj && MAYBE_CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (instance))))
721138fd1498Szrj {
721238fd1498Szrj if (nonnull)
721338fd1498Szrj *nonnull = 1;
721438fd1498Szrj return TREE_TYPE (TREE_TYPE (instance));
721538fd1498Szrj }
721638fd1498Szrj /* fall through. */
721738fd1498Szrj case TARGET_EXPR:
721838fd1498Szrj case PARM_DECL:
721938fd1498Szrj case RESULT_DECL:
722038fd1498Szrj if (MAYBE_CLASS_TYPE_P (TREE_TYPE (instance)))
722138fd1498Szrj {
722238fd1498Szrj if (nonnull)
722338fd1498Szrj *nonnull = 1;
722438fd1498Szrj return TREE_TYPE (instance);
722538fd1498Szrj }
722638fd1498Szrj else if (instance == current_class_ptr)
722738fd1498Szrj {
722838fd1498Szrj if (nonnull)
722938fd1498Szrj *nonnull = 1;
723038fd1498Szrj
723138fd1498Szrj /* if we're in a ctor or dtor, we know our type. If
723238fd1498Szrj current_class_ptr is set but we aren't in a function, we're in
723338fd1498Szrj an NSDMI (and therefore a constructor). */
723438fd1498Szrj if (current_scope () != current_function_decl
723538fd1498Szrj || (DECL_LANG_SPECIFIC (current_function_decl)
723638fd1498Szrj && (DECL_CONSTRUCTOR_P (current_function_decl)
723738fd1498Szrj || DECL_DESTRUCTOR_P (current_function_decl))))
723838fd1498Szrj {
723938fd1498Szrj if (cdtorp)
724038fd1498Szrj *cdtorp = 1;
724138fd1498Szrj return TREE_TYPE (TREE_TYPE (instance));
724238fd1498Szrj }
724338fd1498Szrj }
724438fd1498Szrj else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
724538fd1498Szrj {
724638fd1498Szrj /* We only need one hash table because it is always left empty. */
724738fd1498Szrj if (!fixed_type_or_null_ref_ht)
724838fd1498Szrj fixed_type_or_null_ref_ht
724938fd1498Szrj = new hash_table<nofree_ptr_hash<tree_node> > (37);
725038fd1498Szrj
725138fd1498Szrj /* Reference variables should be references to objects. */
725238fd1498Szrj if (nonnull)
725338fd1498Szrj *nonnull = 1;
725438fd1498Szrj
725538fd1498Szrj /* Enter the INSTANCE in a table to prevent recursion; a
725638fd1498Szrj variable's initializer may refer to the variable
725738fd1498Szrj itself. */
725838fd1498Szrj if (VAR_P (instance)
725938fd1498Szrj && DECL_INITIAL (instance)
726038fd1498Szrj && !type_dependent_expression_p_push (DECL_INITIAL (instance))
726138fd1498Szrj && !fixed_type_or_null_ref_ht->find (instance))
726238fd1498Szrj {
726338fd1498Szrj tree type;
726438fd1498Szrj tree_node **slot;
726538fd1498Szrj
726638fd1498Szrj slot = fixed_type_or_null_ref_ht->find_slot (instance, INSERT);
726738fd1498Szrj *slot = instance;
726838fd1498Szrj type = RECUR (DECL_INITIAL (instance));
726938fd1498Szrj fixed_type_or_null_ref_ht->remove_elt (instance);
727038fd1498Szrj
727138fd1498Szrj return type;
727238fd1498Szrj }
727338fd1498Szrj }
727438fd1498Szrj return NULL_TREE;
727538fd1498Szrj
727638fd1498Szrj default:
727738fd1498Szrj return NULL_TREE;
727838fd1498Szrj }
727938fd1498Szrj #undef RECUR
728038fd1498Szrj }
728138fd1498Szrj
728238fd1498Szrj /* Return nonzero if the dynamic type of INSTANCE is known, and
728338fd1498Szrj equivalent to the static type. We also handle the case where
728438fd1498Szrj INSTANCE is really a pointer. Return negative if this is a
728538fd1498Szrj ctor/dtor. There the dynamic type is known, but this might not be
728638fd1498Szrj the most derived base of the original object, and hence virtual
728738fd1498Szrj bases may not be laid out according to this type.
728838fd1498Szrj
728938fd1498Szrj Used to determine whether the virtual function table is needed
729038fd1498Szrj or not.
729138fd1498Szrj
729238fd1498Szrj *NONNULL is set iff INSTANCE can be known to be nonnull, regardless
729338fd1498Szrj of our knowledge of its type. *NONNULL should be initialized
729438fd1498Szrj before this function is called. */
729538fd1498Szrj
729638fd1498Szrj int
resolves_to_fixed_type_p(tree instance,int * nonnull)729738fd1498Szrj resolves_to_fixed_type_p (tree instance, int* nonnull)
729838fd1498Szrj {
729938fd1498Szrj tree t = TREE_TYPE (instance);
730038fd1498Szrj int cdtorp = 0;
730138fd1498Szrj tree fixed;
730238fd1498Szrj
730338fd1498Szrj /* processing_template_decl can be false in a template if we're in
730438fd1498Szrj instantiate_non_dependent_expr, but we still want to suppress
730538fd1498Szrj this check. */
730638fd1498Szrj if (in_template_function ())
730738fd1498Szrj {
730838fd1498Szrj /* In a template we only care about the type of the result. */
730938fd1498Szrj if (nonnull)
731038fd1498Szrj *nonnull = true;
731138fd1498Szrj return true;
731238fd1498Szrj }
731338fd1498Szrj
731438fd1498Szrj fixed = fixed_type_or_null (instance, nonnull, &cdtorp);
731538fd1498Szrj if (fixed == NULL_TREE)
731638fd1498Szrj return 0;
731738fd1498Szrj if (POINTER_TYPE_P (t))
731838fd1498Szrj t = TREE_TYPE (t);
731938fd1498Szrj if (!same_type_ignoring_top_level_qualifiers_p (t, fixed))
732038fd1498Szrj return 0;
732138fd1498Szrj return cdtorp ? -1 : 1;
732238fd1498Szrj }
732338fd1498Szrj
732438fd1498Szrj
732538fd1498Szrj void
init_class_processing(void)732638fd1498Szrj init_class_processing (void)
732738fd1498Szrj {
732838fd1498Szrj current_class_depth = 0;
732938fd1498Szrj current_class_stack_size = 10;
733038fd1498Szrj current_class_stack
733138fd1498Szrj = XNEWVEC (struct class_stack_node, current_class_stack_size);
733238fd1498Szrj vec_alloc (local_classes, 8);
733338fd1498Szrj sizeof_biggest_empty_class = size_zero_node;
733438fd1498Szrj
733538fd1498Szrj ridpointers[(int) RID_PUBLIC] = access_public_node;
733638fd1498Szrj ridpointers[(int) RID_PRIVATE] = access_private_node;
733738fd1498Szrj ridpointers[(int) RID_PROTECTED] = access_protected_node;
733838fd1498Szrj }
733938fd1498Szrj
734038fd1498Szrj /* Restore the cached PREVIOUS_CLASS_LEVEL. */
734138fd1498Szrj
734238fd1498Szrj static void
restore_class_cache(void)734338fd1498Szrj restore_class_cache (void)
734438fd1498Szrj {
734538fd1498Szrj tree type;
734638fd1498Szrj
734738fd1498Szrj /* We are re-entering the same class we just left, so we don't
734838fd1498Szrj have to search the whole inheritance matrix to find all the
734938fd1498Szrj decls to bind again. Instead, we install the cached
735038fd1498Szrj class_shadowed list and walk through it binding names. */
735138fd1498Szrj push_binding_level (previous_class_level);
735238fd1498Szrj class_binding_level = previous_class_level;
735338fd1498Szrj /* Restore IDENTIFIER_TYPE_VALUE. */
735438fd1498Szrj for (type = class_binding_level->type_shadowed;
735538fd1498Szrj type;
735638fd1498Szrj type = TREE_CHAIN (type))
735738fd1498Szrj SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (type), TREE_TYPE (type));
735838fd1498Szrj }
735938fd1498Szrj
736038fd1498Szrj /* Set global variables CURRENT_CLASS_NAME and CURRENT_CLASS_TYPE as
736138fd1498Szrj appropriate for TYPE.
736238fd1498Szrj
736338fd1498Szrj So that we may avoid calls to lookup_name, we cache the _TYPE
736438fd1498Szrj nodes of local TYPE_DECLs in the TREE_TYPE field of the name.
736538fd1498Szrj
736638fd1498Szrj For multiple inheritance, we perform a two-pass depth-first search
736738fd1498Szrj of the type lattice. */
736838fd1498Szrj
736938fd1498Szrj void
pushclass(tree type)737038fd1498Szrj pushclass (tree type)
737138fd1498Szrj {
737238fd1498Szrj class_stack_node_t csn;
737338fd1498Szrj
737438fd1498Szrj type = TYPE_MAIN_VARIANT (type);
737538fd1498Szrj
737638fd1498Szrj /* Make sure there is enough room for the new entry on the stack. */
737738fd1498Szrj if (current_class_depth + 1 >= current_class_stack_size)
737838fd1498Szrj {
737938fd1498Szrj current_class_stack_size *= 2;
738038fd1498Szrj current_class_stack
738138fd1498Szrj = XRESIZEVEC (struct class_stack_node, current_class_stack,
738238fd1498Szrj current_class_stack_size);
738338fd1498Szrj }
738438fd1498Szrj
738538fd1498Szrj /* Insert a new entry on the class stack. */
738638fd1498Szrj csn = current_class_stack + current_class_depth;
738738fd1498Szrj csn->name = current_class_name;
738838fd1498Szrj csn->type = current_class_type;
738938fd1498Szrj csn->access = current_access_specifier;
739038fd1498Szrj csn->names_used = 0;
739138fd1498Szrj csn->hidden = 0;
739238fd1498Szrj current_class_depth++;
739338fd1498Szrj
739438fd1498Szrj /* Now set up the new type. */
739538fd1498Szrj current_class_name = TYPE_NAME (type);
739638fd1498Szrj if (TREE_CODE (current_class_name) == TYPE_DECL)
739738fd1498Szrj current_class_name = DECL_NAME (current_class_name);
739838fd1498Szrj current_class_type = type;
739938fd1498Szrj
740038fd1498Szrj /* By default, things in classes are private, while things in
740138fd1498Szrj structures or unions are public. */
740238fd1498Szrj current_access_specifier = (CLASSTYPE_DECLARED_CLASS (type)
740338fd1498Szrj ? access_private_node
740438fd1498Szrj : access_public_node);
740538fd1498Szrj
740638fd1498Szrj if (previous_class_level
740738fd1498Szrj && type != previous_class_level->this_entity
740838fd1498Szrj && current_class_depth == 1)
740938fd1498Szrj {
741038fd1498Szrj /* Forcibly remove any old class remnants. */
741138fd1498Szrj invalidate_class_lookup_cache ();
741238fd1498Szrj }
741338fd1498Szrj
741438fd1498Szrj if (!previous_class_level
741538fd1498Szrj || type != previous_class_level->this_entity
741638fd1498Szrj || current_class_depth > 1)
741738fd1498Szrj pushlevel_class ();
741838fd1498Szrj else
741938fd1498Szrj restore_class_cache ();
742038fd1498Szrj }
742138fd1498Szrj
742238fd1498Szrj /* When we exit a toplevel class scope, we save its binding level so
742338fd1498Szrj that we can restore it quickly. Here, we've entered some other
742438fd1498Szrj class, so we must invalidate our cache. */
742538fd1498Szrj
742638fd1498Szrj void
invalidate_class_lookup_cache(void)742738fd1498Szrj invalidate_class_lookup_cache (void)
742838fd1498Szrj {
742938fd1498Szrj previous_class_level = NULL;
743038fd1498Szrj }
743138fd1498Szrj
743238fd1498Szrj /* Get out of the current class scope. If we were in a class scope
743338fd1498Szrj previously, that is the one popped to. */
743438fd1498Szrj
743538fd1498Szrj void
popclass(void)743638fd1498Szrj popclass (void)
743738fd1498Szrj {
743838fd1498Szrj poplevel_class ();
743938fd1498Szrj
744038fd1498Szrj current_class_depth--;
744138fd1498Szrj current_class_name = current_class_stack[current_class_depth].name;
744238fd1498Szrj current_class_type = current_class_stack[current_class_depth].type;
744338fd1498Szrj current_access_specifier = current_class_stack[current_class_depth].access;
744438fd1498Szrj if (current_class_stack[current_class_depth].names_used)
744538fd1498Szrj splay_tree_delete (current_class_stack[current_class_depth].names_used);
744638fd1498Szrj }
744738fd1498Szrj
744838fd1498Szrj /* Mark the top of the class stack as hidden. */
744938fd1498Szrj
745038fd1498Szrj void
push_class_stack(void)745138fd1498Szrj push_class_stack (void)
745238fd1498Szrj {
745338fd1498Szrj if (current_class_depth)
745438fd1498Szrj ++current_class_stack[current_class_depth - 1].hidden;
745538fd1498Szrj }
745638fd1498Szrj
745738fd1498Szrj /* Mark the top of the class stack as un-hidden. */
745838fd1498Szrj
745938fd1498Szrj void
pop_class_stack(void)746038fd1498Szrj pop_class_stack (void)
746138fd1498Szrj {
746238fd1498Szrj if (current_class_depth)
746338fd1498Szrj --current_class_stack[current_class_depth - 1].hidden;
746438fd1498Szrj }
746538fd1498Szrj
746658e805e6Szrj /* If the class type currently being defined is either T or
746758e805e6Szrj a nested type of T, returns the type from the current_class_stack,
746838fd1498Szrj which might be equivalent to but not equal to T in case of
746938fd1498Szrj constrained partial specializations. */
747038fd1498Szrj
747138fd1498Szrj tree
currently_open_class(tree t)747238fd1498Szrj currently_open_class (tree t)
747338fd1498Szrj {
747438fd1498Szrj int i;
747538fd1498Szrj
747638fd1498Szrj if (!CLASS_TYPE_P (t))
747738fd1498Szrj return NULL_TREE;
747838fd1498Szrj
747938fd1498Szrj t = TYPE_MAIN_VARIANT (t);
748038fd1498Szrj
748138fd1498Szrj /* We start looking from 1 because entry 0 is from global scope,
748238fd1498Szrj and has no type. */
748338fd1498Szrj for (i = current_class_depth; i > 0; --i)
748438fd1498Szrj {
748538fd1498Szrj tree c;
748638fd1498Szrj if (i == current_class_depth)
748738fd1498Szrj c = current_class_type;
748838fd1498Szrj else
748938fd1498Szrj {
749038fd1498Szrj if (current_class_stack[i].hidden)
749138fd1498Szrj break;
749238fd1498Szrj c = current_class_stack[i].type;
749338fd1498Szrj }
749438fd1498Szrj if (!c)
749538fd1498Szrj continue;
749638fd1498Szrj if (same_type_p (c, t))
749738fd1498Szrj return c;
749838fd1498Szrj }
749938fd1498Szrj return NULL_TREE;
750038fd1498Szrj }
750138fd1498Szrj
750238fd1498Szrj /* If either current_class_type or one of its enclosing classes are derived
750338fd1498Szrj from T, return the appropriate type. Used to determine how we found
750438fd1498Szrj something via unqualified lookup. */
750538fd1498Szrj
750638fd1498Szrj tree
currently_open_derived_class(tree t)750738fd1498Szrj currently_open_derived_class (tree t)
750838fd1498Szrj {
750938fd1498Szrj int i;
751038fd1498Szrj
751138fd1498Szrj /* The bases of a dependent type are unknown. */
751238fd1498Szrj if (dependent_type_p (t))
751338fd1498Szrj return NULL_TREE;
751438fd1498Szrj
751538fd1498Szrj if (!current_class_type)
751638fd1498Szrj return NULL_TREE;
751738fd1498Szrj
751838fd1498Szrj if (DERIVED_FROM_P (t, current_class_type))
751938fd1498Szrj return current_class_type;
752038fd1498Szrj
752138fd1498Szrj for (i = current_class_depth - 1; i > 0; --i)
752238fd1498Szrj {
752338fd1498Szrj if (current_class_stack[i].hidden)
752438fd1498Szrj break;
752538fd1498Szrj if (DERIVED_FROM_P (t, current_class_stack[i].type))
752638fd1498Szrj return current_class_stack[i].type;
752738fd1498Szrj }
752838fd1498Szrj
752938fd1498Szrj return NULL_TREE;
753038fd1498Szrj }
753138fd1498Szrj
753238fd1498Szrj /* Return the outermost enclosing class type that is still open, or
753338fd1498Szrj NULL_TREE. */
753438fd1498Szrj
753538fd1498Szrj tree
outermost_open_class(void)753638fd1498Szrj outermost_open_class (void)
753738fd1498Szrj {
753838fd1498Szrj if (!current_class_type)
753938fd1498Szrj return NULL_TREE;
754038fd1498Szrj tree r = NULL_TREE;
754138fd1498Szrj if (TYPE_BEING_DEFINED (current_class_type))
754238fd1498Szrj r = current_class_type;
754338fd1498Szrj for (int i = current_class_depth - 1; i > 0; --i)
754438fd1498Szrj {
754538fd1498Szrj if (current_class_stack[i].hidden)
754638fd1498Szrj break;
754738fd1498Szrj tree t = current_class_stack[i].type;
754838fd1498Szrj if (!TYPE_BEING_DEFINED (t))
754938fd1498Szrj break;
755038fd1498Szrj r = t;
755138fd1498Szrj }
755238fd1498Szrj return r;
755338fd1498Szrj }
755438fd1498Szrj
755538fd1498Szrj /* Returns the innermost class type which is not a lambda closure type. */
755638fd1498Szrj
755738fd1498Szrj tree
current_nonlambda_class_type(void)755838fd1498Szrj current_nonlambda_class_type (void)
755938fd1498Szrj {
756038fd1498Szrj tree type = current_class_type;
756138fd1498Szrj while (type && LAMBDA_TYPE_P (type))
756238fd1498Szrj type = decl_type_context (TYPE_NAME (type));
756338fd1498Szrj return type;
756438fd1498Szrj }
756538fd1498Szrj
756638fd1498Szrj /* When entering a class scope, all enclosing class scopes' names with
756738fd1498Szrj static meaning (static variables, static functions, types and
756838fd1498Szrj enumerators) have to be visible. This recursive function calls
756938fd1498Szrj pushclass for all enclosing class contexts until global or a local
757038fd1498Szrj scope is reached. TYPE is the enclosed class. */
757138fd1498Szrj
757238fd1498Szrj void
push_nested_class(tree type)757338fd1498Szrj push_nested_class (tree type)
757438fd1498Szrj {
757538fd1498Szrj /* A namespace might be passed in error cases, like A::B:C. */
757638fd1498Szrj if (type == NULL_TREE
757738fd1498Szrj || !CLASS_TYPE_P (type))
757838fd1498Szrj return;
757938fd1498Szrj
758038fd1498Szrj push_nested_class (DECL_CONTEXT (TYPE_MAIN_DECL (type)));
758138fd1498Szrj
758238fd1498Szrj pushclass (type);
758338fd1498Szrj }
758438fd1498Szrj
758538fd1498Szrj /* Undoes a push_nested_class call. */
758638fd1498Szrj
758738fd1498Szrj void
pop_nested_class(void)758838fd1498Szrj pop_nested_class (void)
758938fd1498Szrj {
759038fd1498Szrj tree context = DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type));
759138fd1498Szrj
759238fd1498Szrj popclass ();
759338fd1498Szrj if (context && CLASS_TYPE_P (context))
759438fd1498Szrj pop_nested_class ();
759538fd1498Szrj }
759638fd1498Szrj
759738fd1498Szrj /* Returns the number of extern "LANG" blocks we are nested within. */
759838fd1498Szrj
759938fd1498Szrj int
current_lang_depth(void)760038fd1498Szrj current_lang_depth (void)
760138fd1498Szrj {
760238fd1498Szrj return vec_safe_length (current_lang_base);
760338fd1498Szrj }
760438fd1498Szrj
760538fd1498Szrj /* Set global variables CURRENT_LANG_NAME to appropriate value
760638fd1498Szrj so that behavior of name-mangling machinery is correct. */
760738fd1498Szrj
760838fd1498Szrj void
push_lang_context(tree name)760938fd1498Szrj push_lang_context (tree name)
761038fd1498Szrj {
761138fd1498Szrj vec_safe_push (current_lang_base, current_lang_name);
761238fd1498Szrj
761338fd1498Szrj if (name == lang_name_cplusplus)
761438fd1498Szrj current_lang_name = name;
761538fd1498Szrj else if (name == lang_name_c)
761638fd1498Szrj current_lang_name = name;
761738fd1498Szrj else
761838fd1498Szrj error ("language string %<\"%E\"%> not recognized", name);
761938fd1498Szrj }
762038fd1498Szrj
762138fd1498Szrj /* Get out of the current language scope. */
762238fd1498Szrj
762338fd1498Szrj void
pop_lang_context(void)762438fd1498Szrj pop_lang_context (void)
762538fd1498Szrj {
762638fd1498Szrj current_lang_name = current_lang_base->pop ();
762738fd1498Szrj }
762838fd1498Szrj
762938fd1498Szrj /* Type instantiation routines. */
763038fd1498Szrj
763138fd1498Szrj /* Given an OVERLOAD and a TARGET_TYPE, return the function that
763238fd1498Szrj matches the TARGET_TYPE. If there is no satisfactory match, return
763338fd1498Szrj error_mark_node, and issue an error & warning messages under
763438fd1498Szrj control of FLAGS. Permit pointers to member function if FLAGS
763538fd1498Szrj permits. If TEMPLATE_ONLY, the name of the overloaded function was
763638fd1498Szrj a template-id, and EXPLICIT_TARGS are the explicitly provided
763738fd1498Szrj template arguments.
763838fd1498Szrj
763938fd1498Szrj If OVERLOAD is for one or more member functions, then ACCESS_PATH
764038fd1498Szrj is the base path used to reference those member functions. If
764138fd1498Szrj the address is resolved to a member function, access checks will be
764238fd1498Szrj performed and errors issued if appropriate. */
764338fd1498Szrj
764438fd1498Szrj static tree
resolve_address_of_overloaded_function(tree target_type,tree overload,tsubst_flags_t complain,bool template_only,tree explicit_targs,tree access_path)764538fd1498Szrj resolve_address_of_overloaded_function (tree target_type,
764638fd1498Szrj tree overload,
764738fd1498Szrj tsubst_flags_t complain,
764838fd1498Szrj bool template_only,
764938fd1498Szrj tree explicit_targs,
765038fd1498Szrj tree access_path)
765138fd1498Szrj {
765238fd1498Szrj /* Here's what the standard says:
765338fd1498Szrj
765438fd1498Szrj [over.over]
765538fd1498Szrj
765638fd1498Szrj If the name is a function template, template argument deduction
765738fd1498Szrj is done, and if the argument deduction succeeds, the deduced
765838fd1498Szrj arguments are used to generate a single template function, which
765938fd1498Szrj is added to the set of overloaded functions considered.
766038fd1498Szrj
766138fd1498Szrj Non-member functions and static member functions match targets of
766238fd1498Szrj type "pointer-to-function" or "reference-to-function." Nonstatic
766338fd1498Szrj member functions match targets of type "pointer-to-member
766438fd1498Szrj function;" the function type of the pointer to member is used to
766538fd1498Szrj select the member function from the set of overloaded member
766638fd1498Szrj functions. If a nonstatic member function is selected, the
766738fd1498Szrj reference to the overloaded function name is required to have the
766838fd1498Szrj form of a pointer to member as described in 5.3.1.
766938fd1498Szrj
767038fd1498Szrj If more than one function is selected, any template functions in
767138fd1498Szrj the set are eliminated if the set also contains a non-template
767238fd1498Szrj function, and any given template function is eliminated if the
767338fd1498Szrj set contains a second template function that is more specialized
767438fd1498Szrj than the first according to the partial ordering rules 14.5.5.2.
767538fd1498Szrj After such eliminations, if any, there shall remain exactly one
767638fd1498Szrj selected function. */
767738fd1498Szrj
767838fd1498Szrj int is_ptrmem = 0;
767938fd1498Szrj /* We store the matches in a TREE_LIST rooted here. The functions
768038fd1498Szrj are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy
768138fd1498Szrj interoperability with most_specialized_instantiation. */
768238fd1498Szrj tree matches = NULL_TREE;
768338fd1498Szrj tree fn;
768438fd1498Szrj tree target_fn_type;
768538fd1498Szrj
768638fd1498Szrj /* By the time we get here, we should be seeing only real
768738fd1498Szrj pointer-to-member types, not the internal POINTER_TYPE to
768838fd1498Szrj METHOD_TYPE representation. */
768938fd1498Szrj gcc_assert (!TYPE_PTR_P (target_type)
769038fd1498Szrj || TREE_CODE (TREE_TYPE (target_type)) != METHOD_TYPE);
769138fd1498Szrj
769238fd1498Szrj gcc_assert (is_overloaded_fn (overload));
769338fd1498Szrj
769438fd1498Szrj /* Check that the TARGET_TYPE is reasonable. */
769538fd1498Szrj if (TYPE_PTRFN_P (target_type)
769638fd1498Szrj || TYPE_REFFN_P (target_type))
769738fd1498Szrj /* This is OK. */;
769838fd1498Szrj else if (TYPE_PTRMEMFUNC_P (target_type))
769938fd1498Szrj /* This is OK, too. */
770038fd1498Szrj is_ptrmem = 1;
770138fd1498Szrj else if (TREE_CODE (target_type) == FUNCTION_TYPE)
770238fd1498Szrj /* This is OK, too. This comes from a conversion to reference
770338fd1498Szrj type. */
770438fd1498Szrj target_type = build_reference_type (target_type);
770538fd1498Szrj else
770638fd1498Szrj {
770738fd1498Szrj if (complain & tf_error)
770838fd1498Szrj error ("cannot resolve overloaded function %qD based on"
770938fd1498Szrj " conversion to type %qT",
771038fd1498Szrj OVL_NAME (overload), target_type);
771138fd1498Szrj return error_mark_node;
771238fd1498Szrj }
771338fd1498Szrj
771438fd1498Szrj /* Non-member functions and static member functions match targets of type
771538fd1498Szrj "pointer-to-function" or "reference-to-function." Nonstatic member
771638fd1498Szrj functions match targets of type "pointer-to-member-function;" the
771738fd1498Szrj function type of the pointer to member is used to select the member
771838fd1498Szrj function from the set of overloaded member functions.
771938fd1498Szrj
772038fd1498Szrj So figure out the FUNCTION_TYPE that we want to match against. */
772138fd1498Szrj target_fn_type = static_fn_type (target_type);
772238fd1498Szrj
772338fd1498Szrj /* If we can find a non-template function that matches, we can just
772438fd1498Szrj use it. There's no point in generating template instantiations
772538fd1498Szrj if we're just going to throw them out anyhow. But, of course, we
772638fd1498Szrj can only do this when we don't *need* a template function. */
772738fd1498Szrj if (!template_only)
772838fd1498Szrj for (lkp_iterator iter (overload); iter; ++iter)
772938fd1498Szrj {
773038fd1498Szrj tree fn = *iter;
773138fd1498Szrj
773238fd1498Szrj if (TREE_CODE (fn) == TEMPLATE_DECL)
773338fd1498Szrj /* We're not looking for templates just yet. */
773438fd1498Szrj continue;
773538fd1498Szrj
773638fd1498Szrj if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) != is_ptrmem)
773738fd1498Szrj /* We're looking for a non-static member, and this isn't
773838fd1498Szrj one, or vice versa. */
773938fd1498Szrj continue;
774038fd1498Szrj
774138fd1498Szrj /* In C++17 we need the noexcept-qualifier to compare types. */
774238fd1498Szrj if (flag_noexcept_type
774338fd1498Szrj && !maybe_instantiate_noexcept (fn, complain))
774438fd1498Szrj continue;
774538fd1498Szrj
774638fd1498Szrj /* See if there's a match. */
774738fd1498Szrj tree fntype = static_fn_type (fn);
774838fd1498Szrj if (same_type_p (target_fn_type, fntype)
774938fd1498Szrj || fnptr_conv_p (target_fn_type, fntype))
775038fd1498Szrj matches = tree_cons (fn, NULL_TREE, matches);
775138fd1498Szrj }
775238fd1498Szrj
775338fd1498Szrj /* Now, if we've already got a match (or matches), there's no need
775438fd1498Szrj to proceed to the template functions. But, if we don't have a
775538fd1498Szrj match we need to look at them, too. */
775638fd1498Szrj if (!matches)
775738fd1498Szrj {
775838fd1498Szrj tree target_arg_types;
775938fd1498Szrj tree target_ret_type;
776038fd1498Szrj tree *args;
776138fd1498Szrj unsigned int nargs, ia;
776238fd1498Szrj tree arg;
776338fd1498Szrj
776438fd1498Szrj target_arg_types = TYPE_ARG_TYPES (target_fn_type);
776538fd1498Szrj target_ret_type = TREE_TYPE (target_fn_type);
776638fd1498Szrj
776738fd1498Szrj nargs = list_length (target_arg_types);
776838fd1498Szrj args = XALLOCAVEC (tree, nargs);
776938fd1498Szrj for (arg = target_arg_types, ia = 0;
777038fd1498Szrj arg != NULL_TREE && arg != void_list_node;
777138fd1498Szrj arg = TREE_CHAIN (arg), ++ia)
777238fd1498Szrj args[ia] = TREE_VALUE (arg);
777338fd1498Szrj nargs = ia;
777438fd1498Szrj
777538fd1498Szrj for (lkp_iterator iter (overload); iter; ++iter)
777638fd1498Szrj {
777738fd1498Szrj tree fn = *iter;
777838fd1498Szrj tree instantiation;
777938fd1498Szrj tree targs;
778038fd1498Szrj
778138fd1498Szrj if (TREE_CODE (fn) != TEMPLATE_DECL)
778238fd1498Szrj /* We're only looking for templates. */
778338fd1498Szrj continue;
778438fd1498Szrj
778538fd1498Szrj if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
778638fd1498Szrj != is_ptrmem)
778738fd1498Szrj /* We're not looking for a non-static member, and this is
778838fd1498Szrj one, or vice versa. */
778938fd1498Szrj continue;
779038fd1498Szrj
779138fd1498Szrj tree ret = target_ret_type;
779238fd1498Szrj
779338fd1498Szrj /* If the template has a deduced return type, don't expose it to
779438fd1498Szrj template argument deduction. */
779538fd1498Szrj if (undeduced_auto_decl (fn))
779638fd1498Szrj ret = NULL_TREE;
779738fd1498Szrj
779838fd1498Szrj /* Try to do argument deduction. */
779938fd1498Szrj targs = make_tree_vec (DECL_NTPARMS (fn));
780038fd1498Szrj instantiation = fn_type_unification (fn, explicit_targs, targs, args,
780138fd1498Szrj nargs, ret,
780238fd1498Szrj DEDUCE_EXACT, LOOKUP_NORMAL,
780338fd1498Szrj false, false);
780438fd1498Szrj if (instantiation == error_mark_node)
780538fd1498Szrj /* Instantiation failed. */
780638fd1498Szrj continue;
780738fd1498Szrj
780838fd1498Szrj /* Constraints must be satisfied. This is done before
780938fd1498Szrj return type deduction since that instantiates the
781038fd1498Szrj function. */
781138fd1498Szrj if (flag_concepts && !constraints_satisfied_p (instantiation))
781238fd1498Szrj continue;
781338fd1498Szrj
781438fd1498Szrj /* And now force instantiation to do return type deduction. */
781538fd1498Szrj if (undeduced_auto_decl (instantiation))
781638fd1498Szrj {
781738fd1498Szrj ++function_depth;
781838fd1498Szrj instantiate_decl (instantiation, /*defer*/false, /*class*/false);
781938fd1498Szrj --function_depth;
782038fd1498Szrj
782138fd1498Szrj require_deduced_type (instantiation);
782238fd1498Szrj }
782338fd1498Szrj
782438fd1498Szrj /* In C++17 we need the noexcept-qualifier to compare types. */
782538fd1498Szrj if (flag_noexcept_type)
782638fd1498Szrj maybe_instantiate_noexcept (instantiation, complain);
782738fd1498Szrj
782838fd1498Szrj /* See if there's a match. */
782938fd1498Szrj tree fntype = static_fn_type (instantiation);
783038fd1498Szrj if (same_type_p (target_fn_type, fntype)
783138fd1498Szrj || fnptr_conv_p (target_fn_type, fntype))
783238fd1498Szrj matches = tree_cons (instantiation, fn, matches);
783338fd1498Szrj }
783438fd1498Szrj
783538fd1498Szrj /* Now, remove all but the most specialized of the matches. */
783638fd1498Szrj if (matches)
783738fd1498Szrj {
783838fd1498Szrj tree match = most_specialized_instantiation (matches);
783938fd1498Szrj
784038fd1498Szrj if (match != error_mark_node)
784138fd1498Szrj matches = tree_cons (TREE_PURPOSE (match),
784238fd1498Szrj NULL_TREE,
784338fd1498Szrj NULL_TREE);
784438fd1498Szrj }
784538fd1498Szrj }
784638fd1498Szrj
784738fd1498Szrj /* Now we should have exactly one function in MATCHES. */
784838fd1498Szrj if (matches == NULL_TREE)
784938fd1498Szrj {
785038fd1498Szrj /* There were *no* matches. */
785138fd1498Szrj if (complain & tf_error)
785238fd1498Szrj {
785338fd1498Szrj error ("no matches converting function %qD to type %q#T",
785438fd1498Szrj OVL_NAME (overload), target_type);
785538fd1498Szrj
785638fd1498Szrj print_candidates (overload);
785738fd1498Szrj }
785838fd1498Szrj return error_mark_node;
785938fd1498Szrj }
786038fd1498Szrj else if (TREE_CHAIN (matches))
786138fd1498Szrj {
786238fd1498Szrj /* There were too many matches. First check if they're all
786338fd1498Szrj the same function. */
786438fd1498Szrj tree match = NULL_TREE;
786538fd1498Szrj
786638fd1498Szrj fn = TREE_PURPOSE (matches);
786738fd1498Szrj
786838fd1498Szrj /* For multi-versioned functions, more than one match is just fine and
786938fd1498Szrj decls_match will return false as they are different. */
787038fd1498Szrj for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match))
787138fd1498Szrj if (!decls_match (fn, TREE_PURPOSE (match))
787238fd1498Szrj && !targetm.target_option.function_versions
787338fd1498Szrj (fn, TREE_PURPOSE (match)))
787438fd1498Szrj break;
787538fd1498Szrj
787638fd1498Szrj if (match)
787738fd1498Szrj {
787838fd1498Szrj if (complain & tf_error)
787938fd1498Szrj {
788038fd1498Szrj error ("converting overloaded function %qD to type %q#T is ambiguous",
788138fd1498Szrj OVL_NAME (overload), target_type);
788238fd1498Szrj
788338fd1498Szrj /* Since print_candidates expects the functions in the
788438fd1498Szrj TREE_VALUE slot, we flip them here. */
788538fd1498Szrj for (match = matches; match; match = TREE_CHAIN (match))
788638fd1498Szrj TREE_VALUE (match) = TREE_PURPOSE (match);
788738fd1498Szrj
788838fd1498Szrj print_candidates (matches);
788938fd1498Szrj }
789038fd1498Szrj
789138fd1498Szrj return error_mark_node;
789238fd1498Szrj }
789338fd1498Szrj }
789438fd1498Szrj
789538fd1498Szrj /* Good, exactly one match. Now, convert it to the correct type. */
789638fd1498Szrj fn = TREE_PURPOSE (matches);
789738fd1498Szrj
789838fd1498Szrj if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
789938fd1498Szrj && !(complain & tf_ptrmem_ok) && !flag_ms_extensions)
790038fd1498Szrj {
790138fd1498Szrj static int explained;
790238fd1498Szrj
790338fd1498Szrj if (!(complain & tf_error))
790438fd1498Szrj return error_mark_node;
790538fd1498Szrj
790638fd1498Szrj permerror (input_location, "assuming pointer to member %qD", fn);
790738fd1498Szrj if (!explained)
790838fd1498Szrj {
790938fd1498Szrj inform (input_location, "(a pointer to member can only be formed with %<&%E%>)", fn);
791038fd1498Szrj explained = 1;
791138fd1498Szrj }
791238fd1498Szrj }
791338fd1498Szrj
791438fd1498Szrj /* If a pointer to a function that is multi-versioned is requested, the
791538fd1498Szrj pointer to the dispatcher function is returned instead. This works
791638fd1498Szrj well because indirectly calling the function will dispatch the right
791738fd1498Szrj function version at run-time. */
791838fd1498Szrj if (DECL_FUNCTION_VERSIONED (fn))
791938fd1498Szrj {
792038fd1498Szrj fn = get_function_version_dispatcher (fn);
792138fd1498Szrj if (fn == NULL)
792238fd1498Szrj return error_mark_node;
792338fd1498Szrj /* Mark all the versions corresponding to the dispatcher as used. */
792438fd1498Szrj if (!(complain & tf_conv))
792538fd1498Szrj mark_versions_used (fn);
792638fd1498Szrj }
792738fd1498Szrj
792838fd1498Szrj /* If we're doing overload resolution purely for the purpose of
792938fd1498Szrj determining conversion sequences, we should not consider the
793038fd1498Szrj function used. If this conversion sequence is selected, the
793138fd1498Szrj function will be marked as used at this point. */
793238fd1498Szrj if (!(complain & tf_conv))
793338fd1498Szrj {
793438fd1498Szrj /* Make =delete work with SFINAE. */
793538fd1498Szrj if (DECL_DELETED_FN (fn) && !(complain & tf_error))
793638fd1498Szrj return error_mark_node;
793738fd1498Szrj if (!mark_used (fn, complain) && !(complain & tf_error))
793838fd1498Szrj return error_mark_node;
793938fd1498Szrj }
794038fd1498Szrj
794138fd1498Szrj /* We could not check access to member functions when this
794238fd1498Szrj expression was originally created since we did not know at that
794338fd1498Szrj time to which function the expression referred. */
794438fd1498Szrj if (DECL_FUNCTION_MEMBER_P (fn))
794538fd1498Szrj {
794638fd1498Szrj gcc_assert (access_path);
794738fd1498Szrj perform_or_defer_access_check (access_path, fn, fn, complain);
794838fd1498Szrj }
794938fd1498Szrj
795038fd1498Szrj if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
795138fd1498Szrj return cp_build_addr_expr (fn, complain);
795238fd1498Szrj else
795338fd1498Szrj {
795438fd1498Szrj /* The target must be a REFERENCE_TYPE. Above, cp_build_unary_op
795538fd1498Szrj will mark the function as addressed, but here we must do it
795638fd1498Szrj explicitly. */
795738fd1498Szrj cxx_mark_addressable (fn);
795838fd1498Szrj
795938fd1498Szrj return fn;
796038fd1498Szrj }
796138fd1498Szrj }
796238fd1498Szrj
796338fd1498Szrj /* This function will instantiate the type of the expression given in
796438fd1498Szrj RHS to match the type of LHSTYPE. If errors exist, then return
796538fd1498Szrj error_mark_node. COMPLAIN is a bit mask. If TF_ERROR is set, then
796638fd1498Szrj we complain on errors. If we are not complaining, never modify rhs,
796738fd1498Szrj as overload resolution wants to try many possible instantiations, in
796838fd1498Szrj the hope that at least one will work.
796938fd1498Szrj
797038fd1498Szrj For non-recursive calls, LHSTYPE should be a function, pointer to
797138fd1498Szrj function, or a pointer to member function. */
797238fd1498Szrj
797338fd1498Szrj tree
instantiate_type(tree lhstype,tree rhs,tsubst_flags_t complain)797438fd1498Szrj instantiate_type (tree lhstype, tree rhs, tsubst_flags_t complain)
797538fd1498Szrj {
797638fd1498Szrj tsubst_flags_t complain_in = complain;
797738fd1498Szrj tree access_path = NULL_TREE;
797838fd1498Szrj
797938fd1498Szrj complain &= ~tf_ptrmem_ok;
798038fd1498Szrj
798138fd1498Szrj if (lhstype == unknown_type_node)
798238fd1498Szrj {
798338fd1498Szrj if (complain & tf_error)
798438fd1498Szrj error ("not enough type information");
798538fd1498Szrj return error_mark_node;
798638fd1498Szrj }
798738fd1498Szrj
798838fd1498Szrj if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))
798938fd1498Szrj {
799038fd1498Szrj tree fntype = non_reference (lhstype);
799138fd1498Szrj if (same_type_p (fntype, TREE_TYPE (rhs)))
799238fd1498Szrj return rhs;
799338fd1498Szrj if (fnptr_conv_p (fntype, TREE_TYPE (rhs)))
799438fd1498Szrj return rhs;
799538fd1498Szrj if (flag_ms_extensions
799638fd1498Szrj && TYPE_PTRMEMFUNC_P (fntype)
799738fd1498Szrj && !TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs)))
799838fd1498Szrj /* Microsoft allows `A::f' to be resolved to a
799938fd1498Szrj pointer-to-member. */
800038fd1498Szrj ;
800138fd1498Szrj else
800238fd1498Szrj {
800338fd1498Szrj if (complain & tf_error)
800438fd1498Szrj error ("cannot convert %qE from type %qT to type %qT",
800538fd1498Szrj rhs, TREE_TYPE (rhs), fntype);
800638fd1498Szrj return error_mark_node;
800738fd1498Szrj }
800838fd1498Szrj }
800938fd1498Szrj
801038fd1498Szrj /* If we instantiate a template, and it is a A ?: C expression
801138fd1498Szrj with omitted B, look through the SAVE_EXPR. */
801238fd1498Szrj if (TREE_CODE (rhs) == SAVE_EXPR)
801338fd1498Szrj rhs = TREE_OPERAND (rhs, 0);
801438fd1498Szrj
801538fd1498Szrj if (BASELINK_P (rhs))
801638fd1498Szrj {
801738fd1498Szrj access_path = BASELINK_ACCESS_BINFO (rhs);
801838fd1498Szrj rhs = BASELINK_FUNCTIONS (rhs);
801938fd1498Szrj }
802038fd1498Szrj
802138fd1498Szrj /* If we are in a template, and have a NON_DEPENDENT_EXPR, we cannot
802238fd1498Szrj deduce any type information. */
802338fd1498Szrj if (TREE_CODE (rhs) == NON_DEPENDENT_EXPR)
802438fd1498Szrj {
802538fd1498Szrj if (complain & tf_error)
802638fd1498Szrj error ("not enough type information");
802738fd1498Szrj return error_mark_node;
802838fd1498Szrj }
802938fd1498Szrj
803038fd1498Szrj /* There are only a few kinds of expressions that may have a type
803138fd1498Szrj dependent on overload resolution. */
803238fd1498Szrj gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
803338fd1498Szrj || TREE_CODE (rhs) == COMPONENT_REF
803438fd1498Szrj || is_overloaded_fn (rhs)
803538fd1498Szrj || (flag_ms_extensions && TREE_CODE (rhs) == FUNCTION_DECL));
803638fd1498Szrj
803738fd1498Szrj /* This should really only be used when attempting to distinguish
803838fd1498Szrj what sort of a pointer to function we have. For now, any
803938fd1498Szrj arithmetic operation which is not supported on pointers
804038fd1498Szrj is rejected as an error. */
804138fd1498Szrj
804238fd1498Szrj switch (TREE_CODE (rhs))
804338fd1498Szrj {
804438fd1498Szrj case COMPONENT_REF:
804538fd1498Szrj {
804638fd1498Szrj tree member = TREE_OPERAND (rhs, 1);
804738fd1498Szrj
804838fd1498Szrj member = instantiate_type (lhstype, member, complain);
804938fd1498Szrj if (member != error_mark_node
805038fd1498Szrj && TREE_SIDE_EFFECTS (TREE_OPERAND (rhs, 0)))
805138fd1498Szrj /* Do not lose object's side effects. */
805238fd1498Szrj return build2 (COMPOUND_EXPR, TREE_TYPE (member),
805338fd1498Szrj TREE_OPERAND (rhs, 0), member);
805438fd1498Szrj return member;
805538fd1498Szrj }
805638fd1498Szrj
805738fd1498Szrj case OFFSET_REF:
805838fd1498Szrj rhs = TREE_OPERAND (rhs, 1);
805938fd1498Szrj if (BASELINK_P (rhs))
806038fd1498Szrj return instantiate_type (lhstype, rhs, complain_in);
806138fd1498Szrj
806238fd1498Szrj /* This can happen if we are forming a pointer-to-member for a
806338fd1498Szrj member template. */
806438fd1498Szrj gcc_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR);
806538fd1498Szrj
806638fd1498Szrj /* Fall through. */
806738fd1498Szrj
806838fd1498Szrj case TEMPLATE_ID_EXPR:
806938fd1498Szrj {
807038fd1498Szrj tree fns = TREE_OPERAND (rhs, 0);
807138fd1498Szrj tree args = TREE_OPERAND (rhs, 1);
807238fd1498Szrj
807338fd1498Szrj return
807438fd1498Szrj resolve_address_of_overloaded_function (lhstype, fns, complain_in,
807538fd1498Szrj /*template_only=*/true,
807638fd1498Szrj args, access_path);
807738fd1498Szrj }
807838fd1498Szrj
807938fd1498Szrj case OVERLOAD:
808038fd1498Szrj case FUNCTION_DECL:
808138fd1498Szrj return
808238fd1498Szrj resolve_address_of_overloaded_function (lhstype, rhs, complain_in,
808338fd1498Szrj /*template_only=*/false,
808438fd1498Szrj /*explicit_targs=*/NULL_TREE,
808538fd1498Szrj access_path);
808638fd1498Szrj
808738fd1498Szrj case ADDR_EXPR:
808838fd1498Szrj {
808938fd1498Szrj if (PTRMEM_OK_P (rhs))
809038fd1498Szrj complain |= tf_ptrmem_ok;
809138fd1498Szrj
809238fd1498Szrj return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
809338fd1498Szrj }
809438fd1498Szrj
809538fd1498Szrj case ERROR_MARK:
809638fd1498Szrj return error_mark_node;
809738fd1498Szrj
809838fd1498Szrj default:
809938fd1498Szrj gcc_unreachable ();
810038fd1498Szrj }
810138fd1498Szrj return error_mark_node;
810238fd1498Szrj }
810338fd1498Szrj
810438fd1498Szrj /* Return the name of the virtual function pointer field
810538fd1498Szrj (as an IDENTIFIER_NODE) for the given TYPE. Note that
810638fd1498Szrj this may have to look back through base types to find the
810738fd1498Szrj ultimate field name. (For single inheritance, these could
810838fd1498Szrj all be the same name. Who knows for multiple inheritance). */
810938fd1498Szrj
811038fd1498Szrj static tree
get_vfield_name(tree type)811138fd1498Szrj get_vfield_name (tree type)
811238fd1498Szrj {
811338fd1498Szrj tree binfo, base_binfo;
811438fd1498Szrj
811538fd1498Szrj for (binfo = TYPE_BINFO (type);
811638fd1498Szrj BINFO_N_BASE_BINFOS (binfo);
811738fd1498Szrj binfo = base_binfo)
811838fd1498Szrj {
811938fd1498Szrj base_binfo = BINFO_BASE_BINFO (binfo, 0);
812038fd1498Szrj
812138fd1498Szrj if (BINFO_VIRTUAL_P (base_binfo)
812238fd1498Szrj || !TYPE_CONTAINS_VPTR_P (BINFO_TYPE (base_binfo)))
812338fd1498Szrj break;
812438fd1498Szrj }
812538fd1498Szrj
812638fd1498Szrj type = BINFO_TYPE (binfo);
812738fd1498Szrj tree ctor_name = constructor_name (type);
812838fd1498Szrj char *buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT)
812938fd1498Szrj + IDENTIFIER_LENGTH (ctor_name) + 2);
813038fd1498Szrj sprintf (buf, VFIELD_NAME_FORMAT, IDENTIFIER_POINTER (ctor_name));
813138fd1498Szrj return get_identifier (buf);
813238fd1498Szrj }
813338fd1498Szrj
813438fd1498Szrj /* Build a dummy reference to ourselves so Derived::Base (and A::A) works,
813538fd1498Szrj according to [class]:
813638fd1498Szrj The class-name is also inserted
813738fd1498Szrj into the scope of the class itself. For purposes of access checking,
813838fd1498Szrj the inserted class name is treated as if it were a public member name. */
813938fd1498Szrj
814038fd1498Szrj void
build_self_reference(void)814138fd1498Szrj build_self_reference (void)
814238fd1498Szrj {
814338fd1498Szrj tree name = DECL_NAME (TYPE_NAME (current_class_type));
814438fd1498Szrj tree value = build_lang_decl (TYPE_DECL, name, current_class_type);
814538fd1498Szrj
814638fd1498Szrj DECL_NONLOCAL (value) = 1;
814738fd1498Szrj DECL_CONTEXT (value) = current_class_type;
814838fd1498Szrj DECL_ARTIFICIAL (value) = 1;
814938fd1498Szrj SET_DECL_SELF_REFERENCE_P (value);
815038fd1498Szrj set_underlying_type (value);
815138fd1498Szrj
815238fd1498Szrj if (processing_template_decl)
815338fd1498Szrj value = push_template_decl (value);
815438fd1498Szrj
815538fd1498Szrj tree saved_cas = current_access_specifier;
815638fd1498Szrj current_access_specifier = access_public_node;
815738fd1498Szrj finish_member_declaration (value);
815838fd1498Szrj current_access_specifier = saved_cas;
815938fd1498Szrj }
816038fd1498Szrj
816138fd1498Szrj /* Returns 1 if TYPE contains only padding bytes. */
816238fd1498Szrj
816338fd1498Szrj int
is_empty_class(tree type)816438fd1498Szrj is_empty_class (tree type)
816538fd1498Szrj {
816638fd1498Szrj if (type == error_mark_node)
816738fd1498Szrj return 0;
816838fd1498Szrj
816938fd1498Szrj if (! CLASS_TYPE_P (type))
817038fd1498Szrj return 0;
817138fd1498Szrj
817238fd1498Szrj return CLASSTYPE_EMPTY_P (type);
817338fd1498Szrj }
817438fd1498Szrj
817538fd1498Szrj /* Returns true if TYPE contains no actual data, just various
817638fd1498Szrj possible combinations of empty classes and possibly a vptr. */
817738fd1498Szrj
817838fd1498Szrj bool
is_really_empty_class(tree type)817938fd1498Szrj is_really_empty_class (tree type)
818038fd1498Szrj {
818138fd1498Szrj if (CLASS_TYPE_P (type))
818238fd1498Szrj {
818338fd1498Szrj tree field;
818438fd1498Szrj tree binfo;
818538fd1498Szrj tree base_binfo;
818638fd1498Szrj int i;
818738fd1498Szrj
818838fd1498Szrj /* CLASSTYPE_EMPTY_P isn't set properly until the class is actually laid
818938fd1498Szrj out, but we'd like to be able to check this before then. */
819038fd1498Szrj if (COMPLETE_TYPE_P (type) && is_empty_class (type))
819138fd1498Szrj return true;
819238fd1498Szrj
819338fd1498Szrj for (binfo = TYPE_BINFO (type), i = 0;
819438fd1498Szrj BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
819538fd1498Szrj if (!is_really_empty_class (BINFO_TYPE (base_binfo)))
819638fd1498Szrj return false;
819738fd1498Szrj for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
819838fd1498Szrj if (TREE_CODE (field) == FIELD_DECL
819938fd1498Szrj && !DECL_ARTIFICIAL (field)
820038fd1498Szrj /* An unnamed bit-field is not a data member. */
820138fd1498Szrj && !DECL_UNNAMED_BIT_FIELD (field)
820238fd1498Szrj && !is_really_empty_class (TREE_TYPE (field)))
820338fd1498Szrj return false;
820438fd1498Szrj return true;
820538fd1498Szrj }
820638fd1498Szrj else if (TREE_CODE (type) == ARRAY_TYPE)
820738fd1498Szrj return (integer_zerop (array_type_nelts_top (type))
820838fd1498Szrj || is_really_empty_class (TREE_TYPE (type)));
820938fd1498Szrj return false;
821038fd1498Szrj }
821138fd1498Szrj
821238fd1498Szrj /* Note that NAME was looked up while the current class was being
821338fd1498Szrj defined and that the result of that lookup was DECL. */
821438fd1498Szrj
821538fd1498Szrj void
maybe_note_name_used_in_class(tree name,tree decl)821638fd1498Szrj maybe_note_name_used_in_class (tree name, tree decl)
821738fd1498Szrj {
821838fd1498Szrj splay_tree names_used;
821938fd1498Szrj
822038fd1498Szrj /* If we're not defining a class, there's nothing to do. */
822138fd1498Szrj if (!(innermost_scope_kind() == sk_class
822238fd1498Szrj && TYPE_BEING_DEFINED (current_class_type)
822338fd1498Szrj && !LAMBDA_TYPE_P (current_class_type)))
822438fd1498Szrj return;
822538fd1498Szrj
822638fd1498Szrj /* If there's already a binding for this NAME, then we don't have
822738fd1498Szrj anything to worry about. */
822838fd1498Szrj if (lookup_member (current_class_type, name,
822938fd1498Szrj /*protect=*/0, /*want_type=*/false, tf_warning_or_error))
823038fd1498Szrj return;
823138fd1498Szrj
823238fd1498Szrj if (!current_class_stack[current_class_depth - 1].names_used)
823338fd1498Szrj current_class_stack[current_class_depth - 1].names_used
823438fd1498Szrj = splay_tree_new (splay_tree_compare_pointers, 0, 0);
823538fd1498Szrj names_used = current_class_stack[current_class_depth - 1].names_used;
823638fd1498Szrj
823738fd1498Szrj splay_tree_insert (names_used,
823838fd1498Szrj (splay_tree_key) name,
823938fd1498Szrj (splay_tree_value) decl);
824038fd1498Szrj }
824138fd1498Szrj
824238fd1498Szrj /* Note that NAME was declared (as DECL) in the current class. Check
824338fd1498Szrj to see that the declaration is valid. */
824438fd1498Szrj
824538fd1498Szrj void
note_name_declared_in_class(tree name,tree decl)824638fd1498Szrj note_name_declared_in_class (tree name, tree decl)
824738fd1498Szrj {
824838fd1498Szrj splay_tree names_used;
824938fd1498Szrj splay_tree_node n;
825038fd1498Szrj
825138fd1498Szrj /* Look to see if we ever used this name. */
825238fd1498Szrj names_used
825338fd1498Szrj = current_class_stack[current_class_depth - 1].names_used;
825438fd1498Szrj if (!names_used)
825538fd1498Szrj return;
825638fd1498Szrj /* The C language allows members to be declared with a type of the same
825738fd1498Szrj name, and the C++ standard says this diagnostic is not required. So
825838fd1498Szrj allow it in extern "C" blocks unless predantic is specified.
825938fd1498Szrj Allow it in all cases if -ms-extensions is specified. */
826038fd1498Szrj if ((!pedantic && current_lang_name == lang_name_c)
826138fd1498Szrj || flag_ms_extensions)
826238fd1498Szrj return;
826338fd1498Szrj n = splay_tree_lookup (names_used, (splay_tree_key) name);
826438fd1498Szrj if (n)
826538fd1498Szrj {
826638fd1498Szrj /* [basic.scope.class]
826738fd1498Szrj
826838fd1498Szrj A name N used in a class S shall refer to the same declaration
826938fd1498Szrj in its context and when re-evaluated in the completed scope of
827038fd1498Szrj S. */
827138fd1498Szrj permerror (input_location, "declaration of %q#D", decl);
827238fd1498Szrj permerror (location_of ((tree) n->value),
827338fd1498Szrj "changes meaning of %qD from %q#D",
827438fd1498Szrj OVL_NAME (decl), (tree) n->value);
827538fd1498Szrj }
827638fd1498Szrj }
827738fd1498Szrj
827838fd1498Szrj /* Returns the VAR_DECL for the complete vtable associated with BINFO.
827938fd1498Szrj Secondary vtables are merged with primary vtables; this function
828038fd1498Szrj will return the VAR_DECL for the primary vtable. */
828138fd1498Szrj
828238fd1498Szrj tree
get_vtbl_decl_for_binfo(tree binfo)828338fd1498Szrj get_vtbl_decl_for_binfo (tree binfo)
828438fd1498Szrj {
828538fd1498Szrj tree decl;
828638fd1498Szrj
828738fd1498Szrj decl = BINFO_VTABLE (binfo);
828838fd1498Szrj if (decl && TREE_CODE (decl) == POINTER_PLUS_EXPR)
828938fd1498Szrj {
829038fd1498Szrj gcc_assert (TREE_CODE (TREE_OPERAND (decl, 0)) == ADDR_EXPR);
829138fd1498Szrj decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
829238fd1498Szrj }
829338fd1498Szrj if (decl)
829438fd1498Szrj gcc_assert (VAR_P (decl));
829538fd1498Szrj return decl;
829638fd1498Szrj }
829738fd1498Szrj
829838fd1498Szrj
829938fd1498Szrj /* Returns the binfo for the primary base of BINFO. If the resulting
830038fd1498Szrj BINFO is a virtual base, and it is inherited elsewhere in the
830138fd1498Szrj hierarchy, then the returned binfo might not be the primary base of
830238fd1498Szrj BINFO in the complete object. Check BINFO_PRIMARY_P or
830338fd1498Szrj BINFO_LOST_PRIMARY_P to be sure. */
830438fd1498Szrj
830538fd1498Szrj static tree
get_primary_binfo(tree binfo)830638fd1498Szrj get_primary_binfo (tree binfo)
830738fd1498Szrj {
830838fd1498Szrj tree primary_base;
830938fd1498Szrj
831038fd1498Szrj primary_base = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo));
831138fd1498Szrj if (!primary_base)
831238fd1498Szrj return NULL_TREE;
831338fd1498Szrj
831438fd1498Szrj return copied_binfo (primary_base, binfo);
831538fd1498Szrj }
831638fd1498Szrj
831738fd1498Szrj /* As above, but iterate until we reach the binfo that actually provides the
831838fd1498Szrj vptr for BINFO. */
831938fd1498Szrj
832038fd1498Szrj static tree
most_primary_binfo(tree binfo)832138fd1498Szrj most_primary_binfo (tree binfo)
832238fd1498Szrj {
832338fd1498Szrj tree b = binfo;
832438fd1498Szrj while (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (b))
832538fd1498Szrj && !BINFO_LOST_PRIMARY_P (b))
832638fd1498Szrj {
832738fd1498Szrj tree primary_base = get_primary_binfo (b);
832838fd1498Szrj gcc_assert (BINFO_PRIMARY_P (primary_base)
832938fd1498Szrj && BINFO_INHERITANCE_CHAIN (primary_base) == b);
833038fd1498Szrj b = primary_base;
833138fd1498Szrj }
833238fd1498Szrj return b;
833338fd1498Szrj }
833438fd1498Szrj
833538fd1498Szrj /* Returns true if BINFO gets its vptr from a virtual base of the most derived
833638fd1498Szrj type. Note that the virtual inheritance might be above or below BINFO in
833738fd1498Szrj the hierarchy. */
833838fd1498Szrj
833938fd1498Szrj bool
vptr_via_virtual_p(tree binfo)834038fd1498Szrj vptr_via_virtual_p (tree binfo)
834138fd1498Szrj {
834238fd1498Szrj if (TYPE_P (binfo))
834338fd1498Szrj binfo = TYPE_BINFO (binfo);
834438fd1498Szrj tree primary = most_primary_binfo (binfo);
834538fd1498Szrj /* Don't limit binfo_via_virtual, we want to return true when BINFO itself is
834638fd1498Szrj a morally virtual base. */
834738fd1498Szrj tree virt = binfo_via_virtual (primary, NULL_TREE);
834838fd1498Szrj return virt != NULL_TREE;
834938fd1498Szrj }
835038fd1498Szrj
835138fd1498Szrj /* If INDENTED_P is zero, indent to INDENT. Return nonzero. */
835238fd1498Szrj
835338fd1498Szrj static int
maybe_indent_hierarchy(FILE * stream,int indent,int indented_p)835438fd1498Szrj maybe_indent_hierarchy (FILE * stream, int indent, int indented_p)
835538fd1498Szrj {
835638fd1498Szrj if (!indented_p)
835738fd1498Szrj fprintf (stream, "%*s", indent, "");
835838fd1498Szrj return 1;
835938fd1498Szrj }
836038fd1498Szrj
836138fd1498Szrj /* Dump the offsets of all the bases rooted at BINFO to STREAM.
836238fd1498Szrj INDENT should be zero when called from the top level; it is
836338fd1498Szrj incremented recursively. IGO indicates the next expected BINFO in
836438fd1498Szrj inheritance graph ordering. */
836538fd1498Szrj
836638fd1498Szrj static tree
dump_class_hierarchy_r(FILE * stream,dump_flags_t flags,tree binfo,tree igo,int indent)836738fd1498Szrj dump_class_hierarchy_r (FILE *stream,
836838fd1498Szrj dump_flags_t flags,
836938fd1498Szrj tree binfo,
837038fd1498Szrj tree igo,
837138fd1498Szrj int indent)
837238fd1498Szrj {
837338fd1498Szrj int indented = 0;
837438fd1498Szrj tree base_binfo;
837538fd1498Szrj int i;
837638fd1498Szrj
837738fd1498Szrj indented = maybe_indent_hierarchy (stream, indent, 0);
837838fd1498Szrj fprintf (stream, "%s (0x" HOST_WIDE_INT_PRINT_HEX ") ",
837938fd1498Szrj type_as_string (BINFO_TYPE (binfo), TFF_PLAIN_IDENTIFIER),
838038fd1498Szrj (HOST_WIDE_INT) (uintptr_t) binfo);
838138fd1498Szrj if (binfo != igo)
838238fd1498Szrj {
838338fd1498Szrj fprintf (stream, "alternative-path\n");
838438fd1498Szrj return igo;
838538fd1498Szrj }
838638fd1498Szrj igo = TREE_CHAIN (binfo);
838738fd1498Szrj
838838fd1498Szrj fprintf (stream, HOST_WIDE_INT_PRINT_DEC,
838938fd1498Szrj tree_to_shwi (BINFO_OFFSET (binfo)));
839038fd1498Szrj if (is_empty_class (BINFO_TYPE (binfo)))
839138fd1498Szrj fprintf (stream, " empty");
839238fd1498Szrj else if (CLASSTYPE_NEARLY_EMPTY_P (BINFO_TYPE (binfo)))
839338fd1498Szrj fprintf (stream, " nearly-empty");
839438fd1498Szrj if (BINFO_VIRTUAL_P (binfo))
839538fd1498Szrj fprintf (stream, " virtual");
839638fd1498Szrj fprintf (stream, "\n");
839738fd1498Szrj
839838fd1498Szrj indented = 0;
839938fd1498Szrj if (BINFO_PRIMARY_P (binfo))
840038fd1498Szrj {
840138fd1498Szrj indented = maybe_indent_hierarchy (stream, indent + 3, indented);
840238fd1498Szrj fprintf (stream, " primary-for %s (0x" HOST_WIDE_INT_PRINT_HEX ")",
840338fd1498Szrj type_as_string (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)),
840438fd1498Szrj TFF_PLAIN_IDENTIFIER),
840538fd1498Szrj (HOST_WIDE_INT) (uintptr_t) BINFO_INHERITANCE_CHAIN (binfo));
840638fd1498Szrj }
840738fd1498Szrj if (BINFO_LOST_PRIMARY_P (binfo))
840838fd1498Szrj {
840938fd1498Szrj indented = maybe_indent_hierarchy (stream, indent + 3, indented);
841038fd1498Szrj fprintf (stream, " lost-primary");
841138fd1498Szrj }
841238fd1498Szrj if (indented)
841338fd1498Szrj fprintf (stream, "\n");
841438fd1498Szrj
841538fd1498Szrj if (!(flags & TDF_SLIM))
841638fd1498Szrj {
841738fd1498Szrj int indented = 0;
841838fd1498Szrj
841938fd1498Szrj if (BINFO_SUBVTT_INDEX (binfo))
842038fd1498Szrj {
842138fd1498Szrj indented = maybe_indent_hierarchy (stream, indent + 3, indented);
842238fd1498Szrj fprintf (stream, " subvttidx=%s",
842338fd1498Szrj expr_as_string (BINFO_SUBVTT_INDEX (binfo),
842438fd1498Szrj TFF_PLAIN_IDENTIFIER));
842538fd1498Szrj }
842638fd1498Szrj if (BINFO_VPTR_INDEX (binfo))
842738fd1498Szrj {
842838fd1498Szrj indented = maybe_indent_hierarchy (stream, indent + 3, indented);
842938fd1498Szrj fprintf (stream, " vptridx=%s",
843038fd1498Szrj expr_as_string (BINFO_VPTR_INDEX (binfo),
843138fd1498Szrj TFF_PLAIN_IDENTIFIER));
843238fd1498Szrj }
843338fd1498Szrj if (BINFO_VPTR_FIELD (binfo))
843438fd1498Szrj {
843538fd1498Szrj indented = maybe_indent_hierarchy (stream, indent + 3, indented);
843638fd1498Szrj fprintf (stream, " vbaseoffset=%s",
843738fd1498Szrj expr_as_string (BINFO_VPTR_FIELD (binfo),
843838fd1498Szrj TFF_PLAIN_IDENTIFIER));
843938fd1498Szrj }
844038fd1498Szrj if (BINFO_VTABLE (binfo))
844138fd1498Szrj {
844238fd1498Szrj indented = maybe_indent_hierarchy (stream, indent + 3, indented);
844338fd1498Szrj fprintf (stream, " vptr=%s",
844438fd1498Szrj expr_as_string (BINFO_VTABLE (binfo),
844538fd1498Szrj TFF_PLAIN_IDENTIFIER));
844638fd1498Szrj }
844738fd1498Szrj
844838fd1498Szrj if (indented)
844938fd1498Szrj fprintf (stream, "\n");
845038fd1498Szrj }
845138fd1498Szrj
845238fd1498Szrj for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
845338fd1498Szrj igo = dump_class_hierarchy_r (stream, flags, base_binfo, igo, indent + 2);
845438fd1498Szrj
845538fd1498Szrj return igo;
845638fd1498Szrj }
845738fd1498Szrj
845838fd1498Szrj /* Dump the BINFO hierarchy for T. */
845938fd1498Szrj
846038fd1498Szrj static void
dump_class_hierarchy_1(FILE * stream,dump_flags_t flags,tree t)846138fd1498Szrj dump_class_hierarchy_1 (FILE *stream, dump_flags_t flags, tree t)
846238fd1498Szrj {
846338fd1498Szrj fprintf (stream, "Class %s\n", type_as_string (t, TFF_PLAIN_IDENTIFIER));
846438fd1498Szrj fprintf (stream, " size=%lu align=%lu\n",
846538fd1498Szrj (unsigned long)(tree_to_shwi (TYPE_SIZE (t)) / BITS_PER_UNIT),
846638fd1498Szrj (unsigned long)(TYPE_ALIGN (t) / BITS_PER_UNIT));
846738fd1498Szrj fprintf (stream, " base size=%lu base align=%lu\n",
846838fd1498Szrj (unsigned long)(tree_to_shwi (TYPE_SIZE (CLASSTYPE_AS_BASE (t)))
846938fd1498Szrj / BITS_PER_UNIT),
847038fd1498Szrj (unsigned long)(TYPE_ALIGN (CLASSTYPE_AS_BASE (t))
847138fd1498Szrj / BITS_PER_UNIT));
847238fd1498Szrj dump_class_hierarchy_r (stream, flags, TYPE_BINFO (t), TYPE_BINFO (t), 0);
847338fd1498Szrj fprintf (stream, "\n");
847438fd1498Szrj }
847538fd1498Szrj
847638fd1498Szrj /* Debug interface to hierarchy dumping. */
847738fd1498Szrj
847838fd1498Szrj void
debug_class(tree t)847938fd1498Szrj debug_class (tree t)
848038fd1498Szrj {
848138fd1498Szrj dump_class_hierarchy_1 (stderr, TDF_SLIM, t);
848238fd1498Szrj }
848338fd1498Szrj
848438fd1498Szrj static void
dump_class_hierarchy(tree t)848538fd1498Szrj dump_class_hierarchy (tree t)
848638fd1498Szrj {
848738fd1498Szrj dump_flags_t flags;
848838fd1498Szrj if (FILE *stream = dump_begin (class_dump_id, &flags))
848938fd1498Szrj {
849038fd1498Szrj dump_class_hierarchy_1 (stream, flags, t);
849138fd1498Szrj dump_end (class_dump_id, stream);
849238fd1498Szrj }
849338fd1498Szrj }
849438fd1498Szrj
849538fd1498Szrj static void
dump_array(FILE * stream,tree decl)849638fd1498Szrj dump_array (FILE * stream, tree decl)
849738fd1498Szrj {
849838fd1498Szrj tree value;
849938fd1498Szrj unsigned HOST_WIDE_INT ix;
850038fd1498Szrj HOST_WIDE_INT elt;
850138fd1498Szrj tree size = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (decl)));
850238fd1498Szrj
850338fd1498Szrj elt = (tree_to_shwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl))))
850438fd1498Szrj / BITS_PER_UNIT);
850538fd1498Szrj fprintf (stream, "%s:", decl_as_string (decl, TFF_PLAIN_IDENTIFIER));
850638fd1498Szrj fprintf (stream, " %s entries",
850738fd1498Szrj expr_as_string (size_binop (PLUS_EXPR, size, size_one_node),
850838fd1498Szrj TFF_PLAIN_IDENTIFIER));
850938fd1498Szrj fprintf (stream, "\n");
851038fd1498Szrj
851138fd1498Szrj FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (decl)),
851238fd1498Szrj ix, value)
851338fd1498Szrj fprintf (stream, "%-4ld %s\n", (long)(ix * elt),
851438fd1498Szrj expr_as_string (value, TFF_PLAIN_IDENTIFIER));
851538fd1498Szrj }
851638fd1498Szrj
851738fd1498Szrj static void
dump_vtable(tree t,tree binfo,tree vtable)851838fd1498Szrj dump_vtable (tree t, tree binfo, tree vtable)
851938fd1498Szrj {
852038fd1498Szrj dump_flags_t flags;
852138fd1498Szrj FILE *stream = dump_begin (class_dump_id, &flags);
852238fd1498Szrj
852338fd1498Szrj if (!stream)
852438fd1498Szrj return;
852538fd1498Szrj
852638fd1498Szrj if (!(flags & TDF_SLIM))
852738fd1498Szrj {
852838fd1498Szrj int ctor_vtbl_p = TYPE_BINFO (t) != binfo;
852938fd1498Szrj
853038fd1498Szrj fprintf (stream, "%s for %s",
853138fd1498Szrj ctor_vtbl_p ? "Construction vtable" : "Vtable",
853238fd1498Szrj type_as_string (BINFO_TYPE (binfo), TFF_PLAIN_IDENTIFIER));
853338fd1498Szrj if (ctor_vtbl_p)
853438fd1498Szrj {
853538fd1498Szrj if (!BINFO_VIRTUAL_P (binfo))
853638fd1498Szrj fprintf (stream, " (0x" HOST_WIDE_INT_PRINT_HEX " instance)",
853738fd1498Szrj (HOST_WIDE_INT) (uintptr_t) binfo);
853838fd1498Szrj fprintf (stream, " in %s", type_as_string (t, TFF_PLAIN_IDENTIFIER));
853938fd1498Szrj }
854038fd1498Szrj fprintf (stream, "\n");
854138fd1498Szrj dump_array (stream, vtable);
854238fd1498Szrj fprintf (stream, "\n");
854338fd1498Szrj }
854438fd1498Szrj
854538fd1498Szrj dump_end (class_dump_id, stream);
854638fd1498Szrj }
854738fd1498Szrj
854838fd1498Szrj static void
dump_vtt(tree t,tree vtt)854938fd1498Szrj dump_vtt (tree t, tree vtt)
855038fd1498Szrj {
855138fd1498Szrj dump_flags_t flags;
855238fd1498Szrj FILE *stream = dump_begin (class_dump_id, &flags);
855338fd1498Szrj
855438fd1498Szrj if (!stream)
855538fd1498Szrj return;
855638fd1498Szrj
855738fd1498Szrj if (!(flags & TDF_SLIM))
855838fd1498Szrj {
855938fd1498Szrj fprintf (stream, "VTT for %s\n",
856038fd1498Szrj type_as_string (t, TFF_PLAIN_IDENTIFIER));
856138fd1498Szrj dump_array (stream, vtt);
856238fd1498Szrj fprintf (stream, "\n");
856338fd1498Szrj }
856438fd1498Szrj
856538fd1498Szrj dump_end (class_dump_id, stream);
856638fd1498Szrj }
856738fd1498Szrj
856838fd1498Szrj /* Dump a function or thunk and its thunkees. */
856938fd1498Szrj
857038fd1498Szrj static void
dump_thunk(FILE * stream,int indent,tree thunk)857138fd1498Szrj dump_thunk (FILE *stream, int indent, tree thunk)
857238fd1498Szrj {
857338fd1498Szrj static const char spaces[] = " ";
857438fd1498Szrj tree name = DECL_NAME (thunk);
857538fd1498Szrj tree thunks;
857638fd1498Szrj
857738fd1498Szrj fprintf (stream, "%.*s%p %s %s", indent, spaces,
857838fd1498Szrj (void *)thunk,
857938fd1498Szrj !DECL_THUNK_P (thunk) ? "function"
858038fd1498Szrj : DECL_THIS_THUNK_P (thunk) ? "this-thunk" : "covariant-thunk",
858138fd1498Szrj name ? IDENTIFIER_POINTER (name) : "<unset>");
858238fd1498Szrj if (DECL_THUNK_P (thunk))
858338fd1498Szrj {
858438fd1498Szrj HOST_WIDE_INT fixed_adjust = THUNK_FIXED_OFFSET (thunk);
858538fd1498Szrj tree virtual_adjust = THUNK_VIRTUAL_OFFSET (thunk);
858638fd1498Szrj
858738fd1498Szrj fprintf (stream, " fixed=" HOST_WIDE_INT_PRINT_DEC, fixed_adjust);
858838fd1498Szrj if (!virtual_adjust)
858938fd1498Szrj /*NOP*/;
859038fd1498Szrj else if (DECL_THIS_THUNK_P (thunk))
859138fd1498Szrj fprintf (stream, " vcall=" HOST_WIDE_INT_PRINT_DEC,
859238fd1498Szrj tree_to_shwi (virtual_adjust));
859338fd1498Szrj else
859438fd1498Szrj fprintf (stream, " vbase=" HOST_WIDE_INT_PRINT_DEC "(%s)",
859538fd1498Szrj tree_to_shwi (BINFO_VPTR_FIELD (virtual_adjust)),
859638fd1498Szrj type_as_string (BINFO_TYPE (virtual_adjust), TFF_SCOPE));
859738fd1498Szrj if (THUNK_ALIAS (thunk))
859838fd1498Szrj fprintf (stream, " alias to %p", (void *)THUNK_ALIAS (thunk));
859938fd1498Szrj }
860038fd1498Szrj fprintf (stream, "\n");
860138fd1498Szrj for (thunks = DECL_THUNKS (thunk); thunks; thunks = TREE_CHAIN (thunks))
860238fd1498Szrj dump_thunk (stream, indent + 2, thunks);
860338fd1498Szrj }
860438fd1498Szrj
860538fd1498Szrj /* Dump the thunks for FN. */
860638fd1498Szrj
860738fd1498Szrj void
debug_thunks(tree fn)860838fd1498Szrj debug_thunks (tree fn)
860938fd1498Szrj {
861038fd1498Szrj dump_thunk (stderr, 0, fn);
861138fd1498Szrj }
861238fd1498Szrj
861338fd1498Szrj /* Virtual function table initialization. */
861438fd1498Szrj
861538fd1498Szrj /* Create all the necessary vtables for T and its base classes. */
861638fd1498Szrj
861738fd1498Szrj static void
finish_vtbls(tree t)861838fd1498Szrj finish_vtbls (tree t)
861938fd1498Szrj {
862038fd1498Szrj tree vbase;
862138fd1498Szrj vec<constructor_elt, va_gc> *v = NULL;
862238fd1498Szrj tree vtable = BINFO_VTABLE (TYPE_BINFO (t));
862338fd1498Szrj
862438fd1498Szrj /* We lay out the primary and secondary vtables in one contiguous
862538fd1498Szrj vtable. The primary vtable is first, followed by the non-virtual
862638fd1498Szrj secondary vtables in inheritance graph order. */
862738fd1498Szrj accumulate_vtbl_inits (TYPE_BINFO (t), TYPE_BINFO (t), TYPE_BINFO (t),
862838fd1498Szrj vtable, t, &v);
862938fd1498Szrj
863038fd1498Szrj /* Then come the virtual bases, also in inheritance graph order. */
863138fd1498Szrj for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
863238fd1498Szrj {
863338fd1498Szrj if (!BINFO_VIRTUAL_P (vbase))
863438fd1498Szrj continue;
863538fd1498Szrj accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), vtable, t, &v);
863638fd1498Szrj }
863738fd1498Szrj
863838fd1498Szrj if (BINFO_VTABLE (TYPE_BINFO (t)))
863938fd1498Szrj initialize_vtable (TYPE_BINFO (t), v);
864038fd1498Szrj }
864138fd1498Szrj
864238fd1498Szrj /* Initialize the vtable for BINFO with the INITS. */
864338fd1498Szrj
864438fd1498Szrj static void
initialize_vtable(tree binfo,vec<constructor_elt,va_gc> * inits)864538fd1498Szrj initialize_vtable (tree binfo, vec<constructor_elt, va_gc> *inits)
864638fd1498Szrj {
864738fd1498Szrj tree decl;
864838fd1498Szrj
864938fd1498Szrj layout_vtable_decl (binfo, vec_safe_length (inits));
865038fd1498Szrj decl = get_vtbl_decl_for_binfo (binfo);
865138fd1498Szrj initialize_artificial_var (decl, inits);
865238fd1498Szrj dump_vtable (BINFO_TYPE (binfo), binfo, decl);
865338fd1498Szrj }
865438fd1498Szrj
865538fd1498Szrj /* Build the VTT (virtual table table) for T.
865638fd1498Szrj A class requires a VTT if it has virtual bases.
865738fd1498Szrj
865838fd1498Szrj This holds
865938fd1498Szrj 1 - primary virtual pointer for complete object T
866038fd1498Szrj 2 - secondary VTTs for each direct non-virtual base of T which requires a
866138fd1498Szrj VTT
866238fd1498Szrj 3 - secondary virtual pointers for each direct or indirect base of T which
866338fd1498Szrj has virtual bases or is reachable via a virtual path from T.
866438fd1498Szrj 4 - secondary VTTs for each direct or indirect virtual base of T.
866538fd1498Szrj
866638fd1498Szrj Secondary VTTs look like complete object VTTs without part 4. */
866738fd1498Szrj
866838fd1498Szrj static void
build_vtt(tree t)866938fd1498Szrj build_vtt (tree t)
867038fd1498Szrj {
867138fd1498Szrj tree type;
867238fd1498Szrj tree vtt;
867338fd1498Szrj tree index;
867438fd1498Szrj vec<constructor_elt, va_gc> *inits;
867538fd1498Szrj
867638fd1498Szrj /* Build up the initializers for the VTT. */
867738fd1498Szrj inits = NULL;
867838fd1498Szrj index = size_zero_node;
867938fd1498Szrj build_vtt_inits (TYPE_BINFO (t), t, &inits, &index);
868038fd1498Szrj
868138fd1498Szrj /* If we didn't need a VTT, we're done. */
868238fd1498Szrj if (!inits)
868338fd1498Szrj return;
868438fd1498Szrj
868538fd1498Szrj /* Figure out the type of the VTT. */
868638fd1498Szrj type = build_array_of_n_type (const_ptr_type_node,
868738fd1498Szrj inits->length ());
868838fd1498Szrj
868938fd1498Szrj /* Now, build the VTT object itself. */
869038fd1498Szrj vtt = build_vtable (t, mangle_vtt_for_type (t), type);
869138fd1498Szrj initialize_artificial_var (vtt, inits);
869238fd1498Szrj /* Add the VTT to the vtables list. */
869338fd1498Szrj DECL_CHAIN (vtt) = DECL_CHAIN (CLASSTYPE_VTABLES (t));
869438fd1498Szrj DECL_CHAIN (CLASSTYPE_VTABLES (t)) = vtt;
869538fd1498Szrj
869638fd1498Szrj dump_vtt (t, vtt);
869738fd1498Szrj }
869838fd1498Szrj
869938fd1498Szrj /* When building a secondary VTT, BINFO_VTABLE is set to a TREE_LIST with
870038fd1498Szrj PURPOSE the RTTI_BINFO, VALUE the real vtable pointer for this binfo,
870138fd1498Szrj and CHAIN the vtable pointer for this binfo after construction is
870238fd1498Szrj complete. VALUE can also be another BINFO, in which case we recurse. */
870338fd1498Szrj
870438fd1498Szrj static tree
binfo_ctor_vtable(tree binfo)870538fd1498Szrj binfo_ctor_vtable (tree binfo)
870638fd1498Szrj {
870738fd1498Szrj tree vt;
870838fd1498Szrj
870938fd1498Szrj while (1)
871038fd1498Szrj {
871138fd1498Szrj vt = BINFO_VTABLE (binfo);
871238fd1498Szrj if (TREE_CODE (vt) == TREE_LIST)
871338fd1498Szrj vt = TREE_VALUE (vt);
871438fd1498Szrj if (TREE_CODE (vt) == TREE_BINFO)
871538fd1498Szrj binfo = vt;
871638fd1498Szrj else
871738fd1498Szrj break;
871838fd1498Szrj }
871938fd1498Szrj
872038fd1498Szrj return vt;
872138fd1498Szrj }
872238fd1498Szrj
872338fd1498Szrj /* Data for secondary VTT initialization. */
872438fd1498Szrj struct secondary_vptr_vtt_init_data
872538fd1498Szrj {
872638fd1498Szrj /* Is this the primary VTT? */
872738fd1498Szrj bool top_level_p;
872838fd1498Szrj
872938fd1498Szrj /* Current index into the VTT. */
873038fd1498Szrj tree index;
873138fd1498Szrj
873238fd1498Szrj /* Vector of initializers built up. */
873338fd1498Szrj vec<constructor_elt, va_gc> *inits;
873438fd1498Szrj
873538fd1498Szrj /* The type being constructed by this secondary VTT. */
873638fd1498Szrj tree type_being_constructed;
873738fd1498Szrj };
873838fd1498Szrj
873938fd1498Szrj /* Recursively build the VTT-initializer for BINFO (which is in the
874038fd1498Szrj hierarchy dominated by T). INITS points to the end of the initializer
874138fd1498Szrj list to date. INDEX is the VTT index where the next element will be
874238fd1498Szrj replaced. Iff BINFO is the binfo for T, this is the top level VTT (i.e.
874338fd1498Szrj not a subvtt for some base of T). When that is so, we emit the sub-VTTs
874438fd1498Szrj for virtual bases of T. When it is not so, we build the constructor
874538fd1498Szrj vtables for the BINFO-in-T variant. */
874638fd1498Szrj
874738fd1498Szrj static void
build_vtt_inits(tree binfo,tree t,vec<constructor_elt,va_gc> ** inits,tree * index)874838fd1498Szrj build_vtt_inits (tree binfo, tree t, vec<constructor_elt, va_gc> **inits,
874938fd1498Szrj tree *index)
875038fd1498Szrj {
875138fd1498Szrj int i;
875238fd1498Szrj tree b;
875338fd1498Szrj tree init;
875438fd1498Szrj secondary_vptr_vtt_init_data data;
875538fd1498Szrj int top_level_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
875638fd1498Szrj
875738fd1498Szrj /* We only need VTTs for subobjects with virtual bases. */
875838fd1498Szrj if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
875938fd1498Szrj return;
876038fd1498Szrj
876138fd1498Szrj /* We need to use a construction vtable if this is not the primary
876238fd1498Szrj VTT. */
876338fd1498Szrj if (!top_level_p)
876438fd1498Szrj {
876538fd1498Szrj build_ctor_vtbl_group (binfo, t);
876638fd1498Szrj
876738fd1498Szrj /* Record the offset in the VTT where this sub-VTT can be found. */
876838fd1498Szrj BINFO_SUBVTT_INDEX (binfo) = *index;
876938fd1498Szrj }
877038fd1498Szrj
877138fd1498Szrj /* Add the address of the primary vtable for the complete object. */
877238fd1498Szrj init = binfo_ctor_vtable (binfo);
877338fd1498Szrj CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init);
877438fd1498Szrj if (top_level_p)
877538fd1498Szrj {
877638fd1498Szrj gcc_assert (!BINFO_VPTR_INDEX (binfo));
877738fd1498Szrj BINFO_VPTR_INDEX (binfo) = *index;
877838fd1498Szrj }
877938fd1498Szrj *index = size_binop (PLUS_EXPR, *index, TYPE_SIZE_UNIT (ptr_type_node));
878038fd1498Szrj
878138fd1498Szrj /* Recursively add the secondary VTTs for non-virtual bases. */
878238fd1498Szrj for (i = 0; BINFO_BASE_ITERATE (binfo, i, b); ++i)
878338fd1498Szrj if (!BINFO_VIRTUAL_P (b))
878438fd1498Szrj build_vtt_inits (b, t, inits, index);
878538fd1498Szrj
878638fd1498Szrj /* Add secondary virtual pointers for all subobjects of BINFO with
878738fd1498Szrj either virtual bases or reachable along a virtual path, except
878838fd1498Szrj subobjects that are non-virtual primary bases. */
878938fd1498Szrj data.top_level_p = top_level_p;
879038fd1498Szrj data.index = *index;
879138fd1498Szrj data.inits = *inits;
879238fd1498Szrj data.type_being_constructed = BINFO_TYPE (binfo);
879338fd1498Szrj
879438fd1498Szrj dfs_walk_once (binfo, dfs_build_secondary_vptr_vtt_inits, NULL, &data);
879538fd1498Szrj
879638fd1498Szrj *index = data.index;
879738fd1498Szrj
879838fd1498Szrj /* data.inits might have grown as we added secondary virtual pointers.
879938fd1498Szrj Make sure our caller knows about the new vector. */
880038fd1498Szrj *inits = data.inits;
880138fd1498Szrj
880238fd1498Szrj if (top_level_p)
880338fd1498Szrj /* Add the secondary VTTs for virtual bases in inheritance graph
880438fd1498Szrj order. */
880538fd1498Szrj for (b = TYPE_BINFO (BINFO_TYPE (binfo)); b; b = TREE_CHAIN (b))
880638fd1498Szrj {
880738fd1498Szrj if (!BINFO_VIRTUAL_P (b))
880838fd1498Szrj continue;
880938fd1498Szrj
881038fd1498Szrj build_vtt_inits (b, t, inits, index);
881138fd1498Szrj }
881238fd1498Szrj else
881338fd1498Szrj /* Remove the ctor vtables we created. */
881438fd1498Szrj dfs_walk_all (binfo, dfs_fixup_binfo_vtbls, NULL, binfo);
881538fd1498Szrj }
881638fd1498Szrj
881738fd1498Szrj /* Called from build_vtt_inits via dfs_walk. BINFO is the binfo for the base
881838fd1498Szrj in most derived. DATA is a SECONDARY_VPTR_VTT_INIT_DATA structure. */
881938fd1498Szrj
882038fd1498Szrj static tree
dfs_build_secondary_vptr_vtt_inits(tree binfo,void * data_)882138fd1498Szrj dfs_build_secondary_vptr_vtt_inits (tree binfo, void *data_)
882238fd1498Szrj {
882338fd1498Szrj secondary_vptr_vtt_init_data *data = (secondary_vptr_vtt_init_data *)data_;
882438fd1498Szrj
882538fd1498Szrj /* We don't care about bases that don't have vtables. */
882638fd1498Szrj if (!TYPE_VFIELD (BINFO_TYPE (binfo)))
882738fd1498Szrj return dfs_skip_bases;
882838fd1498Szrj
882938fd1498Szrj /* We're only interested in proper subobjects of the type being
883038fd1498Szrj constructed. */
883138fd1498Szrj if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), data->type_being_constructed))
883238fd1498Szrj return NULL_TREE;
883338fd1498Szrj
883438fd1498Szrj /* We're only interested in bases with virtual bases or reachable
883538fd1498Szrj via a virtual path from the type being constructed. */
883638fd1498Szrj if (!(CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo))
883738fd1498Szrj || binfo_via_virtual (binfo, data->type_being_constructed)))
883838fd1498Szrj return dfs_skip_bases;
883938fd1498Szrj
884038fd1498Szrj /* We're not interested in non-virtual primary bases. */
884138fd1498Szrj if (!BINFO_VIRTUAL_P (binfo) && BINFO_PRIMARY_P (binfo))
884238fd1498Szrj return NULL_TREE;
884338fd1498Szrj
884438fd1498Szrj /* Record the index where this secondary vptr can be found. */
884538fd1498Szrj if (data->top_level_p)
884638fd1498Szrj {
884738fd1498Szrj gcc_assert (!BINFO_VPTR_INDEX (binfo));
884838fd1498Szrj BINFO_VPTR_INDEX (binfo) = data->index;
884938fd1498Szrj
885038fd1498Szrj if (BINFO_VIRTUAL_P (binfo))
885138fd1498Szrj {
885238fd1498Szrj /* It's a primary virtual base, and this is not a
885338fd1498Szrj construction vtable. Find the base this is primary of in
885438fd1498Szrj the inheritance graph, and use that base's vtable
885538fd1498Szrj now. */
885638fd1498Szrj while (BINFO_PRIMARY_P (binfo))
885738fd1498Szrj binfo = BINFO_INHERITANCE_CHAIN (binfo);
885838fd1498Szrj }
885938fd1498Szrj }
886038fd1498Szrj
886138fd1498Szrj /* Add the initializer for the secondary vptr itself. */
886238fd1498Szrj CONSTRUCTOR_APPEND_ELT (data->inits, NULL_TREE, binfo_ctor_vtable (binfo));
886338fd1498Szrj
886438fd1498Szrj /* Advance the vtt index. */
886538fd1498Szrj data->index = size_binop (PLUS_EXPR, data->index,
886638fd1498Szrj TYPE_SIZE_UNIT (ptr_type_node));
886738fd1498Szrj
886838fd1498Szrj return NULL_TREE;
886938fd1498Szrj }
887038fd1498Szrj
887138fd1498Szrj /* Called from build_vtt_inits via dfs_walk. After building
887238fd1498Szrj constructor vtables and generating the sub-vtt from them, we need
887338fd1498Szrj to restore the BINFO_VTABLES that were scribbled on. DATA is the
887438fd1498Szrj binfo of the base whose sub vtt was generated. */
887538fd1498Szrj
887638fd1498Szrj static tree
dfs_fixup_binfo_vtbls(tree binfo,void * data)887738fd1498Szrj dfs_fixup_binfo_vtbls (tree binfo, void* data)
887838fd1498Szrj {
887938fd1498Szrj tree vtable = BINFO_VTABLE (binfo);
888038fd1498Szrj
888138fd1498Szrj if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
888238fd1498Szrj /* If this class has no vtable, none of its bases do. */
888338fd1498Szrj return dfs_skip_bases;
888438fd1498Szrj
888538fd1498Szrj if (!vtable)
888638fd1498Szrj /* This might be a primary base, so have no vtable in this
888738fd1498Szrj hierarchy. */
888838fd1498Szrj return NULL_TREE;
888938fd1498Szrj
889038fd1498Szrj /* If we scribbled the construction vtable vptr into BINFO, clear it
889138fd1498Szrj out now. */
889238fd1498Szrj if (TREE_CODE (vtable) == TREE_LIST
889338fd1498Szrj && (TREE_PURPOSE (vtable) == (tree) data))
889438fd1498Szrj BINFO_VTABLE (binfo) = TREE_CHAIN (vtable);
889538fd1498Szrj
889638fd1498Szrj return NULL_TREE;
889738fd1498Szrj }
889838fd1498Szrj
889938fd1498Szrj /* Build the construction vtable group for BINFO which is in the
890038fd1498Szrj hierarchy dominated by T. */
890138fd1498Szrj
890238fd1498Szrj static void
build_ctor_vtbl_group(tree binfo,tree t)890338fd1498Szrj build_ctor_vtbl_group (tree binfo, tree t)
890438fd1498Szrj {
890538fd1498Szrj tree type;
890638fd1498Szrj tree vtbl;
890738fd1498Szrj tree id;
890838fd1498Szrj tree vbase;
890938fd1498Szrj vec<constructor_elt, va_gc> *v;
891038fd1498Szrj
891138fd1498Szrj /* See if we've already created this construction vtable group. */
891238fd1498Szrj id = mangle_ctor_vtbl_for_type (t, binfo);
891338fd1498Szrj if (get_global_binding (id))
891438fd1498Szrj return;
891538fd1498Szrj
891638fd1498Szrj gcc_assert (!SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t));
891738fd1498Szrj /* Build a version of VTBL (with the wrong type) for use in
891838fd1498Szrj constructing the addresses of secondary vtables in the
891938fd1498Szrj construction vtable group. */
892038fd1498Szrj vtbl = build_vtable (t, id, ptr_type_node);
892138fd1498Szrj DECL_CONSTRUCTION_VTABLE_P (vtbl) = 1;
892238fd1498Szrj /* Don't export construction vtables from shared libraries. Even on
892338fd1498Szrj targets that don't support hidden visibility, this tells
892438fd1498Szrj can_refer_decl_in_current_unit_p not to assume that it's safe to
892538fd1498Szrj access from a different compilation unit (bz 54314). */
892638fd1498Szrj DECL_VISIBILITY (vtbl) = VISIBILITY_HIDDEN;
892738fd1498Szrj DECL_VISIBILITY_SPECIFIED (vtbl) = true;
892838fd1498Szrj
892938fd1498Szrj v = NULL;
893038fd1498Szrj accumulate_vtbl_inits (binfo, TYPE_BINFO (TREE_TYPE (binfo)),
893138fd1498Szrj binfo, vtbl, t, &v);
893238fd1498Szrj
893338fd1498Szrj /* Add the vtables for each of our virtual bases using the vbase in T
893438fd1498Szrj binfo. */
893538fd1498Szrj for (vbase = TYPE_BINFO (BINFO_TYPE (binfo));
893638fd1498Szrj vbase;
893738fd1498Szrj vbase = TREE_CHAIN (vbase))
893838fd1498Szrj {
893938fd1498Szrj tree b;
894038fd1498Szrj
894138fd1498Szrj if (!BINFO_VIRTUAL_P (vbase))
894238fd1498Szrj continue;
894338fd1498Szrj b = copied_binfo (vbase, binfo);
894438fd1498Szrj
894538fd1498Szrj accumulate_vtbl_inits (b, vbase, binfo, vtbl, t, &v);
894638fd1498Szrj }
894738fd1498Szrj
894838fd1498Szrj /* Figure out the type of the construction vtable. */
894938fd1498Szrj type = build_array_of_n_type (vtable_entry_type, v->length ());
895038fd1498Szrj layout_type (type);
895138fd1498Szrj TREE_TYPE (vtbl) = type;
895238fd1498Szrj DECL_SIZE (vtbl) = DECL_SIZE_UNIT (vtbl) = NULL_TREE;
895338fd1498Szrj layout_decl (vtbl, 0);
895438fd1498Szrj
895538fd1498Szrj /* Initialize the construction vtable. */
895638fd1498Szrj CLASSTYPE_VTABLES (t) = chainon (CLASSTYPE_VTABLES (t), vtbl);
895738fd1498Szrj initialize_artificial_var (vtbl, v);
895838fd1498Szrj dump_vtable (t, binfo, vtbl);
895938fd1498Szrj }
896038fd1498Szrj
896138fd1498Szrj /* Add the vtbl initializers for BINFO (and its bases other than
896238fd1498Szrj non-virtual primaries) to the list of INITS. BINFO is in the
896338fd1498Szrj hierarchy dominated by T. RTTI_BINFO is the binfo within T of
896438fd1498Szrj the constructor the vtbl inits should be accumulated for. (If this
896538fd1498Szrj is the complete object vtbl then RTTI_BINFO will be TYPE_BINFO (T).)
896638fd1498Szrj ORIG_BINFO is the binfo for this object within BINFO_TYPE (RTTI_BINFO).
896738fd1498Szrj BINFO is the active base equivalent of ORIG_BINFO in the inheritance
896838fd1498Szrj graph of T. Both BINFO and ORIG_BINFO will have the same BINFO_TYPE,
896938fd1498Szrj but are not necessarily the same in terms of layout. */
897038fd1498Szrj
897138fd1498Szrj static void
accumulate_vtbl_inits(tree binfo,tree orig_binfo,tree rtti_binfo,tree vtbl,tree t,vec<constructor_elt,va_gc> ** inits)897238fd1498Szrj accumulate_vtbl_inits (tree binfo,
897338fd1498Szrj tree orig_binfo,
897438fd1498Szrj tree rtti_binfo,
897538fd1498Szrj tree vtbl,
897638fd1498Szrj tree t,
897738fd1498Szrj vec<constructor_elt, va_gc> **inits)
897838fd1498Szrj {
897938fd1498Szrj int i;
898038fd1498Szrj tree base_binfo;
898138fd1498Szrj int ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
898238fd1498Szrj
898338fd1498Szrj gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), BINFO_TYPE (orig_binfo)));
898438fd1498Szrj
898538fd1498Szrj /* If it doesn't have a vptr, we don't do anything. */
898638fd1498Szrj if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
898738fd1498Szrj return;
898838fd1498Szrj
898938fd1498Szrj /* If we're building a construction vtable, we're not interested in
899038fd1498Szrj subobjects that don't require construction vtables. */
899138fd1498Szrj if (ctor_vtbl_p
899238fd1498Szrj && !CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo))
899338fd1498Szrj && !binfo_via_virtual (orig_binfo, BINFO_TYPE (rtti_binfo)))
899438fd1498Szrj return;
899538fd1498Szrj
899638fd1498Szrj /* Build the initializers for the BINFO-in-T vtable. */
899738fd1498Szrj dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, vtbl, t, inits);
899838fd1498Szrj
899938fd1498Szrj /* Walk the BINFO and its bases. We walk in preorder so that as we
900038fd1498Szrj initialize each vtable we can figure out at what offset the
900138fd1498Szrj secondary vtable lies from the primary vtable. We can't use
900238fd1498Szrj dfs_walk here because we need to iterate through bases of BINFO
900338fd1498Szrj and RTTI_BINFO simultaneously. */
900438fd1498Szrj for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
900538fd1498Szrj {
900638fd1498Szrj /* Skip virtual bases. */
900738fd1498Szrj if (BINFO_VIRTUAL_P (base_binfo))
900838fd1498Szrj continue;
900938fd1498Szrj accumulate_vtbl_inits (base_binfo,
901038fd1498Szrj BINFO_BASE_BINFO (orig_binfo, i),
901138fd1498Szrj rtti_binfo, vtbl, t,
901238fd1498Szrj inits);
901338fd1498Szrj }
901438fd1498Szrj }
901538fd1498Szrj
901638fd1498Szrj /* Called from accumulate_vtbl_inits. Adds the initializers for the
901738fd1498Szrj BINFO vtable to L. */
901838fd1498Szrj
901938fd1498Szrj static void
dfs_accumulate_vtbl_inits(tree binfo,tree orig_binfo,tree rtti_binfo,tree orig_vtbl,tree t,vec<constructor_elt,va_gc> ** l)902038fd1498Szrj dfs_accumulate_vtbl_inits (tree binfo,
902138fd1498Szrj tree orig_binfo,
902238fd1498Szrj tree rtti_binfo,
902338fd1498Szrj tree orig_vtbl,
902438fd1498Szrj tree t,
902538fd1498Szrj vec<constructor_elt, va_gc> **l)
902638fd1498Szrj {
902738fd1498Szrj tree vtbl = NULL_TREE;
902838fd1498Szrj int ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
902938fd1498Szrj int n_inits;
903038fd1498Szrj
903138fd1498Szrj if (ctor_vtbl_p
903238fd1498Szrj && BINFO_VIRTUAL_P (orig_binfo) && BINFO_PRIMARY_P (orig_binfo))
903338fd1498Szrj {
903438fd1498Szrj /* In the hierarchy of BINFO_TYPE (RTTI_BINFO), this is a
903538fd1498Szrj primary virtual base. If it is not the same primary in
903638fd1498Szrj the hierarchy of T, we'll need to generate a ctor vtable
903738fd1498Szrj for it, to place at its location in T. If it is the same
903838fd1498Szrj primary, we still need a VTT entry for the vtable, but it
903938fd1498Szrj should point to the ctor vtable for the base it is a
904038fd1498Szrj primary for within the sub-hierarchy of RTTI_BINFO.
904138fd1498Szrj
904238fd1498Szrj There are three possible cases:
904338fd1498Szrj
904438fd1498Szrj 1) We are in the same place.
904538fd1498Szrj 2) We are a primary base within a lost primary virtual base of
904638fd1498Szrj RTTI_BINFO.
904738fd1498Szrj 3) We are primary to something not a base of RTTI_BINFO. */
904838fd1498Szrj
904938fd1498Szrj tree b;
905038fd1498Szrj tree last = NULL_TREE;
905138fd1498Szrj
905238fd1498Szrj /* First, look through the bases we are primary to for RTTI_BINFO
905338fd1498Szrj or a virtual base. */
905438fd1498Szrj b = binfo;
905538fd1498Szrj while (BINFO_PRIMARY_P (b))
905638fd1498Szrj {
905738fd1498Szrj b = BINFO_INHERITANCE_CHAIN (b);
905838fd1498Szrj last = b;
905938fd1498Szrj if (BINFO_VIRTUAL_P (b) || b == rtti_binfo)
906038fd1498Szrj goto found;
906138fd1498Szrj }
906238fd1498Szrj /* If we run out of primary links, keep looking down our
906338fd1498Szrj inheritance chain; we might be an indirect primary. */
906438fd1498Szrj for (b = last; b; b = BINFO_INHERITANCE_CHAIN (b))
906538fd1498Szrj if (BINFO_VIRTUAL_P (b) || b == rtti_binfo)
906638fd1498Szrj break;
906738fd1498Szrj found:
906838fd1498Szrj
906938fd1498Szrj /* If we found RTTI_BINFO, this is case 1. If we found a virtual
907038fd1498Szrj base B and it is a base of RTTI_BINFO, this is case 2. In
907138fd1498Szrj either case, we share our vtable with LAST, i.e. the
907238fd1498Szrj derived-most base within B of which we are a primary. */
907338fd1498Szrj if (b == rtti_binfo
907438fd1498Szrj || (b && binfo_for_vbase (BINFO_TYPE (b), BINFO_TYPE (rtti_binfo))))
907538fd1498Szrj /* Just set our BINFO_VTABLE to point to LAST, as we may not have
907638fd1498Szrj set LAST's BINFO_VTABLE yet. We'll extract the actual vptr in
907738fd1498Szrj binfo_ctor_vtable after everything's been set up. */
907838fd1498Szrj vtbl = last;
907938fd1498Szrj
908038fd1498Szrj /* Otherwise, this is case 3 and we get our own. */
908138fd1498Szrj }
908238fd1498Szrj else if (!BINFO_NEW_VTABLE_MARKED (orig_binfo))
908338fd1498Szrj return;
908438fd1498Szrj
908538fd1498Szrj n_inits = vec_safe_length (*l);
908638fd1498Szrj
908738fd1498Szrj if (!vtbl)
908838fd1498Szrj {
908938fd1498Szrj tree index;
909038fd1498Szrj int non_fn_entries;
909138fd1498Szrj
909238fd1498Szrj /* Add the initializer for this vtable. */
909338fd1498Szrj build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo,
909438fd1498Szrj &non_fn_entries, l);
909538fd1498Szrj
909638fd1498Szrj /* Figure out the position to which the VPTR should point. */
909738fd1498Szrj vtbl = build1 (ADDR_EXPR, vtbl_ptr_type_node, orig_vtbl);
909838fd1498Szrj index = size_binop (MULT_EXPR,
909938fd1498Szrj TYPE_SIZE_UNIT (vtable_entry_type),
910038fd1498Szrj size_int (non_fn_entries + n_inits));
910138fd1498Szrj vtbl = fold_build_pointer_plus (vtbl, index);
910238fd1498Szrj }
910338fd1498Szrj
910438fd1498Szrj if (ctor_vtbl_p)
910538fd1498Szrj /* For a construction vtable, we can't overwrite BINFO_VTABLE.
910638fd1498Szrj So, we make a TREE_LIST. Later, dfs_fixup_binfo_vtbls will
910738fd1498Szrj straighten this out. */
910838fd1498Szrj BINFO_VTABLE (binfo) = tree_cons (rtti_binfo, vtbl, BINFO_VTABLE (binfo));
910938fd1498Szrj else if (BINFO_PRIMARY_P (binfo) && BINFO_VIRTUAL_P (binfo))
911038fd1498Szrj /* Throw away any unneeded intializers. */
911138fd1498Szrj (*l)->truncate (n_inits);
911238fd1498Szrj else
911338fd1498Szrj /* For an ordinary vtable, set BINFO_VTABLE. */
911438fd1498Szrj BINFO_VTABLE (binfo) = vtbl;
911538fd1498Szrj }
911638fd1498Szrj
911738fd1498Szrj static GTY(()) tree abort_fndecl_addr;
911838fd1498Szrj static GTY(()) tree dvirt_fn;
911938fd1498Szrj
912038fd1498Szrj /* Construct the initializer for BINFO's virtual function table. BINFO
912138fd1498Szrj is part of the hierarchy dominated by T. If we're building a
912238fd1498Szrj construction vtable, the ORIG_BINFO is the binfo we should use to
912338fd1498Szrj find the actual function pointers to put in the vtable - but they
912438fd1498Szrj can be overridden on the path to most-derived in the graph that
912538fd1498Szrj ORIG_BINFO belongs. Otherwise,
912638fd1498Szrj ORIG_BINFO should be the same as BINFO. The RTTI_BINFO is the
912738fd1498Szrj BINFO that should be indicated by the RTTI information in the
912838fd1498Szrj vtable; it will be a base class of T, rather than T itself, if we
912938fd1498Szrj are building a construction vtable.
913038fd1498Szrj
913138fd1498Szrj The value returned is a TREE_LIST suitable for wrapping in a
913238fd1498Szrj CONSTRUCTOR to use as the DECL_INITIAL for a vtable. If
913338fd1498Szrj NON_FN_ENTRIES_P is not NULL, *NON_FN_ENTRIES_P is set to the
913438fd1498Szrj number of non-function entries in the vtable.
913538fd1498Szrj
913638fd1498Szrj It might seem that this function should never be called with a
913738fd1498Szrj BINFO for which BINFO_PRIMARY_P holds, the vtable for such a
913838fd1498Szrj base is always subsumed by a derived class vtable. However, when
913938fd1498Szrj we are building construction vtables, we do build vtables for
914038fd1498Szrj primary bases; we need these while the primary base is being
914138fd1498Szrj constructed. */
914238fd1498Szrj
914338fd1498Szrj static void
build_vtbl_initializer(tree binfo,tree orig_binfo,tree t,tree rtti_binfo,int * non_fn_entries_p,vec<constructor_elt,va_gc> ** inits)914438fd1498Szrj build_vtbl_initializer (tree binfo,
914538fd1498Szrj tree orig_binfo,
914638fd1498Szrj tree t,
914738fd1498Szrj tree rtti_binfo,
914838fd1498Szrj int* non_fn_entries_p,
914938fd1498Szrj vec<constructor_elt, va_gc> **inits)
915038fd1498Szrj {
915138fd1498Szrj tree v;
915238fd1498Szrj vtbl_init_data vid;
915338fd1498Szrj unsigned ix, jx;
915438fd1498Szrj tree vbinfo;
915538fd1498Szrj vec<tree, va_gc> *vbases;
915638fd1498Szrj constructor_elt *e;
915738fd1498Szrj
915838fd1498Szrj /* Initialize VID. */
915938fd1498Szrj memset (&vid, 0, sizeof (vid));
916038fd1498Szrj vid.binfo = binfo;
916138fd1498Szrj vid.derived = t;
916238fd1498Szrj vid.rtti_binfo = rtti_binfo;
916338fd1498Szrj vid.primary_vtbl_p = SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t);
916438fd1498Szrj vid.ctor_vtbl_p = !SAME_BINFO_TYPE_P (BINFO_TYPE (rtti_binfo), t);
916538fd1498Szrj vid.generate_vcall_entries = true;
916638fd1498Szrj /* The first vbase or vcall offset is at index -3 in the vtable. */
916738fd1498Szrj vid.index = ssize_int(-3 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
916838fd1498Szrj
916938fd1498Szrj /* Add entries to the vtable for RTTI. */
917038fd1498Szrj build_rtti_vtbl_entries (binfo, &vid);
917138fd1498Szrj
917238fd1498Szrj /* Create an array for keeping track of the functions we've
917338fd1498Szrj processed. When we see multiple functions with the same
917438fd1498Szrj signature, we share the vcall offsets. */
917538fd1498Szrj vec_alloc (vid.fns, 32);
917638fd1498Szrj /* Add the vcall and vbase offset entries. */
917738fd1498Szrj build_vcall_and_vbase_vtbl_entries (binfo, &vid);
917838fd1498Szrj
917938fd1498Szrj /* Clear BINFO_VTABLE_PATH_MARKED; it's set by
918038fd1498Szrj build_vbase_offset_vtbl_entries. */
918138fd1498Szrj for (vbases = CLASSTYPE_VBASECLASSES (t), ix = 0;
918238fd1498Szrj vec_safe_iterate (vbases, ix, &vbinfo); ix++)
918338fd1498Szrj BINFO_VTABLE_PATH_MARKED (vbinfo) = 0;
918438fd1498Szrj
918538fd1498Szrj /* If the target requires padding between data entries, add that now. */
918638fd1498Szrj if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1)
918738fd1498Szrj {
918838fd1498Szrj int n_entries = vec_safe_length (vid.inits);
918938fd1498Szrj
919038fd1498Szrj vec_safe_grow (vid.inits, TARGET_VTABLE_DATA_ENTRY_DISTANCE * n_entries);
919138fd1498Szrj
919238fd1498Szrj /* Move data entries into their new positions and add padding
919338fd1498Szrj after the new positions. Iterate backwards so we don't
919438fd1498Szrj overwrite entries that we would need to process later. */
919538fd1498Szrj for (ix = n_entries - 1;
919638fd1498Szrj vid.inits->iterate (ix, &e);
919738fd1498Szrj ix--)
919838fd1498Szrj {
919938fd1498Szrj int j;
920038fd1498Szrj int new_position = (TARGET_VTABLE_DATA_ENTRY_DISTANCE * ix
920138fd1498Szrj + (TARGET_VTABLE_DATA_ENTRY_DISTANCE - 1));
920238fd1498Szrj
920338fd1498Szrj (*vid.inits)[new_position] = *e;
920438fd1498Szrj
920538fd1498Szrj for (j = 1; j < TARGET_VTABLE_DATA_ENTRY_DISTANCE; ++j)
920638fd1498Szrj {
920738fd1498Szrj constructor_elt *f = &(*vid.inits)[new_position - j];
920838fd1498Szrj f->index = NULL_TREE;
920938fd1498Szrj f->value = build1 (NOP_EXPR, vtable_entry_type,
921038fd1498Szrj null_pointer_node);
921138fd1498Szrj }
921238fd1498Szrj }
921338fd1498Szrj }
921438fd1498Szrj
921538fd1498Szrj if (non_fn_entries_p)
921638fd1498Szrj *non_fn_entries_p = vec_safe_length (vid.inits);
921738fd1498Szrj
921838fd1498Szrj /* The initializers for virtual functions were built up in reverse
921938fd1498Szrj order. Straighten them out and add them to the running list in one
922038fd1498Szrj step. */
922138fd1498Szrj jx = vec_safe_length (*inits);
922238fd1498Szrj vec_safe_grow (*inits, jx + vid.inits->length ());
922338fd1498Szrj
922438fd1498Szrj for (ix = vid.inits->length () - 1;
922538fd1498Szrj vid.inits->iterate (ix, &e);
922638fd1498Szrj ix--, jx++)
922738fd1498Szrj (**inits)[jx] = *e;
922838fd1498Szrj
922938fd1498Szrj /* Go through all the ordinary virtual functions, building up
923038fd1498Szrj initializers. */
923138fd1498Szrj for (v = BINFO_VIRTUALS (orig_binfo); v; v = TREE_CHAIN (v))
923238fd1498Szrj {
923338fd1498Szrj tree delta;
923438fd1498Szrj tree vcall_index;
923538fd1498Szrj tree fn, fn_original;
923638fd1498Szrj tree init = NULL_TREE;
923738fd1498Szrj
923838fd1498Szrj fn = BV_FN (v);
923938fd1498Szrj fn_original = fn;
924038fd1498Szrj if (DECL_THUNK_P (fn))
924138fd1498Szrj {
924238fd1498Szrj if (!DECL_NAME (fn))
924338fd1498Szrj finish_thunk (fn);
924438fd1498Szrj if (THUNK_ALIAS (fn))
924538fd1498Szrj {
924638fd1498Szrj fn = THUNK_ALIAS (fn);
924738fd1498Szrj BV_FN (v) = fn;
924838fd1498Szrj }
924938fd1498Szrj fn_original = THUNK_TARGET (fn);
925038fd1498Szrj }
925138fd1498Szrj
925238fd1498Szrj /* If the only definition of this function signature along our
925338fd1498Szrj primary base chain is from a lost primary, this vtable slot will
925438fd1498Szrj never be used, so just zero it out. This is important to avoid
925538fd1498Szrj requiring extra thunks which cannot be generated with the function.
925638fd1498Szrj
925738fd1498Szrj We first check this in update_vtable_entry_for_fn, so we handle
925838fd1498Szrj restored primary bases properly; we also need to do it here so we
925938fd1498Szrj zero out unused slots in ctor vtables, rather than filling them
926038fd1498Szrj with erroneous values (though harmless, apart from relocation
926138fd1498Szrj costs). */
926238fd1498Szrj if (BV_LOST_PRIMARY (v))
926338fd1498Szrj init = size_zero_node;
926438fd1498Szrj
926538fd1498Szrj if (! init)
926638fd1498Szrj {
926738fd1498Szrj /* Pull the offset for `this', and the function to call, out of
926838fd1498Szrj the list. */
926938fd1498Szrj delta = BV_DELTA (v);
927038fd1498Szrj vcall_index = BV_VCALL_INDEX (v);
927138fd1498Szrj
927238fd1498Szrj gcc_assert (TREE_CODE (delta) == INTEGER_CST);
927338fd1498Szrj gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
927438fd1498Szrj
927538fd1498Szrj /* You can't call an abstract virtual function; it's abstract.
927638fd1498Szrj So, we replace these functions with __pure_virtual. */
927738fd1498Szrj if (DECL_PURE_VIRTUAL_P (fn_original))
927838fd1498Szrj {
927938fd1498Szrj fn = abort_fndecl;
928038fd1498Szrj if (!TARGET_VTABLE_USES_DESCRIPTORS)
928138fd1498Szrj {
928238fd1498Szrj if (abort_fndecl_addr == NULL)
928338fd1498Szrj abort_fndecl_addr
928438fd1498Szrj = fold_convert (vfunc_ptr_type_node,
928538fd1498Szrj build_fold_addr_expr (fn));
928638fd1498Szrj init = abort_fndecl_addr;
928738fd1498Szrj }
928838fd1498Szrj }
928938fd1498Szrj /* Likewise for deleted virtuals. */
929038fd1498Szrj else if (DECL_DELETED_FN (fn_original))
929138fd1498Szrj {
929238fd1498Szrj if (!dvirt_fn)
929338fd1498Szrj {
929438fd1498Szrj tree name = get_identifier ("__cxa_deleted_virtual");
929538fd1498Szrj dvirt_fn = get_global_binding (name);
929638fd1498Szrj if (!dvirt_fn)
929738fd1498Szrj dvirt_fn = push_library_fn
929838fd1498Szrj (name,
929938fd1498Szrj build_function_type_list (void_type_node, NULL_TREE),
930038fd1498Szrj NULL_TREE, ECF_NORETURN | ECF_COLD);
930138fd1498Szrj }
930238fd1498Szrj fn = dvirt_fn;
930338fd1498Szrj if (!TARGET_VTABLE_USES_DESCRIPTORS)
930438fd1498Szrj init = fold_convert (vfunc_ptr_type_node,
930538fd1498Szrj build_fold_addr_expr (fn));
930638fd1498Szrj }
930738fd1498Szrj else
930838fd1498Szrj {
930938fd1498Szrj if (!integer_zerop (delta) || vcall_index)
931038fd1498Szrj {
931138fd1498Szrj fn = make_thunk (fn, /*this_adjusting=*/1,
931238fd1498Szrj delta, vcall_index);
931338fd1498Szrj if (!DECL_NAME (fn))
931438fd1498Szrj finish_thunk (fn);
931538fd1498Szrj }
931638fd1498Szrj /* Take the address of the function, considering it to be of an
931738fd1498Szrj appropriate generic type. */
931838fd1498Szrj if (!TARGET_VTABLE_USES_DESCRIPTORS)
931938fd1498Szrj init = fold_convert (vfunc_ptr_type_node,
932038fd1498Szrj build_fold_addr_expr (fn));
932138fd1498Szrj /* Don't refer to a virtual destructor from a constructor
932238fd1498Szrj vtable or a vtable for an abstract class, since destroying
932338fd1498Szrj an object under construction is undefined behavior and we
932438fd1498Szrj don't want it to be considered a candidate for speculative
932538fd1498Szrj devirtualization. But do create the thunk for ABI
932638fd1498Szrj compliance. */
932738fd1498Szrj if (DECL_DESTRUCTOR_P (fn_original)
932838fd1498Szrj && (CLASSTYPE_PURE_VIRTUALS (DECL_CONTEXT (fn_original))
932938fd1498Szrj || orig_binfo != binfo))
933038fd1498Szrj init = size_zero_node;
933138fd1498Szrj }
933238fd1498Szrj }
933338fd1498Szrj
933438fd1498Szrj /* And add it to the chain of initializers. */
933538fd1498Szrj if (TARGET_VTABLE_USES_DESCRIPTORS)
933638fd1498Szrj {
933738fd1498Szrj int i;
933838fd1498Szrj if (init == size_zero_node)
933938fd1498Szrj for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
934038fd1498Szrj CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init);
934138fd1498Szrj else
934238fd1498Szrj for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i)
934338fd1498Szrj {
934438fd1498Szrj tree fdesc = build2 (FDESC_EXPR, vfunc_ptr_type_node,
934538fd1498Szrj fn, build_int_cst (NULL_TREE, i));
934638fd1498Szrj TREE_CONSTANT (fdesc) = 1;
934738fd1498Szrj
934838fd1498Szrj CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, fdesc);
934938fd1498Szrj }
935038fd1498Szrj }
935138fd1498Szrj else
935238fd1498Szrj CONSTRUCTOR_APPEND_ELT (*inits, NULL_TREE, init);
935338fd1498Szrj }
935438fd1498Szrj }
935538fd1498Szrj
935638fd1498Szrj /* Adds to vid->inits the initializers for the vbase and vcall
935738fd1498Szrj offsets in BINFO, which is in the hierarchy dominated by T. */
935838fd1498Szrj
935938fd1498Szrj static void
build_vcall_and_vbase_vtbl_entries(tree binfo,vtbl_init_data * vid)936038fd1498Szrj build_vcall_and_vbase_vtbl_entries (tree binfo, vtbl_init_data* vid)
936138fd1498Szrj {
936238fd1498Szrj tree b;
936338fd1498Szrj
936438fd1498Szrj /* If this is a derived class, we must first create entries
936538fd1498Szrj corresponding to the primary base class. */
936638fd1498Szrj b = get_primary_binfo (binfo);
936738fd1498Szrj if (b)
936838fd1498Szrj build_vcall_and_vbase_vtbl_entries (b, vid);
936938fd1498Szrj
937038fd1498Szrj /* Add the vbase entries for this base. */
937138fd1498Szrj build_vbase_offset_vtbl_entries (binfo, vid);
937238fd1498Szrj /* Add the vcall entries for this base. */
937338fd1498Szrj build_vcall_offset_vtbl_entries (binfo, vid);
937438fd1498Szrj }
937538fd1498Szrj
937638fd1498Szrj /* Returns the initializers for the vbase offset entries in the vtable
937738fd1498Szrj for BINFO (which is part of the class hierarchy dominated by T), in
937838fd1498Szrj reverse order. VBASE_OFFSET_INDEX gives the vtable index
937938fd1498Szrj where the next vbase offset will go. */
938038fd1498Szrj
938138fd1498Szrj static void
build_vbase_offset_vtbl_entries(tree binfo,vtbl_init_data * vid)938238fd1498Szrj build_vbase_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
938338fd1498Szrj {
938438fd1498Szrj tree vbase;
938538fd1498Szrj tree t;
938638fd1498Szrj tree non_primary_binfo;
938738fd1498Szrj
938838fd1498Szrj /* If there are no virtual baseclasses, then there is nothing to
938938fd1498Szrj do. */
939038fd1498Szrj if (!CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
939138fd1498Szrj return;
939238fd1498Szrj
939338fd1498Szrj t = vid->derived;
939438fd1498Szrj
939538fd1498Szrj /* We might be a primary base class. Go up the inheritance hierarchy
939638fd1498Szrj until we find the most derived class of which we are a primary base:
939738fd1498Szrj it is the offset of that which we need to use. */
939838fd1498Szrj non_primary_binfo = binfo;
939938fd1498Szrj while (BINFO_INHERITANCE_CHAIN (non_primary_binfo))
940038fd1498Szrj {
940138fd1498Szrj tree b;
940238fd1498Szrj
940338fd1498Szrj /* If we have reached a virtual base, then it must be a primary
940438fd1498Szrj base (possibly multi-level) of vid->binfo, or we wouldn't
940538fd1498Szrj have called build_vcall_and_vbase_vtbl_entries for it. But it
940638fd1498Szrj might be a lost primary, so just skip down to vid->binfo. */
940738fd1498Szrj if (BINFO_VIRTUAL_P (non_primary_binfo))
940838fd1498Szrj {
940938fd1498Szrj non_primary_binfo = vid->binfo;
941038fd1498Szrj break;
941138fd1498Szrj }
941238fd1498Szrj
941338fd1498Szrj b = BINFO_INHERITANCE_CHAIN (non_primary_binfo);
941438fd1498Szrj if (get_primary_binfo (b) != non_primary_binfo)
941538fd1498Szrj break;
941638fd1498Szrj non_primary_binfo = b;
941738fd1498Szrj }
941838fd1498Szrj
941938fd1498Szrj /* Go through the virtual bases, adding the offsets. */
942038fd1498Szrj for (vbase = TYPE_BINFO (BINFO_TYPE (binfo));
942138fd1498Szrj vbase;
942238fd1498Szrj vbase = TREE_CHAIN (vbase))
942338fd1498Szrj {
942438fd1498Szrj tree b;
942538fd1498Szrj tree delta;
942638fd1498Szrj
942738fd1498Szrj if (!BINFO_VIRTUAL_P (vbase))
942838fd1498Szrj continue;
942938fd1498Szrj
943038fd1498Szrj /* Find the instance of this virtual base in the complete
943138fd1498Szrj object. */
943238fd1498Szrj b = copied_binfo (vbase, binfo);
943338fd1498Szrj
943438fd1498Szrj /* If we've already got an offset for this virtual base, we
943538fd1498Szrj don't need another one. */
943638fd1498Szrj if (BINFO_VTABLE_PATH_MARKED (b))
943738fd1498Szrj continue;
943838fd1498Szrj BINFO_VTABLE_PATH_MARKED (b) = 1;
943938fd1498Szrj
944038fd1498Szrj /* Figure out where we can find this vbase offset. */
944138fd1498Szrj delta = size_binop (MULT_EXPR,
944238fd1498Szrj vid->index,
944338fd1498Szrj fold_convert (ssizetype,
944438fd1498Szrj TYPE_SIZE_UNIT (vtable_entry_type)));
944538fd1498Szrj if (vid->primary_vtbl_p)
944638fd1498Szrj BINFO_VPTR_FIELD (b) = delta;
944738fd1498Szrj
944838fd1498Szrj if (binfo != TYPE_BINFO (t))
944938fd1498Szrj /* The vbase offset had better be the same. */
945038fd1498Szrj gcc_assert (tree_int_cst_equal (delta, BINFO_VPTR_FIELD (vbase)));
945138fd1498Szrj
945238fd1498Szrj /* The next vbase will come at a more negative offset. */
945338fd1498Szrj vid->index = size_binop (MINUS_EXPR, vid->index,
945438fd1498Szrj ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE));
945538fd1498Szrj
945638fd1498Szrj /* The initializer is the delta from BINFO to this virtual base.
945738fd1498Szrj The vbase offsets go in reverse inheritance-graph order, and
945838fd1498Szrj we are walking in inheritance graph order so these end up in
945938fd1498Szrj the right order. */
946038fd1498Szrj delta = size_diffop_loc (input_location,
946138fd1498Szrj BINFO_OFFSET (b), BINFO_OFFSET (non_primary_binfo));
946238fd1498Szrj
946338fd1498Szrj CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE,
946438fd1498Szrj fold_build1_loc (input_location, NOP_EXPR,
946538fd1498Szrj vtable_entry_type, delta));
946638fd1498Szrj }
946738fd1498Szrj }
946838fd1498Szrj
946938fd1498Szrj /* Adds the initializers for the vcall offset entries in the vtable
947038fd1498Szrj for BINFO (which is part of the class hierarchy dominated by VID->DERIVED)
947138fd1498Szrj to VID->INITS. */
947238fd1498Szrj
947338fd1498Szrj static void
build_vcall_offset_vtbl_entries(tree binfo,vtbl_init_data * vid)947438fd1498Szrj build_vcall_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
947538fd1498Szrj {
947638fd1498Szrj /* We only need these entries if this base is a virtual base. We
947738fd1498Szrj compute the indices -- but do not add to the vtable -- when
947838fd1498Szrj building the main vtable for a class. */
947938fd1498Szrj if (binfo == TYPE_BINFO (vid->derived)
948038fd1498Szrj || (BINFO_VIRTUAL_P (binfo)
948138fd1498Szrj /* If BINFO is RTTI_BINFO, then (since BINFO does not
948238fd1498Szrj correspond to VID->DERIVED), we are building a primary
948338fd1498Szrj construction virtual table. Since this is a primary
948438fd1498Szrj virtual table, we do not need the vcall offsets for
948538fd1498Szrj BINFO. */
948638fd1498Szrj && binfo != vid->rtti_binfo))
948738fd1498Szrj {
948838fd1498Szrj /* We need a vcall offset for each of the virtual functions in this
948938fd1498Szrj vtable. For example:
949038fd1498Szrj
949138fd1498Szrj class A { virtual void f (); };
949238fd1498Szrj class B1 : virtual public A { virtual void f (); };
949338fd1498Szrj class B2 : virtual public A { virtual void f (); };
949438fd1498Szrj class C: public B1, public B2 { virtual void f (); };
949538fd1498Szrj
949638fd1498Szrj A C object has a primary base of B1, which has a primary base of A. A
949738fd1498Szrj C also has a secondary base of B2, which no longer has a primary base
949838fd1498Szrj of A. So the B2-in-C construction vtable needs a secondary vtable for
949938fd1498Szrj A, which will adjust the A* to a B2* to call f. We have no way of
950038fd1498Szrj knowing what (or even whether) this offset will be when we define B2,
950138fd1498Szrj so we store this "vcall offset" in the A sub-vtable and look it up in
950238fd1498Szrj a "virtual thunk" for B2::f.
950338fd1498Szrj
950438fd1498Szrj We need entries for all the functions in our primary vtable and
950538fd1498Szrj in our non-virtual bases' secondary vtables. */
950638fd1498Szrj vid->vbase = binfo;
950738fd1498Szrj /* If we are just computing the vcall indices -- but do not need
950838fd1498Szrj the actual entries -- not that. */
950938fd1498Szrj if (!BINFO_VIRTUAL_P (binfo))
951038fd1498Szrj vid->generate_vcall_entries = false;
951138fd1498Szrj /* Now, walk through the non-virtual bases, adding vcall offsets. */
951238fd1498Szrj add_vcall_offset_vtbl_entries_r (binfo, vid);
951338fd1498Szrj }
951438fd1498Szrj }
951538fd1498Szrj
951638fd1498Szrj /* Build vcall offsets, starting with those for BINFO. */
951738fd1498Szrj
951838fd1498Szrj static void
add_vcall_offset_vtbl_entries_r(tree binfo,vtbl_init_data * vid)951938fd1498Szrj add_vcall_offset_vtbl_entries_r (tree binfo, vtbl_init_data* vid)
952038fd1498Szrj {
952138fd1498Szrj int i;
952238fd1498Szrj tree primary_binfo;
952338fd1498Szrj tree base_binfo;
952438fd1498Szrj
952538fd1498Szrj /* Don't walk into virtual bases -- except, of course, for the
952638fd1498Szrj virtual base for which we are building vcall offsets. Any
952738fd1498Szrj primary virtual base will have already had its offsets generated
952838fd1498Szrj through the recursion in build_vcall_and_vbase_vtbl_entries. */
952938fd1498Szrj if (BINFO_VIRTUAL_P (binfo) && vid->vbase != binfo)
953038fd1498Szrj return;
953138fd1498Szrj
953238fd1498Szrj /* If BINFO has a primary base, process it first. */
953338fd1498Szrj primary_binfo = get_primary_binfo (binfo);
953438fd1498Szrj if (primary_binfo)
953538fd1498Szrj add_vcall_offset_vtbl_entries_r (primary_binfo, vid);
953638fd1498Szrj
953738fd1498Szrj /* Add BINFO itself to the list. */
953838fd1498Szrj add_vcall_offset_vtbl_entries_1 (binfo, vid);
953938fd1498Szrj
954038fd1498Szrj /* Scan the non-primary bases of BINFO. */
954138fd1498Szrj for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
954238fd1498Szrj if (base_binfo != primary_binfo)
954338fd1498Szrj add_vcall_offset_vtbl_entries_r (base_binfo, vid);
954438fd1498Szrj }
954538fd1498Szrj
954638fd1498Szrj /* Called from build_vcall_offset_vtbl_entries_r. */
954738fd1498Szrj
954838fd1498Szrj static void
add_vcall_offset_vtbl_entries_1(tree binfo,vtbl_init_data * vid)954938fd1498Szrj add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid)
955038fd1498Szrj {
955138fd1498Szrj /* Make entries for the rest of the virtuals. */
955238fd1498Szrj tree orig_fn;
955338fd1498Szrj
955438fd1498Szrj /* The ABI requires that the methods be processed in declaration
955538fd1498Szrj order. */
955638fd1498Szrj for (orig_fn = TYPE_FIELDS (BINFO_TYPE (binfo));
955738fd1498Szrj orig_fn;
955838fd1498Szrj orig_fn = DECL_CHAIN (orig_fn))
955938fd1498Szrj if (TREE_CODE (orig_fn) == FUNCTION_DECL && DECL_VINDEX (orig_fn))
956038fd1498Szrj add_vcall_offset (orig_fn, binfo, vid);
956138fd1498Szrj }
956238fd1498Szrj
956338fd1498Szrj /* Add a vcall offset entry for ORIG_FN to the vtable. */
956438fd1498Szrj
956538fd1498Szrj static void
add_vcall_offset(tree orig_fn,tree binfo,vtbl_init_data * vid)956638fd1498Szrj add_vcall_offset (tree orig_fn, tree binfo, vtbl_init_data *vid)
956738fd1498Szrj {
956838fd1498Szrj size_t i;
956938fd1498Szrj tree vcall_offset;
957038fd1498Szrj tree derived_entry;
957138fd1498Szrj
957238fd1498Szrj /* If there is already an entry for a function with the same
957338fd1498Szrj signature as FN, then we do not need a second vcall offset.
957438fd1498Szrj Check the list of functions already present in the derived
957538fd1498Szrj class vtable. */
957638fd1498Szrj FOR_EACH_VEC_SAFE_ELT (vid->fns, i, derived_entry)
957738fd1498Szrj {
957838fd1498Szrj if (same_signature_p (derived_entry, orig_fn)
957938fd1498Szrj /* We only use one vcall offset for virtual destructors,
958038fd1498Szrj even though there are two virtual table entries. */
958138fd1498Szrj || (DECL_DESTRUCTOR_P (derived_entry)
958238fd1498Szrj && DECL_DESTRUCTOR_P (orig_fn)))
958338fd1498Szrj return;
958438fd1498Szrj }
958538fd1498Szrj
958638fd1498Szrj /* If we are building these vcall offsets as part of building
958738fd1498Szrj the vtable for the most derived class, remember the vcall
958838fd1498Szrj offset. */
958938fd1498Szrj if (vid->binfo == TYPE_BINFO (vid->derived))
959038fd1498Szrj {
959138fd1498Szrj tree_pair_s elt = {orig_fn, vid->index};
959238fd1498Szrj vec_safe_push (CLASSTYPE_VCALL_INDICES (vid->derived), elt);
959338fd1498Szrj }
959438fd1498Szrj
959538fd1498Szrj /* The next vcall offset will be found at a more negative
959638fd1498Szrj offset. */
959738fd1498Szrj vid->index = size_binop (MINUS_EXPR, vid->index,
959838fd1498Szrj ssize_int (TARGET_VTABLE_DATA_ENTRY_DISTANCE));
959938fd1498Szrj
960038fd1498Szrj /* Keep track of this function. */
960138fd1498Szrj vec_safe_push (vid->fns, orig_fn);
960238fd1498Szrj
960338fd1498Szrj if (vid->generate_vcall_entries)
960438fd1498Szrj {
960538fd1498Szrj tree base;
960638fd1498Szrj tree fn;
960738fd1498Szrj
960838fd1498Szrj /* Find the overriding function. */
960938fd1498Szrj fn = find_final_overrider (vid->rtti_binfo, binfo, orig_fn);
961038fd1498Szrj if (fn == error_mark_node)
961138fd1498Szrj vcall_offset = build_zero_cst (vtable_entry_type);
961238fd1498Szrj else
961338fd1498Szrj {
961438fd1498Szrj base = TREE_VALUE (fn);
961538fd1498Szrj
961638fd1498Szrj /* The vbase we're working on is a primary base of
961738fd1498Szrj vid->binfo. But it might be a lost primary, so its
961838fd1498Szrj BINFO_OFFSET might be wrong, so we just use the
961938fd1498Szrj BINFO_OFFSET from vid->binfo. */
962038fd1498Szrj vcall_offset = size_diffop_loc (input_location,
962138fd1498Szrj BINFO_OFFSET (base),
962238fd1498Szrj BINFO_OFFSET (vid->binfo));
962338fd1498Szrj vcall_offset = fold_build1_loc (input_location,
962438fd1498Szrj NOP_EXPR, vtable_entry_type,
962538fd1498Szrj vcall_offset);
962638fd1498Szrj }
962738fd1498Szrj /* Add the initializer to the vtable. */
962838fd1498Szrj CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, vcall_offset);
962938fd1498Szrj }
963038fd1498Szrj }
963138fd1498Szrj
963238fd1498Szrj /* Return vtbl initializers for the RTTI entries corresponding to the
963338fd1498Szrj BINFO's vtable. The RTTI entries should indicate the object given
963438fd1498Szrj by VID->rtti_binfo. */
963538fd1498Szrj
963638fd1498Szrj static void
build_rtti_vtbl_entries(tree binfo,vtbl_init_data * vid)963738fd1498Szrj build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid)
963838fd1498Szrj {
963938fd1498Szrj tree b;
964038fd1498Szrj tree t;
964138fd1498Szrj tree offset;
964238fd1498Szrj tree decl;
964338fd1498Szrj tree init;
964438fd1498Szrj
964538fd1498Szrj t = BINFO_TYPE (vid->rtti_binfo);
964638fd1498Szrj
964738fd1498Szrj /* To find the complete object, we will first convert to our most
964838fd1498Szrj primary base, and then add the offset in the vtbl to that value. */
964938fd1498Szrj b = most_primary_binfo (binfo);
965038fd1498Szrj offset = size_diffop_loc (input_location,
965138fd1498Szrj BINFO_OFFSET (vid->rtti_binfo), BINFO_OFFSET (b));
965238fd1498Szrj
965338fd1498Szrj /* The second entry is the address of the typeinfo object. */
965438fd1498Szrj if (flag_rtti)
965538fd1498Szrj decl = build_address (get_tinfo_decl (t));
965638fd1498Szrj else
965738fd1498Szrj decl = integer_zero_node;
965838fd1498Szrj
965938fd1498Szrj /* Convert the declaration to a type that can be stored in the
966038fd1498Szrj vtable. */
966138fd1498Szrj init = build_nop (vfunc_ptr_type_node, decl);
966238fd1498Szrj CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, init);
966338fd1498Szrj
966438fd1498Szrj /* Add the offset-to-top entry. It comes earlier in the vtable than
966538fd1498Szrj the typeinfo entry. Convert the offset to look like a
966638fd1498Szrj function pointer, so that we can put it in the vtable. */
966738fd1498Szrj init = build_nop (vfunc_ptr_type_node, offset);
966838fd1498Szrj CONSTRUCTOR_APPEND_ELT (vid->inits, NULL_TREE, init);
966938fd1498Szrj }
967038fd1498Szrj
967138fd1498Szrj /* TRUE iff TYPE is uniquely derived from PARENT. Ignores
967238fd1498Szrj accessibility. */
967338fd1498Szrj
967438fd1498Szrj bool
uniquely_derived_from_p(tree parent,tree type)967538fd1498Szrj uniquely_derived_from_p (tree parent, tree type)
967638fd1498Szrj {
967738fd1498Szrj tree base = lookup_base (type, parent, ba_unique, NULL, tf_none);
967838fd1498Szrj return base && base != error_mark_node;
967938fd1498Szrj }
968038fd1498Szrj
968138fd1498Szrj /* TRUE iff TYPE is publicly & uniquely derived from PARENT. */
968238fd1498Szrj
968338fd1498Szrj bool
publicly_uniquely_derived_p(tree parent,tree type)968438fd1498Szrj publicly_uniquely_derived_p (tree parent, tree type)
968538fd1498Szrj {
968638fd1498Szrj tree base = lookup_base (type, parent, ba_ignore_scope | ba_check,
968738fd1498Szrj NULL, tf_none);
968838fd1498Szrj return base && base != error_mark_node;
968938fd1498Szrj }
969038fd1498Szrj
969138fd1498Szrj /* CTX1 and CTX2 are declaration contexts. Return the innermost common
969238fd1498Szrj class between them, if any. */
969338fd1498Szrj
969438fd1498Szrj tree
common_enclosing_class(tree ctx1,tree ctx2)969538fd1498Szrj common_enclosing_class (tree ctx1, tree ctx2)
969638fd1498Szrj {
969738fd1498Szrj if (!TYPE_P (ctx1) || !TYPE_P (ctx2))
969838fd1498Szrj return NULL_TREE;
969938fd1498Szrj gcc_assert (ctx1 == TYPE_MAIN_VARIANT (ctx1)
970038fd1498Szrj && ctx2 == TYPE_MAIN_VARIANT (ctx2));
970138fd1498Szrj if (ctx1 == ctx2)
970238fd1498Szrj return ctx1;
970338fd1498Szrj for (tree t = ctx1; TYPE_P (t); t = TYPE_CONTEXT (t))
970438fd1498Szrj TYPE_MARKED_P (t) = true;
970538fd1498Szrj tree found = NULL_TREE;
970638fd1498Szrj for (tree t = ctx2; TYPE_P (t); t = TYPE_CONTEXT (t))
970738fd1498Szrj if (TYPE_MARKED_P (t))
970838fd1498Szrj {
970938fd1498Szrj found = t;
971038fd1498Szrj break;
971138fd1498Szrj }
971238fd1498Szrj for (tree t = ctx1; TYPE_P (t); t = TYPE_CONTEXT (t))
971338fd1498Szrj TYPE_MARKED_P (t) = false;
971438fd1498Szrj return found;
971538fd1498Szrj }
971638fd1498Szrj
971738fd1498Szrj #include "gt-cp-class.h"
9718