OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [java/] [mangle.c] - Blame information for rev 20

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* Functions related to mangling class names for the GNU compiler
2
   for the Java(TM) language.
3
   Copyright (C) 1998, 1999, 2001, 2002, 2003
4
   Free Software Foundation, Inc.
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2, or (at your option)
11
any later version.
12
 
13
GCC is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING.  If not, write to
20
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21
Boston, MA 02110-1301, USA.
22
 
23
Java and all Java-based marks are trademarks or registered trademarks
24
of Sun Microsystems, Inc. in the United States and other countries.
25
The Free Software Foundation is independent of Sun Microsystems, Inc.  */
26
 
27
/* Written by Per Bothner <bothner@cygnus.com> */
28
 
29
#include "config.h"
30
#include "system.h"
31
#include "coretypes.h"
32
#include "tm.h"
33
#include "jcf.h"
34
#include "tree.h"
35
#include "java-tree.h"
36
#include "obstack.h"
37
#include "toplev.h"
38
#include "ggc.h"
39
#include "langhooks-def.h"
40
 
41
static void mangle_class_field (tree);
42
static void mangle_vtable (tree);
43
static void mangle_field_decl (tree);
44
static void mangle_method_decl (tree);
45
static void mangle_local_cni_method_decl (tree);
46
 
47
static void mangle_type (tree);
48
static void mangle_pointer_type (tree);
49
static void mangle_array_type (tree);
50
static int  mangle_record_type (tree, int);
51
 
52
static int find_compression_pointer_match (tree);
53
static int find_compression_array_match (tree);
54
static int find_compression_record_match (tree, tree *);
55
static int find_compression_array_template_match (tree);
56
 
57
static void set_type_package_list (tree);
58
static int  entry_match_pointer_p (tree, int);
59
static void emit_compression_string (int);
60
 
61
static void init_mangling (void);
62
static tree finish_mangling (void);
63
static void compression_table_add (tree);
64
 
65
static void mangle_member_name (tree);
66
 
67
static struct obstack mangle_obstack_1;
68
struct obstack *mangle_obstack;
69
 
70
#define MANGLE_RAW_STRING(S) \
71
  obstack_grow (mangle_obstack, (S), sizeof (S)-1)
72
 
73
/* atms: array template mangled string. */
74
static GTY(()) tree atms;
75
 
76
/* This is the mangling interface: a decl, a class field (.class) and
77
   the vtable. */
78
 
79
void
80
java_mangle_decl (tree decl)
81
{
82
  /* A copy of the check from the beginning of lhd_set_decl_assembler_name.
83
     Only FUNCTION_DECLs and VAR_DECLs for variables with static storage
84
     duration need a real DECL_ASSEMBLER_NAME.  */
85
  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
86
              || (TREE_CODE (decl) == VAR_DECL
87
                  && (TREE_STATIC (decl)
88
                      || DECL_EXTERNAL (decl)
89
                      || TREE_PUBLIC (decl))));
90
 
91
  /* Mangling only applies to class members.  */
92
  if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
93
    {
94
      init_mangling ();
95
      switch (TREE_CODE (decl))
96
        {
97
        case VAR_DECL:
98
          if (DECL_LANG_SPECIFIC (decl))
99
            {
100
              if (DECL_CLASS_FIELD_P (decl))
101
                {
102
                  mangle_class_field (DECL_CONTEXT (decl));
103
                  break;
104
                }
105
              else if (DECL_VTABLE_P (decl))
106
                {
107
                  mangle_vtable (DECL_CONTEXT (decl));
108
                  break;
109
                }
110
            }
111
          mangle_field_decl (decl);
112
          break;
113
 
114
        case FUNCTION_DECL:
115
          if (DECL_LANG_SPECIFIC (decl) && DECL_LOCAL_CNI_METHOD_P (decl))
116
            mangle_local_cni_method_decl (decl);
117
          else
118
            mangle_method_decl (decl);
119
          break;
120
 
121
        default:
122
          gcc_unreachable ();
123
        }
124
      SET_DECL_ASSEMBLER_NAME (decl, finish_mangling ());
125
    }
126
  else
127
    lhd_set_decl_assembler_name (decl);
128
}
129
 
130
/* Beginning of the helper functions */
131
 
132
static void
133
mangle_class_field (tree type)
134
{
135
  mangle_record_type (type, /* for_pointer = */ 0);
136
  MANGLE_RAW_STRING ("6class$");
137
  obstack_1grow (mangle_obstack, 'E');
138
}
139
 
140
static void
141
mangle_vtable (tree type)
142
{
143
  MANGLE_RAW_STRING ("TV");
144
  mangle_record_type (type, /* for_pointer = */ 0);
145
  obstack_1grow (mangle_obstack, 'E');
146
}
147
 
148
/* This mangles a field decl */
149
 
150
static void
151
mangle_field_decl (tree decl)
152
{
153
  /* Mangle the name of the this the field belongs to */
154
  mangle_record_type (DECL_CONTEXT (decl), /* for_pointer = */ 0);
155
 
156
  /* Mangle the name of the field */
157
  mangle_member_name (DECL_NAME (decl));
158
 
159
  /* Terminate the mangled name */
160
  obstack_1grow (mangle_obstack, 'E');
161
}
162
 
163
/* This mangles a method decl, first mangling its name and then all
164
   its arguments. */
165
 
166
static void
167
mangle_method_decl (tree mdecl)
168
{
169
  tree method_name = DECL_NAME (mdecl);
170
  tree arglist;
171
 
172
  /* Mangle the name of the type that contains mdecl */
173
  mangle_record_type (DECL_CONTEXT (mdecl), /* for_pointer = */ 0);
174
 
175
  /* Mangle the function name.  There are two cases:
176
       - mdecl is a constructor, use `C1' for its name, (denotes a
177
         complete object constructor.)
178
       - mdecl is not a constructor, standard mangling is performed.
179
     We terminate the mangled function name with a `E'. */
180
  if (ID_INIT_P (method_name))
181
    obstack_grow (mangle_obstack, "C1", 2);
182
  else
183
    mangle_member_name (method_name);
184
  obstack_1grow (mangle_obstack, 'E');
185
 
186
  /* We mangled type.methodName. Now onto the arguments. */
187
  arglist = TYPE_ARG_TYPES (TREE_TYPE (mdecl));
188
  if (TREE_CODE (TREE_TYPE (mdecl)) == METHOD_TYPE)
189
    arglist = TREE_CHAIN (arglist);
190
 
191
  /* No arguments is easy. We shortcut it. */
192
  if (arglist == end_params_node)
193
    obstack_1grow (mangle_obstack, 'v');
194
  else
195
    {
196
      tree arg;
197
      for (arg = arglist; arg != end_params_node;  arg = TREE_CHAIN (arg))
198
        mangle_type (TREE_VALUE (arg));
199
    }
200
}
201
 
202
/* This mangles a CNI method for a local class.  If the target supports
203
   hidden aliases, then G++ will have generated one for us.  It is the
204
   responsibility of java_mark_class_local to check target support, since
205
   we need to set DECL_VISIBILITY (or not) much earlier.  */
206
 
207
static void
208
mangle_local_cni_method_decl (tree decl)
209
{
210
  MANGLE_RAW_STRING ("GA");
211
  mangle_method_decl (decl);
212
}
213
 
214
/* This mangles a member name, like a function name or a field
215
   name. Handle cases were `name' is a C++ keyword.  Return a nonzero
216
   value if unicode encoding was required.  */
217
 
218
static void
219
mangle_member_name (tree name)
220
{
221
  append_gpp_mangled_name (IDENTIFIER_POINTER (name),
222
                           IDENTIFIER_LENGTH (name));
223
 
224
  /* If NAME happens to be a C++ keyword, add `$'. */
225
  if (cxx_keyword_p (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name)))
226
    obstack_1grow (mangle_obstack, '$');
227
}
228
 
229
/* Append the mangled name of TYPE onto OBSTACK.  */
230
 
231
static void
232
mangle_type (tree type)
233
{
234
  switch (TREE_CODE (type))
235
    {
236
      char code;
237
    case BOOLEAN_TYPE: code = 'b';  goto primitive;
238
    case CHAR_TYPE:    code = 'w';  goto primitive;
239
    case VOID_TYPE:    code = 'v';  goto primitive;
240
    case INTEGER_TYPE:
241
      /* Get the original type instead of the arguments promoted type.
242
         Avoid symbol name clashes. Should call a function to do that.
243
         FIXME.  */
244
      if (type == promoted_short_type_node)
245
        type = short_type_node;
246
      if (type == promoted_byte_type_node)
247
        type = byte_type_node;
248
      switch (TYPE_PRECISION (type))
249
        {
250
        case  8:       code = 'c';  goto primitive;
251
        case 16:       code = 's';  goto primitive;
252
        case 32:       code = 'i';  goto primitive;
253
        case 64:       code = 'x';  goto primitive;
254
        default:  goto bad_type;
255
        }
256
    primitive:
257
      obstack_1grow (mangle_obstack, code);
258
      break;
259
 
260
    case REAL_TYPE:
261
      switch (TYPE_PRECISION (type))
262
        {
263
        case 32:       code = 'f';  goto primitive;
264
        case 64:       code = 'd';  goto primitive;
265
        default:  goto bad_type;
266
        }
267
    case POINTER_TYPE:
268
      if (TYPE_ARRAY_P (TREE_TYPE (type)))
269
        mangle_array_type (type);
270
      else
271
        mangle_pointer_type (type);
272
      break;
273
    bad_type:
274
    default:
275
      abort ();
276
    }
277
}
278
 
279
/* The compression table is a vector that keeps track of things we've
280
   already seen, so they can be reused. For example, java.lang.Object
281
   would generate three entries: two package names and a type. If
282
   java.lang.String is presented next, the java.lang will be matched
283
   against the first two entries (and kept for compression as S0_), and
284
   type String would be added to the table. See mangle_record_type.
285
   COMPRESSION_NEXT is the index to the location of the next insertion
286
   of an element.  */
287
 
288
static GTY(()) tree compression_table;
289
static int  compression_next;
290
 
291
/* Find a POINTER_TYPE in the compression table. Use a special
292
   function to match pointer entries and start from the end */
293
 
294
static int
295
find_compression_pointer_match (tree type)
296
{
297
  int i;
298
 
299
  for (i = compression_next-1; i >= 0; i--)
300
    if (entry_match_pointer_p (type, i))
301
      return i;
302
  return -1;
303
}
304
 
305
/* Already recorder arrays are handled like pointer as they're always
306
   associated with it.  */
307
 
308
static int
309
find_compression_array_match (tree type)
310
{
311
  return find_compression_pointer_match (type);
312
}
313
 
314
/* Match the table of type against STRING.  */
315
 
316
static int
317
find_compression_array_template_match (tree string)
318
{
319
  int i;
320
  for (i = 0; i < compression_next; i++)
321
    if (TREE_VEC_ELT (compression_table, i) == string)
322
      return i;
323
  return -1;
324
}
325
 
326
/* We go through the compression table and try to find a complete or
327
   partial match. The function returns the compression table entry
328
   that (eventually partially) matches TYPE. *NEXT_CURRENT can be set
329
   to the rest of TYPE to be mangled. */
330
 
331
static int
332
find_compression_record_match (tree type, tree *next_current)
333
{
334
  int i, match = -1;
335
  tree current, saved_current = NULL_TREE;
336
 
337
  current = TYPE_PACKAGE_LIST (type);
338
 
339
  for (i = 0; i < compression_next; i++)
340
    {
341
      tree compression_entry = TREE_VEC_ELT (compression_table, i);
342
      if (current && compression_entry == TREE_PURPOSE (current))
343
        {
344
          match = i;
345
          saved_current = current;
346
          current = TREE_CHAIN (current);
347
        }
348
      else
349
        /* We don't want to match an element that appears in the middle
350
           of a package name, so skip forward to the next complete type name.
351
           IDENTIFIER_NODEs (except for a "6JArray") are partial package
352
           names while RECORD_TYPEs represent complete type names. */
353
        while (i < compression_next
354
               && TREE_CODE (compression_entry) == IDENTIFIER_NODE
355
               && compression_entry != atms)
356
          compression_entry = TREE_VEC_ELT (compression_table, ++i);
357
    }
358
 
359
  if (!next_current)
360
    return match;
361
 
362
  /* If we have a match, set next_current to the item next to the last
363
     matched value. */
364
  if (match >= 0)
365
    *next_current = TREE_CHAIN (saved_current);
366
  /* We had no match: we'll have to start from the beginning. */
367
  if (match < 0)
368
    *next_current = TYPE_PACKAGE_LIST (type);
369
 
370
  return match;
371
}
372
 
373
/* Mangle a record type. If a nonzero value is returned, it means
374
   that a 'N' was emitted (so that a matching 'E' can be emitted if
375
   necessary.)  FOR_POINTER indicates that this element is for a pointer
376
   symbol, meaning it was preceded by a 'P'. */
377
 
378
static int
379
mangle_record_type (tree type, int for_pointer)
380
{
381
  tree current;
382
  int match;
383
  int nadded_p = 0;
384
  int qualified;
385
 
386
  /* Does this name have a package qualifier? */
387
  qualified = QUALIFIED_P (DECL_NAME (TYPE_NAME (type)));
388
 
389
#define ADD_N() \
390
  do { obstack_1grow (mangle_obstack, 'N'); nadded_p = 1; } while (0)
391
 
392
  if (TREE_CODE (type) != RECORD_TYPE)
393
    abort ();
394
 
395
  if (!TYPE_PACKAGE_LIST (type))
396
    set_type_package_list (type);
397
 
398
  match = find_compression_record_match (type, &current);
399
  if (match >= 0)
400
    {
401
      /* If we had a pointer, and there's more, we need to emit
402
         'N' after 'P' (for_pointer tells us we already emitted it.) */
403
      if (for_pointer && current)
404
        ADD_N();
405
      emit_compression_string (match);
406
    }
407
  while (current)
408
    {
409
      /* Add the new type to the table */
410
      compression_table_add (TREE_PURPOSE (current));
411
      /* Add 'N' if we never got a chance to, but only if we have a qualified
412
         name.  For non-pointer elements, the name is always qualified. */
413
      if ((qualified || !for_pointer) && !nadded_p)
414
        ADD_N();
415
      /* Use the bare type name for the mangle. */
416
      append_gpp_mangled_name (IDENTIFIER_POINTER (TREE_VALUE (current)),
417
                               IDENTIFIER_LENGTH (TREE_VALUE (current)));
418
      current = TREE_CHAIN (current);
419
    }
420
  return nadded_p;
421
#undef ADD_N
422
}
423
 
424
/* Mangle a pointer type. There are two cases: the pointer is already
425
   in the compression table: the compression is emitted sans 'P'
426
   indicator. Otherwise, a 'P' is emitted and, depending on the type,
427
   a partial compression or/plus the rest of the mangling. */
428
 
429
static void
430
mangle_pointer_type (tree type)
431
{
432
  int match;
433
  tree pointer_type;
434
 
435
  /* Search for the type already in the compression table */
436
  if ((match = find_compression_pointer_match (type)) >= 0)
437
    {
438
      emit_compression_string (match);
439
      return;
440
    }
441
 
442
  /* This didn't work. We start by mangling the pointed-to type */
443
  pointer_type = type;
444
  type = TREE_TYPE (type);
445
  if (TREE_CODE (type) != RECORD_TYPE)
446
    abort ();
447
 
448
  obstack_1grow (mangle_obstack, 'P');
449
  if (mangle_record_type (type, /* for_pointer = */ 1))
450
    obstack_1grow (mangle_obstack, 'E');
451
 
452
  /* Don't forget to insert the pointer type in the table */
453
  compression_table_add (pointer_type);
454
}
455
 
456
/* Mangle an array type. Search for an easy solution first, then go
457
   through the process of finding out whether the bare array type or even
458
   the template indicator were already used and compressed appropriately.
459
   It handles pointers. */
460
 
461
static void
462
mangle_array_type (tree p_type)
463
{
464
  tree type, elt_type;
465
  int match;
466
 
467
  type = TREE_TYPE (p_type);
468
  if (!type)
469
    abort ();
470
 
471
  elt_type = TYPE_ARRAY_ELEMENT (type);
472
 
473
  /* We cache a bit of the Jarray <> mangle. */
474
  if (!atms)
475
    {
476
      atms = get_identifier ("6JArray");
477
    }
478
 
479
  /* Maybe we have what we're looking for in the compression table. */
480
  if ((match = find_compression_array_match (p_type)) >= 0)
481
    {
482
      emit_compression_string (match);
483
      return;
484
    }
485
 
486
  /* We know for a fact that all arrays are pointers */
487
  obstack_1grow (mangle_obstack, 'P');
488
  /* Maybe we already have a Jarray<t> somewhere. PSx_ will be enough. */
489
  if ((match = find_compression_record_match (type, NULL)) > 0)
490
    {
491
      emit_compression_string (match);
492
      return;
493
    }
494
 
495
  /* Maybe we already have just JArray somewhere */
496
  if ((match = find_compression_array_template_match (atms)) > 0)
497
    emit_compression_string (match);
498
  else
499
    {
500
      /* Start the template mangled name */
501
      obstack_grow (mangle_obstack,
502
                    IDENTIFIER_POINTER (atms), IDENTIFIER_LENGTH (atms));
503
      /* Insert in the compression table */
504
      compression_table_add (atms);
505
    }
506
 
507
  /* Mangle Jarray <elt_type> */
508
  obstack_1grow (mangle_obstack, 'I');
509
  mangle_type (elt_type);
510
  obstack_1grow (mangle_obstack, 'E');
511
 
512
  /* Add `Jarray <elt_type>' and `Jarray <elt_type> *' to the table */
513
  compression_table_add (type);
514
  compression_table_add (p_type);
515
}
516
 
517
/* Write a substitution string for entry I. Substitution string starts a
518
   -1 (encoded S_.) The base is 36, and the code shamelessly taken from
519
   cp/mangle.c.  */
520
 
521
static void
522
emit_compression_string (int i)
523
{
524
  i -= 1;                       /* Adjust */
525
  obstack_1grow (mangle_obstack, 'S');
526
  if (i >= 0)
527
    {
528
      static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
529
      unsigned HOST_WIDE_INT n;
530
      unsigned HOST_WIDE_INT m=1;
531
      /* How many digits for I in base 36? */
532
      for (n = i; n >= 36; n /= 36, m *=36);
533
      /* Write the digits out */
534
      while (m > 0)
535
        {
536
          int digit = i / m;
537
          obstack_1grow (mangle_obstack, digits [digit]);
538
          i -= digit * m;
539
          m /= 36;
540
        }
541
    }
542
  obstack_1grow (mangle_obstack, '_');
543
}
544
 
545
/* If search the compression table at index I for a pointer type
546
   equivalent to TYPE (meaning that after all the indirection, which
547
   might all be unique, we find the same RECORD_TYPE.) */
548
 
549
static int
550
entry_match_pointer_p (tree type, int i)
551
{
552
  tree t = TREE_VEC_ELT (compression_table, i);
553
 
554
  while (TREE_CODE (type) == POINTER_TYPE
555
         && TREE_CODE (t) == POINTER_TYPE)
556
    {
557
      t = TREE_TYPE (t);
558
      type = TREE_TYPE (type);
559
    }
560
  return (TREE_CODE (type) == RECORD_TYPE
561
          && TREE_CODE (t) == RECORD_TYPE
562
          && t == type);
563
}
564
 
565
/* Go through all qualification of type and build a list of list node
566
   elements containings as a purpose what should be used for a match and
567
   inserted in the compression table; and as it value the raw name of the
568
   part. The result is stored in TYPE_PACKAGE_LIST to be reused.  */
569
 
570
static void
571
set_type_package_list (tree type)
572
{
573
  int i;
574
  const char *type_string = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
575
  char *ptr;
576
  int qualifications;
577
  tree list = NULL_TREE, elt;
578
 
579
  for (ptr = (char *)type_string, qualifications = 0; *ptr; ptr++)
580
    if (*ptr == '.')
581
      qualifications += 1;
582
 
583
  for (ptr = (char *)type_string, i = 0; i < qualifications; ptr++)
584
    {
585
      if (ptr [0] == '.')
586
        {
587
          char c;
588
          tree identifier;
589
 
590
          /* Can't use an obstack, we're already using it to
591
             accumulate the mangling. */
592
          c = ptr [0];
593
          ptr [0] = '\0';
594
          identifier = get_identifier (type_string);
595
          ptr [0] = c;
596
          elt = build_tree_list (identifier, identifier);
597
          TREE_CHAIN (elt) = list;
598
          list = elt;
599
          type_string = ptr+1;
600
          i += 1;
601
        }
602
    }
603
 
604
  elt = build_tree_list (type, get_identifier (type_string));
605
  TREE_CHAIN (elt) = list;
606
  list = elt;
607
  TYPE_PACKAGE_LIST (type) = nreverse (list);
608
}
609
 
610
/* Add TYPE as the last element of the compression table. Resize the
611
   compression table if necessary.  */
612
 
613
static void
614
compression_table_add (tree type)
615
{
616
  if (compression_next == TREE_VEC_LENGTH (compression_table))
617
    {
618
      tree new = make_tree_vec (2*compression_next);
619
      int i;
620
 
621
      for (i = 0; i < compression_next; i++)
622
        TREE_VEC_ELT (new, i) = TREE_VEC_ELT (compression_table, i);
623
 
624
      compression_table = new;
625
    }
626
  TREE_VEC_ELT (compression_table, compression_next++) = type;
627
}
628
 
629
/* Mangling initialization routine.  */
630
 
631
static void
632
init_mangling (void)
633
{
634
  if (!mangle_obstack)
635
    {
636
      mangle_obstack = &mangle_obstack_1;
637
      gcc_obstack_init (mangle_obstack);
638
    }
639
 
640
  gcc_assert (compression_table == NULL);
641
  compression_table = make_tree_vec (10);
642
 
643
  /* Mangled name are to be suffixed */
644
  MANGLE_RAW_STRING ("_Z");
645
}
646
 
647
/* Mangling finalization routine. The mangled name is returned as a
648
   IDENTIFIER_NODE.  */
649
 
650
static tree
651
finish_mangling (void)
652
{
653
  tree result;
654
 
655
  gcc_assert (compression_table);
656
 
657
  compression_table = NULL_TREE;
658
  compression_next = 0;
659
  obstack_1grow (mangle_obstack, '\0');
660
  result = get_identifier (obstack_base (mangle_obstack));
661
  obstack_free (mangle_obstack, obstack_base (mangle_obstack));
662
 
663
  return result;
664
}
665
 
666
#include "gt-java-mangle.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.