1*e4b17023SJohn Marino /* Handle the hair of processing (but not expanding) inline functions.
2*e4b17023SJohn Marino Also manage function and variable name overloading.
3*e4b17023SJohn Marino Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4*e4b17023SJohn Marino 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
5*e4b17023SJohn Marino Free Software Foundation, Inc.
6*e4b17023SJohn Marino Contributed by Michael Tiemann (tiemann@cygnus.com)
7*e4b17023SJohn Marino
8*e4b17023SJohn Marino This file is part of GCC.
9*e4b17023SJohn Marino
10*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
11*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
12*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
13*e4b17023SJohn Marino any later version.
14*e4b17023SJohn Marino
15*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
16*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
17*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18*e4b17023SJohn Marino GNU General Public License for more details.
19*e4b17023SJohn Marino
20*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
21*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
22*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
23*e4b17023SJohn Marino
24*e4b17023SJohn Marino
25*e4b17023SJohn Marino /* Handle method declarations. */
26*e4b17023SJohn Marino #include "config.h"
27*e4b17023SJohn Marino #include "system.h"
28*e4b17023SJohn Marino #include "coretypes.h"
29*e4b17023SJohn Marino #include "tm.h"
30*e4b17023SJohn Marino #include "tree.h"
31*e4b17023SJohn Marino #include "cp-tree.h"
32*e4b17023SJohn Marino #include "output.h"
33*e4b17023SJohn Marino #include "flags.h"
34*e4b17023SJohn Marino #include "toplev.h"
35*e4b17023SJohn Marino #include "tm_p.h"
36*e4b17023SJohn Marino #include "target.h"
37*e4b17023SJohn Marino #include "common/common-target.h"
38*e4b17023SJohn Marino #include "tree-pass.h"
39*e4b17023SJohn Marino #include "diagnostic.h"
40*e4b17023SJohn Marino #include "cgraph.h"
41*e4b17023SJohn Marino #include "gimple.h"
42*e4b17023SJohn Marino
43*e4b17023SJohn Marino /* Various flags to control the mangling process. */
44*e4b17023SJohn Marino
45*e4b17023SJohn Marino enum mangling_flags
46*e4b17023SJohn Marino {
47*e4b17023SJohn Marino /* No flags. */
48*e4b17023SJohn Marino mf_none = 0,
49*e4b17023SJohn Marino /* The thing we are presently mangling is part of a template type,
50*e4b17023SJohn Marino rather than a fully instantiated type. Therefore, we may see
51*e4b17023SJohn Marino complex expressions where we would normally expect to see a
52*e4b17023SJohn Marino simple integer constant. */
53*e4b17023SJohn Marino mf_maybe_uninstantiated = 1,
54*e4b17023SJohn Marino /* When mangling a numeric value, use the form `_XX_' (instead of
55*e4b17023SJohn Marino just `XX') if the value has more than one digit. */
56*e4b17023SJohn Marino mf_use_underscores_around_value = 2
57*e4b17023SJohn Marino };
58*e4b17023SJohn Marino
59*e4b17023SJohn Marino typedef enum mangling_flags mangling_flags;
60*e4b17023SJohn Marino
61*e4b17023SJohn Marino static void do_build_copy_assign (tree);
62*e4b17023SJohn Marino static void do_build_copy_constructor (tree);
63*e4b17023SJohn Marino static tree make_alias_for_thunk (tree);
64*e4b17023SJohn Marino
65*e4b17023SJohn Marino /* Called once to initialize method.c. */
66*e4b17023SJohn Marino
67*e4b17023SJohn Marino void
init_method(void)68*e4b17023SJohn Marino init_method (void)
69*e4b17023SJohn Marino {
70*e4b17023SJohn Marino init_mangle ();
71*e4b17023SJohn Marino }
72*e4b17023SJohn Marino
73*e4b17023SJohn Marino /* Return a this or result adjusting thunk to FUNCTION. THIS_ADJUSTING
74*e4b17023SJohn Marino indicates whether it is a this or result adjusting thunk.
75*e4b17023SJohn Marino FIXED_OFFSET and VIRTUAL_OFFSET indicate how to do the adjustment
76*e4b17023SJohn Marino (see thunk_adjust). VIRTUAL_OFFSET can be NULL, but FIXED_OFFSET
77*e4b17023SJohn Marino never is. VIRTUAL_OFFSET is the /index/ into the vtable for this
78*e4b17023SJohn Marino adjusting thunks, we scale it to a byte offset. For covariant
79*e4b17023SJohn Marino thunks VIRTUAL_OFFSET is the virtual binfo. You must post process
80*e4b17023SJohn Marino the returned thunk with finish_thunk. */
81*e4b17023SJohn Marino
82*e4b17023SJohn Marino tree
make_thunk(tree function,bool this_adjusting,tree fixed_offset,tree virtual_offset)83*e4b17023SJohn Marino make_thunk (tree function, bool this_adjusting,
84*e4b17023SJohn Marino tree fixed_offset, tree virtual_offset)
85*e4b17023SJohn Marino {
86*e4b17023SJohn Marino HOST_WIDE_INT d;
87*e4b17023SJohn Marino tree thunk;
88*e4b17023SJohn Marino
89*e4b17023SJohn Marino gcc_assert (TREE_CODE (function) == FUNCTION_DECL);
90*e4b17023SJohn Marino /* We can have this thunks to covariant thunks, but not vice versa. */
91*e4b17023SJohn Marino gcc_assert (!DECL_THIS_THUNK_P (function));
92*e4b17023SJohn Marino gcc_assert (!DECL_RESULT_THUNK_P (function) || this_adjusting);
93*e4b17023SJohn Marino
94*e4b17023SJohn Marino /* Scale the VIRTUAL_OFFSET to be in terms of bytes. */
95*e4b17023SJohn Marino if (this_adjusting && virtual_offset)
96*e4b17023SJohn Marino virtual_offset
97*e4b17023SJohn Marino = size_binop (MULT_EXPR,
98*e4b17023SJohn Marino virtual_offset,
99*e4b17023SJohn Marino convert (ssizetype,
100*e4b17023SJohn Marino TYPE_SIZE_UNIT (vtable_entry_type)));
101*e4b17023SJohn Marino
102*e4b17023SJohn Marino d = tree_low_cst (fixed_offset, 0);
103*e4b17023SJohn Marino
104*e4b17023SJohn Marino /* See if we already have the thunk in question. For this_adjusting
105*e4b17023SJohn Marino thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it
106*e4b17023SJohn Marino will be a BINFO. */
107*e4b17023SJohn Marino for (thunk = DECL_THUNKS (function); thunk; thunk = DECL_CHAIN (thunk))
108*e4b17023SJohn Marino if (DECL_THIS_THUNK_P (thunk) == this_adjusting
109*e4b17023SJohn Marino && THUNK_FIXED_OFFSET (thunk) == d
110*e4b17023SJohn Marino && !virtual_offset == !THUNK_VIRTUAL_OFFSET (thunk)
111*e4b17023SJohn Marino && (!virtual_offset
112*e4b17023SJohn Marino || (this_adjusting
113*e4b17023SJohn Marino ? tree_int_cst_equal (THUNK_VIRTUAL_OFFSET (thunk),
114*e4b17023SJohn Marino virtual_offset)
115*e4b17023SJohn Marino : THUNK_VIRTUAL_OFFSET (thunk) == virtual_offset)))
116*e4b17023SJohn Marino return thunk;
117*e4b17023SJohn Marino
118*e4b17023SJohn Marino /* All thunks must be created before FUNCTION is actually emitted;
119*e4b17023SJohn Marino the ABI requires that all thunks be emitted together with the
120*e4b17023SJohn Marino function to which they transfer control. */
121*e4b17023SJohn Marino gcc_assert (!TREE_ASM_WRITTEN (function));
122*e4b17023SJohn Marino /* Likewise, we can only be adding thunks to a function declared in
123*e4b17023SJohn Marino the class currently being laid out. */
124*e4b17023SJohn Marino gcc_assert (TYPE_SIZE (DECL_CONTEXT (function))
125*e4b17023SJohn Marino && TYPE_BEING_DEFINED (DECL_CONTEXT (function)));
126*e4b17023SJohn Marino
127*e4b17023SJohn Marino thunk = build_decl (DECL_SOURCE_LOCATION (function),
128*e4b17023SJohn Marino FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
129*e4b17023SJohn Marino DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
130*e4b17023SJohn Marino cxx_dup_lang_specific_decl (thunk);
131*e4b17023SJohn Marino DECL_THUNKS (thunk) = NULL_TREE;
132*e4b17023SJohn Marino
133*e4b17023SJohn Marino DECL_CONTEXT (thunk) = DECL_CONTEXT (function);
134*e4b17023SJohn Marino TREE_READONLY (thunk) = TREE_READONLY (function);
135*e4b17023SJohn Marino TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
136*e4b17023SJohn Marino TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
137*e4b17023SJohn Marino SET_DECL_THUNK_P (thunk, this_adjusting);
138*e4b17023SJohn Marino THUNK_TARGET (thunk) = function;
139*e4b17023SJohn Marino THUNK_FIXED_OFFSET (thunk) = d;
140*e4b17023SJohn Marino THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset;
141*e4b17023SJohn Marino THUNK_ALIAS (thunk) = NULL_TREE;
142*e4b17023SJohn Marino
143*e4b17023SJohn Marino DECL_INTERFACE_KNOWN (thunk) = 1;
144*e4b17023SJohn Marino DECL_NOT_REALLY_EXTERN (thunk) = 1;
145*e4b17023SJohn Marino DECL_COMDAT (thunk) = DECL_COMDAT (function);
146*e4b17023SJohn Marino DECL_SAVED_FUNCTION_DATA (thunk) = NULL;
147*e4b17023SJohn Marino /* The thunk itself is not a constructor or destructor, even if
148*e4b17023SJohn Marino the thing it is thunking to is. */
149*e4b17023SJohn Marino DECL_DESTRUCTOR_P (thunk) = 0;
150*e4b17023SJohn Marino DECL_CONSTRUCTOR_P (thunk) = 0;
151*e4b17023SJohn Marino DECL_EXTERNAL (thunk) = 1;
152*e4b17023SJohn Marino DECL_ARTIFICIAL (thunk) = 1;
153*e4b17023SJohn Marino /* The THUNK is not a pending inline, even if the FUNCTION is. */
154*e4b17023SJohn Marino DECL_PENDING_INLINE_P (thunk) = 0;
155*e4b17023SJohn Marino DECL_DECLARED_INLINE_P (thunk) = 0;
156*e4b17023SJohn Marino /* Nor is it a template instantiation. */
157*e4b17023SJohn Marino DECL_USE_TEMPLATE (thunk) = 0;
158*e4b17023SJohn Marino DECL_TEMPLATE_INFO (thunk) = NULL;
159*e4b17023SJohn Marino
160*e4b17023SJohn Marino /* Add it to the list of thunks associated with FUNCTION. */
161*e4b17023SJohn Marino DECL_CHAIN (thunk) = DECL_THUNKS (function);
162*e4b17023SJohn Marino DECL_THUNKS (function) = thunk;
163*e4b17023SJohn Marino
164*e4b17023SJohn Marino return thunk;
165*e4b17023SJohn Marino }
166*e4b17023SJohn Marino
167*e4b17023SJohn Marino /* Finish THUNK, a thunk decl. */
168*e4b17023SJohn Marino
169*e4b17023SJohn Marino void
finish_thunk(tree thunk)170*e4b17023SJohn Marino finish_thunk (tree thunk)
171*e4b17023SJohn Marino {
172*e4b17023SJohn Marino tree function, name;
173*e4b17023SJohn Marino tree fixed_offset = ssize_int (THUNK_FIXED_OFFSET (thunk));
174*e4b17023SJohn Marino tree virtual_offset = THUNK_VIRTUAL_OFFSET (thunk);
175*e4b17023SJohn Marino
176*e4b17023SJohn Marino gcc_assert (!DECL_NAME (thunk) && DECL_THUNK_P (thunk));
177*e4b17023SJohn Marino if (virtual_offset && DECL_RESULT_THUNK_P (thunk))
178*e4b17023SJohn Marino virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
179*e4b17023SJohn Marino function = THUNK_TARGET (thunk);
180*e4b17023SJohn Marino name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk),
181*e4b17023SJohn Marino fixed_offset, virtual_offset);
182*e4b17023SJohn Marino
183*e4b17023SJohn Marino /* We can end up with declarations of (logically) different
184*e4b17023SJohn Marino covariant thunks, that do identical adjustments. The two thunks
185*e4b17023SJohn Marino will be adjusting between within different hierarchies, which
186*e4b17023SJohn Marino happen to have the same layout. We must nullify one of them to
187*e4b17023SJohn Marino refer to the other. */
188*e4b17023SJohn Marino if (DECL_RESULT_THUNK_P (thunk))
189*e4b17023SJohn Marino {
190*e4b17023SJohn Marino tree cov_probe;
191*e4b17023SJohn Marino
192*e4b17023SJohn Marino for (cov_probe = DECL_THUNKS (function);
193*e4b17023SJohn Marino cov_probe; cov_probe = DECL_CHAIN (cov_probe))
194*e4b17023SJohn Marino if (DECL_NAME (cov_probe) == name)
195*e4b17023SJohn Marino {
196*e4b17023SJohn Marino gcc_assert (!DECL_THUNKS (thunk));
197*e4b17023SJohn Marino THUNK_ALIAS (thunk) = (THUNK_ALIAS (cov_probe)
198*e4b17023SJohn Marino ? THUNK_ALIAS (cov_probe) : cov_probe);
199*e4b17023SJohn Marino break;
200*e4b17023SJohn Marino }
201*e4b17023SJohn Marino }
202*e4b17023SJohn Marino
203*e4b17023SJohn Marino DECL_NAME (thunk) = name;
204*e4b17023SJohn Marino SET_DECL_ASSEMBLER_NAME (thunk, name);
205*e4b17023SJohn Marino }
206*e4b17023SJohn Marino
207*e4b17023SJohn Marino static GTY (()) int thunk_labelno;
208*e4b17023SJohn Marino
209*e4b17023SJohn Marino /* Create a static alias to target. */
210*e4b17023SJohn Marino
211*e4b17023SJohn Marino tree
make_alias_for(tree target,tree newid)212*e4b17023SJohn Marino make_alias_for (tree target, tree newid)
213*e4b17023SJohn Marino {
214*e4b17023SJohn Marino tree alias = build_decl (DECL_SOURCE_LOCATION (target),
215*e4b17023SJohn Marino TREE_CODE (target), newid, TREE_TYPE (target));
216*e4b17023SJohn Marino DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (target);
217*e4b17023SJohn Marino cxx_dup_lang_specific_decl (alias);
218*e4b17023SJohn Marino DECL_CONTEXT (alias) = NULL;
219*e4b17023SJohn Marino TREE_READONLY (alias) = TREE_READONLY (target);
220*e4b17023SJohn Marino TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (target);
221*e4b17023SJohn Marino TREE_PUBLIC (alias) = 0;
222*e4b17023SJohn Marino DECL_INTERFACE_KNOWN (alias) = 1;
223*e4b17023SJohn Marino if (DECL_LANG_SPECIFIC (alias))
224*e4b17023SJohn Marino {
225*e4b17023SJohn Marino DECL_NOT_REALLY_EXTERN (alias) = 1;
226*e4b17023SJohn Marino DECL_USE_TEMPLATE (alias) = 0;
227*e4b17023SJohn Marino DECL_TEMPLATE_INFO (alias) = NULL;
228*e4b17023SJohn Marino }
229*e4b17023SJohn Marino DECL_EXTERNAL (alias) = 0;
230*e4b17023SJohn Marino DECL_ARTIFICIAL (alias) = 1;
231*e4b17023SJohn Marino DECL_TEMPLATE_INSTANTIATED (alias) = 0;
232*e4b17023SJohn Marino if (TREE_CODE (alias) == FUNCTION_DECL)
233*e4b17023SJohn Marino {
234*e4b17023SJohn Marino DECL_SAVED_FUNCTION_DATA (alias) = NULL;
235*e4b17023SJohn Marino DECL_DESTRUCTOR_P (alias) = 0;
236*e4b17023SJohn Marino DECL_CONSTRUCTOR_P (alias) = 0;
237*e4b17023SJohn Marino DECL_PENDING_INLINE_P (alias) = 0;
238*e4b17023SJohn Marino DECL_DECLARED_INLINE_P (alias) = 0;
239*e4b17023SJohn Marino DECL_INITIAL (alias) = error_mark_node;
240*e4b17023SJohn Marino DECL_ARGUMENTS (alias) = copy_list (DECL_ARGUMENTS (target));
241*e4b17023SJohn Marino }
242*e4b17023SJohn Marino else
243*e4b17023SJohn Marino TREE_STATIC (alias) = 1;
244*e4b17023SJohn Marino TREE_ADDRESSABLE (alias) = 1;
245*e4b17023SJohn Marino TREE_USED (alias) = 1;
246*e4b17023SJohn Marino SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
247*e4b17023SJohn Marino TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
248*e4b17023SJohn Marino return alias;
249*e4b17023SJohn Marino }
250*e4b17023SJohn Marino
251*e4b17023SJohn Marino static tree
make_alias_for_thunk(tree function)252*e4b17023SJohn Marino make_alias_for_thunk (tree function)
253*e4b17023SJohn Marino {
254*e4b17023SJohn Marino tree alias;
255*e4b17023SJohn Marino char buf[256];
256*e4b17023SJohn Marino
257*e4b17023SJohn Marino targetm.asm_out.generate_internal_label (buf, "LTHUNK", thunk_labelno);
258*e4b17023SJohn Marino thunk_labelno++;
259*e4b17023SJohn Marino
260*e4b17023SJohn Marino alias = make_alias_for (function, get_identifier (buf));
261*e4b17023SJohn Marino
262*e4b17023SJohn Marino if (!flag_syntax_only)
263*e4b17023SJohn Marino {
264*e4b17023SJohn Marino struct cgraph_node *funcn, *aliasn;
265*e4b17023SJohn Marino funcn = cgraph_get_node (function);
266*e4b17023SJohn Marino gcc_checking_assert (funcn);
267*e4b17023SJohn Marino aliasn = cgraph_same_body_alias (funcn, alias, function);
268*e4b17023SJohn Marino DECL_ASSEMBLER_NAME (function);
269*e4b17023SJohn Marino gcc_assert (aliasn != NULL);
270*e4b17023SJohn Marino }
271*e4b17023SJohn Marino
272*e4b17023SJohn Marino return alias;
273*e4b17023SJohn Marino }
274*e4b17023SJohn Marino
275*e4b17023SJohn Marino /* Emit the definition of a C++ multiple inheritance or covariant
276*e4b17023SJohn Marino return vtable thunk. If EMIT_P is nonzero, the thunk is emitted
277*e4b17023SJohn Marino immediately. */
278*e4b17023SJohn Marino
279*e4b17023SJohn Marino void
use_thunk(tree thunk_fndecl,bool emit_p)280*e4b17023SJohn Marino use_thunk (tree thunk_fndecl, bool emit_p)
281*e4b17023SJohn Marino {
282*e4b17023SJohn Marino tree a, t, function, alias;
283*e4b17023SJohn Marino tree virtual_offset;
284*e4b17023SJohn Marino HOST_WIDE_INT fixed_offset, virtual_value;
285*e4b17023SJohn Marino bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
286*e4b17023SJohn Marino struct cgraph_node *funcn, *thunk_node;
287*e4b17023SJohn Marino
288*e4b17023SJohn Marino /* We should have called finish_thunk to give it a name. */
289*e4b17023SJohn Marino gcc_assert (DECL_NAME (thunk_fndecl));
290*e4b17023SJohn Marino
291*e4b17023SJohn Marino /* We should never be using an alias, always refer to the
292*e4b17023SJohn Marino aliased thunk. */
293*e4b17023SJohn Marino gcc_assert (!THUNK_ALIAS (thunk_fndecl));
294*e4b17023SJohn Marino
295*e4b17023SJohn Marino if (TREE_ASM_WRITTEN (thunk_fndecl))
296*e4b17023SJohn Marino return;
297*e4b17023SJohn Marino
298*e4b17023SJohn Marino function = THUNK_TARGET (thunk_fndecl);
299*e4b17023SJohn Marino if (DECL_RESULT (thunk_fndecl))
300*e4b17023SJohn Marino /* We already turned this thunk into an ordinary function.
301*e4b17023SJohn Marino There's no need to process this thunk again. */
302*e4b17023SJohn Marino return;
303*e4b17023SJohn Marino
304*e4b17023SJohn Marino if (DECL_THUNK_P (function))
305*e4b17023SJohn Marino /* The target is itself a thunk, process it now. */
306*e4b17023SJohn Marino use_thunk (function, emit_p);
307*e4b17023SJohn Marino
308*e4b17023SJohn Marino /* Thunks are always addressable; they only appear in vtables. */
309*e4b17023SJohn Marino TREE_ADDRESSABLE (thunk_fndecl) = 1;
310*e4b17023SJohn Marino
311*e4b17023SJohn Marino /* Figure out what function is being thunked to. It's referenced in
312*e4b17023SJohn Marino this translation unit. */
313*e4b17023SJohn Marino TREE_ADDRESSABLE (function) = 1;
314*e4b17023SJohn Marino mark_used (function);
315*e4b17023SJohn Marino if (!emit_p)
316*e4b17023SJohn Marino return;
317*e4b17023SJohn Marino
318*e4b17023SJohn Marino if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function))
319*e4b17023SJohn Marino alias = make_alias_for_thunk (function);
320*e4b17023SJohn Marino else
321*e4b17023SJohn Marino alias = function;
322*e4b17023SJohn Marino
323*e4b17023SJohn Marino fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
324*e4b17023SJohn Marino virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);
325*e4b17023SJohn Marino
326*e4b17023SJohn Marino if (virtual_offset)
327*e4b17023SJohn Marino {
328*e4b17023SJohn Marino if (!this_adjusting)
329*e4b17023SJohn Marino virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
330*e4b17023SJohn Marino virtual_value = tree_low_cst (virtual_offset, /*pos=*/0);
331*e4b17023SJohn Marino gcc_assert (virtual_value);
332*e4b17023SJohn Marino }
333*e4b17023SJohn Marino else
334*e4b17023SJohn Marino virtual_value = 0;
335*e4b17023SJohn Marino
336*e4b17023SJohn Marino /* And, if we need to emit the thunk, it's used. */
337*e4b17023SJohn Marino mark_used (thunk_fndecl);
338*e4b17023SJohn Marino /* This thunk is actually defined. */
339*e4b17023SJohn Marino DECL_EXTERNAL (thunk_fndecl) = 0;
340*e4b17023SJohn Marino /* The linkage of the function may have changed. FIXME in linkage
341*e4b17023SJohn Marino rewrite. */
342*e4b17023SJohn Marino gcc_assert (DECL_INTERFACE_KNOWN (function));
343*e4b17023SJohn Marino TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
344*e4b17023SJohn Marino DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);
345*e4b17023SJohn Marino DECL_VISIBILITY_SPECIFIED (thunk_fndecl)
346*e4b17023SJohn Marino = DECL_VISIBILITY_SPECIFIED (function);
347*e4b17023SJohn Marino DECL_COMDAT (thunk_fndecl) = DECL_COMDAT (function);
348*e4b17023SJohn Marino DECL_WEAK (thunk_fndecl) = DECL_WEAK (function);
349*e4b17023SJohn Marino
350*e4b17023SJohn Marino if (flag_syntax_only)
351*e4b17023SJohn Marino {
352*e4b17023SJohn Marino TREE_ASM_WRITTEN (thunk_fndecl) = 1;
353*e4b17023SJohn Marino return;
354*e4b17023SJohn Marino }
355*e4b17023SJohn Marino
356*e4b17023SJohn Marino push_to_top_level ();
357*e4b17023SJohn Marino
358*e4b17023SJohn Marino if (TARGET_USE_LOCAL_THUNK_ALIAS_P (function)
359*e4b17023SJohn Marino && targetm_common.have_named_sections)
360*e4b17023SJohn Marino {
361*e4b17023SJohn Marino resolve_unique_section (function, 0, flag_function_sections);
362*e4b17023SJohn Marino
363*e4b17023SJohn Marino if (DECL_SECTION_NAME (function) != NULL && DECL_ONE_ONLY (function))
364*e4b17023SJohn Marino {
365*e4b17023SJohn Marino resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
366*e4b17023SJohn Marino
367*e4b17023SJohn Marino /* Output the thunk into the same section as function. */
368*e4b17023SJohn Marino DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function);
369*e4b17023SJohn Marino }
370*e4b17023SJohn Marino }
371*e4b17023SJohn Marino
372*e4b17023SJohn Marino /* Set up cloned argument trees for the thunk. */
373*e4b17023SJohn Marino t = NULL_TREE;
374*e4b17023SJohn Marino for (a = DECL_ARGUMENTS (function); a; a = DECL_CHAIN (a))
375*e4b17023SJohn Marino {
376*e4b17023SJohn Marino tree x = copy_node (a);
377*e4b17023SJohn Marino DECL_CHAIN (x) = t;
378*e4b17023SJohn Marino DECL_CONTEXT (x) = thunk_fndecl;
379*e4b17023SJohn Marino SET_DECL_RTL (x, NULL);
380*e4b17023SJohn Marino DECL_HAS_VALUE_EXPR_P (x) = 0;
381*e4b17023SJohn Marino TREE_ADDRESSABLE (x) = 0;
382*e4b17023SJohn Marino t = x;
383*e4b17023SJohn Marino }
384*e4b17023SJohn Marino a = nreverse (t);
385*e4b17023SJohn Marino DECL_ARGUMENTS (thunk_fndecl) = a;
386*e4b17023SJohn Marino TREE_ASM_WRITTEN (thunk_fndecl) = 1;
387*e4b17023SJohn Marino funcn = cgraph_get_node (function);
388*e4b17023SJohn Marino gcc_checking_assert (funcn);
389*e4b17023SJohn Marino thunk_node = cgraph_add_thunk (funcn, thunk_fndecl, function,
390*e4b17023SJohn Marino this_adjusting, fixed_offset, virtual_value,
391*e4b17023SJohn Marino virtual_offset, alias);
392*e4b17023SJohn Marino if (DECL_ONE_ONLY (function))
393*e4b17023SJohn Marino cgraph_add_to_same_comdat_group (thunk_node, funcn);
394*e4b17023SJohn Marino
395*e4b17023SJohn Marino if (!this_adjusting
396*e4b17023SJohn Marino || !targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
397*e4b17023SJohn Marino virtual_value, alias))
398*e4b17023SJohn Marino {
399*e4b17023SJohn Marino /* If this is a covariant thunk, or we don't have the necessary
400*e4b17023SJohn Marino code for efficient thunks, generate a thunk function that
401*e4b17023SJohn Marino just makes a call to the real function. Unfortunately, this
402*e4b17023SJohn Marino doesn't work for varargs. */
403*e4b17023SJohn Marino
404*e4b17023SJohn Marino if (varargs_function_p (function))
405*e4b17023SJohn Marino error ("generic thunk code fails for method %q#D which uses %<...%>",
406*e4b17023SJohn Marino function);
407*e4b17023SJohn Marino }
408*e4b17023SJohn Marino
409*e4b17023SJohn Marino pop_from_top_level ();
410*e4b17023SJohn Marino }
411*e4b17023SJohn Marino
412*e4b17023SJohn Marino /* Code for synthesizing methods which have default semantics defined. */
413*e4b17023SJohn Marino
414*e4b17023SJohn Marino /* True iff CTYPE has a trivial SFK. */
415*e4b17023SJohn Marino
416*e4b17023SJohn Marino static bool
type_has_trivial_fn(tree ctype,special_function_kind sfk)417*e4b17023SJohn Marino type_has_trivial_fn (tree ctype, special_function_kind sfk)
418*e4b17023SJohn Marino {
419*e4b17023SJohn Marino switch (sfk)
420*e4b17023SJohn Marino {
421*e4b17023SJohn Marino case sfk_constructor:
422*e4b17023SJohn Marino return !TYPE_HAS_COMPLEX_DFLT (ctype);
423*e4b17023SJohn Marino case sfk_copy_constructor:
424*e4b17023SJohn Marino return !TYPE_HAS_COMPLEX_COPY_CTOR (ctype);
425*e4b17023SJohn Marino case sfk_move_constructor:
426*e4b17023SJohn Marino return !TYPE_HAS_COMPLEX_MOVE_CTOR (ctype);
427*e4b17023SJohn Marino case sfk_copy_assignment:
428*e4b17023SJohn Marino return !TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype);
429*e4b17023SJohn Marino case sfk_move_assignment:
430*e4b17023SJohn Marino return !TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype);
431*e4b17023SJohn Marino case sfk_destructor:
432*e4b17023SJohn Marino return !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype);
433*e4b17023SJohn Marino default:
434*e4b17023SJohn Marino gcc_unreachable ();
435*e4b17023SJohn Marino }
436*e4b17023SJohn Marino }
437*e4b17023SJohn Marino
438*e4b17023SJohn Marino /* Note that CTYPE has a non-trivial SFK even though we previously thought
439*e4b17023SJohn Marino it was trivial. */
440*e4b17023SJohn Marino
441*e4b17023SJohn Marino static void
type_set_nontrivial_flag(tree ctype,special_function_kind sfk)442*e4b17023SJohn Marino type_set_nontrivial_flag (tree ctype, special_function_kind sfk)
443*e4b17023SJohn Marino {
444*e4b17023SJohn Marino switch (sfk)
445*e4b17023SJohn Marino {
446*e4b17023SJohn Marino case sfk_constructor:
447*e4b17023SJohn Marino TYPE_HAS_COMPLEX_DFLT (ctype) = true;
448*e4b17023SJohn Marino return;
449*e4b17023SJohn Marino case sfk_copy_constructor:
450*e4b17023SJohn Marino TYPE_HAS_COMPLEX_COPY_CTOR (ctype) = true;
451*e4b17023SJohn Marino return;
452*e4b17023SJohn Marino case sfk_move_constructor:
453*e4b17023SJohn Marino TYPE_HAS_COMPLEX_MOVE_CTOR (ctype) = true;
454*e4b17023SJohn Marino return;
455*e4b17023SJohn Marino case sfk_copy_assignment:
456*e4b17023SJohn Marino TYPE_HAS_COMPLEX_COPY_ASSIGN (ctype) = true;
457*e4b17023SJohn Marino return;
458*e4b17023SJohn Marino case sfk_move_assignment:
459*e4b17023SJohn Marino TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype) = true;
460*e4b17023SJohn Marino return;
461*e4b17023SJohn Marino case sfk_destructor:
462*e4b17023SJohn Marino TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
463*e4b17023SJohn Marino return;
464*e4b17023SJohn Marino default:
465*e4b17023SJohn Marino gcc_unreachable ();
466*e4b17023SJohn Marino }
467*e4b17023SJohn Marino }
468*e4b17023SJohn Marino
469*e4b17023SJohn Marino /* True iff FN is a trivial defaulted member function ([cd]tor, op=). */
470*e4b17023SJohn Marino
471*e4b17023SJohn Marino bool
trivial_fn_p(tree fn)472*e4b17023SJohn Marino trivial_fn_p (tree fn)
473*e4b17023SJohn Marino {
474*e4b17023SJohn Marino if (!DECL_DEFAULTED_FN (fn))
475*e4b17023SJohn Marino return false;
476*e4b17023SJohn Marino
477*e4b17023SJohn Marino /* If fn is a clone, get the primary variant. */
478*e4b17023SJohn Marino fn = DECL_ORIGIN (fn);
479*e4b17023SJohn Marino return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn));
480*e4b17023SJohn Marino }
481*e4b17023SJohn Marino
482*e4b17023SJohn Marino /* Generate code for default X(X&) or X(X&&) constructor. */
483*e4b17023SJohn Marino
484*e4b17023SJohn Marino static void
do_build_copy_constructor(tree fndecl)485*e4b17023SJohn Marino do_build_copy_constructor (tree fndecl)
486*e4b17023SJohn Marino {
487*e4b17023SJohn Marino tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
488*e4b17023SJohn Marino bool move_p = DECL_MOVE_CONSTRUCTOR_P (fndecl);
489*e4b17023SJohn Marino bool trivial = trivial_fn_p (fndecl);
490*e4b17023SJohn Marino
491*e4b17023SJohn Marino parm = convert_from_reference (parm);
492*e4b17023SJohn Marino
493*e4b17023SJohn Marino if (trivial
494*e4b17023SJohn Marino && is_empty_class (current_class_type))
495*e4b17023SJohn Marino /* Don't copy the padding byte; it might not have been allocated
496*e4b17023SJohn Marino if *this is a base subobject. */;
497*e4b17023SJohn Marino else if (trivial)
498*e4b17023SJohn Marino {
499*e4b17023SJohn Marino tree t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm);
500*e4b17023SJohn Marino finish_expr_stmt (t);
501*e4b17023SJohn Marino }
502*e4b17023SJohn Marino else
503*e4b17023SJohn Marino {
504*e4b17023SJohn Marino tree fields = TYPE_FIELDS (current_class_type);
505*e4b17023SJohn Marino tree member_init_list = NULL_TREE;
506*e4b17023SJohn Marino int cvquals = cp_type_quals (TREE_TYPE (parm));
507*e4b17023SJohn Marino int i;
508*e4b17023SJohn Marino tree binfo, base_binfo;
509*e4b17023SJohn Marino tree init;
510*e4b17023SJohn Marino VEC(tree,gc) *vbases;
511*e4b17023SJohn Marino
512*e4b17023SJohn Marino /* Initialize all the base-classes with the parameter converted
513*e4b17023SJohn Marino to their type so that we get their copy constructor and not
514*e4b17023SJohn Marino another constructor that takes current_class_type. We must
515*e4b17023SJohn Marino deal with the binfo's directly as a direct base might be
516*e4b17023SJohn Marino inaccessible due to ambiguity. */
517*e4b17023SJohn Marino for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
518*e4b17023SJohn Marino VEC_iterate (tree, vbases, i, binfo); i++)
519*e4b17023SJohn Marino {
520*e4b17023SJohn Marino init = build_base_path (PLUS_EXPR, parm, binfo, 1,
521*e4b17023SJohn Marino tf_warning_or_error);
522*e4b17023SJohn Marino if (move_p)
523*e4b17023SJohn Marino init = move (init);
524*e4b17023SJohn Marino member_init_list
525*e4b17023SJohn Marino = tree_cons (binfo,
526*e4b17023SJohn Marino build_tree_list (NULL_TREE, init),
527*e4b17023SJohn Marino member_init_list);
528*e4b17023SJohn Marino }
529*e4b17023SJohn Marino
530*e4b17023SJohn Marino for (binfo = TYPE_BINFO (current_class_type), i = 0;
531*e4b17023SJohn Marino BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
532*e4b17023SJohn Marino {
533*e4b17023SJohn Marino if (BINFO_VIRTUAL_P (base_binfo))
534*e4b17023SJohn Marino continue;
535*e4b17023SJohn Marino
536*e4b17023SJohn Marino init = build_base_path (PLUS_EXPR, parm, base_binfo, 1,
537*e4b17023SJohn Marino tf_warning_or_error);
538*e4b17023SJohn Marino if (move_p)
539*e4b17023SJohn Marino init = move (init);
540*e4b17023SJohn Marino member_init_list
541*e4b17023SJohn Marino = tree_cons (base_binfo,
542*e4b17023SJohn Marino build_tree_list (NULL_TREE, init),
543*e4b17023SJohn Marino member_init_list);
544*e4b17023SJohn Marino }
545*e4b17023SJohn Marino
546*e4b17023SJohn Marino for (; fields; fields = DECL_CHAIN (fields))
547*e4b17023SJohn Marino {
548*e4b17023SJohn Marino tree field = fields;
549*e4b17023SJohn Marino tree expr_type;
550*e4b17023SJohn Marino
551*e4b17023SJohn Marino if (TREE_CODE (field) != FIELD_DECL)
552*e4b17023SJohn Marino continue;
553*e4b17023SJohn Marino
554*e4b17023SJohn Marino expr_type = TREE_TYPE (field);
555*e4b17023SJohn Marino if (DECL_NAME (field))
556*e4b17023SJohn Marino {
557*e4b17023SJohn Marino if (VFIELD_NAME_P (DECL_NAME (field)))
558*e4b17023SJohn Marino continue;
559*e4b17023SJohn Marino }
560*e4b17023SJohn Marino else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type))
561*e4b17023SJohn Marino /* Just use the field; anonymous types can't have
562*e4b17023SJohn Marino nontrivial copy ctors or assignment ops or this
563*e4b17023SJohn Marino function would be deleted. */;
564*e4b17023SJohn Marino else
565*e4b17023SJohn Marino continue;
566*e4b17023SJohn Marino
567*e4b17023SJohn Marino /* Compute the type of "init->field". If the copy-constructor
568*e4b17023SJohn Marino parameter is, for example, "const S&", and the type of
569*e4b17023SJohn Marino the field is "T", then the type will usually be "const
570*e4b17023SJohn Marino T". (There are no cv-qualified variants of reference
571*e4b17023SJohn Marino types.) */
572*e4b17023SJohn Marino if (TREE_CODE (expr_type) != REFERENCE_TYPE)
573*e4b17023SJohn Marino {
574*e4b17023SJohn Marino int quals = cvquals;
575*e4b17023SJohn Marino
576*e4b17023SJohn Marino if (DECL_MUTABLE_P (field))
577*e4b17023SJohn Marino quals &= ~TYPE_QUAL_CONST;
578*e4b17023SJohn Marino quals |= cp_type_quals (expr_type);
579*e4b17023SJohn Marino expr_type = cp_build_qualified_type (expr_type, quals);
580*e4b17023SJohn Marino }
581*e4b17023SJohn Marino
582*e4b17023SJohn Marino init = build3 (COMPONENT_REF, expr_type, parm, field, NULL_TREE);
583*e4b17023SJohn Marino if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE)
584*e4b17023SJohn Marino init = move (init);
585*e4b17023SJohn Marino init = build_tree_list (NULL_TREE, init);
586*e4b17023SJohn Marino
587*e4b17023SJohn Marino member_init_list = tree_cons (field, init, member_init_list);
588*e4b17023SJohn Marino }
589*e4b17023SJohn Marino finish_mem_initializers (member_init_list);
590*e4b17023SJohn Marino }
591*e4b17023SJohn Marino }
592*e4b17023SJohn Marino
593*e4b17023SJohn Marino static void
do_build_copy_assign(tree fndecl)594*e4b17023SJohn Marino do_build_copy_assign (tree fndecl)
595*e4b17023SJohn Marino {
596*e4b17023SJohn Marino tree parm = DECL_CHAIN (DECL_ARGUMENTS (fndecl));
597*e4b17023SJohn Marino tree compound_stmt;
598*e4b17023SJohn Marino bool move_p = move_fn_p (fndecl);
599*e4b17023SJohn Marino bool trivial = trivial_fn_p (fndecl);
600*e4b17023SJohn Marino int flags = LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | LOOKUP_DEFAULTED;
601*e4b17023SJohn Marino
602*e4b17023SJohn Marino compound_stmt = begin_compound_stmt (0);
603*e4b17023SJohn Marino parm = convert_from_reference (parm);
604*e4b17023SJohn Marino
605*e4b17023SJohn Marino if (trivial
606*e4b17023SJohn Marino && is_empty_class (current_class_type))
607*e4b17023SJohn Marino /* Don't copy the padding byte; it might not have been allocated
608*e4b17023SJohn Marino if *this is a base subobject. */;
609*e4b17023SJohn Marino else if (trivial)
610*e4b17023SJohn Marino {
611*e4b17023SJohn Marino tree t = build2 (MODIFY_EXPR, void_type_node, current_class_ref, parm);
612*e4b17023SJohn Marino finish_expr_stmt (t);
613*e4b17023SJohn Marino }
614*e4b17023SJohn Marino else
615*e4b17023SJohn Marino {
616*e4b17023SJohn Marino tree fields;
617*e4b17023SJohn Marino int cvquals = cp_type_quals (TREE_TYPE (parm));
618*e4b17023SJohn Marino int i;
619*e4b17023SJohn Marino tree binfo, base_binfo;
620*e4b17023SJohn Marino
621*e4b17023SJohn Marino /* Assign to each of the direct base classes. */
622*e4b17023SJohn Marino for (binfo = TYPE_BINFO (current_class_type), i = 0;
623*e4b17023SJohn Marino BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
624*e4b17023SJohn Marino {
625*e4b17023SJohn Marino tree converted_parm;
626*e4b17023SJohn Marino VEC(tree,gc) *parmvec;
627*e4b17023SJohn Marino
628*e4b17023SJohn Marino /* We must convert PARM directly to the base class
629*e4b17023SJohn Marino explicitly since the base class may be ambiguous. */
630*e4b17023SJohn Marino converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1,
631*e4b17023SJohn Marino tf_warning_or_error);
632*e4b17023SJohn Marino if (move_p)
633*e4b17023SJohn Marino converted_parm = move (converted_parm);
634*e4b17023SJohn Marino /* Call the base class assignment operator. */
635*e4b17023SJohn Marino parmvec = make_tree_vector_single (converted_parm);
636*e4b17023SJohn Marino finish_expr_stmt
637*e4b17023SJohn Marino (build_special_member_call (current_class_ref,
638*e4b17023SJohn Marino ansi_assopname (NOP_EXPR),
639*e4b17023SJohn Marino &parmvec,
640*e4b17023SJohn Marino base_binfo,
641*e4b17023SJohn Marino flags,
642*e4b17023SJohn Marino tf_warning_or_error));
643*e4b17023SJohn Marino release_tree_vector (parmvec);
644*e4b17023SJohn Marino }
645*e4b17023SJohn Marino
646*e4b17023SJohn Marino /* Assign to each of the non-static data members. */
647*e4b17023SJohn Marino for (fields = TYPE_FIELDS (current_class_type);
648*e4b17023SJohn Marino fields;
649*e4b17023SJohn Marino fields = DECL_CHAIN (fields))
650*e4b17023SJohn Marino {
651*e4b17023SJohn Marino tree comp = current_class_ref;
652*e4b17023SJohn Marino tree init = parm;
653*e4b17023SJohn Marino tree field = fields;
654*e4b17023SJohn Marino tree expr_type;
655*e4b17023SJohn Marino int quals;
656*e4b17023SJohn Marino
657*e4b17023SJohn Marino if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
658*e4b17023SJohn Marino continue;
659*e4b17023SJohn Marino
660*e4b17023SJohn Marino expr_type = TREE_TYPE (field);
661*e4b17023SJohn Marino
662*e4b17023SJohn Marino if (CP_TYPE_CONST_P (expr_type))
663*e4b17023SJohn Marino {
664*e4b17023SJohn Marino error ("non-static const member %q#D, can%'t use default "
665*e4b17023SJohn Marino "assignment operator", field);
666*e4b17023SJohn Marino continue;
667*e4b17023SJohn Marino }
668*e4b17023SJohn Marino else if (TREE_CODE (expr_type) == REFERENCE_TYPE)
669*e4b17023SJohn Marino {
670*e4b17023SJohn Marino error ("non-static reference member %q#D, can%'t use "
671*e4b17023SJohn Marino "default assignment operator", field);
672*e4b17023SJohn Marino continue;
673*e4b17023SJohn Marino }
674*e4b17023SJohn Marino
675*e4b17023SJohn Marino if (DECL_NAME (field))
676*e4b17023SJohn Marino {
677*e4b17023SJohn Marino if (VFIELD_NAME_P (DECL_NAME (field)))
678*e4b17023SJohn Marino continue;
679*e4b17023SJohn Marino }
680*e4b17023SJohn Marino else if (ANON_AGGR_TYPE_P (expr_type)
681*e4b17023SJohn Marino && TYPE_FIELDS (expr_type) != NULL_TREE)
682*e4b17023SJohn Marino /* Just use the field; anonymous types can't have
683*e4b17023SJohn Marino nontrivial copy ctors or assignment ops or this
684*e4b17023SJohn Marino function would be deleted. */;
685*e4b17023SJohn Marino else
686*e4b17023SJohn Marino continue;
687*e4b17023SJohn Marino
688*e4b17023SJohn Marino comp = build3 (COMPONENT_REF, expr_type, comp, field, NULL_TREE);
689*e4b17023SJohn Marino
690*e4b17023SJohn Marino /* Compute the type of init->field */
691*e4b17023SJohn Marino quals = cvquals;
692*e4b17023SJohn Marino if (DECL_MUTABLE_P (field))
693*e4b17023SJohn Marino quals &= ~TYPE_QUAL_CONST;
694*e4b17023SJohn Marino expr_type = cp_build_qualified_type (expr_type, quals);
695*e4b17023SJohn Marino
696*e4b17023SJohn Marino init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE);
697*e4b17023SJohn Marino if (move_p && TREE_CODE (expr_type) != REFERENCE_TYPE)
698*e4b17023SJohn Marino init = move (init);
699*e4b17023SJohn Marino
700*e4b17023SJohn Marino if (DECL_NAME (field))
701*e4b17023SJohn Marino init = cp_build_modify_expr (comp, NOP_EXPR, init,
702*e4b17023SJohn Marino tf_warning_or_error);
703*e4b17023SJohn Marino else
704*e4b17023SJohn Marino init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
705*e4b17023SJohn Marino finish_expr_stmt (init);
706*e4b17023SJohn Marino }
707*e4b17023SJohn Marino }
708*e4b17023SJohn Marino finish_return_stmt (current_class_ref);
709*e4b17023SJohn Marino finish_compound_stmt (compound_stmt);
710*e4b17023SJohn Marino }
711*e4b17023SJohn Marino
712*e4b17023SJohn Marino /* Synthesize FNDECL, a non-static member function. */
713*e4b17023SJohn Marino
714*e4b17023SJohn Marino void
synthesize_method(tree fndecl)715*e4b17023SJohn Marino synthesize_method (tree fndecl)
716*e4b17023SJohn Marino {
717*e4b17023SJohn Marino bool nested = (current_function_decl != NULL_TREE);
718*e4b17023SJohn Marino tree context = decl_function_context (fndecl);
719*e4b17023SJohn Marino bool need_body = true;
720*e4b17023SJohn Marino tree stmt;
721*e4b17023SJohn Marino location_t save_input_location = input_location;
722*e4b17023SJohn Marino int error_count = errorcount;
723*e4b17023SJohn Marino int warning_count = warningcount;
724*e4b17023SJohn Marino
725*e4b17023SJohn Marino /* Reset the source location, we might have been previously
726*e4b17023SJohn Marino deferred, and thus have saved where we were first needed. */
727*e4b17023SJohn Marino DECL_SOURCE_LOCATION (fndecl)
728*e4b17023SJohn Marino = DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (fndecl)));
729*e4b17023SJohn Marino
730*e4b17023SJohn Marino /* If we've been asked to synthesize a clone, just synthesize the
731*e4b17023SJohn Marino cloned function instead. Doing so will automatically fill in the
732*e4b17023SJohn Marino body for the clone. */
733*e4b17023SJohn Marino if (DECL_CLONED_FUNCTION_P (fndecl))
734*e4b17023SJohn Marino fndecl = DECL_CLONED_FUNCTION (fndecl);
735*e4b17023SJohn Marino
736*e4b17023SJohn Marino /* We may be in the middle of deferred access check. Disable
737*e4b17023SJohn Marino it now. */
738*e4b17023SJohn Marino push_deferring_access_checks (dk_no_deferred);
739*e4b17023SJohn Marino
740*e4b17023SJohn Marino if (! context)
741*e4b17023SJohn Marino push_to_top_level ();
742*e4b17023SJohn Marino else if (nested)
743*e4b17023SJohn Marino push_function_context ();
744*e4b17023SJohn Marino
745*e4b17023SJohn Marino input_location = DECL_SOURCE_LOCATION (fndecl);
746*e4b17023SJohn Marino
747*e4b17023SJohn Marino start_preparsed_function (fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
748*e4b17023SJohn Marino stmt = begin_function_body ();
749*e4b17023SJohn Marino
750*e4b17023SJohn Marino if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR)
751*e4b17023SJohn Marino {
752*e4b17023SJohn Marino do_build_copy_assign (fndecl);
753*e4b17023SJohn Marino need_body = false;
754*e4b17023SJohn Marino }
755*e4b17023SJohn Marino else if (DECL_CONSTRUCTOR_P (fndecl))
756*e4b17023SJohn Marino {
757*e4b17023SJohn Marino tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
758*e4b17023SJohn Marino if (arg_chain != void_list_node)
759*e4b17023SJohn Marino do_build_copy_constructor (fndecl);
760*e4b17023SJohn Marino else
761*e4b17023SJohn Marino finish_mem_initializers (NULL_TREE);
762*e4b17023SJohn Marino }
763*e4b17023SJohn Marino
764*e4b17023SJohn Marino /* If we haven't yet generated the body of the function, just
765*e4b17023SJohn Marino generate an empty compound statement. */
766*e4b17023SJohn Marino if (need_body)
767*e4b17023SJohn Marino {
768*e4b17023SJohn Marino tree compound_stmt;
769*e4b17023SJohn Marino compound_stmt = begin_compound_stmt (BCS_FN_BODY);
770*e4b17023SJohn Marino finish_compound_stmt (compound_stmt);
771*e4b17023SJohn Marino }
772*e4b17023SJohn Marino
773*e4b17023SJohn Marino finish_function_body (stmt);
774*e4b17023SJohn Marino expand_or_defer_fn (finish_function (0));
775*e4b17023SJohn Marino
776*e4b17023SJohn Marino input_location = save_input_location;
777*e4b17023SJohn Marino
778*e4b17023SJohn Marino if (! context)
779*e4b17023SJohn Marino pop_from_top_level ();
780*e4b17023SJohn Marino else if (nested)
781*e4b17023SJohn Marino pop_function_context ();
782*e4b17023SJohn Marino
783*e4b17023SJohn Marino pop_deferring_access_checks ();
784*e4b17023SJohn Marino
785*e4b17023SJohn Marino if (error_count != errorcount || warning_count != warningcount)
786*e4b17023SJohn Marino inform (input_location, "synthesized method %qD first required here ",
787*e4b17023SJohn Marino fndecl);
788*e4b17023SJohn Marino }
789*e4b17023SJohn Marino
790*e4b17023SJohn Marino /* Build a reference to type TYPE with cv-quals QUALS, which is an
791*e4b17023SJohn Marino rvalue if RVALUE is true. */
792*e4b17023SJohn Marino
793*e4b17023SJohn Marino static tree
build_stub_type(tree type,int quals,bool rvalue)794*e4b17023SJohn Marino build_stub_type (tree type, int quals, bool rvalue)
795*e4b17023SJohn Marino {
796*e4b17023SJohn Marino tree argtype = cp_build_qualified_type (type, quals);
797*e4b17023SJohn Marino return cp_build_reference_type (argtype, rvalue);
798*e4b17023SJohn Marino }
799*e4b17023SJohn Marino
800*e4b17023SJohn Marino /* Build a dummy glvalue from dereferencing a dummy reference of type
801*e4b17023SJohn Marino REFTYPE. */
802*e4b17023SJohn Marino
803*e4b17023SJohn Marino static tree
build_stub_object(tree reftype)804*e4b17023SJohn Marino build_stub_object (tree reftype)
805*e4b17023SJohn Marino {
806*e4b17023SJohn Marino tree stub = build1 (NOP_EXPR, reftype, integer_one_node);
807*e4b17023SJohn Marino return convert_from_reference (stub);
808*e4b17023SJohn Marino }
809*e4b17023SJohn Marino
810*e4b17023SJohn Marino /* Determine which function will be called when looking up NAME in TYPE,
811*e4b17023SJohn Marino called with a single ARGTYPE argument, or no argument if ARGTYPE is
812*e4b17023SJohn Marino null. FLAGS and COMPLAIN are as for build_new_method_call.
813*e4b17023SJohn Marino
814*e4b17023SJohn Marino Returns a FUNCTION_DECL if all is well.
815*e4b17023SJohn Marino Returns NULL_TREE if overload resolution failed.
816*e4b17023SJohn Marino Returns error_mark_node if the chosen function cannot be called. */
817*e4b17023SJohn Marino
818*e4b17023SJohn Marino static tree
locate_fn_flags(tree type,tree name,tree argtype,int flags,tsubst_flags_t complain)819*e4b17023SJohn Marino locate_fn_flags (tree type, tree name, tree argtype, int flags,
820*e4b17023SJohn Marino tsubst_flags_t complain)
821*e4b17023SJohn Marino {
822*e4b17023SJohn Marino tree ob, fn, fns, binfo, rval;
823*e4b17023SJohn Marino VEC(tree,gc) *args;
824*e4b17023SJohn Marino
825*e4b17023SJohn Marino if (TYPE_P (type))
826*e4b17023SJohn Marino binfo = TYPE_BINFO (type);
827*e4b17023SJohn Marino else
828*e4b17023SJohn Marino {
829*e4b17023SJohn Marino binfo = type;
830*e4b17023SJohn Marino type = BINFO_TYPE (binfo);
831*e4b17023SJohn Marino }
832*e4b17023SJohn Marino
833*e4b17023SJohn Marino ob = build_stub_object (cp_build_reference_type (type, false));
834*e4b17023SJohn Marino args = make_tree_vector ();
835*e4b17023SJohn Marino if (argtype)
836*e4b17023SJohn Marino {
837*e4b17023SJohn Marino tree arg = build_stub_object (argtype);
838*e4b17023SJohn Marino VEC_quick_push (tree, args, arg);
839*e4b17023SJohn Marino }
840*e4b17023SJohn Marino
841*e4b17023SJohn Marino fns = lookup_fnfields (binfo, name, 0);
842*e4b17023SJohn Marino rval = build_new_method_call (ob, fns, &args, binfo, flags, &fn, complain);
843*e4b17023SJohn Marino
844*e4b17023SJohn Marino release_tree_vector (args);
845*e4b17023SJohn Marino if (fn && rval == error_mark_node)
846*e4b17023SJohn Marino return rval;
847*e4b17023SJohn Marino else
848*e4b17023SJohn Marino return fn;
849*e4b17023SJohn Marino }
850*e4b17023SJohn Marino
851*e4b17023SJohn Marino /* Locate the dtor of TYPE. */
852*e4b17023SJohn Marino
853*e4b17023SJohn Marino tree
get_dtor(tree type,tsubst_flags_t complain)854*e4b17023SJohn Marino get_dtor (tree type, tsubst_flags_t complain)
855*e4b17023SJohn Marino {
856*e4b17023SJohn Marino tree fn = locate_fn_flags (type, complete_dtor_identifier, NULL_TREE,
857*e4b17023SJohn Marino LOOKUP_NORMAL, complain);
858*e4b17023SJohn Marino if (fn == error_mark_node)
859*e4b17023SJohn Marino return NULL_TREE;
860*e4b17023SJohn Marino return fn;
861*e4b17023SJohn Marino }
862*e4b17023SJohn Marino
863*e4b17023SJohn Marino /* Locate the default ctor of TYPE. */
864*e4b17023SJohn Marino
865*e4b17023SJohn Marino tree
locate_ctor(tree type)866*e4b17023SJohn Marino locate_ctor (tree type)
867*e4b17023SJohn Marino {
868*e4b17023SJohn Marino tree fn;
869*e4b17023SJohn Marino
870*e4b17023SJohn Marino push_deferring_access_checks (dk_no_check);
871*e4b17023SJohn Marino fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
872*e4b17023SJohn Marino LOOKUP_SPECULATIVE, tf_none);
873*e4b17023SJohn Marino pop_deferring_access_checks ();
874*e4b17023SJohn Marino if (fn == error_mark_node)
875*e4b17023SJohn Marino return NULL_TREE;
876*e4b17023SJohn Marino return fn;
877*e4b17023SJohn Marino }
878*e4b17023SJohn Marino
879*e4b17023SJohn Marino /* Likewise, but give any appropriate errors. */
880*e4b17023SJohn Marino
881*e4b17023SJohn Marino tree
get_default_ctor(tree type)882*e4b17023SJohn Marino get_default_ctor (tree type)
883*e4b17023SJohn Marino {
884*e4b17023SJohn Marino tree fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE,
885*e4b17023SJohn Marino LOOKUP_NORMAL, tf_warning_or_error);
886*e4b17023SJohn Marino if (fn == error_mark_node)
887*e4b17023SJohn Marino return NULL_TREE;
888*e4b17023SJohn Marino return fn;
889*e4b17023SJohn Marino }
890*e4b17023SJohn Marino
891*e4b17023SJohn Marino /* Locate the copy ctor of TYPE. */
892*e4b17023SJohn Marino
893*e4b17023SJohn Marino tree
get_copy_ctor(tree type,tsubst_flags_t complain)894*e4b17023SJohn Marino get_copy_ctor (tree type, tsubst_flags_t complain)
895*e4b17023SJohn Marino {
896*e4b17023SJohn Marino int quals = (TYPE_HAS_CONST_COPY_CTOR (type)
897*e4b17023SJohn Marino ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
898*e4b17023SJohn Marino tree argtype = build_stub_type (type, quals, false);
899*e4b17023SJohn Marino tree fn = locate_fn_flags (type, complete_ctor_identifier, argtype,
900*e4b17023SJohn Marino LOOKUP_NORMAL, complain);
901*e4b17023SJohn Marino if (fn == error_mark_node)
902*e4b17023SJohn Marino return NULL_TREE;
903*e4b17023SJohn Marino return fn;
904*e4b17023SJohn Marino }
905*e4b17023SJohn Marino
906*e4b17023SJohn Marino /* Locate the copy assignment operator of TYPE. */
907*e4b17023SJohn Marino
908*e4b17023SJohn Marino tree
get_copy_assign(tree type)909*e4b17023SJohn Marino get_copy_assign (tree type)
910*e4b17023SJohn Marino {
911*e4b17023SJohn Marino int quals = (TYPE_HAS_CONST_COPY_ASSIGN (type)
912*e4b17023SJohn Marino ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
913*e4b17023SJohn Marino tree argtype = build_stub_type (type, quals, false);
914*e4b17023SJohn Marino tree fn = locate_fn_flags (type, ansi_assopname (NOP_EXPR), argtype,
915*e4b17023SJohn Marino LOOKUP_NORMAL, tf_warning_or_error);
916*e4b17023SJohn Marino if (fn == error_mark_node)
917*e4b17023SJohn Marino return NULL_TREE;
918*e4b17023SJohn Marino return fn;
919*e4b17023SJohn Marino }
920*e4b17023SJohn Marino
921*e4b17023SJohn Marino /* Subroutine of synthesized_method_walk. Update SPEC_P, TRIVIAL_P and
922*e4b17023SJohn Marino DELETED_P or give an error message MSG with argument ARG. */
923*e4b17023SJohn Marino
924*e4b17023SJohn Marino static void
process_subob_fn(tree fn,bool move_p,tree * spec_p,bool * trivial_p,bool * deleted_p,bool * constexpr_p,bool * no_implicit_p,const char * msg,tree arg)925*e4b17023SJohn Marino process_subob_fn (tree fn, bool move_p, tree *spec_p, bool *trivial_p,
926*e4b17023SJohn Marino bool *deleted_p, bool *constexpr_p, bool *no_implicit_p,
927*e4b17023SJohn Marino const char *msg, tree arg)
928*e4b17023SJohn Marino {
929*e4b17023SJohn Marino if (!fn || fn == error_mark_node)
930*e4b17023SJohn Marino goto bad;
931*e4b17023SJohn Marino
932*e4b17023SJohn Marino if (spec_p)
933*e4b17023SJohn Marino {
934*e4b17023SJohn Marino tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
935*e4b17023SJohn Marino *spec_p = merge_exception_specifiers (*spec_p, raises, fn);
936*e4b17023SJohn Marino }
937*e4b17023SJohn Marino
938*e4b17023SJohn Marino if (!trivial_fn_p (fn))
939*e4b17023SJohn Marino {
940*e4b17023SJohn Marino if (trivial_p)
941*e4b17023SJohn Marino *trivial_p = false;
942*e4b17023SJohn Marino if (TREE_CODE (arg) == FIELD_DECL
943*e4b17023SJohn Marino && TREE_CODE (DECL_CONTEXT (arg)) == UNION_TYPE)
944*e4b17023SJohn Marino {
945*e4b17023SJohn Marino if (deleted_p)
946*e4b17023SJohn Marino *deleted_p = true;
947*e4b17023SJohn Marino if (msg)
948*e4b17023SJohn Marino error ("union member %q+D with non-trivial %qD", arg, fn);
949*e4b17023SJohn Marino }
950*e4b17023SJohn Marino }
951*e4b17023SJohn Marino
952*e4b17023SJohn Marino /* Core 1402: A non-trivial non-move ctor suppresses the implicit
953*e4b17023SJohn Marino declaration of the move ctor/op=. */
954*e4b17023SJohn Marino if (no_implicit_p && move_p && !move_signature_fn_p (fn)
955*e4b17023SJohn Marino && !trivial_fn_p (fn))
956*e4b17023SJohn Marino *no_implicit_p = true;
957*e4b17023SJohn Marino
958*e4b17023SJohn Marino if (constexpr_p && !DECL_DECLARED_CONSTEXPR_P (fn))
959*e4b17023SJohn Marino {
960*e4b17023SJohn Marino *constexpr_p = false;
961*e4b17023SJohn Marino if (msg)
962*e4b17023SJohn Marino {
963*e4b17023SJohn Marino inform (0, "defaulted constructor calls non-constexpr "
964*e4b17023SJohn Marino "%q+D", fn);
965*e4b17023SJohn Marino explain_invalid_constexpr_fn (fn);
966*e4b17023SJohn Marino }
967*e4b17023SJohn Marino }
968*e4b17023SJohn Marino
969*e4b17023SJohn Marino return;
970*e4b17023SJohn Marino
971*e4b17023SJohn Marino bad:
972*e4b17023SJohn Marino if (deleted_p)
973*e4b17023SJohn Marino *deleted_p = true;
974*e4b17023SJohn Marino }
975*e4b17023SJohn Marino
976*e4b17023SJohn Marino /* Subroutine of synthesized_method_walk to allow recursion into anonymous
977*e4b17023SJohn Marino aggregates. */
978*e4b17023SJohn Marino
979*e4b17023SJohn Marino static void
walk_field_subobs(tree fields,tree fnname,special_function_kind sfk,int quals,bool copy_arg_p,bool move_p,bool assign_p,tree * spec_p,bool * trivial_p,bool * deleted_p,bool * constexpr_p,bool * no_implicit_p,const char * msg,int flags,tsubst_flags_t complain)980*e4b17023SJohn Marino walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
981*e4b17023SJohn Marino int quals, bool copy_arg_p, bool move_p,
982*e4b17023SJohn Marino bool assign_p, tree *spec_p, bool *trivial_p,
983*e4b17023SJohn Marino bool *deleted_p, bool *constexpr_p, bool *no_implicit_p,
984*e4b17023SJohn Marino const char *msg, int flags, tsubst_flags_t complain)
985*e4b17023SJohn Marino {
986*e4b17023SJohn Marino tree field;
987*e4b17023SJohn Marino for (field = fields; field; field = DECL_CHAIN (field))
988*e4b17023SJohn Marino {
989*e4b17023SJohn Marino tree mem_type, argtype, rval;
990*e4b17023SJohn Marino
991*e4b17023SJohn Marino if (TREE_CODE (field) != FIELD_DECL
992*e4b17023SJohn Marino || DECL_ARTIFICIAL (field))
993*e4b17023SJohn Marino continue;
994*e4b17023SJohn Marino
995*e4b17023SJohn Marino mem_type = strip_array_types (TREE_TYPE (field));
996*e4b17023SJohn Marino if (assign_p)
997*e4b17023SJohn Marino {
998*e4b17023SJohn Marino bool bad = true;
999*e4b17023SJohn Marino if (CP_TYPE_CONST_P (mem_type) && !CLASS_TYPE_P (mem_type))
1000*e4b17023SJohn Marino {
1001*e4b17023SJohn Marino if (msg)
1002*e4b17023SJohn Marino error ("non-static const member %q#D, can%'t use default "
1003*e4b17023SJohn Marino "assignment operator", field);
1004*e4b17023SJohn Marino }
1005*e4b17023SJohn Marino else if (TREE_CODE (mem_type) == REFERENCE_TYPE)
1006*e4b17023SJohn Marino {
1007*e4b17023SJohn Marino if (msg)
1008*e4b17023SJohn Marino error ("non-static reference member %q#D, can%'t use "
1009*e4b17023SJohn Marino "default assignment operator", field);
1010*e4b17023SJohn Marino }
1011*e4b17023SJohn Marino else
1012*e4b17023SJohn Marino bad = false;
1013*e4b17023SJohn Marino
1014*e4b17023SJohn Marino if (bad && deleted_p)
1015*e4b17023SJohn Marino *deleted_p = true;
1016*e4b17023SJohn Marino }
1017*e4b17023SJohn Marino else if (sfk == sfk_constructor)
1018*e4b17023SJohn Marino {
1019*e4b17023SJohn Marino bool bad;
1020*e4b17023SJohn Marino
1021*e4b17023SJohn Marino if (DECL_INITIAL (field))
1022*e4b17023SJohn Marino {
1023*e4b17023SJohn Marino if (msg && DECL_INITIAL (field) == error_mark_node)
1024*e4b17023SJohn Marino inform (0, "initializer for %q+#D is invalid", field);
1025*e4b17023SJohn Marino if (trivial_p)
1026*e4b17023SJohn Marino *trivial_p = false;
1027*e4b17023SJohn Marino #if 0
1028*e4b17023SJohn Marino /* Core 1351: If the field has an NSDMI that could throw, the
1029*e4b17023SJohn Marino default constructor is noexcept(false). FIXME this is
1030*e4b17023SJohn Marino broken by deferred parsing and 1360 saying we can't lazily
1031*e4b17023SJohn Marino declare a non-trivial default constructor. Also this
1032*e4b17023SJohn Marino needs to do deferred instantiation. Disable until the
1033*e4b17023SJohn Marino conflict between 1351 and 1360 is resolved. */
1034*e4b17023SJohn Marino if (spec_p && !expr_noexcept_p (DECL_INITIAL (field), complain))
1035*e4b17023SJohn Marino *spec_p = noexcept_false_spec;
1036*e4b17023SJohn Marino #endif
1037*e4b17023SJohn Marino
1038*e4b17023SJohn Marino /* Don't do the normal processing. */
1039*e4b17023SJohn Marino continue;
1040*e4b17023SJohn Marino }
1041*e4b17023SJohn Marino
1042*e4b17023SJohn Marino bad = false;
1043*e4b17023SJohn Marino if (CP_TYPE_CONST_P (mem_type)
1044*e4b17023SJohn Marino && default_init_uninitialized_part (mem_type))
1045*e4b17023SJohn Marino {
1046*e4b17023SJohn Marino if (msg)
1047*e4b17023SJohn Marino error ("uninitialized non-static const member %q#D",
1048*e4b17023SJohn Marino field);
1049*e4b17023SJohn Marino bad = true;
1050*e4b17023SJohn Marino }
1051*e4b17023SJohn Marino else if (TREE_CODE (mem_type) == REFERENCE_TYPE)
1052*e4b17023SJohn Marino {
1053*e4b17023SJohn Marino if (msg)
1054*e4b17023SJohn Marino error ("uninitialized non-static reference member %q#D",
1055*e4b17023SJohn Marino field);
1056*e4b17023SJohn Marino bad = true;
1057*e4b17023SJohn Marino }
1058*e4b17023SJohn Marino
1059*e4b17023SJohn Marino if (bad && deleted_p)
1060*e4b17023SJohn Marino *deleted_p = true;
1061*e4b17023SJohn Marino
1062*e4b17023SJohn Marino /* For an implicitly-defined default constructor to be constexpr,
1063*e4b17023SJohn Marino every member must have a user-provided default constructor or
1064*e4b17023SJohn Marino an explicit initializer. */
1065*e4b17023SJohn Marino if (constexpr_p && !CLASS_TYPE_P (mem_type)
1066*e4b17023SJohn Marino && TREE_CODE (DECL_CONTEXT (field)) != UNION_TYPE)
1067*e4b17023SJohn Marino {
1068*e4b17023SJohn Marino *constexpr_p = false;
1069*e4b17023SJohn Marino if (msg)
1070*e4b17023SJohn Marino inform (0, "defaulted default constructor does not "
1071*e4b17023SJohn Marino "initialize %q+#D", field);
1072*e4b17023SJohn Marino }
1073*e4b17023SJohn Marino }
1074*e4b17023SJohn Marino
1075*e4b17023SJohn Marino if (!CLASS_TYPE_P (mem_type))
1076*e4b17023SJohn Marino continue;
1077*e4b17023SJohn Marino
1078*e4b17023SJohn Marino if (ANON_AGGR_TYPE_P (mem_type))
1079*e4b17023SJohn Marino {
1080*e4b17023SJohn Marino walk_field_subobs (TYPE_FIELDS (mem_type), fnname, sfk, quals,
1081*e4b17023SJohn Marino copy_arg_p, move_p, assign_p, spec_p, trivial_p,
1082*e4b17023SJohn Marino deleted_p, constexpr_p, no_implicit_p,
1083*e4b17023SJohn Marino msg, flags, complain);
1084*e4b17023SJohn Marino continue;
1085*e4b17023SJohn Marino }
1086*e4b17023SJohn Marino
1087*e4b17023SJohn Marino if (copy_arg_p)
1088*e4b17023SJohn Marino {
1089*e4b17023SJohn Marino int mem_quals = cp_type_quals (mem_type) | quals;
1090*e4b17023SJohn Marino if (DECL_MUTABLE_P (field))
1091*e4b17023SJohn Marino mem_quals &= ~TYPE_QUAL_CONST;
1092*e4b17023SJohn Marino argtype = build_stub_type (mem_type, mem_quals, move_p);
1093*e4b17023SJohn Marino }
1094*e4b17023SJohn Marino else
1095*e4b17023SJohn Marino argtype = NULL_TREE;
1096*e4b17023SJohn Marino
1097*e4b17023SJohn Marino rval = locate_fn_flags (mem_type, fnname, argtype, flags, complain);
1098*e4b17023SJohn Marino
1099*e4b17023SJohn Marino process_subob_fn (rval, move_p, spec_p, trivial_p, deleted_p,
1100*e4b17023SJohn Marino constexpr_p, no_implicit_p, msg, field);
1101*e4b17023SJohn Marino }
1102*e4b17023SJohn Marino }
1103*e4b17023SJohn Marino
1104*e4b17023SJohn Marino /* The caller wants to generate an implicit declaration of SFK for CTYPE
1105*e4b17023SJohn Marino which is const if relevant and CONST_P is set. If spec_p, trivial_p and
1106*e4b17023SJohn Marino deleted_p are non-null, set their referent appropriately. If diag is
1107*e4b17023SJohn Marino true, we're either being called from maybe_explain_implicit_delete to
1108*e4b17023SJohn Marino give errors, or if constexpr_p is non-null, from
1109*e4b17023SJohn Marino explain_invalid_constexpr_fn. */
1110*e4b17023SJohn Marino
1111*e4b17023SJohn Marino static void
synthesized_method_walk(tree ctype,special_function_kind sfk,bool const_p,tree * spec_p,bool * trivial_p,bool * deleted_p,bool * constexpr_p,bool * no_implicit_p,bool diag)1112*e4b17023SJohn Marino synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
1113*e4b17023SJohn Marino tree *spec_p, bool *trivial_p, bool *deleted_p,
1114*e4b17023SJohn Marino bool *constexpr_p, bool *no_implicit_p, bool diag)
1115*e4b17023SJohn Marino {
1116*e4b17023SJohn Marino tree binfo, base_binfo, scope, fnname, rval, argtype;
1117*e4b17023SJohn Marino bool move_p, copy_arg_p, assign_p, expected_trivial, check_vdtor;
1118*e4b17023SJohn Marino VEC(tree,gc) *vbases;
1119*e4b17023SJohn Marino int i, quals, flags;
1120*e4b17023SJohn Marino tsubst_flags_t complain;
1121*e4b17023SJohn Marino const char *msg;
1122*e4b17023SJohn Marino bool ctor_p;
1123*e4b17023SJohn Marino
1124*e4b17023SJohn Marino if (spec_p)
1125*e4b17023SJohn Marino *spec_p = (cxx_dialect >= cxx0x ? noexcept_true_spec : empty_except_spec);
1126*e4b17023SJohn Marino
1127*e4b17023SJohn Marino if (no_implicit_p)
1128*e4b17023SJohn Marino *no_implicit_p = false;
1129*e4b17023SJohn Marino
1130*e4b17023SJohn Marino if (deleted_p)
1131*e4b17023SJohn Marino {
1132*e4b17023SJohn Marino /* "The closure type associated with a lambda-expression has a deleted
1133*e4b17023SJohn Marino default constructor and a deleted copy assignment operator."
1134*e4b17023SJohn Marino This is diagnosed in maybe_explain_implicit_delete. */
1135*e4b17023SJohn Marino if (LAMBDA_TYPE_P (ctype)
1136*e4b17023SJohn Marino && (sfk == sfk_constructor
1137*e4b17023SJohn Marino || sfk == sfk_copy_assignment))
1138*e4b17023SJohn Marino {
1139*e4b17023SJohn Marino *deleted_p = true;
1140*e4b17023SJohn Marino return;
1141*e4b17023SJohn Marino }
1142*e4b17023SJohn Marino
1143*e4b17023SJohn Marino *deleted_p = false;
1144*e4b17023SJohn Marino }
1145*e4b17023SJohn Marino
1146*e4b17023SJohn Marino ctor_p = false;
1147*e4b17023SJohn Marino assign_p = false;
1148*e4b17023SJohn Marino check_vdtor = false;
1149*e4b17023SJohn Marino switch (sfk)
1150*e4b17023SJohn Marino {
1151*e4b17023SJohn Marino case sfk_move_assignment:
1152*e4b17023SJohn Marino case sfk_copy_assignment:
1153*e4b17023SJohn Marino assign_p = true;
1154*e4b17023SJohn Marino fnname = ansi_assopname (NOP_EXPR);
1155*e4b17023SJohn Marino break;
1156*e4b17023SJohn Marino
1157*e4b17023SJohn Marino case sfk_destructor:
1158*e4b17023SJohn Marino check_vdtor = true;
1159*e4b17023SJohn Marino /* The synthesized method will call base dtors, but check complete
1160*e4b17023SJohn Marino here to avoid having to deal with VTT. */
1161*e4b17023SJohn Marino fnname = complete_dtor_identifier;
1162*e4b17023SJohn Marino break;
1163*e4b17023SJohn Marino
1164*e4b17023SJohn Marino case sfk_constructor:
1165*e4b17023SJohn Marino case sfk_move_constructor:
1166*e4b17023SJohn Marino case sfk_copy_constructor:
1167*e4b17023SJohn Marino ctor_p = true;
1168*e4b17023SJohn Marino fnname = complete_ctor_identifier;
1169*e4b17023SJohn Marino break;
1170*e4b17023SJohn Marino
1171*e4b17023SJohn Marino default:
1172*e4b17023SJohn Marino gcc_unreachable ();
1173*e4b17023SJohn Marino }
1174*e4b17023SJohn Marino
1175*e4b17023SJohn Marino /* If that user-written default constructor would satisfy the
1176*e4b17023SJohn Marino requirements of a constexpr constructor (7.1.5), the
1177*e4b17023SJohn Marino implicitly-defined default constructor is constexpr. */
1178*e4b17023SJohn Marino if (constexpr_p)
1179*e4b17023SJohn Marino *constexpr_p = ctor_p;
1180*e4b17023SJohn Marino
1181*e4b17023SJohn Marino move_p = false;
1182*e4b17023SJohn Marino switch (sfk)
1183*e4b17023SJohn Marino {
1184*e4b17023SJohn Marino case sfk_constructor:
1185*e4b17023SJohn Marino case sfk_destructor:
1186*e4b17023SJohn Marino copy_arg_p = false;
1187*e4b17023SJohn Marino break;
1188*e4b17023SJohn Marino
1189*e4b17023SJohn Marino case sfk_move_constructor:
1190*e4b17023SJohn Marino case sfk_move_assignment:
1191*e4b17023SJohn Marino move_p = true;
1192*e4b17023SJohn Marino case sfk_copy_constructor:
1193*e4b17023SJohn Marino case sfk_copy_assignment:
1194*e4b17023SJohn Marino copy_arg_p = true;
1195*e4b17023SJohn Marino break;
1196*e4b17023SJohn Marino
1197*e4b17023SJohn Marino default:
1198*e4b17023SJohn Marino gcc_unreachable ();
1199*e4b17023SJohn Marino }
1200*e4b17023SJohn Marino
1201*e4b17023SJohn Marino expected_trivial = type_has_trivial_fn (ctype, sfk);
1202*e4b17023SJohn Marino if (trivial_p)
1203*e4b17023SJohn Marino *trivial_p = expected_trivial;
1204*e4b17023SJohn Marino
1205*e4b17023SJohn Marino /* The TYPE_HAS_COMPLEX_* flags tell us about constraints from base
1206*e4b17023SJohn Marino class versions and other properties of the type. But a subobject
1207*e4b17023SJohn Marino class can be trivially copyable and yet have overload resolution
1208*e4b17023SJohn Marino choose a template constructor for initialization, depending on
1209*e4b17023SJohn Marino rvalueness and cv-quals. So we can't exit early for copy/move
1210*e4b17023SJohn Marino methods in C++0x. The same considerations apply in C++98/03, but
1211*e4b17023SJohn Marino there the definition of triviality does not consider overload
1212*e4b17023SJohn Marino resolution, so a constructor can be trivial even if it would otherwise
1213*e4b17023SJohn Marino call a non-trivial constructor. */
1214*e4b17023SJohn Marino if (expected_trivial
1215*e4b17023SJohn Marino && (!copy_arg_p || cxx_dialect < cxx0x))
1216*e4b17023SJohn Marino {
1217*e4b17023SJohn Marino if (constexpr_p && sfk == sfk_constructor)
1218*e4b17023SJohn Marino {
1219*e4b17023SJohn Marino bool cx = trivial_default_constructor_is_constexpr (ctype);
1220*e4b17023SJohn Marino *constexpr_p = cx;
1221*e4b17023SJohn Marino if (diag && !cx && TREE_CODE (ctype) == UNION_TYPE)
1222*e4b17023SJohn Marino /* A trivial constructor doesn't have any NSDMI. */
1223*e4b17023SJohn Marino inform (input_location, "defaulted default constructor does "
1224*e4b17023SJohn Marino "not initialize any non-static data member");
1225*e4b17023SJohn Marino }
1226*e4b17023SJohn Marino if (!diag)
1227*e4b17023SJohn Marino return;
1228*e4b17023SJohn Marino }
1229*e4b17023SJohn Marino
1230*e4b17023SJohn Marino ++cp_unevaluated_operand;
1231*e4b17023SJohn Marino ++c_inhibit_evaluation_warnings;
1232*e4b17023SJohn Marino
1233*e4b17023SJohn Marino scope = push_scope (ctype);
1234*e4b17023SJohn Marino
1235*e4b17023SJohn Marino if (diag)
1236*e4b17023SJohn Marino {
1237*e4b17023SJohn Marino flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE|LOOKUP_DEFAULTED;
1238*e4b17023SJohn Marino complain = tf_warning_or_error;
1239*e4b17023SJohn Marino }
1240*e4b17023SJohn Marino else
1241*e4b17023SJohn Marino {
1242*e4b17023SJohn Marino flags = LOOKUP_PROTECT|LOOKUP_SPECULATIVE|LOOKUP_DEFAULTED;
1243*e4b17023SJohn Marino complain = tf_none;
1244*e4b17023SJohn Marino }
1245*e4b17023SJohn Marino
1246*e4b17023SJohn Marino if (const_p)
1247*e4b17023SJohn Marino quals = TYPE_QUAL_CONST;
1248*e4b17023SJohn Marino else
1249*e4b17023SJohn Marino quals = TYPE_UNQUALIFIED;
1250*e4b17023SJohn Marino argtype = NULL_TREE;
1251*e4b17023SJohn Marino
1252*e4b17023SJohn Marino if (!diag)
1253*e4b17023SJohn Marino msg = NULL;
1254*e4b17023SJohn Marino else if (assign_p)
1255*e4b17023SJohn Marino msg = ("base %qT does not have a move assignment operator or trivial "
1256*e4b17023SJohn Marino "copy assignment operator");
1257*e4b17023SJohn Marino else
1258*e4b17023SJohn Marino msg = ("base %qT does not have a move constructor or trivial "
1259*e4b17023SJohn Marino "copy constructor");
1260*e4b17023SJohn Marino
1261*e4b17023SJohn Marino for (binfo = TYPE_BINFO (ctype), i = 0;
1262*e4b17023SJohn Marino BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
1263*e4b17023SJohn Marino {
1264*e4b17023SJohn Marino tree basetype = BINFO_TYPE (base_binfo);
1265*e4b17023SJohn Marino if (copy_arg_p)
1266*e4b17023SJohn Marino argtype = build_stub_type (basetype, quals, move_p);
1267*e4b17023SJohn Marino rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain);
1268*e4b17023SJohn Marino
1269*e4b17023SJohn Marino process_subob_fn (rval, move_p, spec_p, trivial_p, deleted_p,
1270*e4b17023SJohn Marino constexpr_p, no_implicit_p, msg, basetype);
1271*e4b17023SJohn Marino if (ctor_p && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype))
1272*e4b17023SJohn Marino {
1273*e4b17023SJohn Marino /* In a constructor we also need to check the subobject
1274*e4b17023SJohn Marino destructors for cleanup of partially constructed objects. */
1275*e4b17023SJohn Marino rval = locate_fn_flags (base_binfo, complete_dtor_identifier,
1276*e4b17023SJohn Marino NULL_TREE, flags, complain);
1277*e4b17023SJohn Marino /* Note that we don't pass down trivial_p; the subobject
1278*e4b17023SJohn Marino destructors don't affect triviality of the constructor. Nor
1279*e4b17023SJohn Marino do they affect constexpr-ness (a constant expression doesn't
1280*e4b17023SJohn Marino throw) or exception-specification (a throw from one of the
1281*e4b17023SJohn Marino dtors would be a double-fault). */
1282*e4b17023SJohn Marino process_subob_fn (rval, false, NULL, NULL,
1283*e4b17023SJohn Marino deleted_p, NULL, NULL, NULL,
1284*e4b17023SJohn Marino basetype);
1285*e4b17023SJohn Marino }
1286*e4b17023SJohn Marino
1287*e4b17023SJohn Marino if (check_vdtor && type_has_virtual_destructor (basetype))
1288*e4b17023SJohn Marino {
1289*e4b17023SJohn Marino rval = locate_fn_flags (ctype, ansi_opname (DELETE_EXPR),
1290*e4b17023SJohn Marino ptr_type_node, flags, complain);
1291*e4b17023SJohn Marino /* Unlike for base ctor/op=/dtor, for operator delete it's fine
1292*e4b17023SJohn Marino to have a null rval (no class-specific op delete). */
1293*e4b17023SJohn Marino if (rval && rval == error_mark_node && deleted_p)
1294*e4b17023SJohn Marino *deleted_p = true;
1295*e4b17023SJohn Marino check_vdtor = false;
1296*e4b17023SJohn Marino }
1297*e4b17023SJohn Marino }
1298*e4b17023SJohn Marino
1299*e4b17023SJohn Marino vbases = CLASSTYPE_VBASECLASSES (ctype);
1300*e4b17023SJohn Marino if (vbases && assign_p && move_p)
1301*e4b17023SJohn Marino {
1302*e4b17023SJohn Marino /* Should the spec be changed to allow vbases that only occur once? */
1303*e4b17023SJohn Marino if (diag)
1304*e4b17023SJohn Marino error ("%qT has virtual bases, default move assignment operator "
1305*e4b17023SJohn Marino "cannot be generated", ctype);
1306*e4b17023SJohn Marino else if (deleted_p)
1307*e4b17023SJohn Marino *deleted_p = true;
1308*e4b17023SJohn Marino }
1309*e4b17023SJohn Marino else if (!assign_p)
1310*e4b17023SJohn Marino {
1311*e4b17023SJohn Marino if (diag)
1312*e4b17023SJohn Marino msg = ("virtual base %qT does not have a move constructor "
1313*e4b17023SJohn Marino "or trivial copy constructor");
1314*e4b17023SJohn Marino if (vbases && constexpr_p)
1315*e4b17023SJohn Marino *constexpr_p = false;
1316*e4b17023SJohn Marino FOR_EACH_VEC_ELT (tree, vbases, i, base_binfo)
1317*e4b17023SJohn Marino {
1318*e4b17023SJohn Marino tree basetype = BINFO_TYPE (base_binfo);
1319*e4b17023SJohn Marino if (copy_arg_p)
1320*e4b17023SJohn Marino argtype = build_stub_type (basetype, quals, move_p);
1321*e4b17023SJohn Marino rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain);
1322*e4b17023SJohn Marino
1323*e4b17023SJohn Marino process_subob_fn (rval, move_p, spec_p, trivial_p, deleted_p,
1324*e4b17023SJohn Marino constexpr_p, no_implicit_p, msg, basetype);
1325*e4b17023SJohn Marino if (ctor_p && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype))
1326*e4b17023SJohn Marino {
1327*e4b17023SJohn Marino rval = locate_fn_flags (base_binfo, complete_dtor_identifier,
1328*e4b17023SJohn Marino NULL_TREE, flags, complain);
1329*e4b17023SJohn Marino process_subob_fn (rval, false, NULL, NULL,
1330*e4b17023SJohn Marino deleted_p, NULL, NULL, NULL,
1331*e4b17023SJohn Marino basetype);
1332*e4b17023SJohn Marino }
1333*e4b17023SJohn Marino }
1334*e4b17023SJohn Marino }
1335*e4b17023SJohn Marino if (!diag)
1336*e4b17023SJohn Marino /* Leave msg null. */;
1337*e4b17023SJohn Marino else if (assign_p)
1338*e4b17023SJohn Marino msg = ("non-static data member %qD does not have a move "
1339*e4b17023SJohn Marino "assignment operator or trivial copy assignment operator");
1340*e4b17023SJohn Marino else
1341*e4b17023SJohn Marino msg = ("non-static data member %qD does not have a move "
1342*e4b17023SJohn Marino "constructor or trivial copy constructor");
1343*e4b17023SJohn Marino walk_field_subobs (TYPE_FIELDS (ctype), fnname, sfk, quals,
1344*e4b17023SJohn Marino copy_arg_p, move_p, assign_p, spec_p, trivial_p,
1345*e4b17023SJohn Marino deleted_p, constexpr_p, no_implicit_p,
1346*e4b17023SJohn Marino msg, flags, complain);
1347*e4b17023SJohn Marino if (ctor_p)
1348*e4b17023SJohn Marino walk_field_subobs (TYPE_FIELDS (ctype), complete_dtor_identifier,
1349*e4b17023SJohn Marino sfk_destructor, TYPE_UNQUALIFIED, false,
1350*e4b17023SJohn Marino false, false, NULL, NULL,
1351*e4b17023SJohn Marino deleted_p, NULL,
1352*e4b17023SJohn Marino NULL, NULL, flags, complain);
1353*e4b17023SJohn Marino
1354*e4b17023SJohn Marino pop_scope (scope);
1355*e4b17023SJohn Marino
1356*e4b17023SJohn Marino --cp_unevaluated_operand;
1357*e4b17023SJohn Marino --c_inhibit_evaluation_warnings;
1358*e4b17023SJohn Marino }
1359*e4b17023SJohn Marino
1360*e4b17023SJohn Marino /* DECL is a deleted function. If it's implicitly deleted, explain why and
1361*e4b17023SJohn Marino return true; else return false. */
1362*e4b17023SJohn Marino
1363*e4b17023SJohn Marino bool
maybe_explain_implicit_delete(tree decl)1364*e4b17023SJohn Marino maybe_explain_implicit_delete (tree decl)
1365*e4b17023SJohn Marino {
1366*e4b17023SJohn Marino /* If decl is a clone, get the primary variant. */
1367*e4b17023SJohn Marino decl = DECL_ORIGIN (decl);
1368*e4b17023SJohn Marino gcc_assert (DECL_DELETED_FN (decl));
1369*e4b17023SJohn Marino if (DECL_DEFAULTED_FN (decl))
1370*e4b17023SJohn Marino {
1371*e4b17023SJohn Marino /* Not marked GTY; it doesn't need to be GC'd or written to PCH. */
1372*e4b17023SJohn Marino static struct pointer_set_t *explained;
1373*e4b17023SJohn Marino
1374*e4b17023SJohn Marino special_function_kind sfk;
1375*e4b17023SJohn Marino location_t loc;
1376*e4b17023SJohn Marino bool informed;
1377*e4b17023SJohn Marino tree ctype;
1378*e4b17023SJohn Marino
1379*e4b17023SJohn Marino if (!explained)
1380*e4b17023SJohn Marino explained = pointer_set_create ();
1381*e4b17023SJohn Marino if (pointer_set_insert (explained, decl))
1382*e4b17023SJohn Marino return true;
1383*e4b17023SJohn Marino
1384*e4b17023SJohn Marino sfk = special_function_p (decl);
1385*e4b17023SJohn Marino ctype = DECL_CONTEXT (decl);
1386*e4b17023SJohn Marino loc = input_location;
1387*e4b17023SJohn Marino input_location = DECL_SOURCE_LOCATION (decl);
1388*e4b17023SJohn Marino
1389*e4b17023SJohn Marino informed = false;
1390*e4b17023SJohn Marino if (LAMBDA_TYPE_P (ctype))
1391*e4b17023SJohn Marino {
1392*e4b17023SJohn Marino informed = true;
1393*e4b17023SJohn Marino if (sfk == sfk_constructor)
1394*e4b17023SJohn Marino inform (DECL_SOURCE_LOCATION (decl),
1395*e4b17023SJohn Marino "a lambda closure type has a deleted default constructor");
1396*e4b17023SJohn Marino else if (sfk == sfk_copy_assignment)
1397*e4b17023SJohn Marino inform (DECL_SOURCE_LOCATION (decl),
1398*e4b17023SJohn Marino "a lambda closure type has a deleted copy assignment operator");
1399*e4b17023SJohn Marino else
1400*e4b17023SJohn Marino informed = false;
1401*e4b17023SJohn Marino }
1402*e4b17023SJohn Marino else if (DECL_ARTIFICIAL (decl)
1403*e4b17023SJohn Marino && (sfk == sfk_copy_assignment
1404*e4b17023SJohn Marino || sfk == sfk_copy_constructor)
1405*e4b17023SJohn Marino && (type_has_user_declared_move_constructor (ctype)
1406*e4b17023SJohn Marino || type_has_user_declared_move_assign (ctype)))
1407*e4b17023SJohn Marino {
1408*e4b17023SJohn Marino inform (0, "%q+#D is implicitly declared as deleted because %qT "
1409*e4b17023SJohn Marino "declares a move constructor or move assignment operator",
1410*e4b17023SJohn Marino decl, ctype);
1411*e4b17023SJohn Marino informed = true;
1412*e4b17023SJohn Marino }
1413*e4b17023SJohn Marino if (!informed)
1414*e4b17023SJohn Marino {
1415*e4b17023SJohn Marino tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl));
1416*e4b17023SJohn Marino bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
1417*e4b17023SJohn Marino tree scope = push_scope (ctype);
1418*e4b17023SJohn Marino inform (0, "%q+#D is implicitly deleted because the default "
1419*e4b17023SJohn Marino "definition would be ill-formed:", decl);
1420*e4b17023SJohn Marino pop_scope (scope);
1421*e4b17023SJohn Marino synthesized_method_walk (ctype, sfk, const_p,
1422*e4b17023SJohn Marino NULL, NULL, NULL, NULL, NULL, true);
1423*e4b17023SJohn Marino }
1424*e4b17023SJohn Marino
1425*e4b17023SJohn Marino input_location = loc;
1426*e4b17023SJohn Marino return true;
1427*e4b17023SJohn Marino }
1428*e4b17023SJohn Marino return false;
1429*e4b17023SJohn Marino }
1430*e4b17023SJohn Marino
1431*e4b17023SJohn Marino /* DECL is a defaulted function which was declared constexpr. Explain why
1432*e4b17023SJohn Marino it can't be constexpr. */
1433*e4b17023SJohn Marino
1434*e4b17023SJohn Marino void
explain_implicit_non_constexpr(tree decl)1435*e4b17023SJohn Marino explain_implicit_non_constexpr (tree decl)
1436*e4b17023SJohn Marino {
1437*e4b17023SJohn Marino tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl));
1438*e4b17023SJohn Marino bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
1439*e4b17023SJohn Marino bool dummy;
1440*e4b17023SJohn Marino synthesized_method_walk (DECL_CLASS_CONTEXT (decl),
1441*e4b17023SJohn Marino special_function_p (decl), const_p,
1442*e4b17023SJohn Marino NULL, NULL, NULL, &dummy, NULL, true);
1443*e4b17023SJohn Marino }
1444*e4b17023SJohn Marino
1445*e4b17023SJohn Marino /* Implicitly declare the special function indicated by KIND, as a
1446*e4b17023SJohn Marino member of TYPE. For copy constructors and assignment operators,
1447*e4b17023SJohn Marino CONST_P indicates whether these functions should take a const
1448*e4b17023SJohn Marino reference argument or a non-const reference. Returns the
1449*e4b17023SJohn Marino FUNCTION_DECL for the implicitly declared function. */
1450*e4b17023SJohn Marino
1451*e4b17023SJohn Marino static tree
implicitly_declare_fn(special_function_kind kind,tree type,bool const_p)1452*e4b17023SJohn Marino implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
1453*e4b17023SJohn Marino {
1454*e4b17023SJohn Marino tree fn;
1455*e4b17023SJohn Marino tree parameter_types = void_list_node;
1456*e4b17023SJohn Marino tree return_type;
1457*e4b17023SJohn Marino tree fn_type;
1458*e4b17023SJohn Marino tree raises = empty_except_spec;
1459*e4b17023SJohn Marino tree rhs_parm_type = NULL_TREE;
1460*e4b17023SJohn Marino tree this_parm;
1461*e4b17023SJohn Marino tree name;
1462*e4b17023SJohn Marino HOST_WIDE_INT saved_processing_template_decl;
1463*e4b17023SJohn Marino bool deleted_p;
1464*e4b17023SJohn Marino bool trivial_p;
1465*e4b17023SJohn Marino bool constexpr_p;
1466*e4b17023SJohn Marino bool no_implicit_p;
1467*e4b17023SJohn Marino
1468*e4b17023SJohn Marino /* Because we create declarations for implicitly declared functions
1469*e4b17023SJohn Marino lazily, we may be creating the declaration for a member of TYPE
1470*e4b17023SJohn Marino while in some completely different context. However, TYPE will
1471*e4b17023SJohn Marino never be a dependent class (because we never want to do lookups
1472*e4b17023SJohn Marino for implicitly defined functions in a dependent class).
1473*e4b17023SJohn Marino Furthermore, we must set PROCESSING_TEMPLATE_DECL to zero here
1474*e4b17023SJohn Marino because we only create clones for constructors and destructors
1475*e4b17023SJohn Marino when not in a template. */
1476*e4b17023SJohn Marino gcc_assert (!dependent_type_p (type));
1477*e4b17023SJohn Marino saved_processing_template_decl = processing_template_decl;
1478*e4b17023SJohn Marino processing_template_decl = 0;
1479*e4b17023SJohn Marino
1480*e4b17023SJohn Marino type = TYPE_MAIN_VARIANT (type);
1481*e4b17023SJohn Marino
1482*e4b17023SJohn Marino if (targetm.cxx.cdtor_returns_this () && !TYPE_FOR_JAVA (type))
1483*e4b17023SJohn Marino {
1484*e4b17023SJohn Marino if (kind == sfk_destructor)
1485*e4b17023SJohn Marino /* See comment in check_special_function_return_type. */
1486*e4b17023SJohn Marino return_type = build_pointer_type (void_type_node);
1487*e4b17023SJohn Marino else
1488*e4b17023SJohn Marino return_type = build_pointer_type (type);
1489*e4b17023SJohn Marino }
1490*e4b17023SJohn Marino else
1491*e4b17023SJohn Marino return_type = void_type_node;
1492*e4b17023SJohn Marino
1493*e4b17023SJohn Marino switch (kind)
1494*e4b17023SJohn Marino {
1495*e4b17023SJohn Marino case sfk_destructor:
1496*e4b17023SJohn Marino /* Destructor. */
1497*e4b17023SJohn Marino name = constructor_name (type);
1498*e4b17023SJohn Marino break;
1499*e4b17023SJohn Marino
1500*e4b17023SJohn Marino case sfk_constructor:
1501*e4b17023SJohn Marino /* Default constructor. */
1502*e4b17023SJohn Marino name = constructor_name (type);
1503*e4b17023SJohn Marino break;
1504*e4b17023SJohn Marino
1505*e4b17023SJohn Marino case sfk_copy_constructor:
1506*e4b17023SJohn Marino case sfk_copy_assignment:
1507*e4b17023SJohn Marino case sfk_move_constructor:
1508*e4b17023SJohn Marino case sfk_move_assignment:
1509*e4b17023SJohn Marino {
1510*e4b17023SJohn Marino bool move_p;
1511*e4b17023SJohn Marino if (kind == sfk_copy_assignment
1512*e4b17023SJohn Marino || kind == sfk_move_assignment)
1513*e4b17023SJohn Marino {
1514*e4b17023SJohn Marino return_type = build_reference_type (type);
1515*e4b17023SJohn Marino name = ansi_assopname (NOP_EXPR);
1516*e4b17023SJohn Marino }
1517*e4b17023SJohn Marino else
1518*e4b17023SJohn Marino name = constructor_name (type);
1519*e4b17023SJohn Marino
1520*e4b17023SJohn Marino if (const_p)
1521*e4b17023SJohn Marino rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
1522*e4b17023SJohn Marino else
1523*e4b17023SJohn Marino rhs_parm_type = type;
1524*e4b17023SJohn Marino move_p = (kind == sfk_move_assignment
1525*e4b17023SJohn Marino || kind == sfk_move_constructor);
1526*e4b17023SJohn Marino rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p);
1527*e4b17023SJohn Marino
1528*e4b17023SJohn Marino parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
1529*e4b17023SJohn Marino break;
1530*e4b17023SJohn Marino }
1531*e4b17023SJohn Marino default:
1532*e4b17023SJohn Marino gcc_unreachable ();
1533*e4b17023SJohn Marino }
1534*e4b17023SJohn Marino
1535*e4b17023SJohn Marino synthesized_method_walk (type, kind, const_p, &raises, &trivial_p,
1536*e4b17023SJohn Marino &deleted_p, &constexpr_p, &no_implicit_p, false);
1537*e4b17023SJohn Marino /* Don't bother marking a deleted constructor as constexpr. */
1538*e4b17023SJohn Marino if (deleted_p)
1539*e4b17023SJohn Marino constexpr_p = false;
1540*e4b17023SJohn Marino /* A trivial copy/move constructor is also a constexpr constructor. */
1541*e4b17023SJohn Marino else if (trivial_p && cxx_dialect >= cxx0x
1542*e4b17023SJohn Marino && (kind == sfk_copy_constructor
1543*e4b17023SJohn Marino || kind == sfk_move_constructor))
1544*e4b17023SJohn Marino gcc_assert (constexpr_p);
1545*e4b17023SJohn Marino
1546*e4b17023SJohn Marino if (!trivial_p && type_has_trivial_fn (type, kind))
1547*e4b17023SJohn Marino type_set_nontrivial_flag (type, kind);
1548*e4b17023SJohn Marino
1549*e4b17023SJohn Marino /* Create the function. */
1550*e4b17023SJohn Marino fn_type = build_method_type_directly (type, return_type, parameter_types);
1551*e4b17023SJohn Marino if (raises)
1552*e4b17023SJohn Marino fn_type = build_exception_variant (fn_type, raises);
1553*e4b17023SJohn Marino fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
1554*e4b17023SJohn Marino DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
1555*e4b17023SJohn Marino if (kind == sfk_constructor || kind == sfk_copy_constructor
1556*e4b17023SJohn Marino || kind == sfk_move_constructor)
1557*e4b17023SJohn Marino DECL_CONSTRUCTOR_P (fn) = 1;
1558*e4b17023SJohn Marino else if (kind == sfk_destructor)
1559*e4b17023SJohn Marino DECL_DESTRUCTOR_P (fn) = 1;
1560*e4b17023SJohn Marino else
1561*e4b17023SJohn Marino {
1562*e4b17023SJohn Marino DECL_ASSIGNMENT_OPERATOR_P (fn) = 1;
1563*e4b17023SJohn Marino SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR);
1564*e4b17023SJohn Marino }
1565*e4b17023SJohn Marino
1566*e4b17023SJohn Marino /* If pointers to member functions use the least significant bit to
1567*e4b17023SJohn Marino indicate whether a function is virtual, ensure a pointer
1568*e4b17023SJohn Marino to this function will have that bit clear. */
1569*e4b17023SJohn Marino if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
1570*e4b17023SJohn Marino && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT)
1571*e4b17023SJohn Marino DECL_ALIGN (fn) = 2 * BITS_PER_UNIT;
1572*e4b17023SJohn Marino
1573*e4b17023SJohn Marino /* Create the explicit arguments. */
1574*e4b17023SJohn Marino if (rhs_parm_type)
1575*e4b17023SJohn Marino {
1576*e4b17023SJohn Marino /* Note that this parameter is *not* marked DECL_ARTIFICIAL; we
1577*e4b17023SJohn Marino want its type to be included in the mangled function
1578*e4b17023SJohn Marino name. */
1579*e4b17023SJohn Marino tree decl = cp_build_parm_decl (NULL_TREE, rhs_parm_type);
1580*e4b17023SJohn Marino TREE_READONLY (decl) = 1;
1581*e4b17023SJohn Marino retrofit_lang_decl (decl);
1582*e4b17023SJohn Marino DECL_PARM_INDEX (decl) = DECL_PARM_LEVEL (decl) = 1;
1583*e4b17023SJohn Marino DECL_ARGUMENTS (fn) = decl;
1584*e4b17023SJohn Marino }
1585*e4b17023SJohn Marino /* Add the "this" parameter. */
1586*e4b17023SJohn Marino this_parm = build_this_parm (fn_type, TYPE_UNQUALIFIED);
1587*e4b17023SJohn Marino DECL_CHAIN (this_parm) = DECL_ARGUMENTS (fn);
1588*e4b17023SJohn Marino DECL_ARGUMENTS (fn) = this_parm;
1589*e4b17023SJohn Marino
1590*e4b17023SJohn Marino grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL);
1591*e4b17023SJohn Marino set_linkage_according_to_type (type, fn);
1592*e4b17023SJohn Marino rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
1593*e4b17023SJohn Marino DECL_IN_AGGR_P (fn) = 1;
1594*e4b17023SJohn Marino DECL_ARTIFICIAL (fn) = 1;
1595*e4b17023SJohn Marino DECL_DEFAULTED_FN (fn) = 1;
1596*e4b17023SJohn Marino if (cxx_dialect >= cxx0x)
1597*e4b17023SJohn Marino {
1598*e4b17023SJohn Marino DECL_DELETED_FN (fn) = deleted_p;
1599*e4b17023SJohn Marino DECL_DECLARED_CONSTEXPR_P (fn) = constexpr_p;
1600*e4b17023SJohn Marino }
1601*e4b17023SJohn Marino FNDECL_SUPPRESS_IMPLICIT_DECL (fn) = no_implicit_p;
1602*e4b17023SJohn Marino DECL_EXTERNAL (fn) = true;
1603*e4b17023SJohn Marino DECL_NOT_REALLY_EXTERN (fn) = 1;
1604*e4b17023SJohn Marino DECL_DECLARED_INLINE_P (fn) = 1;
1605*e4b17023SJohn Marino gcc_assert (!TREE_USED (fn));
1606*e4b17023SJohn Marino
1607*e4b17023SJohn Marino /* Restore PROCESSING_TEMPLATE_DECL. */
1608*e4b17023SJohn Marino processing_template_decl = saved_processing_template_decl;
1609*e4b17023SJohn Marino
1610*e4b17023SJohn Marino return fn;
1611*e4b17023SJohn Marino }
1612*e4b17023SJohn Marino
1613*e4b17023SJohn Marino /* Gives any errors about defaulted functions which need to be deferred
1614*e4b17023SJohn Marino until the containing class is complete. */
1615*e4b17023SJohn Marino
1616*e4b17023SJohn Marino void
defaulted_late_check(tree fn)1617*e4b17023SJohn Marino defaulted_late_check (tree fn)
1618*e4b17023SJohn Marino {
1619*e4b17023SJohn Marino /* Complain about invalid signature for defaulted fn. */
1620*e4b17023SJohn Marino tree ctx = DECL_CONTEXT (fn);
1621*e4b17023SJohn Marino special_function_kind kind = special_function_p (fn);
1622*e4b17023SJohn Marino bool fn_const_p = (copy_fn_p (fn) == 2);
1623*e4b17023SJohn Marino tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p);
1624*e4b17023SJohn Marino
1625*e4b17023SJohn Marino if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)),
1626*e4b17023SJohn Marino TREE_TYPE (TREE_TYPE (implicit_fn)))
1627*e4b17023SJohn Marino || !compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
1628*e4b17023SJohn Marino TYPE_ARG_TYPES (TREE_TYPE (implicit_fn))))
1629*e4b17023SJohn Marino {
1630*e4b17023SJohn Marino error ("defaulted declaration %q+D", fn);
1631*e4b17023SJohn Marino error_at (DECL_SOURCE_LOCATION (fn),
1632*e4b17023SJohn Marino "does not match expected signature %qD", implicit_fn);
1633*e4b17023SJohn Marino }
1634*e4b17023SJohn Marino
1635*e4b17023SJohn Marino /* 8.4.2/2: If it is explicitly defaulted on its first declaration, it is
1636*e4b17023SJohn Marino implicitly considered to have the same exception-specification as if
1637*e4b17023SJohn Marino it had been implicitly declared. */
1638*e4b17023SJohn Marino if (DECL_DEFAULTED_IN_CLASS_P (fn))
1639*e4b17023SJohn Marino {
1640*e4b17023SJohn Marino tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
1641*e4b17023SJohn Marino if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
1642*e4b17023SJohn Marino {
1643*e4b17023SJohn Marino maybe_instantiate_noexcept (fn);
1644*e4b17023SJohn Marino if (!comp_except_specs (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)),
1645*e4b17023SJohn Marino eh_spec, ce_normal))
1646*e4b17023SJohn Marino error ("function %q+D defaulted on its first declaration "
1647*e4b17023SJohn Marino "with an exception-specification that differs from "
1648*e4b17023SJohn Marino "the implicit declaration %q#D", fn, implicit_fn);
1649*e4b17023SJohn Marino }
1650*e4b17023SJohn Marino TREE_TYPE (fn) = build_exception_variant (TREE_TYPE (fn), eh_spec);
1651*e4b17023SJohn Marino if (DECL_DECLARED_CONSTEXPR_P (implicit_fn))
1652*e4b17023SJohn Marino {
1653*e4b17023SJohn Marino /* Hmm...should we do this for out-of-class too? Should it be OK to
1654*e4b17023SJohn Marino add constexpr later like inline, rather than requiring
1655*e4b17023SJohn Marino declarations to match? */
1656*e4b17023SJohn Marino DECL_DECLARED_CONSTEXPR_P (fn) = true;
1657*e4b17023SJohn Marino if (kind == sfk_constructor)
1658*e4b17023SJohn Marino TYPE_HAS_CONSTEXPR_CTOR (ctx) = true;
1659*e4b17023SJohn Marino }
1660*e4b17023SJohn Marino }
1661*e4b17023SJohn Marino
1662*e4b17023SJohn Marino if (!DECL_DECLARED_CONSTEXPR_P (implicit_fn)
1663*e4b17023SJohn Marino && DECL_DECLARED_CONSTEXPR_P (fn))
1664*e4b17023SJohn Marino {
1665*e4b17023SJohn Marino if (!CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
1666*e4b17023SJohn Marino {
1667*e4b17023SJohn Marino error ("explicitly defaulted function %q+D cannot be declared "
1668*e4b17023SJohn Marino "as constexpr because the implicit declaration is not "
1669*e4b17023SJohn Marino "constexpr:", fn);
1670*e4b17023SJohn Marino explain_implicit_non_constexpr (fn);
1671*e4b17023SJohn Marino }
1672*e4b17023SJohn Marino DECL_DECLARED_CONSTEXPR_P (fn) = false;
1673*e4b17023SJohn Marino }
1674*e4b17023SJohn Marino
1675*e4b17023SJohn Marino if (DECL_DELETED_FN (implicit_fn))
1676*e4b17023SJohn Marino DECL_DELETED_FN (fn) = 1;
1677*e4b17023SJohn Marino }
1678*e4b17023SJohn Marino
1679*e4b17023SJohn Marino /* Returns true iff FN can be explicitly defaulted, and gives any
1680*e4b17023SJohn Marino errors if defaulting FN is ill-formed. */
1681*e4b17023SJohn Marino
1682*e4b17023SJohn Marino bool
defaultable_fn_check(tree fn)1683*e4b17023SJohn Marino defaultable_fn_check (tree fn)
1684*e4b17023SJohn Marino {
1685*e4b17023SJohn Marino special_function_kind kind = sfk_none;
1686*e4b17023SJohn Marino
1687*e4b17023SJohn Marino if (template_parm_scope_p ())
1688*e4b17023SJohn Marino {
1689*e4b17023SJohn Marino error ("a template cannot be defaulted");
1690*e4b17023SJohn Marino return false;
1691*e4b17023SJohn Marino }
1692*e4b17023SJohn Marino
1693*e4b17023SJohn Marino if (DECL_CONSTRUCTOR_P (fn))
1694*e4b17023SJohn Marino {
1695*e4b17023SJohn Marino if (FUNCTION_FIRST_USER_PARMTYPE (fn) == void_list_node)
1696*e4b17023SJohn Marino kind = sfk_constructor;
1697*e4b17023SJohn Marino else if (copy_fn_p (fn) > 0
1698*e4b17023SJohn Marino && (TREE_CHAIN (FUNCTION_FIRST_USER_PARMTYPE (fn))
1699*e4b17023SJohn Marino == void_list_node))
1700*e4b17023SJohn Marino kind = sfk_copy_constructor;
1701*e4b17023SJohn Marino else if (move_fn_p (fn))
1702*e4b17023SJohn Marino kind = sfk_move_constructor;
1703*e4b17023SJohn Marino }
1704*e4b17023SJohn Marino else if (DECL_DESTRUCTOR_P (fn))
1705*e4b17023SJohn Marino kind = sfk_destructor;
1706*e4b17023SJohn Marino else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
1707*e4b17023SJohn Marino && DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR)
1708*e4b17023SJohn Marino {
1709*e4b17023SJohn Marino if (copy_fn_p (fn))
1710*e4b17023SJohn Marino kind = sfk_copy_assignment;
1711*e4b17023SJohn Marino else if (move_fn_p (fn))
1712*e4b17023SJohn Marino kind = sfk_move_assignment;
1713*e4b17023SJohn Marino }
1714*e4b17023SJohn Marino
1715*e4b17023SJohn Marino if (kind == sfk_none)
1716*e4b17023SJohn Marino {
1717*e4b17023SJohn Marino error ("%qD cannot be defaulted", fn);
1718*e4b17023SJohn Marino return false;
1719*e4b17023SJohn Marino }
1720*e4b17023SJohn Marino else
1721*e4b17023SJohn Marino {
1722*e4b17023SJohn Marino tree t = FUNCTION_FIRST_USER_PARMTYPE (fn);
1723*e4b17023SJohn Marino for (; t && t != void_list_node; t = TREE_CHAIN (t))
1724*e4b17023SJohn Marino if (TREE_PURPOSE (t))
1725*e4b17023SJohn Marino {
1726*e4b17023SJohn Marino error ("defaulted function %q+D with default argument", fn);
1727*e4b17023SJohn Marino break;
1728*e4b17023SJohn Marino }
1729*e4b17023SJohn Marino if (TYPE_BEING_DEFINED (DECL_CONTEXT (fn)))
1730*e4b17023SJohn Marino /* Defer checking. */;
1731*e4b17023SJohn Marino else if (!processing_template_decl)
1732*e4b17023SJohn Marino defaulted_late_check (fn);
1733*e4b17023SJohn Marino
1734*e4b17023SJohn Marino return true;
1735*e4b17023SJohn Marino }
1736*e4b17023SJohn Marino }
1737*e4b17023SJohn Marino
1738*e4b17023SJohn Marino /* Add an implicit declaration to TYPE for the kind of function
1739*e4b17023SJohn Marino indicated by SFK. Return the FUNCTION_DECL for the new implicit
1740*e4b17023SJohn Marino declaration. */
1741*e4b17023SJohn Marino
1742*e4b17023SJohn Marino tree
lazily_declare_fn(special_function_kind sfk,tree type)1743*e4b17023SJohn Marino lazily_declare_fn (special_function_kind sfk, tree type)
1744*e4b17023SJohn Marino {
1745*e4b17023SJohn Marino tree fn;
1746*e4b17023SJohn Marino /* Whether or not the argument has a const reference type. */
1747*e4b17023SJohn Marino bool const_p = false;
1748*e4b17023SJohn Marino
1749*e4b17023SJohn Marino switch (sfk)
1750*e4b17023SJohn Marino {
1751*e4b17023SJohn Marino case sfk_constructor:
1752*e4b17023SJohn Marino CLASSTYPE_LAZY_DEFAULT_CTOR (type) = 0;
1753*e4b17023SJohn Marino break;
1754*e4b17023SJohn Marino case sfk_copy_constructor:
1755*e4b17023SJohn Marino const_p = TYPE_HAS_CONST_COPY_CTOR (type);
1756*e4b17023SJohn Marino CLASSTYPE_LAZY_COPY_CTOR (type) = 0;
1757*e4b17023SJohn Marino break;
1758*e4b17023SJohn Marino case sfk_move_constructor:
1759*e4b17023SJohn Marino CLASSTYPE_LAZY_MOVE_CTOR (type) = 0;
1760*e4b17023SJohn Marino break;
1761*e4b17023SJohn Marino case sfk_copy_assignment:
1762*e4b17023SJohn Marino const_p = TYPE_HAS_CONST_COPY_ASSIGN (type);
1763*e4b17023SJohn Marino CLASSTYPE_LAZY_COPY_ASSIGN (type) = 0;
1764*e4b17023SJohn Marino break;
1765*e4b17023SJohn Marino case sfk_move_assignment:
1766*e4b17023SJohn Marino CLASSTYPE_LAZY_MOVE_ASSIGN (type) = 0;
1767*e4b17023SJohn Marino break;
1768*e4b17023SJohn Marino case sfk_destructor:
1769*e4b17023SJohn Marino CLASSTYPE_LAZY_DESTRUCTOR (type) = 0;
1770*e4b17023SJohn Marino break;
1771*e4b17023SJohn Marino default:
1772*e4b17023SJohn Marino gcc_unreachable ();
1773*e4b17023SJohn Marino }
1774*e4b17023SJohn Marino
1775*e4b17023SJohn Marino /* Declare the function. */
1776*e4b17023SJohn Marino fn = implicitly_declare_fn (sfk, type, const_p);
1777*e4b17023SJohn Marino
1778*e4b17023SJohn Marino /* [class.copy]/8 If the class definition declares a move constructor or
1779*e4b17023SJohn Marino move assignment operator, the implicitly declared copy constructor is
1780*e4b17023SJohn Marino defined as deleted.... */
1781*e4b17023SJohn Marino if ((sfk == sfk_copy_assignment
1782*e4b17023SJohn Marino || sfk == sfk_copy_constructor)
1783*e4b17023SJohn Marino && (type_has_user_declared_move_constructor (type)
1784*e4b17023SJohn Marino || type_has_user_declared_move_assign (type)))
1785*e4b17023SJohn Marino DECL_DELETED_FN (fn) = true;
1786*e4b17023SJohn Marino
1787*e4b17023SJohn Marino /* For move variants, rather than declare them as deleted we just
1788*e4b17023SJohn Marino don't declare them at all. */
1789*e4b17023SJohn Marino if (DECL_DELETED_FN (fn)
1790*e4b17023SJohn Marino && (sfk == sfk_move_constructor
1791*e4b17023SJohn Marino || sfk == sfk_move_assignment))
1792*e4b17023SJohn Marino return NULL_TREE;
1793*e4b17023SJohn Marino
1794*e4b17023SJohn Marino /* We also suppress implicit move if it would call a non-trivial copy. */
1795*e4b17023SJohn Marino if (FNDECL_SUPPRESS_IMPLICIT_DECL (fn))
1796*e4b17023SJohn Marino return NULL_TREE;
1797*e4b17023SJohn Marino
1798*e4b17023SJohn Marino /* A destructor may be virtual. */
1799*e4b17023SJohn Marino if (sfk == sfk_destructor
1800*e4b17023SJohn Marino || sfk == sfk_move_assignment
1801*e4b17023SJohn Marino || sfk == sfk_copy_assignment)
1802*e4b17023SJohn Marino check_for_override (fn, type);
1803*e4b17023SJohn Marino /* Add it to CLASSTYPE_METHOD_VEC. */
1804*e4b17023SJohn Marino add_method (type, fn, NULL_TREE);
1805*e4b17023SJohn Marino /* Add it to TYPE_METHODS. */
1806*e4b17023SJohn Marino if (sfk == sfk_destructor
1807*e4b17023SJohn Marino && DECL_VIRTUAL_P (fn)
1808*e4b17023SJohn Marino && abi_version_at_least (2))
1809*e4b17023SJohn Marino /* The ABI requires that a virtual destructor go at the end of the
1810*e4b17023SJohn Marino vtable. */
1811*e4b17023SJohn Marino TYPE_METHODS (type) = chainon (TYPE_METHODS (type), fn);
1812*e4b17023SJohn Marino else
1813*e4b17023SJohn Marino {
1814*e4b17023SJohn Marino /* G++ 3.2 put the implicit destructor at the *beginning* of the
1815*e4b17023SJohn Marino TYPE_METHODS list, which cause the destructor to be emitted
1816*e4b17023SJohn Marino in an incorrect location in the vtable. */
1817*e4b17023SJohn Marino if (warn_abi && sfk == sfk_destructor && DECL_VIRTUAL_P (fn))
1818*e4b17023SJohn Marino warning (OPT_Wabi, "vtable layout for class %qT may not be ABI-compliant"
1819*e4b17023SJohn Marino "and may change in a future version of GCC due to "
1820*e4b17023SJohn Marino "implicit virtual destructor",
1821*e4b17023SJohn Marino type);
1822*e4b17023SJohn Marino DECL_CHAIN (fn) = TYPE_METHODS (type);
1823*e4b17023SJohn Marino TYPE_METHODS (type) = fn;
1824*e4b17023SJohn Marino }
1825*e4b17023SJohn Marino maybe_add_class_template_decl_list (type, fn, /*friend_p=*/0);
1826*e4b17023SJohn Marino if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
1827*e4b17023SJohn Marino || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
1828*e4b17023SJohn Marino /* Create appropriate clones. */
1829*e4b17023SJohn Marino clone_function_decl (fn, /*update_method_vec=*/true);
1830*e4b17023SJohn Marino
1831*e4b17023SJohn Marino return fn;
1832*e4b17023SJohn Marino }
1833*e4b17023SJohn Marino
1834*e4b17023SJohn Marino /* Given a FUNCTION_DECL FN and a chain LIST, skip as many elements of LIST
1835*e4b17023SJohn Marino as there are artificial parms in FN. */
1836*e4b17023SJohn Marino
1837*e4b17023SJohn Marino tree
skip_artificial_parms_for(const_tree fn,tree list)1838*e4b17023SJohn Marino skip_artificial_parms_for (const_tree fn, tree list)
1839*e4b17023SJohn Marino {
1840*e4b17023SJohn Marino if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
1841*e4b17023SJohn Marino list = TREE_CHAIN (list);
1842*e4b17023SJohn Marino else
1843*e4b17023SJohn Marino return list;
1844*e4b17023SJohn Marino
1845*e4b17023SJohn Marino if (DECL_HAS_IN_CHARGE_PARM_P (fn))
1846*e4b17023SJohn Marino list = TREE_CHAIN (list);
1847*e4b17023SJohn Marino if (DECL_HAS_VTT_PARM_P (fn))
1848*e4b17023SJohn Marino list = TREE_CHAIN (list);
1849*e4b17023SJohn Marino return list;
1850*e4b17023SJohn Marino }
1851*e4b17023SJohn Marino
1852*e4b17023SJohn Marino /* Given a FUNCTION_DECL FN and a chain LIST, return the number of
1853*e4b17023SJohn Marino artificial parms in FN. */
1854*e4b17023SJohn Marino
1855*e4b17023SJohn Marino int
num_artificial_parms_for(const_tree fn)1856*e4b17023SJohn Marino num_artificial_parms_for (const_tree fn)
1857*e4b17023SJohn Marino {
1858*e4b17023SJohn Marino int count = 0;
1859*e4b17023SJohn Marino
1860*e4b17023SJohn Marino if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
1861*e4b17023SJohn Marino count++;
1862*e4b17023SJohn Marino else
1863*e4b17023SJohn Marino return 0;
1864*e4b17023SJohn Marino
1865*e4b17023SJohn Marino if (DECL_HAS_IN_CHARGE_PARM_P (fn))
1866*e4b17023SJohn Marino count++;
1867*e4b17023SJohn Marino if (DECL_HAS_VTT_PARM_P (fn))
1868*e4b17023SJohn Marino count++;
1869*e4b17023SJohn Marino return count;
1870*e4b17023SJohn Marino }
1871*e4b17023SJohn Marino
1872*e4b17023SJohn Marino
1873*e4b17023SJohn Marino #include "gt-cp-method.h"
1874