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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [java/] [jcf-parse.c] - Blame information for rev 304

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

Line No. Rev Author Line
1 287 jeremybenn
/* Parser for Java(TM) .class files.
2
   Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3
   2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4
 
5
This file is part of GCC.
6
 
7
GCC 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 3, or (at your option)
10
any later version.
11
 
12
GCC 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 GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.
20
 
21
Java and all Java-based marks are trademarks or registered trademarks
22
of Sun Microsystems, Inc. in the United States and other countries.
23
The Free Software Foundation is independent of Sun Microsystems, Inc.  */
24
 
25
/* Written by Per Bothner <bothner@cygnus.com> */
26
 
27
#include "config.h"
28
#include "system.h"
29
#include "coretypes.h"
30
#include "tm.h"
31
#include "tree.h"
32
#include "real.h"
33
#include "obstack.h"
34
#include "flags.h"
35
#include "java-except.h"
36
#include "input.h"
37
#include "javaop.h"
38
#include "java-tree.h"
39
#include "toplev.h"
40
#include "parse.h"
41
#include "ggc.h"
42
#include "debug.h"
43
#include "assert.h"
44
#include "tm_p.h"
45
#include "cgraph.h"
46
#include "vecprim.h"
47
 
48
#ifdef HAVE_LOCALE_H
49
#include <locale.h>
50
#endif
51
 
52
#ifdef HAVE_LANGINFO_CODESET
53
#include <langinfo.h>
54
#endif
55
 
56
/* A CONSTANT_Utf8 element is converted to an IDENTIFIER_NODE at parse time. */
57
#define JPOOL_UTF(JCF, INDEX) CPOOL_UTF(&(JCF)->cpool, INDEX)
58
#define JPOOL_UTF_LENGTH(JCF, INDEX) IDENTIFIER_LENGTH (JPOOL_UTF (JCF, INDEX))
59
#define JPOOL_UTF_DATA(JCF, INDEX) \
60
  ((const unsigned char *) IDENTIFIER_POINTER (JPOOL_UTF (JCF, INDEX)))
61
#define HANDLE_CONSTANT_Utf8(JCF, INDEX, LENGTH) \
62
  do { \
63
    unsigned char save;  unsigned char *text; \
64
    JCF_FILL (JCF, (LENGTH)+1); /* Make sure we read 1 byte beyond string. */ \
65
    text = (JCF)->read_ptr; \
66
    save = text[LENGTH]; \
67
    text[LENGTH] = 0; \
68
    (JCF)->cpool.data[INDEX].t = get_identifier ((const char *) text); \
69
    text[LENGTH] = save; \
70
    JCF_SKIP (JCF, LENGTH); } while (0)
71
 
72
#include "jcf.h"
73
 
74
extern struct obstack temporary_obstack;
75
 
76
static GTY(()) tree parse_roots[3];
77
 
78
/* The FIELD_DECL for the current field.  */
79
#define current_field parse_roots[0]
80
 
81
/* The METHOD_DECL for the current method.  */
82
#define current_method parse_roots[1]
83
 
84
/* A list of TRANSLATION_UNIT_DECLs for the files to be compiled.  */
85
#define current_file_list parse_roots[2]
86
 
87
/* Line 0 in current file, if compiling from bytecode. */
88
static location_t file_start_location;
89
 
90
/* The Java archive that provides main_class;  the main input file. */
91
static GTY(()) struct JCF * main_jcf;
92
 
93
/* The number of source files passed to us by -fsource-filename and an
94
   array of pointers to each name.  Used by find_sourcefile().  */
95
static int num_files = 0;
96
static char **filenames;
97
 
98
static struct ZipFile *localToFile;
99
 
100
/* A map of byte offsets in the reflection data that are fields which
101
   need renumbering.  */
102
bitmap field_offsets;
103
bitmap_obstack bit_obstack;
104
 
105
/* Declarations of some functions used here.  */
106
static void handle_innerclass_attribute (int count, JCF *, int len);
107
static tree give_name_to_class (JCF *jcf, int index);
108
static char *compute_class_name (struct ZipDirectory *zdir);
109
static int classify_zip_file (struct ZipDirectory *zdir);
110
static void parse_zip_file_entries (void);
111
static void process_zip_dir (FILE *);
112
static void parse_class_file (void);
113
static void handle_deprecated (void);
114
static void set_source_filename (JCF *, int);
115
static void jcf_parse (struct JCF*);
116
static void load_inner_classes (tree);
117
static void handle_annotation (JCF *jcf, int level);
118
static void java_layout_seen_class_methods (void);
119
 
120
/* Handle "Deprecated" attribute.  */
121
static void
122
handle_deprecated (void)
123
{
124
  if (current_field != NULL_TREE)
125
    FIELD_DEPRECATED (current_field) = 1;
126
  else if (current_method != NULL_TREE)
127
    METHOD_DEPRECATED (current_method) = 1;
128
  else if (current_class != NULL_TREE)
129
    CLASS_DEPRECATED (TYPE_NAME (current_class)) = 1;
130
  else
131
    {
132
      /* Shouldn't happen.  */
133
      gcc_unreachable ();
134
    }
135
}
136
 
137
 
138
 
139
/* Reverse a string.  */
140
static char *
141
reverse (const char *s)
142
{
143
  if (s == NULL)
144
    return NULL;
145
  else
146
    {
147
      int len = strlen (s);
148
      char *d = XNEWVAR (char, len + 1);
149
      const char *sp;
150
      char *dp;
151
 
152
      d[len] = 0;
153
      for (dp = &d[0], sp = &s[len-1]; sp >= s; dp++, sp--)
154
        *dp = *sp;
155
 
156
      return d;
157
    }
158
}
159
 
160
/* Compare two strings for qsort().  */
161
static int
162
cmpstringp (const void *p1, const void *p2)
163
{
164
  /* The arguments to this function are "pointers to
165
     pointers to char", but strcmp() arguments are "pointers
166
     to char", hence the following cast plus dereference */
167
 
168
  return strcmp(*(const char *const*) p1, *(const char *const*) p2);
169
}
170
 
171
/* Create an array of strings, one for each source file that we've
172
   seen.  fsource_filename can either be the name of a single .java
173
   file or a file that contains a list of filenames separated by
174
   newlines.  */
175
void
176
java_read_sourcefilenames (const char *fsource_filename)
177
{
178
  if (fsource_filename
179
      && filenames == 0
180
      && strlen (fsource_filename) > strlen (".java")
181
      && strcmp ((fsource_filename
182
                  + strlen (fsource_filename)
183
                  - strlen (".java")),
184
                 ".java") != 0)
185
    {
186
/*       fsource_filename isn't a .java file but a list of filenames
187
       separated by newlines */
188
      FILE *finput = fopen (fsource_filename, "r");
189
      int len = 0;
190
      int longest_line = 0;
191
 
192
      gcc_assert (finput);
193
 
194
      /* Find out how many files there are, and how long the filenames are.  */
195
      while (! feof (finput))
196
        {
197
          int ch = getc (finput);
198
          if (ch == '\n')
199
            {
200
              num_files++;
201
              if (len > longest_line)
202
                longest_line = len;
203
              len = 0;
204
              continue;
205
            }
206
          if (ch == EOF)
207
            break;
208
          len++;
209
        }
210
 
211
      rewind (finput);
212
 
213
      /* Read the filenames.  Put a pointer to each filename into the
214
         array FILENAMES.  */
215
      {
216
        char *linebuf = (char *) alloca (longest_line + 1);
217
        int i = 0;
218
        int charpos;
219
 
220
        filenames = XNEWVEC (char *, num_files);
221
 
222
        charpos = 0;
223
        for (;;)
224
          {
225
            int ch = getc (finput);
226
            if (ch == EOF)
227
              break;
228
            if (ch == '\n')
229
              {
230
                linebuf[charpos] = 0;
231
                gcc_assert (i < num_files);
232
                /* ???  Perhaps we should use lrealpath() here.  Doing
233
                   so would tidy up things like /../ but the rest of
234
                   gcc seems to assume relative pathnames, not
235
                   absolute pathnames.  */
236
/*              realname = lrealpath (linebuf); */
237
                filenames[i++] = reverse (linebuf);
238
                charpos = 0;
239
                continue;
240
              }
241
            gcc_assert (charpos < longest_line);
242
            linebuf[charpos++] = ch;
243
          }
244
 
245
        if (num_files > 1)
246
          qsort (filenames, num_files, sizeof (char *), cmpstringp);
247
      }
248
      fclose (finput);
249
    }
250
  else
251
    {
252
      filenames = XNEWVEC (char *, 1);
253
      filenames[0] = reverse (fsource_filename);
254
      num_files = 1;
255
    }
256
}
257
 
258
/* Given a relative pathname such as foo/bar.java, attempt to find a
259
   longer pathname with the same suffix.
260
 
261
   This is a best guess heuristic; with some weird class hierarchies we
262
   may fail to pick the correct source file.  For example, if we have
263
   the filenames foo/bar.java and also foo/foo/bar.java, we do not
264
   have enough information to know which one is the right match for
265
   foo/bar.java.  */
266
 
267
static const char *
268
find_sourcefile (const char *name)
269
{
270
  int i = 0, j = num_files-1;
271
  char *found = NULL;
272
 
273
  if (filenames)
274
    {
275
      char *revname = reverse (name);
276
 
277
      do
278
        {
279
          int k = (i+j) / 2;
280
          int cmp = strncmp (revname, filenames[k], strlen (revname));
281
          if (cmp == 0)
282
            {
283
              /*  OK, so we found one.  But is it a unique match?  */
284
              if ((k > i
285
                   && strncmp (revname, filenames[k-1], strlen (revname)) == 0)
286
                  || (k < j
287
                      && (strncmp (revname, filenames[k+1], strlen (revname))
288
                          == 0)))
289
                ;
290
              else
291
                found = filenames[k];
292
              break;
293
            }
294
          if (cmp > 0)
295
            i = k+1;
296
          else
297
            j = k-1;
298
        }
299
      while (i <= j);
300
 
301
      free (revname);
302
    }
303
 
304
  if (found && strlen (found) > strlen (name))
305
    return reverse (found);
306
  else
307
    return name;
308
}
309
 
310
 
311
 
312
/* Handle "SourceFile" attribute. */
313
 
314
static void
315
set_source_filename (JCF *jcf, int index)
316
{
317
  tree sfname_id = get_name_constant (jcf, index);
318
  const char *sfname = IDENTIFIER_POINTER (sfname_id);
319
  const char *old_filename = input_filename;
320
  int new_len = IDENTIFIER_LENGTH (sfname_id);
321
  if (old_filename != NULL)
322
    {
323
      int old_len = strlen (old_filename);
324
      /* Use the current input_filename (derived from the class name)
325
         if it has a directory prefix, but otherwise matches sfname. */
326
      if (old_len > new_len
327
          && strcmp (sfname, old_filename + old_len - new_len) == 0
328
          && (old_filename[old_len - new_len - 1] == '/'
329
              || old_filename[old_len - new_len - 1] == '\\'))
330
        return;
331
    }
332
  if (strchr (sfname, '/') == NULL && strchr (sfname, '\\') == NULL)
333
    {
334
      const char *class_name
335
        = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class)));
336
      const char *dot = strrchr (class_name, '.');
337
      if (dot != NULL)
338
        {
339
          /* Length of prefix, not counting final dot. */
340
          int i = dot - class_name;
341
          /* Concatenate current package prefix with new sfname. */
342
          char *buf = XNEWVEC (char, i + new_len + 2); /* Space for '.' and '\0'. */
343
          strcpy (buf + i + 1, sfname);
344
          /* Copy package from class_name, replacing '.' by DIR_SEPARATOR.
345
             Note we start at the end with the final package dot. */
346
          for (; i >= 0;  i--)
347
            {
348
              char c = class_name[i];
349
              if (c == '.')
350
                c = DIR_SEPARATOR;
351
              buf[i] = c;
352
            }
353
          sfname_id = get_identifier (buf);
354
          free (buf);
355
          sfname = IDENTIFIER_POINTER (sfname_id);
356
        }
357
    }
358
 
359
  sfname = find_sourcefile (sfname);
360
  line_table->maps[line_table->used-1].to_file = sfname;
361
  if (current_class == main_class) main_input_filename = sfname;
362
}
363
 
364
 
365
 
366
 
367
/* Annotation handling.
368
 
369
   The technique we use here is to copy the annotation data directly
370
   from the input class file into the output file.  We don't decode the
371
   data at all, merely rewriting constant indexes whenever we come
372
   across them: this is necessary because the constant pool in the
373
   output file isn't the same as the constant pool in in the input.
374
 
375
   The main advantage of this technique is that the resulting
376
   annotation data is pointer-free, so it doesn't have to be relocated
377
   at startup time.  As a consequence of this, annotations have no
378
   performance impact unless they are used.  Also, this representation
379
   is very dense.  */
380
 
381
 
382
/* Expand TYPE_REFLECTION_DATA by DELTA bytes.  Return the address of
383
   the start of the newly allocated region.  */
384
 
385
static unsigned char*
386
annotation_grow (int delta)
387
{
388
  unsigned char **data = &TYPE_REFLECTION_DATA (current_class);
389
  long *datasize = &TYPE_REFLECTION_DATASIZE (current_class);
390
  long len = *datasize;
391
 
392
  if (*data == NULL)
393
    {
394
      *data = XNEWVAR (unsigned char, delta);
395
    }
396
  else
397
    {
398
      int newlen = *datasize + delta;
399
      if (floor_log2 (newlen) != floor_log2 (*datasize))
400
        *data = XRESIZEVAR (unsigned char, *data,  2 << (floor_log2 (newlen)));
401
    }
402
  *datasize += delta;
403
  return *data + len;
404
}
405
 
406
/* annotation_rewrite_TYPE.  Rewrite various int types at p.  Use Java
407
   byte order (i.e. big endian.)  */
408
 
409
static void
410
annotation_rewrite_byte (unsigned int n, unsigned char *p)
411
{
412
  p[0] = n;
413
}
414
 
415
static void
416
annotation_rewrite_short (unsigned int n, unsigned char *p)
417
{
418
  p[0] = n>>8;
419
  p[1] = n;
420
}
421
 
422
static void
423
annotation_rewrite_int (unsigned int n, unsigned char *p)
424
{
425
  p[0] = n>>24;
426
  p[1] = n>>16;
427
  p[2] = n>>8;
428
  p[3] = n;
429
}
430
 
431
/* Read a 16-bit unsigned int in Java byte order (i.e. big
432
   endian.)  */
433
 
434
static uint16
435
annotation_read_short (unsigned char *p)
436
{
437
  uint16 tmp = p[0];
438
  tmp = (tmp << 8) | p[1];
439
  return tmp;
440
}
441
 
442
/* annotation_write_TYPE.  Rewrite various int types, appending them
443
   to TYPE_REFLECTION_DATA.  Use Java byte order (i.e. big
444
   endian.)  */
445
 
446
static void
447
annotation_write_byte (unsigned int n)
448
{
449
  annotation_rewrite_byte (n, annotation_grow (1));
450
}
451
 
452
static void
453
annotation_write_short (unsigned int n)
454
{
455
  annotation_rewrite_short (n, annotation_grow (2));
456
}
457
 
458
static void
459
annotation_write_int (unsigned int n)
460
{
461
  annotation_rewrite_int (n, annotation_grow (4));
462
}
463
 
464
/* Create a 64-bit constant in the constant pool.
465
 
466
   This is used for both integer and floating-point types.  As a
467
   consequence, it will not work if the target floating-point format
468
   is anything other than IEEE-754.  While this is arguably a bug, the
469
   runtime library makes exactly the same assumption and it's unlikely
470
   that Java will ever run on a non-IEEE machine.  */
471
 
472
static int
473
handle_long_constant (JCF *jcf, CPool *cpool, enum cpool_tag kind,
474
                    int index, bool big_endian)
475
{
476
  /* If we're on a 64-bit platform we can fit a long or double
477
     into the same space as a jword.  */
478
  if (POINTER_SIZE >= 64)
479
    index = find_constant1 (cpool, kind, JPOOL_LONG (jcf, index));
480
 
481
  /* In a compiled program the constant pool is in native word
482
     order.  How weird is that???  */
483
  else if (big_endian)
484
    index = find_constant2 (cpool, kind,
485
                            JPOOL_INT (jcf, index),
486
                            JPOOL_INT (jcf, index+1));
487
  else
488
    index = find_constant2 (cpool, kind,
489
                            JPOOL_INT (jcf, index+1),
490
                            JPOOL_INT (jcf, index));
491
 
492
  return index;
493
}
494
 
495
/* Given a class file and an index into its constant pool, create an
496
   entry in the outgoing constant pool for the same item.  */
497
 
498
static uint16
499
handle_constant (JCF *jcf, int index, enum cpool_tag purpose)
500
{
501
  unsigned int kind;
502
  CPool *cpool = cpool_for_class (output_class);
503
 
504
  if (index == 0)
505
    return 0;
506
 
507
  if (! CPOOL_INDEX_IN_RANGE (&jcf->cpool, index))
508
    error ("<constant pool index %d not in range>", index);
509
 
510
  kind = JPOOL_TAG (jcf, index);
511
 
512
  if ((kind & ~CONSTANT_ResolvedFlag) != purpose)
513
    {
514
      if (purpose == CONSTANT_Class
515
          && kind == CONSTANT_Utf8)
516
        ;
517
      else
518
        error ("<constant pool index %d unexpected type", index);
519
    }
520
 
521
  switch (kind)
522
    {
523
    case CONSTANT_Class:
524
    case CONSTANT_ResolvedClass:
525
      {
526
        /* For some reason I know not the what of, class names in
527
           annotations are UTF-8 strings in the constant pool but
528
           class names in EnclosingMethod attributes are real class
529
           references.  Set CONSTANT_LazyFlag here so that the VM
530
           doesn't attempt to resolve them at class initialization
531
           time.  */
532
        tree resolved_class, class_name;
533
        resolved_class = get_class_constant (jcf, index);
534
        class_name = build_internal_class_name (resolved_class);
535
        index = alloc_name_constant (CONSTANT_Class | CONSTANT_LazyFlag,
536
                                     (unmangle_classname
537
                                      (IDENTIFIER_POINTER(class_name),
538
                                       IDENTIFIER_LENGTH(class_name))));
539
        break;
540
      }
541
    case CONSTANT_Utf8:
542
      {
543
        tree utf8 = get_constant (jcf, index);
544
        if (purpose == CONSTANT_Class)
545
          /* Create a constant pool entry for a type signature.  This
546
             one has '.' rather than '/' because it isn't going into a
547
             class file, it's going into a compiled object.
548
 
549
             This has to match the logic in
550
             _Jv_ClassReader::prepare_pool_entry().  */
551
          utf8 = unmangle_classname (IDENTIFIER_POINTER(utf8),
552
                                     IDENTIFIER_LENGTH(utf8));
553
        index = alloc_name_constant (kind, utf8);
554
      }
555
      break;
556
 
557
    case CONSTANT_Long:
558
      index = handle_long_constant (jcf, cpool, CONSTANT_Long, index,
559
                                    WORDS_BIG_ENDIAN);
560
      break;
561
 
562
    case CONSTANT_Double:
563
      index = handle_long_constant (jcf, cpool, CONSTANT_Double, index,
564
                                    FLOAT_WORDS_BIG_ENDIAN);
565
      break;
566
 
567
    case CONSTANT_Float:
568
    case CONSTANT_Integer:
569
      index = find_constant1 (cpool, kind, JPOOL_INT (jcf, index));
570
      break;
571
 
572
    case CONSTANT_NameAndType:
573
      {
574
        uint16 name = JPOOL_USHORT1 (jcf, index);
575
        uint16 sig = JPOOL_USHORT2 (jcf, index);
576
        uint32 name_index = handle_constant (jcf, name, CONSTANT_Utf8);
577
        uint32 sig_index = handle_constant (jcf, sig, CONSTANT_Class);
578
        jword new_index = (name_index << 16) | sig_index;
579
        index = find_constant1 (cpool, kind, new_index);
580
      }
581
      break;
582
 
583
    default:
584
      abort ();
585
    }
586
 
587
  return index;
588
}
589
 
590
/* Read an element_value structure from an annotation in JCF.  Return
591
   the constant pool index for the resulting constant pool entry.  */
592
 
593
static int
594
handle_element_value (JCF *jcf, int level)
595
{
596
  uint8 tag = JCF_readu (jcf);
597
  int index = 0;
598
 
599
  annotation_write_byte (tag);
600
  switch (tag)
601
    {
602
    case 'B':
603
    case 'C':
604
    case 'S':
605
    case 'Z':
606
    case 'I':
607
      {
608
        uint16 cindex = JCF_readu2 (jcf);
609
        index = handle_constant (jcf, cindex,
610
                                 CONSTANT_Integer);
611
        annotation_write_short (index);
612
      }
613
      break;
614
    case 'D':
615
      {
616
        uint16 cindex = JCF_readu2 (jcf);
617
        index = handle_constant (jcf, cindex,
618
                                 CONSTANT_Double);
619
        annotation_write_short (index);
620
      }
621
      break;
622
    case 'F':
623
      {
624
        uint16 cindex = JCF_readu2 (jcf);
625
        index = handle_constant (jcf, cindex,
626
                                 CONSTANT_Float);
627
        annotation_write_short (index);
628
      }
629
      break;
630
    case 'J':
631
      {
632
        uint16 cindex = JCF_readu2 (jcf);
633
        index = handle_constant (jcf, cindex,
634
                                 CONSTANT_Long);
635
        annotation_write_short (index);
636
      }
637
      break;
638
    case 's':
639
      {
640
        uint16 cindex = JCF_readu2 (jcf);
641
        /* Despite what the JVM spec says, compilers generate a Utf8
642
           constant here, not a String.  */
643
        index = handle_constant (jcf, cindex,
644
                                 CONSTANT_Utf8);
645
        annotation_write_short (index);
646
      }
647
      break;
648
 
649
    case 'e':
650
      {
651
        uint16 type_name_index = JCF_readu2 (jcf);
652
        uint16 const_name_index = JCF_readu2 (jcf);
653
        index = handle_constant (jcf, type_name_index,
654
                                 CONSTANT_Class);
655
        annotation_write_short (index);
656
        index = handle_constant (jcf, const_name_index,
657
                                 CONSTANT_Utf8);
658
        annotation_write_short (index);
659
     }
660
      break;
661
    case 'c':
662
      {
663
        uint16 class_info_index = JCF_readu2 (jcf);
664
        index = handle_constant (jcf, class_info_index,
665
                                 CONSTANT_Class);
666
        annotation_write_short (index);
667
      }
668
      break;
669
    case '@':
670
      {
671
        handle_annotation (jcf, level + 1);
672
      }
673
      break;
674
    case '[':
675
      {
676
        uint16 n_array_elts = JCF_readu2 (jcf);
677
        annotation_write_short (n_array_elts);
678
        while (n_array_elts--)
679
          handle_element_value (jcf, level + 1);
680
      }
681
      break;
682
    default:
683
      abort();
684
      break;
685
    }
686
  return index;
687
}
688
 
689
/* Read an annotation structure from JCF.  Write it to the
690
   reflection_data field of the outgoing class.  */
691
 
692
static void
693
handle_annotation (JCF *jcf, int level)
694
{
695
  uint16 type_index = JCF_readu2 (jcf);
696
  uint16 npairs = JCF_readu2 (jcf);
697
  int index = handle_constant (jcf, type_index,
698
                               CONSTANT_Class);
699
  annotation_write_short (index);
700
  annotation_write_short (npairs);
701
  while (npairs--)
702
    {
703
      uint16 name_index = JCF_readu2 (jcf);
704
      index = handle_constant (jcf, name_index,
705
                               CONSTANT_Utf8);
706
      annotation_write_short (index);
707
      handle_element_value (jcf, level + 2);
708
    }
709
}
710
 
711
/* Read an annotation count from JCF, and write the following
712
   annotations to the reflection_data field of the outgoing class.  */
713
 
714
static void
715
handle_annotations (JCF *jcf, int level)
716
{
717
  uint16 num = JCF_readu2 (jcf);
718
  annotation_write_short (num);
719
  while (num--)
720
    handle_annotation (jcf, level);
721
}
722
 
723
/* As handle_annotations(), but perform a sanity check that we write
724
   the same number of bytes that we were expecting.  */
725
 
726
static void
727
handle_annotation_attribute (int ATTRIBUTE_UNUSED index, JCF *jcf,
728
                             long length)
729
{
730
  long old_datasize = TYPE_REFLECTION_DATASIZE (current_class);
731
 
732
  handle_annotations (jcf, 0);
733
 
734
  gcc_assert (old_datasize + length
735
              == TYPE_REFLECTION_DATASIZE (current_class));
736
}
737
 
738
/* gcj permutes its fields array after generating annotation_data, so
739
   we have to fixup field indexes for fields that have moved.  Given
740
   ARG, a VEC_int, fixup the field indexes in the reflection_data of
741
   the outgoing class.  We use field_offsets to tell us where the
742
   fixups must go.  */
743
 
744
void
745
rewrite_reflection_indexes (void *arg)
746
{
747
  bitmap_iterator bi;
748
  unsigned int offset;
749
  VEC(int, heap) *map = (VEC(int, heap) *) arg;
750
  unsigned char *data = TYPE_REFLECTION_DATA (current_class);
751
 
752
  if (map)
753
    {
754
      EXECUTE_IF_SET_IN_BITMAP (field_offsets, 0, offset, bi)
755
        {
756
          uint16 index = annotation_read_short (data + offset);
757
          annotation_rewrite_short
758
            (VEC_index (int, map, index), data + offset);
759
        }
760
    }
761
}
762
 
763
/* Read the RuntimeVisibleAnnotations from JCF and write them to the
764
   reflection_data of the outgoing class.  */
765
 
766
static void
767
handle_member_annotations (int member_index, JCF *jcf,
768
                           const unsigned char *name ATTRIBUTE_UNUSED,
769
                           long len, jv_attr_type member_type)
770
{
771
  int new_len = len + 1;
772
  annotation_write_byte (member_type);
773
  if (member_type != JV_CLASS_ATTR)
774
    new_len += 2;
775
  annotation_write_int (new_len);
776
  annotation_write_byte (JV_ANNOTATIONS_KIND);
777
  if (member_type == JV_FIELD_ATTR)
778
    bitmap_set_bit (field_offsets, TYPE_REFLECTION_DATASIZE (current_class));
779
  if (member_type != JV_CLASS_ATTR)
780
    annotation_write_short (member_index);
781
  handle_annotation_attribute (member_index, jcf, len);
782
}
783
 
784
/* Read the RuntimeVisibleParameterAnnotations from JCF and write them
785
   to the reflection_data of the outgoing class.  */
786
 
787
static void
788
handle_parameter_annotations (int member_index, JCF *jcf,
789
                              const unsigned char *name ATTRIBUTE_UNUSED,
790
                              long len, jv_attr_type member_type)
791
{
792
  int new_len = len + 1;
793
  uint8 num;
794
  annotation_write_byte (member_type);
795
  if (member_type != JV_CLASS_ATTR)
796
    new_len += 2;
797
  annotation_write_int (new_len);
798
  annotation_write_byte (JV_PARAMETER_ANNOTATIONS_KIND);
799
  if (member_type != JV_CLASS_ATTR)
800
    annotation_write_short (member_index);
801
  num = JCF_readu (jcf);
802
  annotation_write_byte (num);
803
  while (num--)
804
    handle_annotations (jcf, 0);
805
}
806
 
807
 
808
/* Read the AnnotationDefault data from JCF and write them to the
809
   reflection_data of the outgoing class.  */
810
 
811
static void
812
handle_default_annotation (int member_index, JCF *jcf,
813
                           const unsigned char *name ATTRIBUTE_UNUSED,
814
                           long len, jv_attr_type member_type)
815
{
816
  int new_len = len + 1;
817
  annotation_write_byte (member_type);
818
  if (member_type != JV_CLASS_ATTR)
819
    new_len += 2;
820
  annotation_write_int (new_len);
821
  annotation_write_byte (JV_ANNOTATION_DEFAULT_KIND);
822
  if (member_type != JV_CLASS_ATTR)
823
    annotation_write_short (member_index);
824
  handle_element_value (jcf, 0);
825
}
826
 
827
/* As above, for the EnclosingMethod attribute.  */
828
 
829
static void
830
handle_enclosingmethod_attribute (int member_index, JCF *jcf,
831
                           const unsigned char *name ATTRIBUTE_UNUSED,
832
                           long len, jv_attr_type member_type)
833
{
834
  int new_len = len + 1;
835
  uint16 index;
836
  annotation_write_byte (member_type);
837
  if (member_type != JV_CLASS_ATTR)
838
    new_len += 2;
839
  annotation_write_int (new_len);
840
  annotation_write_byte (JV_ENCLOSING_METHOD_KIND);
841
  if (member_type != JV_CLASS_ATTR)
842
    annotation_write_short (member_index);
843
 
844
  index = JCF_readu2 (jcf);
845
  index = handle_constant (jcf, index, CONSTANT_Class);
846
  annotation_write_short (index);
847
 
848
  index = JCF_readu2 (jcf);
849
  index = handle_constant (jcf, index, CONSTANT_NameAndType);
850
  annotation_write_short (index);
851
}
852
 
853
/* As above, for the Signature attribute.  */
854
 
855
static void
856
handle_signature_attribute (int member_index, JCF *jcf,
857
                           const unsigned char *name ATTRIBUTE_UNUSED,
858
                           long len, jv_attr_type member_type)
859
{
860
  int new_len = len + 1;
861
  uint16 index;
862
  annotation_write_byte (member_type);
863
  if (member_type != JV_CLASS_ATTR)
864
    new_len += 2;
865
  annotation_write_int (new_len);
866
  annotation_write_byte (JV_SIGNATURE_KIND);
867
  if (member_type != JV_CLASS_ATTR)
868
    annotation_write_short (member_index);
869
 
870
  index = JCF_readu2 (jcf);
871
  index = handle_constant (jcf, index, CONSTANT_Utf8);
872
  annotation_write_short (index);
873
}
874
 
875
 
876
 
877
#define HANDLE_SOURCEFILE(INDEX) set_source_filename (jcf, INDEX)
878
 
879
#define HANDLE_CLASS_INFO(ACCESS_FLAGS, THIS, SUPER, INTERFACES_COUNT) \
880
{ tree super_class = SUPER==0 ? NULL_TREE : get_class_constant (jcf, SUPER); \
881
  output_class = current_class = give_name_to_class (jcf, THIS); \
882
  set_super_info (ACCESS_FLAGS, current_class, super_class, INTERFACES_COUNT);}
883
 
884
#define HANDLE_CLASS_INTERFACE(INDEX) \
885
  add_interface (current_class, get_class_constant (jcf, INDEX))
886
 
887
#define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
888
{ int sig_index = SIGNATURE; \
889
  current_field = add_field (current_class, get_name_constant (jcf, NAME), \
890
                             parse_signature (jcf, sig_index), ACCESS_FLAGS); \
891
 set_java_signature (TREE_TYPE (current_field), JPOOL_UTF (jcf, sig_index)); \
892
 if ((ACCESS_FLAGS) & ACC_FINAL) \
893
   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (current_field); \
894
}
895
 
896
#define HANDLE_END_FIELDS() \
897
  (current_field = NULL_TREE)
898
 
899
#define HANDLE_CONSTANTVALUE(INDEX) \
900
{ tree constant;  int index = INDEX; \
901
  if (JPOOL_TAG (jcf, index) == CONSTANT_String) { \
902
    tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index)); \
903
    constant = build_utf8_ref (name); \
904
  } \
905
  else \
906
    constant = get_constant (jcf, index); \
907
  set_constant_value (current_field, constant); }
908
 
909
#define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
910
 (current_method = add_method (current_class, ACCESS_FLAGS, \
911
                               get_name_constant (jcf, NAME), \
912
                               get_name_constant (jcf, SIGNATURE)), \
913
  DECL_LOCALVARIABLES_OFFSET (current_method) = 0, \
914
  DECL_LINENUMBERS_OFFSET (current_method) = 0)
915
 
916
#define HANDLE_END_METHODS() \
917
{ current_method = NULL_TREE; }
918
 
919
#define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
920
{ DECL_MAX_STACK (current_method) = (MAX_STACK); \
921
  DECL_MAX_LOCALS (current_method) = (MAX_LOCALS); \
922
  DECL_CODE_LENGTH (current_method) = (CODE_LENGTH); \
923
  DECL_CODE_OFFSET (current_method) = JCF_TELL (jcf); }
924
 
925
#define HANDLE_LOCALVARIABLETABLE_ATTRIBUTE(COUNT) \
926
{ int n = (COUNT); \
927
  DECL_LOCALVARIABLES_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
928
  JCF_SKIP (jcf, n * 10); }
929
 
930
#define HANDLE_LINENUMBERTABLE_ATTRIBUTE(COUNT) \
931
{ int n = (COUNT); \
932
  DECL_LINENUMBERS_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
933
  JCF_SKIP (jcf, n * 4); }
934
 
935
#define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
936
{ \
937
  int n = COUNT; \
938
  tree list = DECL_FUNCTION_THROWS (current_method); \
939
  while (--n >= 0) \
940
    { \
941
      tree thrown_class = get_class_constant (jcf, JCF_readu2 (jcf)); \
942
      list = tree_cons (NULL_TREE, thrown_class, list); \
943
    } \
944
  DECL_FUNCTION_THROWS (current_method) = nreverse (list); \
945
}
946
 
947
#define HANDLE_DEPRECATED_ATTRIBUTE()  handle_deprecated ()
948
 
949
/* Link seen inner classes to their outer context and register the
950
   inner class to its outer context. They will be later loaded.  */
951
#define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \
952
  handle_innerclass_attribute (COUNT, jcf, attribute_length)
953
 
954
#define HANDLE_SYNTHETIC_ATTRIBUTE()                                    \
955
{                                                                       \
956
  /* Irrelevant decls should have been nullified by the END macros.     \
957
     DECL_ARTIFICIAL on fields is used for something else (See          \
958
     PUSH_FIELD in java-tree.h) */                                      \
959
  if (current_method)                                                   \
960
    DECL_ARTIFICIAL (current_method) = 1;                               \
961
  else if (current_field)                                               \
962
    FIELD_SYNTHETIC (current_field) = 1;                                \
963
  else                                                                  \
964
    TYPE_SYNTHETIC (current_class) = 1;                                 \
965
}
966
 
967
#define HANDLE_GCJCOMPILED_ATTRIBUTE()          \
968
{                                               \
969
  if (current_class == object_type_node)        \
970
    jcf->right_zip = 1;                         \
971
}
972
 
973
#define HANDLE_RUNTIMEVISIBLEANNOTATIONS_ATTRIBUTE()                    \
974
{                                                                       \
975
  handle_member_annotations (index, jcf, name_data, attribute_length, attr_type); \
976
}
977
 
978
#define HANDLE_RUNTIMEINVISIBLEANNOTATIONS_ATTRIBUTE()  \
979
{                                                       \
980
  JCF_SKIP(jcf, attribute_length);                      \
981
}
982
 
983
#define HANDLE_RUNTIMEVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE()           \
984
{                                                                       \
985
  handle_parameter_annotations (index, jcf, name_data, attribute_length, attr_type); \
986
}
987
 
988
#define HANDLE_RUNTIMEINVISIBLEPARAMETERANNOTATIONS_ATTRIBUTE() \
989
{                                                               \
990
  JCF_SKIP(jcf, attribute_length);                              \
991
}
992
 
993
#define HANDLE_ANNOTATIONDEFAULT_ATTRIBUTE()                            \
994
{                                                                       \
995
  handle_default_annotation (index, jcf, name_data, attribute_length, attr_type); \
996
}
997
 
998
#define HANDLE_ENCLOSINGMETHOD_ATTRIBUTE()                              \
999
{                                                                       \
1000
  handle_enclosingmethod_attribute (index, jcf, name_data,              \
1001
                                    attribute_length, attr_type);       \
1002
}
1003
 
1004
#define HANDLE_SIGNATURE_ATTRIBUTE()                            \
1005
{                                                               \
1006
  handle_signature_attribute (index, jcf, name_data,            \
1007
                              attribute_length, attr_type);     \
1008
}
1009
 
1010
#include "jcf-reader.c"
1011
 
1012
tree
1013
parse_signature (JCF *jcf, int sig_index)
1014
{
1015
  gcc_assert (sig_index > 0
1016
              && sig_index < JPOOL_SIZE (jcf)
1017
              && JPOOL_TAG (jcf, sig_index) == CONSTANT_Utf8);
1018
 
1019
  return parse_signature_string (JPOOL_UTF_DATA (jcf, sig_index),
1020
                                 JPOOL_UTF_LENGTH (jcf, sig_index));
1021
}
1022
 
1023
tree
1024
get_constant (JCF *jcf, int index)
1025
{
1026
  tree value;
1027
  int tag;
1028
  if (index <= 0 || index >= JPOOL_SIZE(jcf))
1029
    goto bad;
1030
  tag = JPOOL_TAG (jcf, index);
1031
  if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
1032
    return jcf->cpool.data[index].t;
1033
  switch (tag)
1034
    {
1035
    case CONSTANT_Integer:
1036
      {
1037
        jint num = JPOOL_INT(jcf, index);
1038
        value = build_int_cst (int_type_node, num);
1039
        break;
1040
      }
1041
    case CONSTANT_Long:
1042
      {
1043
        unsigned HOST_WIDE_INT num = JPOOL_UINT (jcf, index);
1044
        unsigned HOST_WIDE_INT lo;
1045
        HOST_WIDE_INT hi;
1046
 
1047
        lshift_double (num, 0, 32, 64, &lo, &hi, 0);
1048
        num = JPOOL_UINT (jcf, index+1);
1049
        add_double (lo, hi, num, 0, &lo, &hi);
1050
        value = build_int_cst_wide_type (long_type_node, lo, hi);
1051
        break;
1052
      }
1053
 
1054
    case CONSTANT_Float:
1055
      {
1056
        jint num = JPOOL_INT(jcf, index);
1057
        long buf = num;
1058
        REAL_VALUE_TYPE d;
1059
 
1060
        real_from_target_fmt (&d, &buf, &ieee_single_format);
1061
        value = build_real (float_type_node, d);
1062
        break;
1063
      }
1064
 
1065
    case CONSTANT_Double:
1066
      {
1067
        long buf[2], lo, hi;
1068
        REAL_VALUE_TYPE d;
1069
 
1070
        hi = JPOOL_UINT (jcf, index);
1071
        lo = JPOOL_UINT (jcf, index+1);
1072
 
1073
        if (FLOAT_WORDS_BIG_ENDIAN)
1074
          buf[0] = hi, buf[1] = lo;
1075
        else
1076
          buf[0] = lo, buf[1] = hi;
1077
 
1078
        real_from_target_fmt (&d, buf, &ieee_double_format);
1079
        value = build_real (double_type_node, d);
1080
        break;
1081
      }
1082
 
1083
    case CONSTANT_String:
1084
      {
1085
        tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
1086
        const char *utf8_ptr = IDENTIFIER_POINTER (name);
1087
        int utf8_len = IDENTIFIER_LENGTH (name);
1088
        const unsigned char *utf8;
1089
        int i;
1090
 
1091
        /* Check for a malformed Utf8 string.  */
1092
        utf8 = (const unsigned char *) utf8_ptr;
1093
        i = utf8_len;
1094
        while (i > 0)
1095
          {
1096
            int char_len = UT8_CHAR_LENGTH (*utf8);
1097
            if (char_len < 0 || char_len > 3 || char_len > i)
1098
              fatal_error ("bad string constant");
1099
 
1100
            utf8 += char_len;
1101
            i -= char_len;
1102
          }
1103
 
1104
        /* Allocate a new string value.  */
1105
        value = build_string (utf8_len, utf8_ptr);
1106
        TREE_TYPE (value) = build_pointer_type (string_type_node);
1107
      }
1108
      break;
1109
    default:
1110
      goto bad;
1111
    }
1112
  JPOOL_TAG (jcf, index) = tag | CONSTANT_ResolvedFlag;
1113
  jcf->cpool.data[index].t = value;
1114
  return value;
1115
 bad:
1116
  internal_error ("bad value constant type %d, index %d",
1117
                  JPOOL_TAG (jcf, index), index);
1118
}
1119
 
1120
tree
1121
get_name_constant (JCF *jcf, int index)
1122
{
1123
  tree name = get_constant (jcf, index);
1124
  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
1125
  return name;
1126
}
1127
 
1128
/* Handle reading innerclass attributes. If a nonzero entry (denoting
1129
   a non anonymous entry) is found, We augment the inner class list of
1130
   the outer context with the newly resolved innerclass.  */
1131
 
1132
static void
1133
handle_innerclass_attribute (int count, JCF *jcf, int attribute_length)
1134
{
1135
  int c = count;
1136
 
1137
  annotation_write_byte (JV_CLASS_ATTR);
1138
  annotation_write_int (attribute_length+1);
1139
  annotation_write_byte (JV_INNER_CLASSES_KIND);
1140
  annotation_write_short (count);
1141
 
1142
  while (c--)
1143
    {
1144
      /* Read inner_class_info_index. This may be 0 */
1145
      int icii = JCF_readu2 (jcf);
1146
      /* Read outer_class_info_index. If the innerclasses attribute
1147
         entry isn't a member (like an inner class) the value is 0. */
1148
      int ocii = JCF_readu2 (jcf);
1149
      /* Read inner_name_index. If the class we're dealing with is
1150
         an anonymous class, it must be 0. */
1151
      int ini = JCF_readu2 (jcf);
1152
      /* Read the access flag. */
1153
      int acc = JCF_readu2 (jcf);
1154
 
1155
      annotation_write_short (handle_constant (jcf, icii, CONSTANT_Class));
1156
      annotation_write_short (handle_constant (jcf, ocii, CONSTANT_Class));
1157
      annotation_write_short (handle_constant (jcf, ini, CONSTANT_Utf8));
1158
      annotation_write_short (acc);
1159
 
1160
      /* If icii is 0, don't try to read the class. */
1161
      if (icii >= 0)
1162
        {
1163
          tree klass = get_class_constant (jcf, icii);
1164
          tree decl = TYPE_NAME (klass);
1165
          /* Skip reading further if ocii is null */
1166
          if (DECL_P (decl) && !CLASS_COMPLETE_P (decl) && ocii)
1167
            {
1168
              tree outer = TYPE_NAME (get_class_constant (jcf, ocii));
1169
              tree alias = (ini ? get_name_constant (jcf, ini) : NULL_TREE);
1170
              set_class_decl_access_flags (acc, decl);
1171
              DECL_CONTEXT (decl) = outer;
1172
              DECL_INNER_CLASS_LIST (outer) =
1173
                tree_cons (decl, alias, DECL_INNER_CLASS_LIST (outer));
1174
              CLASS_COMPLETE_P (decl) = 1;
1175
            }
1176
        }
1177
    }
1178
}
1179
 
1180
static tree
1181
give_name_to_class (JCF *jcf, int i)
1182
{
1183
  gcc_assert (i > 0
1184
              && i < JPOOL_SIZE (jcf)
1185
              && JPOOL_TAG (jcf, i) == CONSTANT_Class);
1186
 
1187
    {
1188
      tree package_name = NULL_TREE, tmp;
1189
      tree this_class;
1190
      int j = JPOOL_USHORT1 (jcf, i);
1191
      /* verify_constant_pool confirmed that j is a CONSTANT_Utf8. */
1192
      tree class_name = unmangle_classname ((const char *) JPOOL_UTF_DATA (jcf, j),
1193
                                            JPOOL_UTF_LENGTH (jcf, j));
1194
      this_class = lookup_class (class_name);
1195
      {
1196
      tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
1197
      const char *sfname = find_sourcefile (IDENTIFIER_POINTER (source_name));
1198
      linemap_add (line_table, LC_ENTER, false, sfname, 0);
1199
      input_location = linemap_line_start (line_table, 0, 1);
1200
      file_start_location = input_location;
1201
      DECL_SOURCE_LOCATION (TYPE_NAME (this_class)) = input_location;
1202
      if (main_input_filename == NULL && jcf == main_jcf)
1203
        main_input_filename = sfname;
1204
      }
1205
 
1206
      jcf->cpool.data[i].t = this_class;
1207
      JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
1208
      split_qualified_name (&package_name, &tmp,
1209
                            DECL_NAME (TYPE_NAME (this_class)));
1210
      TYPE_PACKAGE (this_class) = package_name;
1211
      return this_class;
1212
    }
1213
}
1214
 
1215
/* Get the class of the CONSTANT_Class whose constant pool index is I. */
1216
 
1217
tree
1218
get_class_constant (JCF *jcf, int i)
1219
{
1220
  tree type;
1221
  gcc_assert (i > 0
1222
              && i < JPOOL_SIZE (jcf)
1223
              && (JPOOL_TAG (jcf, i) & ~CONSTANT_ResolvedFlag) == CONSTANT_Class);
1224
 
1225
  if (JPOOL_TAG (jcf, i) != CONSTANT_ResolvedClass)
1226
    {
1227
      int name_index = JPOOL_USHORT1 (jcf, i);
1228
      /* verify_constant_pool confirmed that name_index is a CONSTANT_Utf8. */
1229
      const char *name = (const char *) JPOOL_UTF_DATA (jcf, name_index);
1230
      int nlength = JPOOL_UTF_LENGTH (jcf, name_index);
1231
 
1232
      if (name[0] == '[')  /* Handle array "classes". */
1233
          type = TREE_TYPE (parse_signature_string ((const unsigned char *) name, nlength));
1234
      else
1235
        {
1236
          tree cname = unmangle_classname (name, nlength);
1237
          type = lookup_class (cname);
1238
        }
1239
      jcf->cpool.data[i].t = type;
1240
      JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
1241
    }
1242
  else
1243
    type = jcf->cpool.data[i].t;
1244
  return type;
1245
}
1246
 
1247
/* Read a class with the fully qualified-name NAME.
1248
   Return 1 iff we read the requested file.
1249
   (It is still possible we failed if the file did not
1250
   define the class it is supposed to.) */
1251
 
1252
int
1253
read_class (tree name)
1254
{
1255
  JCF this_jcf, *jcf;
1256
  tree icv, klass = NULL_TREE;
1257
  tree save_current_class = current_class;
1258
  tree save_output_class = output_class;
1259
  location_t save_location = input_location;
1260
  JCF *save_current_jcf = current_jcf;
1261
 
1262
  if ((icv = IDENTIFIER_CLASS_VALUE (name)) != NULL_TREE)
1263
    {
1264
      klass = TREE_TYPE (icv);
1265
      jcf = TYPE_JCF (klass);
1266
    }
1267
  else
1268
    jcf = NULL;
1269
 
1270
  if (jcf == NULL)
1271
    {
1272
      const char* path_name;
1273
      this_jcf.zipd = NULL;
1274
      jcf = &this_jcf;
1275
 
1276
      path_name = find_class (IDENTIFIER_POINTER (name),
1277
                              IDENTIFIER_LENGTH (name),
1278
                              &this_jcf);
1279
      if (path_name == 0)
1280
        return 0;
1281
      else
1282
        free(CONST_CAST (char *, path_name));
1283
    }
1284
 
1285
  current_jcf = jcf;
1286
 
1287
  if (klass == NULL_TREE || ! CLASS_PARSED_P (klass))
1288
    {
1289
      output_class = current_class = klass;
1290
      if (JCF_SEEN_IN_ZIP (current_jcf))
1291
        read_zip_member(current_jcf,
1292
                        current_jcf->zipd, current_jcf->zipd->zipf);
1293
      jcf_parse (current_jcf);
1294
      /* Parsing might change the class, in which case we have to
1295
         put it back where we found it.  */
1296
      if (current_class != klass && icv != NULL_TREE)
1297
        TREE_TYPE (icv) = current_class;
1298
      klass = current_class;
1299
    }
1300
  layout_class (klass);
1301
  load_inner_classes (klass);
1302
 
1303
  output_class = save_output_class;
1304
  current_class = save_current_class;
1305
  input_location = save_location;
1306
  current_jcf = save_current_jcf;
1307
  return 1;
1308
}
1309
 
1310
/* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if
1311
   called from the parser, otherwise it's a RECORD_TYPE node. If
1312
   VERBOSE is 1, print error message on failure to load a class. */
1313
void
1314
load_class (tree class_or_name, int verbose)
1315
{
1316
  tree name, saved;
1317
  int class_loaded = 0;
1318
  tree class_decl = NULL_TREE;
1319
  bool is_compiled_class = false;
1320
 
1321
  /* We've already failed, don't try again.  */
1322
  if (TREE_CODE (class_or_name) == RECORD_TYPE
1323
      && TYPE_DUMMY (class_or_name))
1324
    return;
1325
 
1326
  /* class_or_name can be the name of the class we want to load */
1327
  if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
1328
    name = class_or_name;
1329
  /* In some cases, it's a dependency that we process earlier that
1330
     we though */
1331
  else if (TREE_CODE (class_or_name) == TREE_LIST)
1332
    name = TYPE_NAME (TREE_PURPOSE (class_or_name));
1333
  /* Or it's a type in the making */
1334
  else
1335
    name = DECL_NAME (TYPE_NAME (class_or_name));
1336
 
1337
  class_decl = IDENTIFIER_CLASS_VALUE (name);
1338
  if (class_decl != NULL_TREE)
1339
    {
1340
      tree type = TREE_TYPE (class_decl);
1341
      is_compiled_class
1342
        = ((TYPE_JCF (type) && JCF_SEEN_IN_ZIP (TYPE_JCF (type)))
1343
           || CLASS_FROM_CURRENTLY_COMPILED_P (type));
1344
    }
1345
 
1346
  saved = name;
1347
 
1348
  /* If flag_verify_invocations is unset, we don't try to load a class
1349
     unless we're looking for Object (which is fixed by the ABI) or
1350
     it's a class that we're going to compile.  */
1351
  if (flag_verify_invocations
1352
      || class_or_name == object_type_node
1353
      || is_compiled_class
1354
      || TREE_CODE (class_or_name) == IDENTIFIER_NODE)
1355
    {
1356
      while (1)
1357
        {
1358
          const char *separator;
1359
 
1360
          /* We've already loaded it.  */
1361
          if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE)
1362
            {
1363
              tree tmp_decl = IDENTIFIER_CLASS_VALUE (name);
1364
              if (CLASS_PARSED_P (TREE_TYPE (tmp_decl)))
1365
                break;
1366
            }
1367
 
1368
          if (read_class (name))
1369
            break;
1370
 
1371
          /* We failed loading name. Now consider that we might be looking
1372
             for an inner class.  */
1373
          if ((separator = strrchr (IDENTIFIER_POINTER (name), '$'))
1374
              || (separator = strrchr (IDENTIFIER_POINTER (name), '.')))
1375
            name = get_identifier_with_length (IDENTIFIER_POINTER (name),
1376
                                               (separator
1377
                                                - IDENTIFIER_POINTER (name)));
1378
          /* Otherwise, we failed, we bail. */
1379
          else
1380
            break;
1381
        }
1382
 
1383
      {
1384
        /* have we found the class we're looking for?  */
1385
        tree type_decl = IDENTIFIER_CLASS_VALUE (saved);
1386
        tree type = type_decl ? TREE_TYPE (type_decl) : NULL;
1387
        class_loaded = type && CLASS_PARSED_P (type);
1388
      }
1389
    }
1390
 
1391
  if (!class_loaded)
1392
    {
1393
      if (flag_verify_invocations || ! flag_indirect_dispatch)
1394
        {
1395
          if (verbose)
1396
            error ("cannot find file for class %s", IDENTIFIER_POINTER (saved));
1397
        }
1398
      else if (verbose)
1399
        {
1400
          /* This is just a diagnostic during testing, not a real problem.  */
1401
          if (!quiet_flag)
1402
            warning (0, "cannot find file for class %s",
1403
                     IDENTIFIER_POINTER (saved));
1404
 
1405
          /* Fake it.  */
1406
          if (TREE_CODE (class_or_name) == RECORD_TYPE)
1407
            {
1408
              set_super_info (0, class_or_name, object_type_node, 0);
1409
              TYPE_DUMMY (class_or_name) = 1;
1410
              /* We won't be able to output any debug info for this class.  */
1411
              DECL_IGNORED_P (TYPE_NAME (class_or_name)) = 1;
1412
            }
1413
        }
1414
    }
1415
}
1416
 
1417
/* Parse the .class file JCF. */
1418
 
1419
static void
1420
jcf_parse (JCF* jcf)
1421
{
1422
  int i, code;
1423
 
1424
  bitmap_clear (field_offsets);
1425
 
1426
  if (jcf_parse_preamble (jcf) != 0)
1427
    fatal_error ("not a valid Java .class file");
1428
  code = jcf_parse_constant_pool (jcf);
1429
  if (code != 0)
1430
    fatal_error ("error while parsing constant pool");
1431
  code = verify_constant_pool (jcf);
1432
  if (code > 0)
1433
    fatal_error ("error in constant pool entry #%d\n", code);
1434
 
1435
  jcf_parse_class (jcf);
1436
  if (main_class == NULL_TREE)
1437
    main_class = current_class;
1438
  if (! quiet_flag && TYPE_NAME (current_class))
1439
    fprintf (stderr, " %s %s",
1440
             (jcf->access_flags & ACC_INTERFACE) ? "interface" : "class",
1441
             IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
1442
  if (CLASS_PARSED_P (current_class))
1443
    {
1444
      /* FIXME - where was first time */
1445
      fatal_error ("reading class %s for the second time from %s",
1446
                   IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))),
1447
                   jcf->filename);
1448
    }
1449
  CLASS_PARSED_P (current_class) = 1;
1450
 
1451
  for (i = 1; i < JPOOL_SIZE(jcf); i++)
1452
    {
1453
      switch (JPOOL_TAG (jcf, i))
1454
        {
1455
        case CONSTANT_Class:
1456
          get_class_constant (jcf, i);
1457
          break;
1458
        }
1459
    }
1460
 
1461
  code = jcf_parse_fields (jcf);
1462
  if (code != 0)
1463
    fatal_error ("error while parsing fields");
1464
  code = jcf_parse_methods (jcf);
1465
  if (code != 0)
1466
    fatal_error ("error while parsing methods");
1467
  code = jcf_parse_final_attributes (jcf);
1468
  if (code != 0)
1469
    fatal_error ("error while parsing final attributes");
1470
 
1471
  if (TYPE_REFLECTION_DATA (current_class))
1472
    annotation_write_byte (JV_DONE_ATTR);
1473
 
1474
  linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1475
 
1476
  /* The fields of class_type_node are already in correct order. */
1477
  if (current_class != class_type_node && current_class != object_type_node)
1478
    TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class));
1479
 
1480
  if (current_class == object_type_node)
1481
    layout_class_methods (object_type_node);
1482
  else
1483
    all_class_list = tree_cons (NULL_TREE,
1484
                                TYPE_NAME (current_class), all_class_list );
1485
}
1486
 
1487
/* If we came across inner classes, load them now. */
1488
static void
1489
load_inner_classes (tree cur_class)
1490
{
1491
  tree current;
1492
  for (current = DECL_INNER_CLASS_LIST (TYPE_NAME (cur_class)); current;
1493
       current = TREE_CHAIN (current))
1494
    {
1495
      tree name = DECL_NAME (TREE_PURPOSE (current));
1496
      tree decl = IDENTIFIER_GLOBAL_VALUE (name);
1497
      if (decl && ! CLASS_LOADED_P (TREE_TYPE (decl))
1498
          && !CLASS_BEING_LAIDOUT (TREE_TYPE (decl)))
1499
        load_class (name, 1);
1500
    }
1501
}
1502
 
1503
static void
1504
duplicate_class_warning (const char *filename)
1505
{
1506
  location_t warn_loc;
1507
  linemap_add (line_table, LC_RENAME, 0, filename, 0);
1508
  warn_loc = linemap_line_start (line_table, 0, 1);
1509
  warning_at (warn_loc, 0, "duplicate class will only be compiled once");
1510
}
1511
 
1512
static void
1513
java_layout_seen_class_methods (void)
1514
{
1515
  tree previous_list = all_class_list;
1516
  tree end = NULL_TREE;
1517
  tree current;
1518
 
1519
  while (1)
1520
    {
1521
      for (current = previous_list;
1522
           current != end; current = TREE_CHAIN (current))
1523
        {
1524
          tree decl = TREE_VALUE (current);
1525
          tree cls = TREE_TYPE (decl);
1526
 
1527
          input_location = DECL_SOURCE_LOCATION (decl);
1528
 
1529
          if (! CLASS_LOADED_P (cls))
1530
            load_class (cls, 0);
1531
 
1532
          layout_class_methods (cls);
1533
        }
1534
 
1535
      /* Note that new classes might have been added while laying out
1536
         methods, changing the value of all_class_list.  */
1537
 
1538
      if (previous_list != all_class_list)
1539
        {
1540
          end = previous_list;
1541
          previous_list = all_class_list;
1542
        }
1543
      else
1544
        break;
1545
    }
1546
}
1547
 
1548
static void
1549
parse_class_file (void)
1550
{
1551
  tree method;
1552
  location_t save_location = input_location;
1553
 
1554
  java_layout_seen_class_methods ();
1555
 
1556
  input_location = DECL_SOURCE_LOCATION (TYPE_NAME (current_class));
1557
  {
1558
    /* Re-enter the current file.  */
1559
    expanded_location loc = expand_location (input_location);
1560
    linemap_add (line_table, LC_ENTER, 0, loc.file, loc.line);
1561
  }
1562
  file_start_location = input_location;
1563
  (*debug_hooks->start_source_file) (input_line, input_filename);
1564
 
1565
  java_mark_class_local (current_class);
1566
 
1567
  gen_indirect_dispatch_tables (current_class);
1568
 
1569
  for (method = TYPE_METHODS (current_class);
1570
       method != NULL_TREE; method = TREE_CHAIN (method))
1571
    {
1572
      JCF *jcf = current_jcf;
1573
 
1574
      if (METHOD_ABSTRACT (method) || METHOD_DUMMY (method))
1575
        continue;
1576
 
1577
      if (METHOD_NATIVE (method))
1578
        {
1579
          tree arg;
1580
          int  decl_max_locals;
1581
 
1582
          if (! flag_jni)
1583
            continue;
1584
          /* We need to compute the DECL_MAX_LOCALS. We need to take
1585
             the wide types into account too. */
1586
          for (arg = TYPE_ARG_TYPES (TREE_TYPE (method)), decl_max_locals = 0;
1587
               arg != end_params_node;
1588
               arg = TREE_CHAIN (arg), decl_max_locals += 1)
1589
            {
1590
              if (TREE_VALUE (arg) && TYPE_IS_WIDE (TREE_VALUE (arg)))
1591
                decl_max_locals += 1;
1592
            }
1593
          DECL_MAX_LOCALS (method) = decl_max_locals;
1594
          start_java_method (method);
1595
          give_name_to_locals (jcf);
1596
          *get_stmts () = build_jni_stub (method);
1597
          end_java_method ();
1598
          continue;
1599
        }
1600
 
1601
      if (DECL_CODE_OFFSET (method) == 0)
1602
        {
1603
          current_function_decl = method;
1604
          error ("missing Code attribute");
1605
          continue;
1606
        }
1607
 
1608
      input_location = DECL_SOURCE_LOCATION (TYPE_NAME (current_class));
1609
      if (DECL_LINENUMBERS_OFFSET (method))
1610
        {
1611
          int i;
1612
          int min_line = 0;
1613
          unsigned char *ptr;
1614
          JCF_SEEK (jcf, DECL_LINENUMBERS_OFFSET (method));
1615
          linenumber_count = i = JCF_readu2 (jcf);
1616
          linenumber_table = ptr = jcf->read_ptr;
1617
 
1618
          for (ptr += 2; --i >= 0; ptr += 4)
1619
            {
1620
              int line = GET_u2 (ptr);
1621
              /* Set initial input_line to smallest linenumber.
1622
               * Needs to be set before init_function_start. */
1623
              if (min_line == 0 || line < min_line)
1624
                min_line = line;
1625
            }
1626
          if (min_line != 0)
1627
            input_location = linemap_line_start (line_table, min_line, 1);
1628
        }
1629
      else
1630
        {
1631
          linenumber_table = NULL;
1632
          linenumber_count = 0;
1633
        }
1634
 
1635
      start_java_method (method);
1636
 
1637
      note_instructions (jcf, method);
1638
 
1639
      give_name_to_locals (jcf);
1640
 
1641
      /* Bump up start_label_pc_this_method so we get a unique label number
1642
         and reset highest_label_pc_this_method. */
1643
      if (highest_label_pc_this_method >= 0)
1644
        {
1645
          /* We adjust to the next multiple of 1000.  This is just a frill
1646
             so the last 3 digits of the label number match the bytecode
1647
             offset, which might make debugging marginally more convenient. */
1648
          start_label_pc_this_method
1649
            = ((((start_label_pc_this_method + highest_label_pc_this_method)
1650
                 / 1000)
1651
                + 1)
1652
               * 1000);
1653
          highest_label_pc_this_method = -1;
1654
        }
1655
 
1656
      /* Convert bytecode to trees.  */
1657
      expand_byte_code (jcf, method);
1658
 
1659
      end_java_method ();
1660
    }
1661
 
1662
  finish_class ();
1663
 
1664
  (*debug_hooks->end_source_file) (LOCATION_LINE (save_location));
1665
  input_location = save_location;
1666
}
1667
 
1668
void
1669
add_predefined_file (tree name)
1670
{
1671
  predef_filenames = tree_cons (NULL_TREE, name, predef_filenames);
1672
}
1673
 
1674
int
1675
predefined_filename_p (tree node)
1676
{
1677
  tree iter;
1678
 
1679
  for (iter = predef_filenames; iter != NULL_TREE; iter = TREE_CHAIN (iter))
1680
    {
1681
      if (TREE_VALUE (iter) == node)
1682
        return 1;
1683
    }
1684
  return 0;
1685
}
1686
 
1687
/* Generate a function that does all static initialization for this
1688
   translation unit.  */
1689
 
1690
static void
1691
java_emit_static_constructor (void)
1692
{
1693
  tree body = NULL;
1694
 
1695
  emit_register_classes (&body);
1696
  write_resource_constructor (&body);
1697
 
1698
  if (body)
1699
    {
1700
      tree name = get_identifier ("_Jv_global_static_constructor");
1701
 
1702
      tree decl
1703
        = build_decl (input_location, FUNCTION_DECL, name,
1704
                      build_function_type (void_type_node, void_list_node));
1705
 
1706
      tree resdecl = build_decl (input_location,
1707
                                 RESULT_DECL, NULL_TREE, void_type_node);
1708
      DECL_ARTIFICIAL (resdecl) = 1;
1709
      DECL_RESULT (decl) = resdecl;
1710
      current_function_decl = decl;
1711
      allocate_struct_function (decl, false);
1712
 
1713
      TREE_STATIC (decl) = 1;
1714
      TREE_USED (decl) = 1;
1715
      DECL_ARTIFICIAL (decl) = 1;
1716
      DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
1717
      DECL_SAVED_TREE (decl) = body;
1718
      DECL_UNINLINABLE (decl) = 1;
1719
 
1720
      DECL_INITIAL (decl) = make_node (BLOCK);
1721
      TREE_USED (DECL_INITIAL (decl)) = 1;
1722
 
1723
      DECL_STATIC_CONSTRUCTOR (decl) = 1;
1724
      java_genericize (decl);
1725
      cgraph_finalize_function (decl, false);
1726
    }
1727
}
1728
 
1729
 
1730
void
1731
java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
1732
{
1733
  int filename_count = 0;
1734
  location_t save_location = input_location;
1735
  char *file_list = NULL, *list, *next;
1736
  tree node;
1737
  FILE *finput = NULL;
1738
  int in_quotes = 0;
1739
 
1740
  bitmap_obstack_initialize (&bit_obstack);
1741
  field_offsets = BITMAP_ALLOC (&bit_obstack);
1742
 
1743
  if (flag_filelist_file)
1744
    {
1745
      int avail = 2000;
1746
      finput = fopen (main_input_filename, "r");
1747
      if (finput == NULL)
1748
        fatal_error ("can't open %s: %m", input_filename);
1749
      list = XNEWVEC (char, avail);
1750
      next = list;
1751
      for (;;)
1752
        {
1753
          int count;
1754
          if (avail < 500)
1755
            {
1756
              count = next - list;
1757
              avail = 2 * (count + avail);
1758
              list = XRESIZEVEC (char, list, avail);
1759
              next = list + count;
1760
              avail = avail - count;
1761
            }
1762
          /* Subtract to to guarantee space for final '\0'. */
1763
          count = fread (next, 1, avail - 1, finput);
1764
          if (count == 0)
1765
            {
1766
              if (! feof (finput))
1767
                fatal_error ("error closing %s: %m", input_filename);
1768
              *next = '\0';
1769
              break;
1770
            }
1771
          avail -= count;
1772
          next += count;
1773
        }
1774
      fclose (finput);
1775
      finput = NULL;
1776
      file_list = list;
1777
    }
1778
  else
1779
    list = CONST_CAST (char *, main_input_filename);
1780
 
1781
  while (list)
1782
    {
1783
      for (next = list; ; )
1784
        {
1785
          char ch = *next;
1786
          if (flag_filelist_file && ! in_quotes
1787
              && (ch == '\n' || ch == '\r' || ch == '\t' || ch == ' '
1788
                  || ch == '&') /* FIXME */)
1789
            {
1790
              if (next == list)
1791
                {
1792
                  next++;
1793
                  list = next;
1794
                  continue;
1795
                }
1796
              else
1797
                {
1798
                  *next++ = '\0';
1799
                  break;
1800
                }
1801
            }
1802
          if (flag_filelist_file && ch == '"')
1803
            {
1804
              in_quotes = ! in_quotes;
1805
              *next++ = '\0';
1806
              if (in_quotes)
1807
                list = next;
1808
              else
1809
                break;
1810
            }
1811
          if (ch == '\0')
1812
            {
1813
              next = NULL;
1814
              break;
1815
            }
1816
          next++;
1817
        }
1818
 
1819
      /* Exclude .java files.  */
1820
      if (strlen (list) > 5 && ! strcmp (list + strlen (list) - 5, ".java"))
1821
        {
1822
          /* Nothing. */
1823
        }
1824
      else if (list[0])
1825
        {
1826
          node = get_identifier (list);
1827
 
1828
          filename_count++;
1829
 
1830
          /* Exclude file that we see twice on the command line. */
1831
 
1832
          if (IS_A_COMMAND_LINE_FILENAME_P (node))
1833
            duplicate_class_warning (IDENTIFIER_POINTER (node));
1834
          else
1835
            {
1836
              tree file_decl = build_decl (input_location,
1837
                                           TRANSLATION_UNIT_DECL, node, NULL);
1838
              TREE_CHAIN (file_decl) = current_file_list;
1839
              current_file_list = file_decl;
1840
              IS_A_COMMAND_LINE_FILENAME_P (node) = 1;
1841
            }
1842
        }
1843
      list = next;
1844
    }
1845
 
1846
  if (file_list != NULL)
1847
    free (file_list);
1848
 
1849
  if (filename_count == 0)
1850
    warning (0, "no input file specified");
1851
 
1852
  if (resource_name)
1853
    {
1854
      const char *resource_filename;
1855
 
1856
      /* Only one resource file may be compiled at a time.  */
1857
      assert (TREE_CHAIN (current_file_list) == NULL);
1858
 
1859
      resource_filename = IDENTIFIER_POINTER (DECL_NAME (current_file_list));
1860
      compile_resource_file (resource_name, resource_filename);
1861
 
1862
      goto finish;
1863
    }
1864
 
1865
  current_jcf = main_jcf;
1866
  current_file_list = nreverse (current_file_list);
1867
  for (node = current_file_list; node; node = TREE_CHAIN (node))
1868
    {
1869
      unsigned char magic_string[4];
1870
      char *real_path;
1871
      uint32 magic = 0;
1872
      tree name = DECL_NAME (node);
1873
      tree real_file;
1874
      const char *filename = IDENTIFIER_POINTER (name);
1875
 
1876
      /* Skip already parsed files */
1877
      real_path = lrealpath (filename);
1878
      real_file = get_identifier (real_path);
1879
      free (real_path);
1880
      if (HAS_BEEN_ALREADY_PARSED_P (real_file))
1881
        continue;
1882
 
1883
      /* Close previous descriptor, if any */
1884
      if (finput && fclose (finput))
1885
        fatal_error ("can't close input file %s: %m", main_input_filename);
1886
 
1887
      finput = fopen (filename, "rb");
1888
      if (finput == NULL)
1889
        fatal_error ("can't open %s: %m", filename);
1890
 
1891
#ifdef IO_BUFFER_SIZE
1892
      setvbuf (finput, xmalloc (IO_BUFFER_SIZE),
1893
               _IOFBF, IO_BUFFER_SIZE);
1894
#endif
1895
 
1896
      /* Figure what kind of file we're dealing with */
1897
      if (fread (magic_string, 1, 4, finput) == 4)
1898
        {
1899
          fseek (finput, 0L, SEEK_SET);
1900
          magic = GET_u4 (magic_string);
1901
        }
1902
      if (magic == 0xcafebabe)
1903
        {
1904
          CLASS_FILE_P (node) = 1;
1905
          current_jcf = GGC_NEW (JCF);
1906
          JCF_ZERO (current_jcf);
1907
          current_jcf->read_state = finput;
1908
          current_jcf->filbuf = jcf_filbuf_from_stdio;
1909
          jcf_parse (current_jcf);
1910
          DECL_SOURCE_LOCATION (node) = file_start_location;
1911
          TYPE_JCF (current_class) = current_jcf;
1912
          if (CLASS_FROM_CURRENTLY_COMPILED_P (current_class))
1913
            {
1914
              /* We've already compiled this class.  */
1915
              duplicate_class_warning (filename);
1916
              continue;
1917
            }
1918
          CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
1919
          TREE_TYPE (node) = current_class;
1920
        }
1921
      else if (magic == (JCF_u4)ZIPMAGIC)
1922
        {
1923
          main_jcf = GGC_NEW (JCF);
1924
          JCF_ZERO (main_jcf);
1925
          main_jcf->read_state = finput;
1926
          main_jcf->filbuf = jcf_filbuf_from_stdio;
1927
          linemap_add (line_table, LC_ENTER, false, filename, 0);
1928
          input_location = linemap_line_start (line_table, 0, 1);
1929
          if (open_in_zip (main_jcf, filename, NULL, 0) <  0)
1930
            fatal_error ("bad zip/jar file %s", filename);
1931
          localToFile = SeenZipFiles;
1932
          /* Register all the classes defined there.  */
1933
          process_zip_dir ((FILE *) main_jcf->read_state);
1934
          linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1935
          parse_zip_file_entries ();
1936
        }
1937
      else if (magic == (JCF_u4) ZIPEMPTYMAGIC)
1938
        {
1939
          /* Ignore an empty input jar.  */
1940
        }
1941
      else
1942
        {
1943
          gcc_unreachable ();
1944
#if 0
1945
          java_push_parser_context ();
1946
          java_parser_context_save_global ();
1947
 
1948
          parse_source_file_1 (real_file, filename, finput);
1949
          java_parser_context_restore_global ();
1950
          java_pop_parser_context (1);
1951
          linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1952
#endif
1953
        }
1954
    }
1955
 
1956
  for (node = current_file_list; node; node = TREE_CHAIN (node))
1957
    {
1958
      input_location = DECL_SOURCE_LOCATION (node);
1959
      if (CLASS_FILE_P (node))
1960
        {
1961
          /* FIXME: These two flags really should be independent.  We
1962
             should be able to compile fully binary compatible, but
1963
             with flag_verify_invocations on.  */
1964
          flag_verify_invocations = ! flag_indirect_dispatch;
1965
          output_class = current_class = TREE_TYPE (node);
1966
 
1967
          current_jcf = TYPE_JCF (current_class);
1968
          layout_class (current_class);
1969
          load_inner_classes (current_class);
1970
          parse_class_file ();
1971
          JCF_FINISH (current_jcf);
1972
        }
1973
    }
1974
  input_location = save_location;
1975
 
1976
  bitmap_obstack_release (&bit_obstack);
1977
 
1978
 finish:
1979
  /* Arrange for any necessary initialization to happen.  */
1980
  java_emit_static_constructor ();
1981
  gcc_assert (global_bindings_p ());
1982
}
1983
 
1984
 
1985
/* Return the name of the class corresponding to the name of the file
1986
   in this zip entry.  The result is newly allocated using ALLOC.  */
1987
static char *
1988
compute_class_name (struct ZipDirectory *zdir)
1989
{
1990
  char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1991
  char *class_name;
1992
  int i;
1993
  int filename_length = zdir->filename_length;
1994
 
1995
  while (filename_length > 2 && strncmp (class_name_in_zip_dir, "./", 2) == 0)
1996
    {
1997
      class_name_in_zip_dir += 2;
1998
      filename_length -= 2;
1999
    }
2000
 
2001
  filename_length -= strlen (".class");
2002
  class_name = XNEWVEC (char, filename_length + 1);
2003
  memcpy (class_name, class_name_in_zip_dir, filename_length);
2004
  class_name [filename_length] = '\0';
2005
 
2006
  for (i = 0; i < filename_length; i++)
2007
    if (class_name[i] == '/')
2008
      class_name[i] = '.';
2009
 
2010
  return class_name;
2011
}
2012
 
2013
/* Return 0 if we should skip this entry, 1 if it is a .class file, 2
2014
   if it is a property file of some sort.  */
2015
static int
2016
classify_zip_file (struct ZipDirectory *zdir)
2017
{
2018
  char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
2019
 
2020
  if (zdir->filename_length > 6
2021
      && !strncmp (&class_name_in_zip_dir[zdir->filename_length - 6],
2022
                   ".class", 6))
2023
    return 1;
2024
 
2025
  /* For now we drop the manifest, but not other information.  */
2026
  if (zdir->filename_length == 20
2027
      && !strncmp (class_name_in_zip_dir, "META-INF/MANIFEST.MF", 20))
2028
    return 0;
2029
 
2030
  /* Drop directory entries.  */
2031
  if (zdir->filename_length > 0
2032
      && class_name_in_zip_dir[zdir->filename_length - 1] == '/')
2033
    return 0;
2034
 
2035
  return 2;
2036
}
2037
 
2038
/* Process all class entries found in the zip file.  */
2039
static void
2040
parse_zip_file_entries (void)
2041
{
2042
  struct ZipDirectory *zdir;
2043
  int i;
2044
 
2045
  for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
2046
       i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
2047
    {
2048
      tree klass;
2049
 
2050
      switch (classify_zip_file (zdir))
2051
        {
2052
        case 0:
2053
          continue;
2054
 
2055
        case 1:
2056
          {
2057
            char *class_name = compute_class_name (zdir);
2058
            int previous_alias_set = -1;
2059
            klass = lookup_class (get_identifier (class_name));
2060
            FREE (class_name);
2061
            current_jcf = TYPE_JCF (klass);
2062
            output_class = current_class = klass;
2063
 
2064
            /* This is a dummy class, and now we're compiling it for
2065
               real.  */
2066
            gcc_assert (! TYPE_DUMMY (klass));
2067
 
2068
            /* This is for a corner case where we have a superclass
2069
               but no superclass fields.
2070
 
2071
               This can happen if we earlier failed to lay out this
2072
               class because its superclass was still in the process
2073
               of being laid out; this occurs when we have recursive
2074
               class dependencies via inner classes.  We must record
2075
               the previous alias set and restore it after laying out
2076
               the class.
2077
 
2078
               FIXME: this really is a kludge.  We should figure out a
2079
               way to lay out the class properly before this
2080
               happens.  */
2081
            if (TYPE_SIZE (klass) && CLASSTYPE_SUPER (klass)
2082
                && integer_zerop (TYPE_SIZE (klass)))
2083
              {
2084
                TYPE_SIZE (klass) = NULL_TREE;
2085
                previous_alias_set = TYPE_ALIAS_SET (klass);
2086
                TYPE_ALIAS_SET (klass) = -1;
2087
              }
2088
 
2089
            if (! CLASS_LOADED_P (klass))
2090
              {
2091
                if (! CLASS_PARSED_P (klass))
2092
                  {
2093
                    read_zip_member (current_jcf, zdir, localToFile);
2094
                    jcf_parse (current_jcf);
2095
                  }
2096
                layout_class (current_class);
2097
                load_inner_classes (current_class);
2098
              }
2099
 
2100
            if (previous_alias_set != -1)
2101
              TYPE_ALIAS_SET (klass) = previous_alias_set;
2102
 
2103
            if (TYPE_SIZE (current_class) != error_mark_node)
2104
              {
2105
                parse_class_file ();
2106
                free (current_jcf->buffer); /* No longer necessary */
2107
                /* Note: there is a way to free this buffer right after a
2108
                   class seen in a zip file has been parsed. The idea is the
2109
                   set its jcf in such a way that buffer will be reallocated
2110
                   the time the code for the class will be generated. FIXME. */
2111
              }
2112
          }
2113
          break;
2114
 
2115
        case 2:
2116
          {
2117
            char *file_name, *class_name_in_zip_dir, *buffer;
2118
            JCF *jcf;
2119
            file_name = XNEWVEC (char, zdir->filename_length + 1);
2120
            class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
2121
            strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
2122
            file_name[zdir->filename_length] = '\0';
2123
            jcf = XNEW (JCF);
2124
            JCF_ZERO (jcf);
2125
            jcf->read_state  = finput;
2126
            jcf->filbuf      = jcf_filbuf_from_stdio;
2127
            jcf->classname   = NULL;
2128
            jcf->filename    = file_name;
2129
            jcf->zipd        = zdir;
2130
 
2131
            if (read_zip_member (jcf, zdir, localToFile) < 0)
2132
              fatal_error ("error while reading %s from zip file", file_name);
2133
 
2134
            buffer = XNEWVEC (char, zdir->filename_length + 1 +
2135
                            (jcf->buffer_end - jcf->buffer));
2136
            strcpy (buffer, file_name);
2137
            /* This is not a typo: we overwrite the trailing \0 of the
2138
               file name; this is just how the data is laid out.  */
2139
            memcpy (buffer + zdir->filename_length,
2140
                    jcf->buffer, jcf->buffer_end - jcf->buffer);
2141
 
2142
            compile_resource_data (file_name, buffer,
2143
                                   jcf->buffer_end - jcf->buffer);
2144
            JCF_FINISH (jcf);
2145
            free (jcf);
2146
            free (buffer);
2147
          }
2148
          break;
2149
 
2150
        default:
2151
          gcc_unreachable ();
2152
        }
2153
    }
2154
}
2155
 
2156
/* Read all the entries of the zip file, creates a class and a JCF. Sets the
2157
   jcf up for further processing and link it to the created class.  */
2158
 
2159
static void
2160
process_zip_dir (FILE *finput)
2161
{
2162
  int i;
2163
  ZipDirectory *zdir;
2164
 
2165
  for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
2166
       i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
2167
    {
2168
      char *class_name, *file_name, *class_name_in_zip_dir;
2169
      tree klass;
2170
      JCF  *jcf;
2171
 
2172
      class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
2173
 
2174
      /* Here we skip non-class files; we handle them later.  */
2175
      if (classify_zip_file (zdir) != 1)
2176
        continue;
2177
 
2178
      class_name = compute_class_name (zdir);
2179
      file_name  = XNEWVEC (char, zdir->filename_length+1);
2180
      jcf = GGC_NEW (JCF);
2181
      JCF_ZERO (jcf);
2182
 
2183
      strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
2184
      file_name [zdir->filename_length] = '\0';
2185
 
2186
      klass = lookup_class (get_identifier (class_name));
2187
 
2188
      if (CLASS_FROM_CURRENTLY_COMPILED_P (klass))
2189
        {
2190
          /* We've already compiled this class.  */
2191
          duplicate_class_warning (file_name);
2192
          continue;
2193
        }
2194
      /* This function is only called when processing a zip file seen
2195
         on the command line.  */
2196
      CLASS_FROM_CURRENTLY_COMPILED_P (klass) = 1;
2197
 
2198
      jcf->read_state  = finput;
2199
      jcf->filbuf      = jcf_filbuf_from_stdio;
2200
      jcf->classname   = class_name;
2201
      jcf->filename    = file_name;
2202
      jcf->zipd        = zdir;
2203
 
2204
      TYPE_JCF (klass) = jcf;
2205
    }
2206
}
2207
 
2208
#include "gt-java-jcf-parse.h"
2209
#include "gtype-java.h"

powered by: WebSVN 2.1.0

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