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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [java/] [jcf-parse.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
/* Parser for Java(TM) .class files.
2
   Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3
   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 2, 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 COPYING.  If not, write to
19
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20
Boston, MA 02110-1301, USA.
21
 
22
Java and all Java-based marks are trademarks or registered trademarks
23
of Sun Microsystems, Inc. in the United States and other countries.
24
The Free Software Foundation is independent of Sun Microsystems, Inc.  */
25
 
26
/* Written by Per Bothner <bothner@cygnus.com> */
27
 
28
#include "config.h"
29
#include "system.h"
30
#include "coretypes.h"
31
#include "tm.h"
32
#include "tree.h"
33
#include "real.h"
34
#include "obstack.h"
35
#include "flags.h"
36
#include "java-except.h"
37
#include "input.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
 
47
#ifdef HAVE_LOCALE_H
48
#include <locale.h>
49
#endif
50
 
51
#ifdef HAVE_LANGINFO_CODESET
52
#include <langinfo.h>
53
#endif
54
 
55
/* A CONSTANT_Utf8 element is converted to an IDENTIFIER_NODE at parse time. */
56
#define JPOOL_UTF(JCF, INDEX) CPOOL_UTF(&(JCF)->cpool, INDEX)
57
#define JPOOL_UTF_LENGTH(JCF, INDEX) IDENTIFIER_LENGTH (JPOOL_UTF (JCF, INDEX))
58
#define JPOOL_UTF_DATA(JCF, INDEX) \
59
  ((const unsigned char *) IDENTIFIER_POINTER (JPOOL_UTF (JCF, INDEX)))
60
#define HANDLE_CONSTANT_Utf8(JCF, INDEX, LENGTH) \
61
  do { \
62
    unsigned char save;  unsigned char *text; \
63
    JCF_FILL (JCF, (LENGTH)+1); /* Make sure we read 1 byte beyond string. */ \
64
    text = (JCF)->read_ptr; \
65
    save = text[LENGTH]; \
66
    text[LENGTH] = 0; \
67
    (JCF)->cpool.data[INDEX].t = get_identifier ((const char *) text); \
68
    text[LENGTH] = save; \
69
    JCF_SKIP (JCF, LENGTH); } while (0)
70
 
71
#include "jcf.h"
72
 
73
extern struct obstack temporary_obstack;
74
 
75
static GTY(()) tree parse_roots[3];
76
 
77
/* The FIELD_DECL for the current field.  */
78
#define current_field parse_roots[0]
79
 
80
/* The METHOD_DECL for the current method.  */
81
#define current_method parse_roots[1]
82
 
83
/* A list of TRANSLATION_UNIT_DECLs for the files to be compiled.  */
84
#define current_file_list parse_roots[2]
85
 
86
/* Line 0 in current file, if compiling from bytecode. */
87
static location_t file_start_location;
88
 
89
/* The Java archive that provides main_class;  the main input file. */
90
static GTY(()) struct JCF * main_jcf;
91
 
92
static struct ZipFile *localToFile;
93
 
94
/* Declarations of some functions used here.  */
95
static void handle_innerclass_attribute (int count, JCF *);
96
static tree give_name_to_class (JCF *jcf, int index);
97
static char *compute_class_name (struct ZipDirectory *zdir);
98
static int classify_zip_file (struct ZipDirectory *zdir);
99
static void parse_zip_file_entries (void);
100
static void process_zip_dir (FILE *);
101
static void parse_source_file_1 (tree, const char *, FILE *);
102
static void parse_source_file_2 (void);
103
static void parse_source_file_3 (void);
104
static void parse_class_file (void);
105
static void handle_deprecated (void);
106
static void set_source_filename (JCF *, int);
107
static void jcf_parse (struct JCF*);
108
static void load_inner_classes (tree);
109
 
110
/* Handle "Deprecated" attribute.  */
111
static void
112
handle_deprecated (void)
113
{
114
  if (current_field != NULL_TREE)
115
    FIELD_DEPRECATED (current_field) = 1;
116
  else if (current_method != NULL_TREE)
117
    METHOD_DEPRECATED (current_method) = 1;
118
  else if (current_class != NULL_TREE)
119
    CLASS_DEPRECATED (TYPE_NAME (current_class)) = 1;
120
  else
121
    {
122
      /* Shouldn't happen.  */
123
      abort ();
124
    }
125
}
126
 
127
/* Handle "SourceFile" attribute. */
128
 
129
static void
130
set_source_filename (JCF *jcf, int index)
131
{
132
  tree sfname_id = get_name_constant (jcf, index);
133
  const char *sfname = IDENTIFIER_POINTER (sfname_id);
134
  const char *old_filename = input_filename;
135
  int new_len = IDENTIFIER_LENGTH (sfname_id);
136
  if (old_filename != NULL)
137
    {
138
      int old_len = strlen (old_filename);
139
      /* Use the current input_filename (derived from the class name)
140
         if it has a directory prefix, but otherwise matches sfname. */
141
      if (old_len > new_len
142
          && strcmp (sfname, old_filename + old_len - new_len) == 0
143
          && (old_filename[old_len - new_len - 1] == '/'
144
              || old_filename[old_len - new_len - 1] == '\\'))
145
        {
146
#ifndef USE_MAPPED_LOCATION
147
          DECL_SOURCE_LOCATION (TYPE_NAME (current_class)) = input_location;
148
          file_start_location = input_location;
149
#endif
150
          return;
151
        }
152
    }
153
  if (strchr (sfname, '/') == NULL && strchr (sfname, '\\') == NULL)
154
    {
155
      const char *class_name
156
        = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class)));
157
      char *dot = strrchr (class_name, '.');
158
      if (dot != NULL)
159
        {
160
          /* Length of prefix, not counting final dot. */
161
          int i = dot - class_name;
162
          /* Concatenate current package prefix with new sfname. */
163
          char *buf = xmalloc (i + new_len + 2); /* Space for '.' and '\0'. */
164
          strcpy (buf + i + 1, sfname);
165
          /* Copy package from class_name, replacing '.' by DIR_SEPARATOR.
166
             Note we start at the end with the final package dot. */
167
          for (; i >= 0;  i--)
168
            {
169
              char c = class_name[i];
170
              if (c == '.')
171
                c = DIR_SEPARATOR;
172
              buf[i] = c;
173
            }
174
          sfname_id = get_identifier (buf);
175
          free (buf);
176
          sfname = IDENTIFIER_POINTER (sfname_id);
177
        }
178
    }
179
 
180
#ifdef USE_MAPPED_LOCATION
181
  line_table.maps[line_table.used-1].to_file = sfname;
182
#else
183
  input_filename = sfname;
184
  DECL_SOURCE_LOCATION (TYPE_NAME (current_class)) = input_location;
185
  file_start_location = input_location;
186
#endif
187
  if (current_class == main_class) main_input_filename = sfname;
188
}
189
 
190
#define HANDLE_SOURCEFILE(INDEX) set_source_filename (jcf, INDEX)
191
 
192
#define HANDLE_CLASS_INFO(ACCESS_FLAGS, THIS, SUPER, INTERFACES_COUNT) \
193
{ tree super_class = SUPER==0 ? NULL_TREE : get_class_constant (jcf, SUPER); \
194
  output_class = current_class = give_name_to_class (jcf, THIS); \
195
  set_super_info (ACCESS_FLAGS, current_class, super_class, INTERFACES_COUNT);}
196
 
197
#define HANDLE_CLASS_INTERFACE(INDEX) \
198
  add_interface (current_class, get_class_constant (jcf, INDEX))
199
 
200
#define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
201
{ int sig_index = SIGNATURE; \
202
  current_field = add_field (current_class, get_name_constant (jcf, NAME), \
203
                             parse_signature (jcf, sig_index), ACCESS_FLAGS); \
204
 set_java_signature (TREE_TYPE (current_field), JPOOL_UTF (jcf, sig_index)); \
205
 if ((ACCESS_FLAGS) & ACC_FINAL) \
206
   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (current_field); \
207
}
208
 
209
#define HANDLE_END_FIELDS() \
210
  (current_field = NULL_TREE)
211
 
212
#define HANDLE_CONSTANTVALUE(INDEX) \
213
{ tree constant;  int index = INDEX; \
214
  if (! flag_emit_class_files && JPOOL_TAG (jcf, index) == CONSTANT_String) { \
215
    tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index)); \
216
    constant = build_utf8_ref (name); \
217
  } \
218
  else \
219
    constant = get_constant (jcf, index); \
220
  set_constant_value (current_field, constant); }
221
 
222
#define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
223
 (current_method = add_method (current_class, ACCESS_FLAGS, \
224
                               get_name_constant (jcf, NAME), \
225
                               get_name_constant (jcf, SIGNATURE)), \
226
  DECL_LOCALVARIABLES_OFFSET (current_method) = 0, \
227
  DECL_LINENUMBERS_OFFSET (current_method) = 0)
228
 
229
#define HANDLE_END_METHODS() \
230
{ current_method = NULL_TREE; }
231
 
232
#define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
233
{ DECL_MAX_STACK (current_method) = (MAX_STACK); \
234
  DECL_MAX_LOCALS (current_method) = (MAX_LOCALS); \
235
  DECL_CODE_LENGTH (current_method) = (CODE_LENGTH); \
236
  DECL_CODE_OFFSET (current_method) = JCF_TELL (jcf); }
237
 
238
#define HANDLE_LOCALVARIABLETABLE_ATTRIBUTE(COUNT) \
239
{ int n = (COUNT); \
240
  DECL_LOCALVARIABLES_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
241
  JCF_SKIP (jcf, n * 10); }
242
 
243
#define HANDLE_LINENUMBERTABLE_ATTRIBUTE(COUNT) \
244
{ int n = (COUNT); \
245
  DECL_LINENUMBERS_OFFSET (current_method) = JCF_TELL (jcf) - 2; \
246
  JCF_SKIP (jcf, n * 4); }
247
 
248
#define HANDLE_EXCEPTIONS_ATTRIBUTE(COUNT) \
249
{ \
250
  int n = COUNT; \
251
  tree list = DECL_FUNCTION_THROWS (current_method); \
252
  while (--n >= 0) \
253
    { \
254
      tree thrown_class = get_class_constant (jcf, JCF_readu2 (jcf)); \
255
      list = tree_cons (NULL_TREE, thrown_class, list); \
256
    } \
257
  DECL_FUNCTION_THROWS (current_method) = nreverse (list); \
258
}
259
 
260
#define HANDLE_DEPRECATED_ATTRIBUTE()  handle_deprecated ()
261
 
262
/* Link seen inner classes to their outer context and register the
263
   inner class to its outer context. They will be later loaded.  */
264
#define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) \
265
  handle_innerclass_attribute (COUNT, jcf)
266
 
267
#define HANDLE_SYNTHETIC_ATTRIBUTE()                                    \
268
{                                                                       \
269
  /* Irrelevant decls should have been nullified by the END macros.     \
270
     We only handle the `Synthetic' attribute on method DECLs.          \
271
     DECL_ARTIFICIAL on fields is used for something else (See          \
272
     PUSH_FIELD in java-tree.h) */                                      \
273
  if (current_method)                                                   \
274
    DECL_ARTIFICIAL (current_method) = 1;                               \
275
}
276
 
277
#define HANDLE_GCJCOMPILED_ATTRIBUTE()          \
278
{                                               \
279
  if (current_class == object_type_node)        \
280
    jcf->right_zip = 1;                         \
281
}
282
 
283
#include "jcf-reader.c"
284
 
285
tree
286
parse_signature (JCF *jcf, int sig_index)
287
{
288
  if (sig_index <= 0 || sig_index >= JPOOL_SIZE (jcf)
289
      || JPOOL_TAG (jcf, sig_index) != CONSTANT_Utf8)
290
    abort ();
291
  else
292
    return parse_signature_string (JPOOL_UTF_DATA (jcf, sig_index),
293
                                   JPOOL_UTF_LENGTH (jcf, sig_index));
294
}
295
 
296
tree
297
get_constant (JCF *jcf, int index)
298
{
299
  tree value;
300
  int tag;
301
  if (index <= 0 || index >= JPOOL_SIZE(jcf))
302
    goto bad;
303
  tag = JPOOL_TAG (jcf, index);
304
  if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
305
    return jcf->cpool.data[index].t;
306
  switch (tag)
307
    {
308
    case CONSTANT_Integer:
309
      {
310
        jint num = JPOOL_INT(jcf, index);
311
        value = build_int_cst (int_type_node, num);
312
        break;
313
      }
314
    case CONSTANT_Long:
315
      {
316
        unsigned HOST_WIDE_INT num = JPOOL_UINT (jcf, index);
317
        unsigned HOST_WIDE_INT lo;
318
        HOST_WIDE_INT hi;
319
 
320
        lshift_double (num, 0, 32, 64, &lo, &hi, 0);
321
        num = JPOOL_UINT (jcf, index+1);
322
        add_double (lo, hi, num, 0, &lo, &hi);
323
        value = build_int_cst_wide (long_type_node, lo, hi);
324
        value = force_fit_type (value, 0, false, false);
325
        break;
326
      }
327
 
328
    case CONSTANT_Float:
329
      {
330
        jint num = JPOOL_INT(jcf, index);
331
        long buf = num;
332
        REAL_VALUE_TYPE d;
333
 
334
        real_from_target_fmt (&d, &buf, &ieee_single_format);
335
        value = build_real (float_type_node, d);
336
        break;
337
      }
338
 
339
    case CONSTANT_Double:
340
      {
341
        long buf[2], lo, hi;
342
        REAL_VALUE_TYPE d;
343
 
344
        hi = JPOOL_UINT (jcf, index);
345
        lo = JPOOL_UINT (jcf, index+1);
346
 
347
        if (FLOAT_WORDS_BIG_ENDIAN)
348
          buf[0] = hi, buf[1] = lo;
349
        else
350
          buf[0] = lo, buf[1] = hi;
351
 
352
        real_from_target_fmt (&d, buf, &ieee_double_format);
353
        value = build_real (double_type_node, d);
354
        break;
355
      }
356
 
357
    case CONSTANT_String:
358
      {
359
        tree name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
360
        const char *utf8_ptr = IDENTIFIER_POINTER (name);
361
        int utf8_len = IDENTIFIER_LENGTH (name);
362
        const unsigned char *utf8;
363
        int i;
364
 
365
        /* Check for a malformed Utf8 string.  */
366
        utf8 = (const unsigned char *) utf8_ptr;
367
        i = utf8_len;
368
        while (i > 0)
369
          {
370
            int char_len = UT8_CHAR_LENGTH (*utf8);
371
            if (char_len < 0 || char_len > 3 || char_len > i)
372
              fatal_error ("bad string constant");
373
 
374
            utf8 += char_len;
375
            i -= char_len;
376
          }
377
 
378
        /* Allocate a new string value.  */
379
        value = build_string (utf8_len, utf8_ptr);
380
        TREE_TYPE (value) = build_pointer_type (string_type_node);
381
      }
382
      break;
383
    default:
384
      goto bad;
385
    }
386
  JPOOL_TAG (jcf, index) = tag | CONSTANT_ResolvedFlag;
387
  jcf->cpool.data[index].t = value;
388
  return value;
389
 bad:
390
  internal_error ("bad value constant type %d, index %d",
391
                  JPOOL_TAG (jcf, index), index);
392
}
393
 
394
tree
395
get_name_constant (JCF *jcf, int index)
396
{
397
  tree name = get_constant (jcf, index);
398
 
399
  if (TREE_CODE (name) != IDENTIFIER_NODE)
400
    abort ();
401
 
402
  return name;
403
}
404
 
405
/* Handle reading innerclass attributes. If a nonzero entry (denoting
406
   a non anonymous entry) is found, We augment the inner class list of
407
   the outer context with the newly resolved innerclass.  */
408
 
409
static void
410
handle_innerclass_attribute (int count, JCF *jcf)
411
{
412
  int c = (count);
413
  while (c--)
414
    {
415
      /* Read inner_class_info_index. This may be 0 */
416
      int icii = JCF_readu2 (jcf);
417
      /* Read outer_class_info_index. If the innerclasses attribute
418
         entry isn't a member (like an inner class) the value is 0. */
419
      int ocii = JCF_readu2 (jcf);
420
      /* Read inner_name_index. If the class we're dealing with is
421
         an anonymous class, it must be 0. */
422
      int ini = JCF_readu2 (jcf);
423
      /* Read the access flag. */
424
      int acc = JCF_readu2 (jcf);
425
      /* If icii is 0, don't try to read the class. */
426
      if (icii >= 0)
427
        {
428
          tree class = get_class_constant (jcf, icii);
429
          tree decl = TYPE_NAME (class);
430
          /* Skip reading further if ocii is null */
431
          if (DECL_P (decl) && !CLASS_COMPLETE_P (decl) && ocii)
432
            {
433
              tree outer = TYPE_NAME (get_class_constant (jcf, ocii));
434
              tree alias = (ini ? get_name_constant (jcf, ini) : NULL_TREE);
435
              set_class_decl_access_flags (acc, decl);
436
              DECL_CONTEXT (decl) = outer;
437
              DECL_INNER_CLASS_LIST (outer) =
438
                tree_cons (decl, alias, DECL_INNER_CLASS_LIST (outer));
439
              CLASS_COMPLETE_P (decl) = 1;
440
            }
441
        }
442
    }
443
}
444
 
445
static tree
446
give_name_to_class (JCF *jcf, int i)
447
{
448
  if (i <= 0 || i >= JPOOL_SIZE (jcf)
449
      || JPOOL_TAG (jcf, i) != CONSTANT_Class)
450
    abort ();
451
  else
452
    {
453
      tree package_name = NULL_TREE, tmp;
454
      tree this_class;
455
      int j = JPOOL_USHORT1 (jcf, i);
456
      /* verify_constant_pool confirmed that j is a CONSTANT_Utf8. */
457
      tree class_name = unmangle_classname ((const char *) JPOOL_UTF_DATA (jcf, j),
458
                                            JPOOL_UTF_LENGTH (jcf, j));
459
      this_class = lookup_class (class_name);
460
#ifdef USE_MAPPED_LOCATION
461
      {
462
      tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
463
      const char *sfname = IDENTIFIER_POINTER (source_name);
464
      linemap_add (&line_table, LC_ENTER, false, sfname, 0);
465
      input_location = linemap_line_start (&line_table, 0, 1);
466
      file_start_location = input_location;
467
      DECL_SOURCE_LOCATION (TYPE_NAME (this_class)) = input_location;
468
      if (main_input_filename == NULL && jcf == main_jcf)
469
        main_input_filename = sfname;
470
      }
471
#else
472
      input_location = DECL_SOURCE_LOCATION (TYPE_NAME (this_class));
473
      if (main_input_filename == NULL && jcf == main_jcf)
474
        main_input_filename = input_filename;
475
#endif
476
 
477
      jcf->cpool.data[i].t = this_class;
478
      JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
479
      split_qualified_name (&package_name, &tmp,
480
                            DECL_NAME (TYPE_NAME (this_class)));
481
      TYPE_PACKAGE (this_class) = package_name;
482
      return this_class;
483
    }
484
}
485
 
486
/* Get the class of the CONSTANT_Class whose constant pool index is I. */
487
 
488
tree
489
get_class_constant (JCF *jcf, int i)
490
{
491
  tree type;
492
  if (i <= 0 || i >= JPOOL_SIZE (jcf)
493
      || (JPOOL_TAG (jcf, i) & ~CONSTANT_ResolvedFlag) != CONSTANT_Class)
494
    abort ();
495
 
496
  if (JPOOL_TAG (jcf, i) != CONSTANT_ResolvedClass)
497
    {
498
      int name_index = JPOOL_USHORT1 (jcf, i);
499
      /* verify_constant_pool confirmed that name_index is a CONSTANT_Utf8. */
500
      const char *name = (const char *) JPOOL_UTF_DATA (jcf, name_index);
501
      int nlength = JPOOL_UTF_LENGTH (jcf, name_index);
502
 
503
      if (name[0] == '[')  /* Handle array "classes". */
504
          type = TREE_TYPE (parse_signature_string ((const unsigned char *) name, nlength));
505
      else
506
        {
507
          tree cname = unmangle_classname (name, nlength);
508
          type = lookup_class (cname);
509
        }
510
      jcf->cpool.data[i].t = type;
511
      JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
512
    }
513
  else
514
    type = jcf->cpool.data[i].t;
515
  return type;
516
}
517
 
518
/* Read a class with the fully qualified-name NAME.
519
   Return 1 iff we read the requested file.
520
   (It is still possible we failed if the file did not
521
   define the class it is supposed to.) */
522
 
523
int
524
read_class (tree name)
525
{
526
  JCF this_jcf, *jcf;
527
  tree icv, class = NULL_TREE;
528
  tree save_current_class = current_class;
529
  tree save_output_class = output_class;
530
  location_t save_location = input_location;
531
  JCF *save_current_jcf = current_jcf;
532
 
533
  if ((icv = IDENTIFIER_CLASS_VALUE (name)) != NULL_TREE)
534
    {
535
      class = TREE_TYPE (icv);
536
      jcf = TYPE_JCF (class);
537
    }
538
  else
539
    jcf = NULL;
540
 
541
  if (jcf == NULL)
542
    {
543
      const char* path_name;
544
      this_jcf.zipd = NULL;
545
      jcf = &this_jcf;
546
 
547
      path_name = find_class (IDENTIFIER_POINTER (name),
548
                              IDENTIFIER_LENGTH (name),
549
                              &this_jcf, 1);
550
      if (path_name == 0)
551
        return 0;
552
      else
553
        free((char *) path_name);
554
    }
555
 
556
  current_jcf = jcf;
557
 
558
  if (current_jcf->java_source)
559
    {
560
      const char *filename = current_jcf->filename;
561
      char *real_path;
562
      tree given_file, real_file;
563
      FILE *finput;
564
      int generate;
565
 
566
      java_parser_context_save_global ();
567
      java_push_parser_context ();
568
 
569
      given_file = get_identifier (filename);
570
      filename = IDENTIFIER_POINTER (given_file);
571
      real_path = lrealpath (filename);
572
      real_file = get_identifier (real_path);
573
      free (real_path);
574
 
575
      generate = IS_A_COMMAND_LINE_FILENAME_P (given_file);
576
      output_class = current_class = NULL_TREE;
577
      current_function_decl = NULL_TREE;
578
 
579
      if (! HAS_BEEN_ALREADY_PARSED_P (real_file))
580
        {
581
          if (! (finput = fopen (filename, "r")))
582
            fatal_error ("can't reopen %s: %m", filename);
583
 
584
          parse_source_file_1 (real_file, filename, finput);
585
          parse_source_file_2 ();
586
          parse_source_file_3 ();
587
 
588
          if (fclose (finput))
589
            fatal_error ("can't close %s: %m", input_filename);
590
#ifdef USE_MAPPED_LOCATION
591
          linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
592
#endif
593
        }
594
      JCF_FINISH (current_jcf);
595
      java_pop_parser_context (generate);
596
      java_parser_context_restore_global ();
597
    }
598
  else
599
    {
600
      if (class == NULL_TREE || ! CLASS_PARSED_P (class))
601
        {
602
          java_parser_context_save_global ();
603
          java_push_parser_context ();
604
          output_class = current_class = class;
605
          ctxp->save_location = input_location;
606
          if (JCF_SEEN_IN_ZIP (current_jcf))
607
            read_zip_member(current_jcf,
608
                            current_jcf->zipd, current_jcf->zipd->zipf);
609
          jcf_parse (current_jcf);
610
          /* Parsing might change the class, in which case we have to
611
             put it back where we found it.  */
612
          if (current_class != class && icv != NULL_TREE)
613
            TREE_TYPE (icv) = current_class;
614
          class = current_class;
615
          java_pop_parser_context (0);
616
          java_parser_context_restore_global ();
617
        }
618
      layout_class (class);
619
      load_inner_classes (class);
620
    }
621
 
622
  output_class = save_output_class;
623
  current_class = save_current_class;
624
  input_location = save_location;
625
  current_jcf = save_current_jcf;
626
  return 1;
627
}
628
 
629
/* Load CLASS_OR_NAME. CLASS_OR_NAME can be a mere identifier if
630
   called from the parser, otherwise it's a RECORD_TYPE node. If
631
   VERBOSE is 1, print error message on failure to load a class. */
632
void
633
load_class (tree class_or_name, int verbose)
634
{
635
  tree name, saved;
636
  int class_loaded = 0;
637
  tree class_decl = NULL_TREE;
638
  bool is_compiled_class = false;
639
 
640
  /* We've already failed, don't try again.  */
641
  if (TREE_CODE (class_or_name) == RECORD_TYPE
642
      && TYPE_DUMMY (class_or_name))
643
    return;
644
 
645
  /* class_or_name can be the name of the class we want to load */
646
  if (TREE_CODE (class_or_name) == IDENTIFIER_NODE)
647
    name = class_or_name;
648
  /* In some cases, it's a dependency that we process earlier that
649
     we though */
650
  else if (TREE_CODE (class_or_name) == TREE_LIST)
651
    name = TYPE_NAME (TREE_PURPOSE (class_or_name));
652
  /* Or it's a type in the making */
653
  else
654
    name = DECL_NAME (TYPE_NAME (class_or_name));
655
 
656
  class_decl = IDENTIFIER_CLASS_VALUE (name);
657
  if (class_decl != NULL_TREE)
658
    {
659
      tree type = TREE_TYPE (class_decl);
660
      is_compiled_class
661
        = ((TYPE_JCF (type) && JCF_SEEN_IN_ZIP (TYPE_JCF (type)))
662
           || CLASS_FROM_CURRENTLY_COMPILED_P (type));
663
    }
664
 
665
  /* If the class is from source code, then it must already be loaded.  */
666
  class_decl = IDENTIFIER_CLASS_VALUE (name);
667
  if (class_decl && CLASS_FROM_SOURCE_P (TREE_TYPE (class_decl)))
668
    return;
669
 
670
  saved = name;
671
 
672
  /* If flag_verify_invocations is unset, we don't try to load a class
673
     unless we're looking for Object (which is fixed by the ABI) or
674
     it's a class that we're going to compile.  */
675
  if (flag_verify_invocations
676
      || class_or_name == object_type_node
677
      || is_compiled_class
678
      || TREE_CODE (class_or_name) == IDENTIFIER_NODE)
679
    {
680
      while (1)
681
        {
682
          char *separator;
683
 
684
          /* We've already loaded it.  */
685
          if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE)
686
            {
687
              tree tmp_decl = IDENTIFIER_CLASS_VALUE (name);
688
              if (CLASS_PARSED_P (TREE_TYPE (tmp_decl)))
689
                break;
690
            }
691
 
692
          if (read_class (name))
693
            break;
694
 
695
          /* We failed loading name. Now consider that we might be looking
696
             for an inner class.  */
697
          if ((separator = strrchr (IDENTIFIER_POINTER (name), '$'))
698
              || (separator = strrchr (IDENTIFIER_POINTER (name), '.')))
699
            {
700
              int c = *separator;
701
              *separator = '\0';
702
              name = get_identifier (IDENTIFIER_POINTER (name));
703
              *separator = c;
704
            }
705
          /* Otherwise, we failed, we bail. */
706
          else
707
            break;
708
        }
709
 
710
      {
711
        /* have we found the class we're looking for?  */
712
        tree type_decl = IDENTIFIER_CLASS_VALUE (saved);
713
        tree type = type_decl ? TREE_TYPE (type_decl) : NULL;
714
        class_loaded = type && CLASS_PARSED_P (type);
715
      }
716
    }
717
 
718
  if (!class_loaded)
719
    {
720
      if (flag_verify_invocations || ! flag_indirect_dispatch
721
          || flag_emit_class_files)
722
        {
723
          if (verbose)
724
            error ("cannot find file for class %s", IDENTIFIER_POINTER (saved));
725
        }
726
      else if (verbose)
727
        {
728
          /* This is just a diagnostic during testing, not a real problem.  */
729
          if (!quiet_flag)
730
            warning (0, "cannot find file for class %s",
731
                     IDENTIFIER_POINTER (saved));
732
 
733
          /* Fake it.  */
734
          if (TREE_CODE (class_or_name) == RECORD_TYPE)
735
            {
736
              set_super_info (0, class_or_name, object_type_node, 0);
737
              TYPE_DUMMY (class_or_name) = 1;
738
              /* We won't be able to output any debug info for this class.  */
739
              DECL_IGNORED_P (TYPE_NAME (class_or_name)) = 1;
740
            }
741
        }
742
    }
743
}
744
 
745
/* Parse the .class file JCF. */
746
 
747
static void
748
jcf_parse (JCF* jcf)
749
{
750
  int i, code;
751
 
752
  if (jcf_parse_preamble (jcf) != 0)
753
    fatal_error ("not a valid Java .class file");
754
  code = jcf_parse_constant_pool (jcf);
755
  if (code != 0)
756
    fatal_error ("error while parsing constant pool");
757
  code = verify_constant_pool (jcf);
758
  if (code > 0)
759
    fatal_error ("error in constant pool entry #%d\n", code);
760
 
761
  jcf_parse_class (jcf);
762
  if (main_class == NULL_TREE)
763
    main_class = current_class;
764
  if (! quiet_flag && TYPE_NAME (current_class))
765
    fprintf (stderr, " %s %s",
766
             (jcf->access_flags & ACC_INTERFACE) ? "interface" : "class",
767
             IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
768
  if (CLASS_PARSED_P (current_class))
769
    {
770
      /* FIXME - where was first time */
771
      fatal_error ("reading class %s for the second time from %s",
772
                   IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))),
773
                   jcf->filename);
774
    }
775
  CLASS_PARSED_P (current_class) = 1;
776
 
777
  for (i = 1; i < JPOOL_SIZE(jcf); i++)
778
    {
779
      switch (JPOOL_TAG (jcf, i))
780
        {
781
        case CONSTANT_Class:
782
          get_class_constant (jcf, i);
783
          break;
784
        }
785
    }
786
 
787
  code = jcf_parse_fields (jcf);
788
  if (code != 0)
789
    fatal_error ("error while parsing fields");
790
  code = jcf_parse_methods (jcf);
791
  if (code != 0)
792
    fatal_error ("error while parsing methods");
793
  code = jcf_parse_final_attributes (jcf);
794
  if (code != 0)
795
    fatal_error ("error while parsing final attributes");
796
#ifdef USE_MAPPED_LOCATION
797
  linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
798
#endif
799
 
800
  /* The fields of class_type_node are already in correct order. */
801
  if (current_class != class_type_node && current_class != object_type_node)
802
    TYPE_FIELDS (current_class) = nreverse (TYPE_FIELDS (current_class));
803
 
804
  if (current_class == object_type_node)
805
    {
806
      layout_class_methods (object_type_node);
807
      /* If we don't have the right archive, emit a verbose warning.
808
         If we're generating bytecode, emit the warning only if
809
         -fforce-classes-archive-check was specified. */
810
      if (!jcf->right_zip
811
          && (!flag_emit_class_files || flag_force_classes_archive_check))
812
        fatal_error ("the %<java.lang.Object%> that was found in %qs didn't have the special zero-length %<gnu.gcj.gcj-compiled%> attribute.  This generally means that your classpath is incorrectly set.  Use %<info gcj \"Input Options\"%> to see the info page describing how to set the classpath", jcf->filename);
813
    }
814
  else
815
    all_class_list = tree_cons (NULL_TREE,
816
                                TYPE_NAME (current_class), all_class_list );
817
}
818
 
819
/* If we came across inner classes, load them now. */
820
static void
821
load_inner_classes (tree cur_class)
822
{
823
  tree current;
824
  for (current = DECL_INNER_CLASS_LIST (TYPE_NAME (cur_class)); current;
825
       current = TREE_CHAIN (current))
826
    {
827
      tree name = DECL_NAME (TREE_PURPOSE (current));
828
      tree decl = IDENTIFIER_GLOBAL_VALUE (name);
829
      if (decl && ! CLASS_LOADED_P (TREE_TYPE (decl))
830
          && !CLASS_BEING_LAIDOUT (TREE_TYPE (decl)))
831
        load_class (name, 1);
832
    }
833
}
834
 
835
static void
836
duplicate_class_warning (const char *filename)
837
{
838
  location_t warn_loc;
839
#ifdef USE_MAPPED_LOCATION
840
  linemap_add (&line_table, LC_RENAME, 0, filename, 0);
841
  warn_loc = linemap_line_start (&line_table, 0, 1);
842
#else
843
  warn_loc.file = filename;
844
  warn_loc.line = 0;
845
#endif
846
  warning (0, "%Hduplicate class will only be compiled once", &warn_loc);
847
}
848
 
849
static void
850
parse_class_file (void)
851
{
852
  tree method;
853
  location_t save_location = input_location;
854
 
855
  java_layout_seen_class_methods ();
856
 
857
  input_location = DECL_SOURCE_LOCATION (TYPE_NAME (current_class));
858
  file_start_location = input_location;
859
  (*debug_hooks->start_source_file) (input_line, input_filename);
860
 
861
  gen_indirect_dispatch_tables (current_class);
862
 
863
  java_mark_class_local (current_class);
864
 
865
  for (method = TYPE_METHODS (current_class);
866
       method != NULL_TREE; method = TREE_CHAIN (method))
867
    {
868
      JCF *jcf = current_jcf;
869
 
870
      if (METHOD_ABSTRACT (method) || METHOD_DUMMY (method))
871
        continue;
872
 
873
      if (METHOD_NATIVE (method))
874
        {
875
          tree arg;
876
          int  decl_max_locals;
877
 
878
          if (! flag_jni)
879
            continue;
880
          /* We need to compute the DECL_MAX_LOCALS. We need to take
881
             the wide types into account too. */
882
          for (arg = TYPE_ARG_TYPES (TREE_TYPE (method)), decl_max_locals = 0;
883
               arg != end_params_node;
884
               arg = TREE_CHAIN (arg), decl_max_locals += 1)
885
            {
886
              if (TREE_VALUE (arg) && TYPE_IS_WIDE (TREE_VALUE (arg)))
887
                decl_max_locals += 1;
888
            }
889
          DECL_MAX_LOCALS (method) = decl_max_locals;
890
          start_java_method (method);
891
          give_name_to_locals (jcf);
892
          *get_stmts () = build_jni_stub (method);
893
          end_java_method ();
894
          continue;
895
        }
896
 
897
      if (DECL_CODE_OFFSET (method) == 0)
898
        {
899
          current_function_decl = method;
900
          error ("missing Code attribute");
901
          continue;
902
        }
903
 
904
      input_location = DECL_SOURCE_LOCATION (TYPE_NAME (current_class));
905
      if (DECL_LINENUMBERS_OFFSET (method))
906
        {
907
          int i;
908
          int min_line = 0;
909
          unsigned char *ptr;
910
          JCF_SEEK (jcf, DECL_LINENUMBERS_OFFSET (method));
911
          linenumber_count = i = JCF_readu2 (jcf);
912
          linenumber_table = ptr = jcf->read_ptr;
913
 
914
          for (ptr += 2; --i >= 0; ptr += 4)
915
            {
916
              int line = GET_u2 (ptr);
917
              /* Set initial input_line to smallest linenumber.
918
               * Needs to be set before init_function_start. */
919
              if (min_line == 0 || line < min_line)
920
                min_line = line;
921
            }
922
#ifdef USE_MAPPED_LOCATION
923
          if (min_line != 0)
924
            input_location = linemap_line_start (&line_table, min_line, 1);
925
#else
926
          if (min_line != 0)
927
            input_line = min_line;
928
#endif
929
        }
930
      else
931
        {
932
          linenumber_table = NULL;
933
          linenumber_count = 0;
934
        }
935
 
936
      start_java_method (method);
937
 
938
      note_instructions (jcf, method);
939
 
940
      give_name_to_locals (jcf);
941
 
942
      /* Bump up start_label_pc_this_method so we get a unique label number
943
         and reset highest_label_pc_this_method. */
944
      if (highest_label_pc_this_method >= 0)
945
        {
946
          /* We adjust to the next multiple of 1000.  This is just a frill
947
             so the last 3 digits of the label number match the bytecode
948
             offset, which might make debugging marginally more convenient. */
949
          start_label_pc_this_method
950
            = ((((start_label_pc_this_method + highest_label_pc_this_method)
951
                 / 1000)
952
                + 1)
953
               * 1000);
954
          highest_label_pc_this_method = -1;
955
        }
956
 
957
      /* Convert bytecode to trees.  */
958
      expand_byte_code (jcf, method);
959
 
960
      end_java_method ();
961
    }
962
 
963
  if (flag_emit_class_files)
964
    write_classfile (current_class);
965
 
966
  finish_class ();
967
 
968
  (*debug_hooks->end_source_file) (LOCATION_LINE (save_location));
969
  input_location = save_location;
970
}
971
 
972
/* Parse a source file, as pointed by the current value of INPUT_FILENAME. */
973
 
974
static void
975
parse_source_file_1 (tree real_file, const char *filename, FILE *finput)
976
{
977
  int save_error_count = java_error_count;
978
 
979
  /* Mark the file as parsed.  */
980
  HAS_BEEN_ALREADY_PARSED_P (real_file) = 1;
981
 
982
  lang_init_source (1);             /* Error msgs have no method prototypes */
983
 
984
  /* There's no point in trying to find the current encoding unless we
985
     are going to do something intelligent with it -- hence the test
986
     for iconv.  */
987
#if defined (HAVE_LOCALE_H) && defined (HAVE_ICONV) && defined (HAVE_LANGINFO_CODESET)
988
  setlocale (LC_CTYPE, "");
989
  if (current_encoding == NULL)
990
    current_encoding = nl_langinfo (CODESET);
991
#endif 
992
  if (current_encoding == NULL || *current_encoding == '\0')
993
    current_encoding = DEFAULT_ENCODING;
994
 
995
#ifdef USE_MAPPED_LOCATION
996
  linemap_add (&line_table, LC_ENTER, false, filename, 0);
997
  input_location = linemap_line_start (&line_table, 0, 125);
998
#else
999
  input_filename = filename;
1000
  input_line = 0;
1001
#endif
1002
  ctxp->file_start_location = input_location;
1003
  ctxp->filename = filename;
1004
 
1005
  jcf_dependency_add_file (input_filename, 0);
1006
 
1007
  /* Initialize the parser */
1008
  java_init_lex (finput, current_encoding);
1009
  java_parse_abort_on_error ();
1010
 
1011
  java_parse ();                    /* Parse and build partial tree nodes. */
1012
  java_parse_abort_on_error ();
1013
}
1014
 
1015
/* Process a parsed source file, resolving names etc. */
1016
 
1017
static void
1018
parse_source_file_2 (void)
1019
{
1020
  int save_error_count = java_error_count;
1021
  flag_verify_invocations = true;
1022
  java_complete_class ();           /* Parse unsatisfied class decl. */
1023
  java_parse_abort_on_error ();
1024
}
1025
 
1026
static void
1027
parse_source_file_3 (void)
1028
{
1029
  int save_error_count = java_error_count;
1030
  java_check_circular_reference (); /* Check on circular references */
1031
  java_parse_abort_on_error ();
1032
  java_fix_constructors ();         /* Fix the constructors */
1033
  java_parse_abort_on_error ();
1034
  java_reorder_fields ();           /* Reorder the fields */
1035
}
1036
 
1037
void
1038
add_predefined_file (tree name)
1039
{
1040
  predef_filenames = tree_cons (NULL_TREE, name, predef_filenames);
1041
}
1042
 
1043
int
1044
predefined_filename_p (tree node)
1045
{
1046
  tree iter;
1047
 
1048
  for (iter = predef_filenames; iter != NULL_TREE; iter = TREE_CHAIN (iter))
1049
    {
1050
      if (TREE_VALUE (iter) == node)
1051
        return 1;
1052
    }
1053
  return 0;
1054
}
1055
 
1056
/* Generate a function that does all static initialization for this
1057
   translation unit.  */
1058
 
1059
static void
1060
java_emit_static_constructor (void)
1061
{
1062
  tree body = NULL;
1063
 
1064
  emit_register_classes (&body);
1065
  write_resource_constructor (&body);
1066
 
1067
  if (body)
1068
    cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY);
1069
}
1070
 
1071
void
1072
java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
1073
{
1074
  int filename_count = 0;
1075
  location_t save_location = input_location;
1076
  char *file_list = NULL, *list, *next;
1077
  tree node;
1078
  FILE *finput = NULL;
1079
  int in_quotes = 0;
1080
 
1081
  if (flag_filelist_file)
1082
    {
1083
      int avail = 2000;
1084
      finput = fopen (main_input_filename, "r");
1085
      if (finput == NULL)
1086
        fatal_error ("can't open %s: %m", input_filename);
1087
      list = xmalloc(avail);
1088
      next = list;
1089
      for (;;)
1090
        {
1091
          int count;
1092
          if (avail < 500)
1093
            {
1094
              count = next - list;
1095
              avail = 2 * (count + avail);
1096
              list = xrealloc (list, avail);
1097
              next = list + count;
1098
              avail = avail - count;
1099
            }
1100
          /* Subtract to to guarantee space for final '\0'. */
1101
          count = fread (next, 1, avail - 1, finput);
1102
          if (count == 0)
1103
            {
1104
              if (! feof (finput))
1105
                fatal_error ("error closing %s: %m", input_filename);
1106
              *next = '\0';
1107
              break;
1108
            }
1109
          avail -= count;
1110
          next += count;
1111
        }
1112
      fclose (finput);
1113
      finput = NULL;
1114
      file_list = list;
1115
    }
1116
  else
1117
    list = (char *) main_input_filename;
1118
 
1119
  while (list)
1120
    {
1121
      for (next = list; ; )
1122
        {
1123
          char ch = *next;
1124
          if (flag_filelist_file && ! in_quotes
1125
              && (ch == '\n' || ch == '\r' || ch == '\t' || ch == ' '
1126
                  || ch == '&') /* FIXME */)
1127
            {
1128
              if (next == list)
1129
                {
1130
                  next++;
1131
                  list = next;
1132
                  continue;
1133
                }
1134
              else
1135
                {
1136
                  *next++ = '\0';
1137
                  break;
1138
                }
1139
            }
1140
          if (flag_filelist_file && ch == '"')
1141
            {
1142
              in_quotes = ! in_quotes;
1143
              *next++ = '\0';
1144
              if (in_quotes)
1145
                list = next;
1146
              else
1147
                break;
1148
            }
1149
          if (ch == '\0')
1150
            {
1151
              next = NULL;
1152
              break;
1153
            }
1154
          next++;
1155
        }
1156
 
1157
      if (list[0])
1158
        {
1159
          node = get_identifier (list);
1160
 
1161
          filename_count++;
1162
 
1163
          /* Exclude file that we see twice on the command line. */
1164
 
1165
          if (IS_A_COMMAND_LINE_FILENAME_P (node))
1166
            duplicate_class_warning (IDENTIFIER_POINTER (node));
1167
          else
1168
            {
1169
              tree file_decl = build_decl (TRANSLATION_UNIT_DECL, node, NULL);
1170
              TREE_CHAIN (file_decl) = current_file_list;
1171
              current_file_list = file_decl;
1172
              IS_A_COMMAND_LINE_FILENAME_P (node) = 1;
1173
            }
1174
        }
1175
      list = next;
1176
    }
1177
 
1178
  if (file_list != NULL)
1179
    free (file_list);
1180
 
1181
  if (filename_count == 0)
1182
    warning (0, "no input file specified");
1183
 
1184
  if (resource_name)
1185
    {
1186
      const char *resource_filename;
1187
 
1188
      /* Only one resource file may be compiled at a time.  */
1189
      assert (TREE_CHAIN (current_file_list) == NULL);
1190
 
1191
      resource_filename = IDENTIFIER_POINTER (DECL_NAME (current_file_list));
1192
      compile_resource_file (resource_name, resource_filename);
1193
 
1194
      goto finish;
1195
    }
1196
 
1197
  current_jcf = main_jcf;
1198
  current_file_list = nreverse (current_file_list);
1199
  for (node = current_file_list; node; node = TREE_CHAIN (node))
1200
    {
1201
      unsigned char magic_string[4];
1202
      char *real_path;
1203
      uint32 magic = 0;
1204
      tree name = DECL_NAME (node);
1205
      tree real_file;
1206
      const char *filename = IDENTIFIER_POINTER (name);
1207
 
1208
      /* Skip already parsed files */
1209
      real_path = lrealpath (filename);
1210
      real_file = get_identifier (real_path);
1211
      free (real_path);
1212
      if (HAS_BEEN_ALREADY_PARSED_P (real_file))
1213
        continue;
1214
 
1215
      /* Close previous descriptor, if any */
1216
      if (finput && fclose (finput))
1217
        fatal_error ("can't close input file %s: %m", main_input_filename);
1218
 
1219
      finput = fopen (filename, "rb");
1220
      if (finput == NULL)
1221
        fatal_error ("can't open %s: %m", filename);
1222
 
1223
#ifdef IO_BUFFER_SIZE
1224
      setvbuf (finput, xmalloc (IO_BUFFER_SIZE),
1225
               _IOFBF, IO_BUFFER_SIZE);
1226
#endif
1227
 
1228
      /* Figure what kind of file we're dealing with */
1229
      if (fread (magic_string, 1, 4, finput) == 4)
1230
        {
1231
          fseek (finput, 0L, SEEK_SET);
1232
          magic = GET_u4 (magic_string);
1233
        }
1234
      if (magic == 0xcafebabe)
1235
        {
1236
          CLASS_FILE_P (node) = 1;
1237
          current_jcf = ggc_alloc (sizeof (JCF));
1238
          JCF_ZERO (current_jcf);
1239
          current_jcf->read_state = finput;
1240
          current_jcf->filbuf = jcf_filbuf_from_stdio;
1241
          jcf_parse (current_jcf);
1242
          DECL_SOURCE_LOCATION (node) = file_start_location;
1243
          TYPE_JCF (current_class) = current_jcf;
1244
          if (CLASS_FROM_CURRENTLY_COMPILED_P (current_class))
1245
            {
1246
              /* We've already compiled this class.  */
1247
              duplicate_class_warning (filename);
1248
              continue;
1249
            }
1250
          CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
1251
          TREE_TYPE (node) = current_class;
1252
        }
1253
      else if (magic == (JCF_u4)ZIPMAGIC)
1254
        {
1255
          main_jcf = ggc_alloc (sizeof (JCF));
1256
          JCF_ZERO (main_jcf);
1257
          main_jcf->read_state = finput;
1258
          main_jcf->filbuf = jcf_filbuf_from_stdio;
1259
#ifdef USE_MAPPED_LOCATION
1260
          linemap_add (&line_table, LC_ENTER, false, filename, 0);
1261
          input_location = linemap_line_start (&line_table, 0, 1);
1262
#endif
1263
          if (open_in_zip (main_jcf, filename, NULL, 0) <  0)
1264
            fatal_error ("bad zip/jar file %s", filename);
1265
          localToFile = SeenZipFiles;
1266
          /* Register all the classes defined there.  */
1267
          process_zip_dir (main_jcf->read_state);
1268
#ifdef USE_MAPPED_LOCATION
1269
          linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
1270
#endif
1271
          parse_zip_file_entries ();
1272
        }
1273
      else
1274
        {
1275
          java_push_parser_context ();
1276
          java_parser_context_save_global ();
1277
 
1278
          parse_source_file_1 (real_file, filename, finput);
1279
          java_parser_context_restore_global ();
1280
          java_pop_parser_context (1);
1281
#ifdef USE_MAPPED_LOCATION
1282
          linemap_add (&line_table, LC_LEAVE, false, NULL, 0);
1283
#endif
1284
        }
1285
    }
1286
 
1287
  for (ctxp = ctxp_for_generation;  ctxp;  ctxp = ctxp->next)
1288
    {
1289
      input_location = ctxp->file_start_location;
1290
      parse_source_file_2 ();
1291
    }
1292
 
1293
  for (ctxp = ctxp_for_generation; ctxp; ctxp = ctxp->next)
1294
    {
1295
      input_location = ctxp->file_start_location;
1296
      parse_source_file_3 ();
1297
    }
1298
 
1299
  for (node = current_file_list; node; node = TREE_CHAIN (node))
1300
    {
1301
      input_location = DECL_SOURCE_LOCATION (node);
1302
      if (CLASS_FILE_P (node))
1303
        {
1304
          /* FIXME: These two flags really should be independent.  We
1305
             should be able to compile fully binary compatible, but
1306
             with flag_verify_invocations on.  */
1307
          flag_verify_invocations = ! flag_indirect_dispatch;
1308
          output_class = current_class = TREE_TYPE (node);
1309
 
1310
          current_jcf = TYPE_JCF (current_class);
1311
          layout_class (current_class);
1312
          load_inner_classes (current_class);
1313
          parse_class_file ();
1314
          JCF_FINISH (current_jcf);
1315
        }
1316
    }
1317
  input_location = save_location;
1318
 
1319
  java_expand_classes ();
1320
  if (java_report_errors () || flag_syntax_only)
1321
    return;
1322
 
1323
  /* Expand all classes compiled from source.  */
1324
  java_finish_classes ();
1325
 
1326
 finish:
1327
  /* Arrange for any necessary initialization to happen.  */
1328
  java_emit_static_constructor ();
1329
 
1330
  /* Only finalize the compilation unit after we've told cgraph which
1331
     functions have their addresses stored.  */
1332
  cgraph_finalize_compilation_unit ();
1333
  cgraph_optimize ();
1334
}
1335
 
1336
 
1337
/* Return the name of the class corresponding to the name of the file
1338
   in this zip entry.  The result is newly allocated using ALLOC.  */
1339
static char *
1340
compute_class_name (struct ZipDirectory *zdir)
1341
{
1342
  char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1343
  char *class_name;
1344
  int i;
1345
  int filename_length = zdir->filename_length;
1346
 
1347
  while (filename_length > 2 && strncmp (class_name_in_zip_dir, "./", 2) == 0)
1348
    {
1349
      class_name_in_zip_dir += 2;
1350
      filename_length -= 2;
1351
    }
1352
 
1353
  filename_length -= strlen (".class");
1354
  class_name = ALLOC (filename_length + 1);
1355
  memcpy (class_name, class_name_in_zip_dir, filename_length);
1356
  class_name [filename_length] = '\0';
1357
 
1358
  for (i = 0; i < filename_length; i++)
1359
    if (class_name[i] == '/')
1360
      class_name[i] = '.';
1361
 
1362
  return class_name;
1363
}
1364
 
1365
/* Return 0 if we should skip this entry, 1 if it is a .class file, 2
1366
   if it is a property file of some sort.  */
1367
static int
1368
classify_zip_file (struct ZipDirectory *zdir)
1369
{
1370
  char *class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1371
 
1372
  if (zdir->filename_length > 6
1373
      && !strncmp (&class_name_in_zip_dir[zdir->filename_length - 6],
1374
                   ".class", 6))
1375
    return 1;
1376
 
1377
  /* For now we drop the manifest, but not other information.  */
1378
  if (zdir->filename_length == 20
1379
      && !strncmp (class_name_in_zip_dir, "META-INF/MANIFEST.MF", 20))
1380
    return 0;
1381
 
1382
  /* Drop directory entries.  */
1383
  if (zdir->filename_length > 0
1384
      && class_name_in_zip_dir[zdir->filename_length - 1] == '/')
1385
    return 0;
1386
 
1387
  return 2;
1388
}
1389
 
1390
/* Process all class entries found in the zip file.  */
1391
static void
1392
parse_zip_file_entries (void)
1393
{
1394
  struct ZipDirectory *zdir;
1395
  int i;
1396
 
1397
  for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
1398
       i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
1399
    {
1400
      tree class;
1401
 
1402
      switch (classify_zip_file (zdir))
1403
        {
1404
        case 0:
1405
          continue;
1406
 
1407
        case 1:
1408
          {
1409
            char *class_name = compute_class_name (zdir);
1410
            class = lookup_class (get_identifier (class_name));
1411
            FREE (class_name);
1412
            current_jcf = TYPE_JCF (class);
1413
            output_class = current_class = class;
1414
 
1415
            if (CLASS_FROM_CURRENTLY_COMPILED_P (current_class))
1416
              {
1417
                /* We've already compiled this class.  */
1418
                duplicate_class_warning (current_jcf->filename);
1419
                break;
1420
              }
1421
 
1422
            CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
1423
 
1424
            if (TYPE_DUMMY (class))
1425
              {
1426
                /* This is a dummy class, and now we're compiling it
1427
                   for real.  */
1428
                abort ();
1429
              }
1430
 
1431
            /* This is for a corner case where we have a superclass
1432
               but no superclass fields.
1433
 
1434
               This can happen if we earlier failed to lay out this
1435
               class because its superclass was still in the process
1436
               of being laid out; this occurs when we have recursive
1437
               class dependencies via inner classes.  Setting
1438
               TYPE_SIZE to null here causes CLASS_LOADED_P to return
1439
               false, so layout_class() will be called again.  */
1440
            if (TYPE_SIZE (class) && CLASSTYPE_SUPER (class)
1441
                && integer_zerop (TYPE_SIZE (class)))
1442
              TYPE_SIZE (class) = NULL_TREE;
1443
 
1444
            if (! CLASS_LOADED_P (class))
1445
              {
1446
                if (! CLASS_PARSED_P (class))
1447
                  {
1448
                    read_zip_member (current_jcf, zdir, localToFile);
1449
                    jcf_parse (current_jcf);
1450
                  }
1451
                layout_class (current_class);
1452
                load_inner_classes (current_class);
1453
              }
1454
 
1455
            if (TYPE_SIZE (current_class) != error_mark_node)
1456
              {
1457
                parse_class_file ();
1458
                FREE (current_jcf->buffer); /* No longer necessary */
1459
                /* Note: there is a way to free this buffer right after a
1460
                   class seen in a zip file has been parsed. The idea is the
1461
                   set its jcf in such a way that buffer will be reallocated
1462
                   the time the code for the class will be generated. FIXME. */
1463
              }
1464
          }
1465
          break;
1466
 
1467
        case 2:
1468
          {
1469
            char *file_name, *class_name_in_zip_dir, *buffer;
1470
            JCF *jcf;
1471
            file_name = ALLOC (zdir->filename_length + 1);
1472
            class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1473
            strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
1474
            file_name[zdir->filename_length] = '\0';
1475
            jcf = ALLOC (sizeof (JCF));
1476
            JCF_ZERO (jcf);
1477
            jcf->read_state  = finput;
1478
            jcf->filbuf      = jcf_filbuf_from_stdio;
1479
            jcf->java_source = 0;
1480
            jcf->classname   = NULL;
1481
            jcf->filename    = file_name;
1482
            jcf->zipd        = zdir;
1483
 
1484
            if (read_zip_member (jcf, zdir, localToFile) < 0)
1485
              fatal_error ("error while reading %s from zip file", file_name);
1486
 
1487
            buffer = ALLOC (zdir->filename_length + 1 +
1488
                            (jcf->buffer_end - jcf->buffer));
1489
            strcpy (buffer, file_name);
1490
            /* This is not a typo: we overwrite the trailing \0 of the
1491
               file name; this is just how the data is laid out.  */
1492
            memcpy (buffer + zdir->filename_length,
1493
                    jcf->buffer, jcf->buffer_end - jcf->buffer);
1494
 
1495
            compile_resource_data (file_name, buffer,
1496
                                   jcf->buffer_end - jcf->buffer);
1497
            JCF_FINISH (jcf);
1498
            FREE (jcf);
1499
            FREE (buffer);
1500
          }
1501
          break;
1502
 
1503
        default:
1504
          abort ();
1505
        }
1506
    }
1507
}
1508
 
1509
/* Read all the entries of the zip file, creates a class and a JCF. Sets the
1510
   jcf up for further processing and link it to the created class.  */
1511
 
1512
static void
1513
process_zip_dir (FILE *finput)
1514
{
1515
  int i;
1516
  ZipDirectory *zdir;
1517
 
1518
  for (i = 0, zdir = (ZipDirectory *)localToFile->central_directory;
1519
       i < localToFile->count; i++, zdir = ZIPDIR_NEXT (zdir))
1520
    {
1521
      char *class_name, *file_name, *class_name_in_zip_dir;
1522
      tree class;
1523
      JCF  *jcf;
1524
 
1525
      class_name_in_zip_dir = ZIPDIR_FILENAME (zdir);
1526
 
1527
      /* Here we skip non-class files; we handle them later.  */
1528
      if (classify_zip_file (zdir) != 1)
1529
        continue;
1530
 
1531
      class_name = compute_class_name (zdir);
1532
      file_name  = ALLOC (zdir->filename_length+1);
1533
      jcf = ggc_alloc (sizeof (JCF));
1534
      JCF_ZERO (jcf);
1535
 
1536
      strncpy (file_name, class_name_in_zip_dir, zdir->filename_length);
1537
      file_name [zdir->filename_length] = '\0';
1538
 
1539
      class = lookup_class (get_identifier (class_name));
1540
 
1541
      jcf->read_state  = finput;
1542
      jcf->filbuf      = jcf_filbuf_from_stdio;
1543
      jcf->java_source = 0;
1544
      jcf->classname   = class_name;
1545
      jcf->filename    = file_name;
1546
      jcf->zipd        = zdir;
1547
 
1548
      TYPE_JCF (class) = jcf;
1549
    }
1550
}
1551
 
1552
/* Initialization.  */
1553
 
1554
void
1555
init_jcf_parse (void)
1556
{
1557
  init_src_parse ();
1558
}
1559
 
1560
#include "gt-java-jcf-parse.h"

powered by: WebSVN 2.1.0

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