xref: /dflybsd-src/contrib/gcc-4.7/gcc/cp/method.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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