OSDN Git Service

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