source: trunk/third/gcc/cp/sig.c @ 8834

Revision 8834, 32.9 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, which included commits to RCS files with non-trunk default branches.
Line 
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
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING.  If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, 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
31extern struct obstack *current_obstack;
32extern struct obstack permanent_obstack;
33extern struct obstack *saveable_obstack;
34
35extern void error ();
36extern void sorry ();
37extern void compiler_error ();
38extern void make_decl_rtl                       PROTO((tree, char *, int));
39
40/* Used to help generate globally unique names for signature tables.  */
41
42static 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
47static tree
48build_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
76static void
77build_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
99static tree
100build_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
237tree
238build_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
248tree
249build_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
260static tree
261get_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
293static tree
294build_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
332void
333append_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
383static int
384match_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.  */
423static void
424undo_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
441static tree
442build_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_TYPE (pfn) = ptr_type_node;
575              TREE_ADDRESSABLE (rhs_method) = 1;
576              offset_p = 0;     /* we can't offset the rhs sig table */
577            }
578          else if (DECL_VINDEX (rhs_method))
579            {
580              /* virtual member function */
581              tag = integer_one_node;
582              vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0);
583              delta = BINFO_OFFSET (get_binfo (DECL_CLASS_CONTEXT (rhs_method),
584                                               rhstype, 1));
585              index = DECL_VINDEX (rhs_method);
586              vt_off = get_vfield_offset (get_binfo (DECL_CONTEXT (rhs_method),
587                                                     rhstype, 0));
588            }
589          else
590            {
591              /* non-virtual member function */
592              tag = integer_zero_node;
593              vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0);
594              delta = BINFO_OFFSET (get_binfo (DECL_CLASS_CONTEXT (rhs_method),
595                                               rhstype, 1));
596              index = integer_zero_node;
597              pfn = build_unary_op (ADDR_EXPR, rhs_method, 0);
598              TREE_TYPE (pfn) = ptr_type_node;
599              TREE_ADDRESSABLE (rhs_method) = 1;
600            }
601
602          /* Since digest_init doesn't handle initializing selected fields
603             of a struct (i.e., anonymous union), we build the constructor
604             by hand, without calling digest_init.  */
605          tag_decl = TYPE_FIELDS (sigtable_entry_type);
606          vb_off_decl = TREE_CHAIN (tag_decl);
607          delta_decl = TREE_CHAIN (vb_off_decl);
608          index_decl = TREE_CHAIN (delta_decl);
609          pfn_decl = TREE_CHAIN (index_decl);
610          vt_off_decl = TREE_CHAIN (pfn_decl);
611         
612          tag = convert (TREE_TYPE (tag_decl), tag);
613          vb_off = convert (TREE_TYPE (vb_off_decl), vb_off);
614          delta = convert (TREE_TYPE (delta_decl), delta);
615          index = convert (TREE_TYPE (index_decl), index);
616
617          if (DECL_VINDEX (rhs_method))
618            {
619              vt_off = convert (TREE_TYPE (vt_off_decl), vt_off);
620
621              tbl_entry = build_tree_list (vt_off_decl, vt_off);
622            }
623          else
624            {
625              pfn = convert (TREE_TYPE (pfn_decl), pfn);
626
627              tbl_entry = build_tree_list (pfn_decl, pfn);
628            }
629          tbl_entry = tree_cons (delta_decl, delta,
630                                 tree_cons (index_decl, index, tbl_entry));
631          tbl_entry = tree_cons (tag_decl, tag,
632                                 tree_cons (vb_off_decl, vb_off, tbl_entry));
633          tbl_entry = build (CONSTRUCTOR, sigtable_entry_type,
634                             NULL_TREE, tbl_entry);
635
636          TREE_CONSTANT (tbl_entry) = 1;
637        }
638
639      /* Chain those function address expressions together.  */
640      if (result)
641        result = tree_cons (NULL_TREE, tbl_entry, result);
642      else
643        result = build_tree_list (NULL_TREE, tbl_entry);
644    }
645
646  if (result == NULL_TREE)
647    {
648      /* The signature was empty, we don't need a signature table.  */
649      undo_casts (sig_ty);
650      return NULL_TREE;
651    }
652
653  if (offset_p)
654    {
655      if (first_rhs_field == TYPE_FIELDS (rhstype))
656        {
657          /* The sptr field on the lhs can be copied from the rhs.  */
658          undo_casts (sig_ty);
659          return integer_zero_node;
660        }
661      else
662        {
663          /* The sptr field on the lhs will point into the rhs sigtable.  */
664          undo_casts (sig_ty);
665          return build_component_ref (rhs, DECL_NAME (first_rhs_field),
666                                      NULL_TREE, 0);
667        }
668    }
669
670  /* We need to construct a new signature table.  */
671  result = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (result));
672  TREE_HAS_CONSTRUCTOR (result) = 1;
673  TREE_CONSTANT (result) = !sig_ptr_p;
674
675  undo_casts (sig_ty);
676  return result;
677}
678
679/* Build a signature table declaration and initialize it or return an
680   existing one if we built one already.  If we don't get a constructor
681   as initialization expression, we don't need a new signature table
682   variable and just hand back the init expression.
683
684   The declaration processing is done by hand instead of using `cp_finish_decl'
685   so that we can make signature pointers global variables instead of
686   static ones.  */
687
688static tree
689build_sigtable (sig_type, rhs_type, init_from)
690     tree sig_type, rhs_type, init_from;
691{
692  tree name = NULL_TREE;
693  tree decl = NULL_TREE;
694  tree init_expr;
695
696  push_obstacks_nochange ();
697  end_temporary_allocation ();
698
699  if (! IS_SIGNATURE (rhs_type))
700    {
701      name = get_sigtable_name (sig_type, rhs_type);
702      decl = IDENTIFIER_GLOBAL_VALUE (name);
703    }
704  if (decl == NULL_TREE)
705    {
706      tree init;
707
708      /* We allow only one signature table to be generated for signatures
709         with opaque types.  Otherwise we create a loophole in the type
710         system since we could cast data from one classes implementation
711         of the opaque type to that of another class.  */
712      if (SIGNATURE_HAS_OPAQUE_TYPEDECLS (sig_type)
713          && SIGTABLE_HAS_BEEN_GENERATED (sig_type))
714        {
715          error ("signature with opaque type implemented by multiple classes");
716          return error_mark_node;
717        }
718      SIGTABLE_HAS_BEEN_GENERATED (sig_type) = 1;
719
720      init_expr = build_signature_table_constructor (sig_type, init_from);
721      if (init_expr == NULL_TREE || TREE_CODE (init_expr) != CONSTRUCTOR)
722        return init_expr;
723
724      if (name == NULL_TREE)
725        name = get_sigtable_name (sig_type, rhs_type);
726      {
727        tree context = current_function_decl;
728
729        /* Make the signature table global, not just static in whichever
730           function a signature pointer/ref is used for the first time.  */
731        current_function_decl = NULL_TREE;
732        decl = pushdecl_top_level (build_decl (VAR_DECL, name, sig_type));
733        current_function_decl = context;
734      }
735      IDENTIFIER_GLOBAL_VALUE (name) = decl;
736      store_init_value (decl, init_expr);
737      if (IS_SIGNATURE (rhs_type))
738        {
739          init = DECL_INITIAL (decl);
740          DECL_INITIAL (decl) = error_mark_node;
741        }
742
743      DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
744                               DECL_ALIGN (decl));
745#if 0
746      /* GDB-4.7 doesn't find the initialization value of a signature table
747         when it is constant.  */
748      TREE_READONLY (decl) = 1;
749#endif
750      TREE_STATIC (decl) = 1;
751      TREE_USED (decl) = 1;
752
753      make_decl_rtl (decl, NULL, 1);
754      if (IS_SIGNATURE (rhs_type))
755        expand_static_init (decl, init);
756    }
757
758  pop_obstacks ();
759
760  return decl;
761}
762
763/* Create a constructor or modify expression if the LHS of an assignment
764   is a signature pointer or a signature reference.  If LHS is a record
765   type node, we build a constructor, otherwise a compound expression.  */
766
767tree
768build_signature_pointer_constructor (lhs, rhs)
769     tree lhs, rhs;
770{
771  register struct obstack *ambient_obstack = current_obstack;
772  register struct obstack *ambient_saveable_obstack = saveable_obstack;
773  int initp = (TREE_CODE (lhs) == RECORD_TYPE);
774  tree lhstype = initp ? lhs : TREE_TYPE (lhs);
775  tree rhstype = TREE_TYPE (rhs);
776  tree sig_ty  = SIGNATURE_TYPE (lhstype);
777  tree sig_tbl, sptr_expr, optr_expr;
778  tree result;
779
780  if (! ((TREE_CODE (rhstype) == POINTER_TYPE
781          && TREE_CODE (TREE_TYPE (rhstype)) == RECORD_TYPE)
782         || (TYPE_LANG_SPECIFIC (rhstype) &&
783             (IS_SIGNATURE_POINTER (rhstype)
784              || IS_SIGNATURE_REFERENCE (rhstype)))))
785    {
786      error ("invalid assignment to signature pointer or reference");
787      return error_mark_node;
788    }
789
790  if (TYPE_SIZE (sig_ty) == NULL_TREE)
791    {
792      cp_error ("undefined signature `%T' used in signature %s declaration",
793                sig_ty,
794                IS_SIGNATURE_POINTER (lhstype) ? "pointer" : "reference");
795      return error_mark_node;
796    }
797
798  /* If SIG_TY is permanent, make the signature table constructor and
799     the signature pointer/reference constructor permanent too.  */
800  if (TREE_PERMANENT (sig_ty))
801    {
802      current_obstack = &permanent_obstack;
803      saveable_obstack = &permanent_obstack;
804    }
805
806  if (TYPE_LANG_SPECIFIC (rhstype) &&
807      (IS_SIGNATURE_POINTER (rhstype) || IS_SIGNATURE_REFERENCE (rhstype)))
808    {
809      if (SIGNATURE_TYPE (rhstype) == sig_ty)
810        {
811          /* LHS and RHS are signature pointers/refs of the same signature.  */
812          optr_expr = build_optr_ref (rhs);
813          sptr_expr = build_sptr_ref (rhs);
814        }
815      else
816        {
817          /* We need to create a new signature table and copy
818             elements from the rhs signature table.  */
819          tree rhs_sptr_ref = build_sptr_ref (rhs);
820          tree rhs_tbl = build1 (INDIRECT_REF, SIGNATURE_TYPE (rhstype),
821                                 rhs_sptr_ref);
822
823          sig_tbl = build_sigtable (sig_ty, SIGNATURE_TYPE (rhstype), rhs_tbl);
824          if (sig_tbl == error_mark_node)
825            return error_mark_node;
826
827          optr_expr = build_optr_ref (rhs);
828          if (sig_tbl == NULL_TREE)
829            /* The signature was empty.  The signature pointer is
830               pretty useless, but the user has been warned.  */
831            sptr_expr = copy_node (null_pointer_node);
832          else if (sig_tbl == integer_zero_node)
833            sptr_expr = rhs_sptr_ref;
834          else
835            sptr_expr = build_unary_op (ADDR_EXPR, sig_tbl, 0);
836          TREE_TYPE (sptr_expr) = build_pointer_type (sig_ty);
837        }
838    }
839  else
840    {
841      sig_tbl = build_sigtable (sig_ty, TREE_TYPE (rhstype), rhs);
842      if (sig_tbl == error_mark_node)
843        return error_mark_node;
844
845      optr_expr = rhs;
846      if (sig_tbl == NULL_TREE)
847        /* The signature was empty.  The signature pointer is
848           pretty useless, but the user has been warned.  */
849        {
850          sptr_expr = copy_node (null_pointer_node);
851          TREE_TYPE (sptr_expr) = build_pointer_type (sig_ty);
852        }
853      else
854        sptr_expr = build_unary_op (ADDR_EXPR, sig_tbl, 0);
855    }
856
857  if (initp)
858    {
859      result = tree_cons (NULL_TREE, optr_expr,
860                          build_tree_list (NULL_TREE, sptr_expr));
861      result = build_nt (CONSTRUCTOR, NULL_TREE, result);
862      TREE_HAS_CONSTRUCTOR (result) = 1;
863      result = digest_init (lhstype, result, 0);
864    }
865  else
866    {
867      if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype))
868          readonly_error (lhs, "assignment", 0);
869
870      optr_expr = build_modify_expr (build_optr_ref (lhs), NOP_EXPR,
871                                     optr_expr);
872      sptr_expr = build_modify_expr (build_sptr_ref (lhs), NOP_EXPR,
873                                     sptr_expr);
874
875      result = tree_cons (NULL_TREE, optr_expr,
876                          tree_cons (NULL_TREE, sptr_expr,
877                                     build_tree_list (NULL_TREE, lhs)));
878      result = build_compound_expr (result);
879    }
880
881  current_obstack = ambient_obstack;
882  saveable_obstack = ambient_saveable_obstack;
883  return result;
884}
885
886/* Build a temporary variable declaration for the instance of a signature
887   member function call if it isn't a declaration node already.  Simply
888   using a SAVE_EXPR doesn't work since we need `this' in both branches
889   of a conditional expression.  */
890
891static tree
892save_this (instance)
893     tree instance;
894{
895  tree decl;
896
897  if (TREE_CODE_CLASS (TREE_CODE (instance)) == 'd')
898    decl = instance;
899  else
900    {
901      decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (instance));
902      DECL_REGISTER (decl) = 1;
903      layout_decl (decl, 0);
904      expand_decl (decl);
905    }
906
907  return decl;
908}
909
910/* Build a signature member function call.  Looks up the signature table
911   entry corresponding to FUNCTION.  Depending on the value of the CODE
912   field, either call the function in PFN directly, or use OFFSET to
913   index INSTANCE's virtual function table.  */
914
915tree
916build_signature_method_call (basetype, instance, function, parms)
917     tree basetype, instance, function, parms;
918{
919  tree saved_instance = save_this (instance);   /* Create temp for `this'.  */
920  tree object_ptr = build_optr_ref (saved_instance);
921  tree new_object_ptr, new_parms;
922  tree signature_tbl_ptr = build_sptr_ref (saved_instance);
923  tree sig_field_name = DECL_NAME (DECL_MEMFUNC_POINTER_TO (function));
924  tree basetype_path = TYPE_BINFO (basetype);
925  tree tbl_entry = build_component_ref (build1 (INDIRECT_REF, basetype,
926                                                signature_tbl_ptr),
927                                        sig_field_name, basetype_path, 1);
928  tree tag, delta, pfn, vt_off, index, vfn;
929  tree deflt_call = NULL_TREE, direct_call, virtual_call, result;
930
931  tbl_entry = save_expr (tbl_entry);
932  tag = build_component_ref (tbl_entry, tag_identifier, NULL_TREE, 1);
933  delta = build_component_ref (tbl_entry, delta_identifier, NULL_TREE, 1);
934  pfn = build_component_ref (tbl_entry, pfn_identifier, NULL_TREE, 1);
935  vt_off = build_component_ref (tbl_entry, vt_off_identifier, NULL_TREE, 1);
936  index = build_component_ref (tbl_entry, index_identifier, NULL_TREE, 1);
937  TREE_TYPE (pfn) = build_pointer_type (TREE_TYPE (function));
938
939  if (IS_DEFAULT_IMPLEMENTATION (function))
940    {
941      pfn = save_expr (pfn);
942      deflt_call = build_function_call (pfn, parms);
943    }
944
945  new_object_ptr = build (PLUS_EXPR, build_pointer_type (basetype),
946                          convert (ptrdiff_type_node, object_ptr),
947                          convert (ptrdiff_type_node, delta));
948
949  parms = tree_cons (NULL_TREE,
950                     convert (build_pointer_type (basetype), object_ptr),
951                     TREE_CHAIN (parms));
952  new_parms = tree_cons (NULL_TREE, new_object_ptr, TREE_CHAIN (parms));
953
954  {
955    /* Cast the signature method to have `this' of a normal pointer type.  */
956    tree old_this = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn))));
957
958    TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))) =
959      build_type_variant (build_pointer_type (basetype),
960                          TYPE_READONLY (old_this),
961                          TYPE_VOLATILE (old_this));
962
963    direct_call = build_function_call (pfn, new_parms);
964
965    {
966      tree vfld, vtbl, aref;
967
968      vfld = build (PLUS_EXPR,
969                    build_pointer_type (build_pointer_type (vtbl_type_node)),
970                    convert (ptrdiff_type_node, object_ptr),
971                    convert (ptrdiff_type_node, vt_off));
972      vtbl = build_indirect_ref (build_indirect_ref (vfld, NULL_PTR),
973                                 NULL_PTR);
974      aref = build_array_ref (vtbl, index);
975
976      if (flag_vtable_thunks)
977        vfn = aref;
978      else
979        vfn = build_component_ref (aref, pfn_identifier, 0, 0);
980
981      TREE_TYPE (vfn) = build_pointer_type (TREE_TYPE (function));
982
983      if (flag_vtable_thunks)
984        virtual_call = build_function_call (vfn, parms);
985      else
986        virtual_call = build_function_call (vfn, new_parms);
987    }
988
989    /* Undo the cast, make `this' a signature pointer again.  */
990    TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))) = old_this;
991  }
992
993  /* Once the function was found, there should be no reason why we
994     couldn't build the member function pointer call.  */
995  if (!direct_call || direct_call == error_mark_node
996      || !virtual_call || virtual_call == error_mark_node
997      || (IS_DEFAULT_IMPLEMENTATION (function)
998          && (!deflt_call || deflt_call == error_mark_node)))
999    {
1000      compiler_error ("cannot build call of signature member function `%s'",
1001                      fndecl_as_string (NULL, function, 1));
1002      return error_mark_node;
1003    }
1004
1005  if (IS_DEFAULT_IMPLEMENTATION (function))
1006    {
1007      tree test = build_binary_op_nodefault (LT_EXPR, tag, integer_zero_node,
1008                                             LT_EXPR);
1009      result = build_conditional_expr (tag,
1010                                       build_conditional_expr (test,
1011                                                               deflt_call,
1012                                                               virtual_call),
1013                                       direct_call);
1014    }
1015  else
1016    result = build_conditional_expr (tag, virtual_call, direct_call);
1017
1018  /* If we created a temporary variable for `this', initialize it first.  */
1019  if (instance != saved_instance)
1020    result = build (COMPOUND_EXPR, TREE_TYPE (result),
1021                    build_modify_expr (saved_instance, NOP_EXPR, instance),
1022                    result);
1023
1024  return result;
1025}
1026
1027/* Create a COMPONENT_REF expression for referencing the OPTR field
1028   of a signature pointer or reference.  */
1029
1030tree
1031build_optr_ref (instance)
1032     tree instance;
1033{
1034  tree field = get_identifier (SIGNATURE_OPTR_NAME);
1035
1036  return build_component_ref (instance, field, NULL_TREE, 1);
1037}
1038
1039/* Create a COMPONENT_REF expression for referencing the SPTR field
1040   of a signature pointer or reference.  */
1041
1042tree
1043build_sptr_ref (instance)
1044     tree instance;
1045{
1046  tree field = get_identifier (SIGNATURE_SPTR_NAME);
1047
1048  return build_component_ref (instance, field, NULL_TREE, 1);
1049}
Note: See TracBrowser for help on using the repository browser.