OSDN Git Service

77th Cygnus<->FSF merge
[pf3gnuchains/gcc-fork.git] / gcc / cp / sig.c
1 /* Functions dealing with signatures and signature pointers/references.
2    Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
3    Contributed by Gerald Baumgartner (gb@cs.purdue.edu)
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22
23 #include "config.h"
24 #include <stdio.h>
25 #include "obstack.h"
26 #include "tree.h"
27 #include "cp-tree.h"
28 #include "flags.h"
29 #include "assert.h"
30
31 extern struct obstack *current_obstack;
32 extern struct obstack permanent_obstack;
33 extern struct obstack *saveable_obstack;
34
35 extern void error ();
36 extern void sorry ();
37 extern void compiler_error ();
38 extern void make_decl_rtl                       PROTO((tree, char *, int));
39
40 /* Used to help generate globally unique names for signature tables.  */
41
42 static int global_sigtable_name_counter;
43
44 /* Build an identifier for a signature pointer or reference, so we
45    can use it's name in function name mangling.  */
46
47 static tree
48 build_signature_pointer_or_reference_name (to_type, constp, volatilep, refp)
49      tree to_type;
50      int constp, volatilep, refp;
51 {
52   char * sig_name = TYPE_NAME_STRING (to_type);
53   int name_len = TYPE_NAME_LENGTH (to_type) + constp + volatilep;
54   char * name;
55
56   if (refp)
57     {
58       name = (char *) alloca (name_len + sizeof (SIGNATURE_REFERENCE_NAME) +2);
59       sprintf (name, SIGNATURE_REFERENCE_NAME_FORMAT,
60                constp ? "C" : "", volatilep ? "V": "", sig_name);
61     }
62   else
63     {
64       name = (char *) alloca (name_len + sizeof (SIGNATURE_POINTER_NAME) + 2);
65       sprintf (name, SIGNATURE_POINTER_NAME_FORMAT,
66                constp ? "C" : "", volatilep ? "V": "", sig_name);
67     }
68   return get_identifier (name);
69 }
70
71 /* Build a DECL node for a signature pointer or reference, so we can
72    tell the debugger the structure of signature pointers/references.
73    This function is called at most eight times for a given signature,
74    once for each [const] [volatile] signature pointer/reference.  */
75
76 static void
77 build_signature_pointer_or_reference_decl (type, name)
78      tree type, name;
79 {
80   tree decl;
81
82   /* We don't enter this declaration in any sort of symbol table.  */
83   decl = build_decl (TYPE_DECL, name, type);
84   TYPE_NAME (type) = decl;
85   TREE_CHAIN (type) = decl;
86 }
87
88 /* Construct, lay out and return the type of pointers or references
89    to signature TO_TYPE.  If such a type has already been constructed,
90    reuse it. If CONSTP or VOLATILEP is specified, make the `optr' const
91    or volatile, respectively.   If we are constructing a const/volatile
92    type variant and the main type variant doesn't exist yet, it is built
93    as well.  If REFP is 1, we construct a signature reference, otherwise
94    a signature pointer is constructed.
95
96    This function is a subroutine of `build_signature_pointer_type' and
97    `build_signature_reference_type'.  */
98
99 static tree
100 build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
101      tree to_type;
102      int constp, volatilep, refp;
103 {
104   register tree t, m;
105   register struct obstack *ambient_obstack = current_obstack;
106   register struct obstack *ambient_saveable_obstack = saveable_obstack;
107
108   m = refp ? SIGNATURE_REFERENCE_TO (to_type) : SIGNATURE_POINTER_TO (to_type);
109
110   /* If we don't have the main variant yet, construct it.  */
111   if (m == NULL_TREE
112       && (constp || volatilep))
113     m = build_signature_pointer_or_reference_type (to_type, 0, 0, refp);
114
115   /* Treat any nonzero argument as 1.  */
116   constp = !!constp;
117   volatilep = !!volatilep;
118   refp = !!refp;
119
120   /* If not generating auxiliary info, search the chain of variants to see
121      if there is already one there just like the one we need to have.  If so,
122      use that existing one.
123
124      We don't do this in the case where we are generating aux info because
125      in that case we want each typedef names to get it's own distinct type
126      node, even if the type of this new typedef is the same as some other
127      (existing) type.  */
128
129   if (m && !flag_gen_aux_info)
130     for (t = m; t; t = TYPE_NEXT_VARIANT (t))
131       if (constp == TYPE_READONLY (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (t))))
132           && volatilep == TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (t)))))
133         return t;
134
135   /* We need a new one.  If TO_TYPE is permanent, make this permanent too.  */
136   if (TREE_PERMANENT (to_type))
137     {
138       current_obstack = &permanent_obstack;
139       saveable_obstack = &permanent_obstack;
140     }
141
142   /* A signature pointer or reference to a signature `s' looks like this:
143
144        struct {
145          void * optr;
146          const s * sptr;
147        };
148
149      A `const' signature pointer/reference is a
150
151        struct {
152          const void * optr;
153          const s * sptr;
154        };
155
156      Similarly, for `volatile' and `const volatile'.
157    */
158
159   t = make_lang_type (RECORD_TYPE);
160   {
161     tree obj_type = build_type_variant (void_type_node, constp, volatilep);
162     tree optr_type = build_pointer_type (obj_type);
163     tree optr, sptr;
164
165     optr = build_lang_field_decl (FIELD_DECL,
166                                   get_identifier (SIGNATURE_OPTR_NAME),
167                                   optr_type);
168     DECL_FIELD_CONTEXT (optr) = t;
169     DECL_CLASS_CONTEXT (optr) = t;
170
171     if (m)
172       /* We can share the `sptr' field among type variants.  */
173       sptr = TREE_CHAIN (TYPE_FIELDS (m));
174     else
175       {
176         tree sig_tbl_type = cp_build_type_variant (to_type, 1, 0);
177         
178         sptr = build_lang_field_decl (FIELD_DECL,
179                                       get_identifier (SIGNATURE_SPTR_NAME),
180                                       build_pointer_type (sig_tbl_type));
181         DECL_FIELD_CONTEXT (sptr) = t;
182         DECL_CLASS_CONTEXT (sptr) = t;
183         TREE_CHAIN (sptr) = NULL_TREE;
184       }
185
186     TREE_CHAIN (optr) = sptr;
187     TYPE_FIELDS (t) = optr;
188     TYPE_ALIGN (t) = TYPE_ALIGN (optr_type);
189
190     /* A signature pointer/reference type isn't a `real' class type.  */
191     IS_AGGR_TYPE (t) = 0;
192   }
193
194   {
195     tree name = build_signature_pointer_or_reference_name (to_type, constp,
196                                                            volatilep, refp);
197
198     /* Build a DECL node for this type, so the debugger has access to it.  */
199     build_signature_pointer_or_reference_decl (t, name);
200   }
201
202   CLASSTYPE_GOT_SEMICOLON (t) = 1;
203   IS_SIGNATURE_POINTER (t) = ! refp;
204   IS_SIGNATURE_REFERENCE (t) = refp;
205   SIGNATURE_TYPE (t) = to_type;
206
207   if (m)
208     {
209       /* Add this type to the chain of variants of TYPE.
210          Every type has to be its own TYPE_MAIN_VARIANT.  */
211       TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
212       TYPE_NEXT_VARIANT (m) = t;
213     }
214   else if (refp)
215     /* Record this type as the reference to TO_TYPE.  */
216     SIGNATURE_REFERENCE_TO (to_type) = t;
217   else
218     /* Record this type as the pointer to TO_TYPE.  */
219     SIGNATURE_POINTER_TO (to_type) = t;
220
221   /* Lay out the type.  This function has many callers that are concerned
222      with expression-construction, and this simplifies them all.
223      Also, it guarantees the TYPE_SIZE is permanent if the type is.  */
224   layout_type (t);
225
226   current_obstack = ambient_obstack;
227   saveable_obstack = ambient_saveable_obstack;
228
229   /* Output debug information for this type.  */
230   rest_of_type_compilation (t, 1);
231
232   return t;
233 }
234
235 /* Construct, lay out and return the type of pointers to signature TO_TYPE.  */
236
237 tree
238 build_signature_pointer_type (to_type, constp, volatilep)
239      tree to_type;
240      int constp, volatilep;
241 {
242   return
243     build_signature_pointer_or_reference_type (to_type, constp, volatilep, 0);
244 }
245
246 /* Construct, lay out and return the type of pointers to signature TO_TYPE.  */
247
248 tree
249 build_signature_reference_type (to_type, constp, volatilep)
250      tree to_type;
251      int constp, volatilep;
252 {
253   return
254     build_signature_pointer_or_reference_type (to_type, constp, volatilep, 1);
255 }
256
257 /* Return the name of the signature table (as an IDENTIFIER_NODE)
258    for the given signature type SIG_TYPE and rhs type RHS_TYPE.  */
259
260 static tree
261 get_sigtable_name (sig_type, rhs_type)
262      tree sig_type, rhs_type;
263 {
264   tree sig_type_id = build_typename_overload (sig_type);
265   tree rhs_type_id = build_typename_overload (rhs_type);
266   char *buf = (char *) alloca (sizeof (SIGTABLE_NAME_FORMAT_LONG)
267                                + IDENTIFIER_LENGTH (sig_type_id)
268                                + IDENTIFIER_LENGTH (rhs_type_id) + 20);
269   char *sig_ptr = IDENTIFIER_POINTER (sig_type_id);
270   char *rhs_ptr = IDENTIFIER_POINTER (rhs_type_id);
271   int i, j;
272
273   for (i = 0; sig_ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++)
274     /* do nothing */;
275   while (sig_ptr[i] >= '0' && sig_ptr[i] <= '9')
276     i += 1;
277
278   for (j = 0; rhs_ptr[j] == OPERATOR_TYPENAME_FORMAT[j]; j++)
279     /* do nothing */;
280   while (rhs_ptr[j] >= '0' && rhs_ptr[j] <= '9')
281     j += 1;
282
283   if (IS_SIGNATURE (rhs_type))
284     sprintf (buf, SIGTABLE_NAME_FORMAT_LONG, sig_ptr+i, rhs_ptr+j,
285              global_sigtable_name_counter++);
286   else
287     sprintf (buf, SIGTABLE_NAME_FORMAT, sig_ptr+i, rhs_ptr+j);
288   return get_identifier (buf);
289 }
290
291 /* Build a field decl that points to a signature member function.  */
292
293 static tree
294 build_member_function_pointer (member)
295      tree member;
296 {
297   char *namstr = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (member));
298   int namlen = IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (member));
299   char *name;
300   tree entry;
301   
302   name = (char *) alloca (namlen + sizeof (SIGNATURE_FIELD_NAME) + 2);
303   sprintf (name, SIGNATURE_FIELD_NAME_FORMAT, namstr);
304
305   /* @@ Do we really want to xref signature table fields?  */
306   GNU_xref_ref (current_function_decl, name);
307
308   entry = build_lang_field_decl (FIELD_DECL, get_identifier (name),
309                                  TYPE_MAIN_VARIANT (sigtable_entry_type));
310   TREE_CONSTANT (entry) = 1;
311   TREE_READONLY (entry) = 1;
312
313   /* @@ Do we really want to xref signature table fields?  */
314   GNU_xref_decl (current_function_decl, entry);
315
316   return entry;
317 }
318
319 /* For each FUNCTION_DECL in a signature we construct a member function
320    pointer of the appropriate type.  We also need two flags to test
321    whether the member function pointer points to a virtual function or
322    to a default implementation.  Those flags will be the two lower order
323    bits of the member function pointer (or the two higher order bits,
324    based on the configuration).
325
326    The new FIELD_DECLs are appended at the end of the last (and only)
327    sublist of `list_of_fieldlists.'
328
329    As a side effect, each member function in the signature gets the
330    `decl.ignored' bit turned on, so we don't output debug info for it.  */
331
332 void
333 append_signature_fields (list_of_fieldlists)
334      tree list_of_fieldlists;
335 {
336   tree l, x;
337   tree last_x = NULL_TREE;
338   tree mfptr;
339   tree last_mfptr;
340   tree mfptr_list = NULL_TREE;
341               
342   /* For signatures it should actually be only a list with one element.  */
343   for (l = list_of_fieldlists; l; l = TREE_CHAIN (l))
344     {
345       for (x = TREE_VALUE (l); x; x = TREE_CHAIN (x))
346         {
347           if (TREE_CODE (x) == FUNCTION_DECL)
348             {
349               mfptr = build_member_function_pointer (x);
350               DECL_MEMFUNC_POINTER_TO (x) = mfptr;
351               DECL_MEMFUNC_POINTING_TO (mfptr) = x;
352               DECL_IGNORED_P (x) = 1;
353               DECL_IN_AGGR_P (mfptr) = 1;
354               if (! mfptr_list)
355                 mfptr_list = last_mfptr = mfptr;
356               else
357                 {
358                   TREE_CHAIN (last_mfptr) = mfptr;
359                   last_mfptr = mfptr;
360                 }
361             }
362           last_x = x;
363         }
364     }
365
366   /* Append the lists.  */
367   if (last_x && mfptr_list)
368     {
369       TREE_CHAIN (last_x) = mfptr_list;
370       TREE_CHAIN (last_mfptr) = NULL_TREE;
371     }
372 }
373
374 /* Compare the types of a signature member function and a class member
375    function.  Returns 1 if the types are in the C++ `<=' relationship.
376
377    If we have a signature pointer/reference as argument or return type
378    we don't want to do a recursive conformance check.  The conformance
379    check only succeeds if both LHS and RHS refer to the same signature
380    pointer.  Otherwise we need to keep information about parameter types
381    around at run time to initialize the signature table correctly.  */
382
383 static int
384 match_method_types (sig_mtype, class_mtype)
385      tree sig_mtype, class_mtype;
386 {
387   tree sig_return_type = TREE_TYPE (sig_mtype);
388   tree sig_arg_types = TYPE_ARG_TYPES (sig_mtype);
389   tree class_return_type = TREE_TYPE (class_mtype);
390   tree class_arg_types = TYPE_ARG_TYPES (class_mtype);
391
392   /* The return types have to be the same.  */
393   if (! comptypes (sig_return_type, class_return_type, 1))
394     return 0;
395
396   /* Compare the first argument `this.'  */
397   {
398     /* Get the type of what the `optr' is pointing to.  */
399     tree sig_this =
400       TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (sig_arg_types))));
401     tree class_this = TREE_VALUE (class_arg_types);
402
403     if (TREE_CODE (class_this) == RECORD_TYPE)  /* Is `this' a sig ptr?  */
404       class_this = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (class_this)));
405     else
406       class_this = TREE_TYPE (class_this);
407
408     /* If a signature method's `this' is const or volatile, so has to be
409        the corresponding class method's `this.'  */
410     if ((TYPE_READONLY (sig_this) && ! TYPE_READONLY (class_this))
411         || (TYPE_VOLATILE (sig_this) && ! TYPE_VOLATILE (class_this)))
412       return 0;
413   }
414
415   sig_arg_types = TREE_CHAIN (sig_arg_types);
416   class_arg_types = TREE_CHAIN (class_arg_types);
417
418   /* The number of arguments and the argument types have to be the same.  */
419   return compparms (sig_arg_types, class_arg_types, 3);
420 }
421
422 /* Undo casts of opaque type variables to the RHS types.  */
423 static void
424 undo_casts (sig_ty)
425      tree sig_ty;
426 {
427   tree field = TYPE_FIELDS (sig_ty);
428
429   /* Since all the FIELD_DECLs for the signature table entries are at the end
430      of the chain (see `append_signature_fields'), we can do it this way.  */
431   for (; field && TREE_CODE (field) != FIELD_DECL; field = TREE_CHAIN (field))
432     if (TYPE_MAIN_VARIANT (TREE_TYPE (field)) == opaque_type_node)
433       TREE_TYPE (TREE_TYPE (field)) = TREE_TYPE (ptr_type_node);
434 }
435
436 /* Do the type checking necessary to see whether the `rhs' conforms to
437    the lhs's `sig_ty'.  Depending on the type of `rhs' return a NULL_TREE,
438    an integer_zero_node, a constructor, or an expression offsetting the
439    `rhs' signature table.  */
440
441 static tree
442 build_signature_table_constructor (sig_ty, rhs)
443      tree sig_ty, rhs;
444 {
445   tree rhstype = TREE_TYPE (rhs);
446   tree sig_field = TYPE_FIELDS (sig_ty);
447   tree result = NULL_TREE;
448   tree first_rhs_field = NULL_TREE;
449   tree last_rhs_field;
450   int sig_ptr_p = IS_SIGNATURE (rhstype);
451   int offset_p = sig_ptr_p;
452
453   rhstype = sig_ptr_p ? rhstype : TREE_TYPE (rhstype);
454
455   if (CLASSTYPE_TAGS (sig_ty))
456     {
457       sorry ("conformance check with signature containing class declarations");
458       return error_mark_node;
459     }
460
461   for (; sig_field; sig_field = TREE_CHAIN (sig_field))
462     {
463       tree basetype_path, baselink, basetypes;
464       tree sig_method, sig_mname, sig_mtype;
465       tree rhs_method, tbl_entry;
466
467       if (TREE_CODE (sig_field) == TYPE_DECL)
468         {
469           tree sig_field_type = TREE_TYPE (sig_field);
470
471           if (TYPE_MAIN_VARIANT (sig_field_type) == opaque_type_node)
472             {
473               /* We've got an opaque type here.  */
474               tree oty_name = DECL_NAME (sig_field);
475               tree oty_type = lookup_field (rhstype, oty_name, 1, 1);
476
477               if (oty_type == NULL_TREE || oty_type == error_mark_node)
478                 {
479                   cp_error ("class `%T' does not contain type `%T'",
480                             rhstype, oty_type);
481                   undo_casts (sig_ty);
482                   return error_mark_node;
483                 }
484               oty_type = TREE_TYPE (oty_type);
485
486               /* Cast `sig_field' to be of type `oty_type'.  This will be
487                  undone in `undo_casts' by walking over all the TYPE_DECLs.  */
488               TREE_TYPE (sig_field_type) = TREE_TYPE (oty_type);
489             }
490           /* If we don't have an opaque type, we can ignore the `typedef'.  */
491           continue;
492         }
493
494       /* Find the signature method corresponding to `sig_field'.  */
495       sig_method = DECL_MEMFUNC_POINTING_TO (sig_field);
496       sig_mname = DECL_NAME (sig_method);
497       sig_mtype = TREE_TYPE (sig_method);
498
499       basetype_path = TYPE_BINFO (rhstype);
500       baselink = lookup_fnfields (basetype_path, sig_mname, 0);
501       if (baselink == NULL_TREE || baselink == error_mark_node)
502         {
503           if (! IS_DEFAULT_IMPLEMENTATION (sig_method))
504             {
505               cp_error ("class `%T' does not contain method `%D'",
506                         rhstype, sig_mname);
507               undo_casts (sig_ty);
508               return error_mark_node;
509             }
510           else
511             {
512               /* We use the signature's default implementation.  */
513               rhs_method = sig_method;
514             }
515         }
516       else
517         {
518           /* Find the class method of the correct type.  */
519
520           basetypes = TREE_PURPOSE (baselink);
521           if (TREE_CODE (basetypes) == TREE_LIST)
522             basetypes = TREE_VALUE (basetypes);
523
524           rhs_method = TREE_VALUE (baselink);
525           for (; rhs_method; rhs_method = TREE_CHAIN (rhs_method))
526             if (sig_mname == DECL_NAME (rhs_method)
527                 && ! DECL_STATIC_FUNCTION_P (rhs_method)
528                 && match_method_types (sig_mtype, TREE_TYPE (rhs_method)))
529               break;
530
531           if (rhs_method == NULL_TREE
532               || (compute_access (basetypes, rhs_method)
533                   != access_public))
534             {
535               error ("class `%s' does not contain a method conforming to `%s'",
536                      TYPE_NAME_STRING (rhstype),
537                      fndecl_as_string (NULL, sig_method, 1));
538               undo_casts (sig_ty);
539               return error_mark_node;
540             }
541         }
542
543       if (sig_ptr_p && rhs_method != sig_method)
544         {
545           tree rhs_field = DECL_MEMFUNC_POINTER_TO (rhs_method);
546
547           if (first_rhs_field == NULL_TREE)
548             {
549               first_rhs_field = rhs_field;
550               last_rhs_field = rhs_field;
551             }
552           else if (TREE_CHAIN (last_rhs_field) == rhs_field)
553             last_rhs_field = rhs_field;
554           else
555             offset_p = 0;
556           
557           tbl_entry = build_component_ref (rhs, DECL_NAME (rhs_field),
558                                            NULL_TREE, 1);
559         }
560       else
561         {
562           tree tag, vb_off, delta, index, pfn, vt_off;
563           tree tag_decl, vb_off_decl, delta_decl, index_decl;
564           tree pfn_decl, vt_off_decl;
565
566           if (rhs_method == sig_method)
567             {
568               /* default implementation */
569               tag = build_unary_op (NEGATE_EXPR, integer_one_node, 0);
570               vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0);
571               delta = integer_zero_node;
572               index = integer_zero_node;
573               pfn = build_unary_op (ADDR_EXPR, rhs_method, 0);
574               TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (rhs_method)) = 1;
575               TREE_TYPE (pfn) = ptr_type_node;
576               TREE_ADDRESSABLE (rhs_method) = 1;
577               offset_p = 0;     /* we can't offset the rhs sig table */
578             }
579           else if (DECL_VINDEX (rhs_method))
580             {
581               /* virtual member function */
582               tag = integer_one_node;
583               vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0);
584               delta = BINFO_OFFSET (get_binfo (DECL_CLASS_CONTEXT (rhs_method),
585                                                rhstype, 1));
586               index = DECL_VINDEX (rhs_method);
587               vt_off = get_vfield_offset (get_binfo (DECL_CONTEXT (rhs_method),
588                                                      rhstype, 0));
589             }
590           else
591             {
592               /* non-virtual member function */
593               tag = integer_zero_node;
594               vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0);
595               delta = BINFO_OFFSET (get_binfo (DECL_CLASS_CONTEXT (rhs_method),
596                                                rhstype, 1));
597               index = integer_zero_node;
598               pfn = build_unary_op (ADDR_EXPR, rhs_method, 0);
599               TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (rhs_method)) = 1;
600               TREE_TYPE (pfn) = ptr_type_node;
601               TREE_ADDRESSABLE (rhs_method) = 1;
602             }
603
604           /* Since digest_init doesn't handle initializing selected fields
605              of a struct (i.e., anonymous union), we build the constructor
606              by hand, without calling digest_init.  */
607           tag_decl = TYPE_FIELDS (sigtable_entry_type);
608           vb_off_decl = TREE_CHAIN (tag_decl);
609           delta_decl = TREE_CHAIN (vb_off_decl);
610           index_decl = TREE_CHAIN (delta_decl);
611           pfn_decl = TREE_CHAIN (index_decl);
612           vt_off_decl = TREE_CHAIN (pfn_decl);
613           
614           tag = convert (TREE_TYPE (tag_decl), tag);
615           vb_off = convert (TREE_TYPE (vb_off_decl), vb_off);
616           delta = convert (TREE_TYPE (delta_decl), delta);
617           index = convert (TREE_TYPE (index_decl), index);
618
619           if (DECL_VINDEX (rhs_method))
620             {
621               vt_off = convert (TREE_TYPE (vt_off_decl), vt_off);
622
623               tbl_entry = build_tree_list (vt_off_decl, vt_off);
624             }
625           else
626             {
627               pfn = convert (TREE_TYPE (pfn_decl), pfn);
628
629               tbl_entry = build_tree_list (pfn_decl, pfn);
630             }
631           tbl_entry = tree_cons (delta_decl, delta,
632                                  tree_cons (index_decl, index, tbl_entry));
633           tbl_entry = tree_cons (tag_decl, tag,
634                                  tree_cons (vb_off_decl, vb_off, tbl_entry));
635           tbl_entry = build (CONSTRUCTOR, sigtable_entry_type,
636                              NULL_TREE, tbl_entry);
637
638           TREE_CONSTANT (tbl_entry) = 1;
639         }
640
641       /* Chain those function address expressions together.  */
642       if (result)
643         result = tree_cons (NULL_TREE, tbl_entry, result);
644       else
645         result = build_tree_list (NULL_TREE, tbl_entry);
646     }
647
648   if (result == NULL_TREE)
649     {
650       /* The signature was empty, we don't need a signature table.  */
651       undo_casts (sig_ty);
652       return NULL_TREE;
653     }
654
655   if (offset_p)
656     {
657       if (first_rhs_field == TYPE_FIELDS (rhstype))
658         {
659           /* The sptr field on the lhs can be copied from the rhs.  */
660           undo_casts (sig_ty);
661           return integer_zero_node;
662         }
663       else
664         {
665           /* The sptr field on the lhs will point into the rhs sigtable.  */
666           undo_casts (sig_ty);
667           return build_component_ref (rhs, DECL_NAME (first_rhs_field),
668                                       NULL_TREE, 0);
669         }
670     }
671
672   /* We need to construct a new signature table.  */
673   result = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (result));
674   TREE_HAS_CONSTRUCTOR (result) = 1;
675   TREE_CONSTANT (result) = !sig_ptr_p;
676
677   undo_casts (sig_ty);
678   return result;
679 }
680
681 /* Build a signature table declaration and initialize it or return an
682    existing one if we built one already.  If we don't get a constructor
683    as initialization expression, we don't need a new signature table
684    variable and just hand back the init expression.
685
686    The declaration processing is done by hand instead of using `cp_finish_decl'
687    so that we can make signature pointers global variables instead of
688    static ones.  */
689
690 static tree
691 build_sigtable (sig_type, rhs_type, init_from)
692      tree sig_type, rhs_type, init_from;
693 {
694   tree name = NULL_TREE;
695   tree decl = NULL_TREE;
696   tree init_expr;
697
698   push_obstacks_nochange ();
699   end_temporary_allocation ();
700
701   if (! IS_SIGNATURE (rhs_type))
702     {
703       name = get_sigtable_name (sig_type, rhs_type);
704       decl = IDENTIFIER_GLOBAL_VALUE (name);
705     }
706   if (decl == NULL_TREE)
707     {
708       tree init;
709
710       /* We allow only one signature table to be generated for signatures
711          with opaque types.  Otherwise we create a loophole in the type
712          system since we could cast data from one classes implementation
713          of the opaque type to that of another class.  */
714       if (SIGNATURE_HAS_OPAQUE_TYPEDECLS (sig_type)
715           && SIGTABLE_HAS_BEEN_GENERATED (sig_type))
716         {
717           error ("signature with opaque type implemented by multiple classes");
718           return error_mark_node;
719         }
720       SIGTABLE_HAS_BEEN_GENERATED (sig_type) = 1;
721
722       init_expr = build_signature_table_constructor (sig_type, init_from);
723       if (init_expr == NULL_TREE || TREE_CODE (init_expr) != CONSTRUCTOR)
724         return init_expr;
725
726       if (name == NULL_TREE)
727         name = get_sigtable_name (sig_type, rhs_type);
728       {
729         tree context = current_function_decl;
730
731         /* Make the signature table global, not just static in whichever
732            function a signature pointer/ref is used for the first time.  */
733         current_function_decl = NULL_TREE;
734         decl = pushdecl_top_level (build_decl (VAR_DECL, name, sig_type));
735         current_function_decl = context;
736       }
737       IDENTIFIER_GLOBAL_VALUE (name) = decl;
738       store_init_value (decl, init_expr);
739       if (IS_SIGNATURE (rhs_type))
740         {
741           init = DECL_INITIAL (decl);
742           DECL_INITIAL (decl) = error_mark_node;
743         }
744
745       DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
746                                DECL_ALIGN (decl));
747 #if 0
748       /* GDB-4.7 doesn't find the initialization value of a signature table
749          when it is constant.  */
750       TREE_READONLY (decl) = 1;
751 #endif
752       TREE_STATIC (decl) = 1;
753       TREE_USED (decl) = 1;
754
755       make_decl_rtl (decl, NULL, 1);
756       if (IS_SIGNATURE (rhs_type))
757         expand_static_init (decl, init);
758     }
759
760   pop_obstacks ();
761
762   return decl;
763 }
764
765 /* Create a constructor or modify expression if the LHS of an assignment
766    is a signature pointer or a signature reference.  If LHS is a record
767    type node, we build a constructor, otherwise a compound expression.  */
768
769 tree
770 build_signature_pointer_constructor (lhs, rhs)
771      tree lhs, rhs;
772 {
773   register struct obstack *ambient_obstack = current_obstack;
774   register struct obstack *ambient_saveable_obstack = saveable_obstack;
775   int initp = (TREE_CODE (lhs) == RECORD_TYPE);
776   tree lhstype = initp ? lhs : TREE_TYPE (lhs);
777   tree rhstype = TREE_TYPE (rhs);
778   tree sig_ty  = SIGNATURE_TYPE (lhstype);
779   tree sig_tbl, sptr_expr, optr_expr;
780   tree result;
781
782   if (! ((TREE_CODE (rhstype) == POINTER_TYPE
783           && TREE_CODE (TREE_TYPE (rhstype)) == RECORD_TYPE)
784          || (TYPE_LANG_SPECIFIC (rhstype) &&
785              (IS_SIGNATURE_POINTER (rhstype)
786               || IS_SIGNATURE_REFERENCE (rhstype)))))
787     {
788       error ("invalid assignment to signature pointer or reference");
789       return error_mark_node;
790     }
791
792   if (TYPE_SIZE (sig_ty) == NULL_TREE)
793     {
794       cp_error ("undefined signature `%T' used in signature %s declaration",
795                 sig_ty,
796                 IS_SIGNATURE_POINTER (lhstype) ? "pointer" : "reference");
797       return error_mark_node;
798     }
799
800   /* If SIG_TY is permanent, make the signature table constructor and
801      the signature pointer/reference constructor permanent too.  */
802   if (TREE_PERMANENT (sig_ty))
803     {
804       current_obstack = &permanent_obstack;
805       saveable_obstack = &permanent_obstack;
806     }
807
808   if (TYPE_LANG_SPECIFIC (rhstype) &&
809       (IS_SIGNATURE_POINTER (rhstype) || IS_SIGNATURE_REFERENCE (rhstype)))
810     {
811       if (SIGNATURE_TYPE (rhstype) == sig_ty)
812         {
813           /* LHS and RHS are signature pointers/refs of the same signature.  */
814           optr_expr = build_optr_ref (rhs);
815           sptr_expr = build_sptr_ref (rhs);
816         }
817       else
818         {
819           /* We need to create a new signature table and copy
820              elements from the rhs signature table.  */
821           tree rhs_sptr_ref = build_sptr_ref (rhs);
822           tree rhs_tbl = build1 (INDIRECT_REF, SIGNATURE_TYPE (rhstype),
823                                  rhs_sptr_ref);
824
825           sig_tbl = build_sigtable (sig_ty, SIGNATURE_TYPE (rhstype), rhs_tbl);
826           if (sig_tbl == error_mark_node)
827             return error_mark_node;
828
829           optr_expr = build_optr_ref (rhs);
830           if (sig_tbl == NULL_TREE)
831             /* The signature was empty.  The signature pointer is
832                pretty useless, but the user has been warned.  */
833             sptr_expr = copy_node (null_pointer_node);
834           else if (sig_tbl == integer_zero_node)
835             sptr_expr = rhs_sptr_ref;
836           else
837             sptr_expr = build_unary_op (ADDR_EXPR, sig_tbl, 0);
838           TREE_TYPE (sptr_expr) = build_pointer_type (sig_ty);
839         }
840     }
841   else
842     {
843       sig_tbl = build_sigtable (sig_ty, TREE_TYPE (rhstype), rhs);
844       if (sig_tbl == error_mark_node)
845         return error_mark_node;
846
847       optr_expr = rhs;
848       if (sig_tbl == NULL_TREE)
849         /* The signature was empty.  The signature pointer is
850            pretty useless, but the user has been warned.  */
851         {
852           sptr_expr = copy_node (null_pointer_node);
853           TREE_TYPE (sptr_expr) = build_pointer_type (sig_ty);
854         }
855       else
856         sptr_expr = build_unary_op (ADDR_EXPR, sig_tbl, 0);
857     }
858
859   if (initp)
860     {
861       result = tree_cons (NULL_TREE, optr_expr,
862                           build_tree_list (NULL_TREE, sptr_expr));
863       result = build_nt (CONSTRUCTOR, NULL_TREE, result);
864       TREE_HAS_CONSTRUCTOR (result) = 1;
865       result = digest_init (lhstype, result, 0);
866     }
867   else
868     {
869       if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype))
870           readonly_error (lhs, "assignment", 0);
871
872       optr_expr = build_modify_expr (build_optr_ref (lhs), NOP_EXPR,
873                                      optr_expr);
874       sptr_expr = build_modify_expr (build_sptr_ref (lhs), NOP_EXPR,
875                                      sptr_expr);
876
877       result = tree_cons (NULL_TREE, optr_expr,
878                           tree_cons (NULL_TREE, sptr_expr,
879                                      build_tree_list (NULL_TREE, lhs)));
880       result = build_compound_expr (result);
881     }
882
883   current_obstack = ambient_obstack;
884   saveable_obstack = ambient_saveable_obstack;
885   return result;
886 }
887
888 /* Build a temporary variable declaration for the instance of a signature
889    member function call if it isn't a declaration node already.  Simply
890    using a SAVE_EXPR doesn't work since we need `this' in both branches
891    of a conditional expression.  */
892
893 static tree
894 save_this (instance)
895      tree instance;
896 {
897   tree decl;
898
899   if (TREE_CODE_CLASS (TREE_CODE (instance)) == 'd')
900     decl = instance;
901   else
902     {
903       decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (instance));
904       DECL_REGISTER (decl) = 1;
905       layout_decl (decl, 0);
906       expand_decl (decl);
907     }
908
909   return decl;
910 }
911
912 /* Build a signature member function call.  Looks up the signature table
913    entry corresponding to FUNCTION.  Depending on the value of the CODE
914    field, either call the function in PFN directly, or use OFFSET to
915    index INSTANCE's virtual function table.  */
916
917 tree
918 build_signature_method_call (basetype, instance, function, parms)
919      tree basetype, instance, function, parms;
920 {
921   tree saved_instance = save_this (instance);   /* Create temp for `this'.  */
922   tree object_ptr = build_optr_ref (saved_instance);
923   tree new_object_ptr, new_parms;
924   tree signature_tbl_ptr = build_sptr_ref (saved_instance);
925   tree sig_field_name = DECL_NAME (DECL_MEMFUNC_POINTER_TO (function));
926   tree basetype_path = TYPE_BINFO (basetype);
927   tree tbl_entry = build_component_ref (build1 (INDIRECT_REF, basetype,
928                                                 signature_tbl_ptr),
929                                         sig_field_name, basetype_path, 1);
930   tree tag, delta, pfn, vt_off, index, vfn;
931   tree deflt_call = NULL_TREE, direct_call, virtual_call, result;
932
933   tbl_entry = save_expr (tbl_entry);
934   tag = build_component_ref (tbl_entry, tag_identifier, NULL_TREE, 1);
935   delta = build_component_ref (tbl_entry, delta_identifier, NULL_TREE, 1);
936   pfn = build_component_ref (tbl_entry, pfn_identifier, NULL_TREE, 1);
937   vt_off = build_component_ref (tbl_entry, vt_off_identifier, NULL_TREE, 1);
938   index = build_component_ref (tbl_entry, index_identifier, NULL_TREE, 1);
939   TREE_TYPE (pfn) = build_pointer_type (TREE_TYPE (function)); 
940
941   if (IS_DEFAULT_IMPLEMENTATION (function))
942     {
943       pfn = save_expr (pfn);
944       deflt_call = build_function_call (pfn, parms);
945     }
946
947   new_object_ptr = build (PLUS_EXPR, build_pointer_type (basetype),
948                           convert (ptrdiff_type_node, object_ptr),
949                           convert (ptrdiff_type_node, delta));
950
951   parms = tree_cons (NULL_TREE,
952                      convert (build_pointer_type (basetype), object_ptr),
953                      TREE_CHAIN (parms));
954   new_parms = tree_cons (NULL_TREE, new_object_ptr, TREE_CHAIN (parms));
955
956   {
957     /* Cast the signature method to have `this' of a normal pointer type.  */
958     tree old_this = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn))));
959
960     TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))) =
961       build_type_variant (build_pointer_type (basetype),
962                           TYPE_READONLY (old_this),
963                           TYPE_VOLATILE (old_this));
964
965     direct_call = build_function_call (pfn, new_parms);
966
967     {
968       tree vfld, vtbl, aref;
969
970       vfld = build (PLUS_EXPR,
971                     build_pointer_type (build_pointer_type (vtbl_type_node)),
972                     convert (ptrdiff_type_node, object_ptr),
973                     convert (ptrdiff_type_node, vt_off));
974       vtbl = build_indirect_ref (build_indirect_ref (vfld, NULL_PTR),
975                                  NULL_PTR);
976       aref = build_array_ref (vtbl, index);
977
978       if (flag_vtable_thunks)
979         vfn = aref;
980       else
981         vfn = build_component_ref (aref, pfn_identifier, 0, 0);
982
983       TREE_TYPE (vfn) = build_pointer_type (TREE_TYPE (function));
984
985       if (flag_vtable_thunks)
986         virtual_call = build_function_call (vfn, parms);
987       else
988         virtual_call = build_function_call (vfn, new_parms);
989     }
990
991     /* Undo the cast, make `this' a signature pointer again.  */
992     TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))) = old_this;
993   }
994
995   /* Once the function was found, there should be no reason why we
996      couldn't build the member function pointer call.  */
997   if (!direct_call || direct_call == error_mark_node
998       || !virtual_call || virtual_call == error_mark_node
999       || (IS_DEFAULT_IMPLEMENTATION (function)
1000           && (!deflt_call || deflt_call == error_mark_node)))
1001     {
1002       compiler_error ("cannot build call of signature member function `%s'",
1003                       fndecl_as_string (NULL, function, 1));
1004       return error_mark_node;
1005     }
1006
1007   if (IS_DEFAULT_IMPLEMENTATION (function))
1008     {
1009       tree test = build_binary_op_nodefault (LT_EXPR, tag, integer_zero_node,
1010                                              LT_EXPR);
1011       result = build_conditional_expr (tag,
1012                                        build_conditional_expr (test,
1013                                                                deflt_call,
1014                                                                virtual_call),
1015                                        direct_call);
1016     }
1017   else
1018     result = build_conditional_expr (tag, virtual_call, direct_call);
1019
1020   /* If we created a temporary variable for `this', initialize it first.  */
1021   if (instance != saved_instance)
1022     result = build (COMPOUND_EXPR, TREE_TYPE (result),
1023                     build_modify_expr (saved_instance, NOP_EXPR, instance),
1024                     result);
1025
1026   return result;
1027 }
1028
1029 /* Create a COMPONENT_REF expression for referencing the OPTR field
1030    of a signature pointer or reference.  */
1031
1032 tree
1033 build_optr_ref (instance)
1034      tree instance;
1035 {
1036   tree field = get_identifier (SIGNATURE_OPTR_NAME);
1037
1038   return build_component_ref (instance, field, NULL_TREE, 1);
1039 }
1040
1041 /* Create a COMPONENT_REF expression for referencing the SPTR field
1042    of a signature pointer or reference.  */
1043
1044 tree
1045 build_sptr_ref (instance)
1046      tree instance;
1047 {
1048   tree field = get_identifier (SIGNATURE_SPTR_NAME);
1049
1050   return build_component_ref (instance, field, NULL_TREE, 1);
1051 }