00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "config.h"
00029 #include "system.h"
00030 #include "tree.h"
00031 #include "input.h"
00032 #include "rtl.h"
00033 #include "expr.h"
00034 #include "java-tree.h"
00035 #include "jcf.h"
00036 #include "toplev.h"
00037 #include "langhooks.h"
00038 #include "langhooks-def.h"
00039 #include "flags.h"
00040 #include "xref.h"
00041 #include "ggc.h"
00042 #include "diagnostic.h"
00043
00044 struct string_option
00045 {
00046 const char *const string;
00047 int *const variable;
00048 const int on_value;
00049 };
00050
00051 static const char *java_init PARAMS ((const char *));
00052 static void java_finish PARAMS ((void));
00053 static void java_init_options PARAMS ((void));
00054 static void java_post_options PARAMS ((void));
00055
00056 static int java_decode_option PARAMS ((int, char **));
00057 static void put_decl_string PARAMS ((const char *, int));
00058 static void put_decl_node PARAMS ((tree));
00059 static void java_dummy_print PARAMS ((diagnostic_context *, const char *));
00060 static void lang_print_error PARAMS ((diagnostic_context *, const char *));
00061 static int process_option_with_no PARAMS ((const char *,
00062 const struct string_option *,
00063 int));
00064
00065 #ifndef TARGET_OBJECT_SUFFIX
00066 # define TARGET_OBJECT_SUFFIX ".o"
00067 #endif
00068
00069
00070
00071
00072
00073 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
00074
00075 static const char java_tree_code_type[] = {
00076 'x',
00077 #include "java-tree.def"
00078 };
00079 #undef DEFTREECODE
00080
00081
00082
00083
00084
00085 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
00086
00087 static const int java_tree_code_length[] = {
00088 0,
00089 #include "java-tree.def"
00090 };
00091 #undef DEFTREECODE
00092
00093
00094
00095 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
00096
00097 static const char *const java_tree_code_name[] = {
00098 "@@dummy",
00099 #include "java-tree.def"
00100 };
00101 #undef DEFTREECODE
00102
00103 int compiling_from_source;
00104
00105 char * resource_name;
00106
00107 int flag_emit_class_files = 0;
00108
00109
00110
00111 int flag_filelist_file = 0;
00112
00113
00114
00115
00116 int flag_emit_xref = 0;
00117
00118
00119 int flag_wall = 0;
00120
00121
00122 int flag_redundant = 0;
00123
00124
00125 int flag_use_divide_subroutine = 1;
00126
00127
00128 int flag_use_boehm_gc = 0;
00129
00130
00131
00132 int flag_hash_synchronization;
00133
00134
00135
00136 int flag_jni = 0;
00137
00138
00139
00140 int flag_newer = 1;
00141
00142
00143 int flag_check_references = 0;
00144
00145
00146 const char *current_encoding = NULL;
00147
00148
00149 int flag_extraneous_semicolon;
00150
00151
00152 int flag_force_classes_archive_check;
00153
00154
00155
00156 int flag_optimize_sci = 1;
00157
00158
00159
00160 int flag_indirect_dispatch = 0;
00161
00162
00163 int flag_store_check = 1;
00164
00165
00166 static int version_flag = 0;
00167
00168
00169
00170 int flag_really_inline = 0;
00171
00172
00173
00174
00175
00176
00177
00178 static const struct string_option
00179 lang_f_options[] =
00180 {
00181 {"emit-class-file", &flag_emit_class_files, 1},
00182 {"emit-class-files", &flag_emit_class_files, 1},
00183 {"filelist-file", &flag_filelist_file, 1},
00184 {"use-divide-subroutine", &flag_use_divide_subroutine, 1},
00185 {"use-boehm-gc", &flag_use_boehm_gc, 1},
00186 {"hash-synchronization", &flag_hash_synchronization, 1},
00187 {"jni", &flag_jni, 1},
00188 {"check-references", &flag_check_references, 1},
00189 {"force-classes-archive-check", &flag_force_classes_archive_check, 1},
00190 {"optimize-static-class-initialization", &flag_optimize_sci, 1 },
00191 {"indirect-dispatch", &flag_indirect_dispatch, 1},
00192 {"store-check", &flag_store_check, 1}
00193 };
00194
00195 static const struct string_option
00196 lang_W_options[] =
00197 {
00198 { "redundant-modifiers", &flag_redundant, 1 },
00199 { "extraneous-semicolon", &flag_extraneous_semicolon, 1 },
00200 { "out-of-date", &flag_newer, 1 }
00201 };
00202
00203 JCF *current_jcf;
00204
00205
00206
00207 static int dependency_tracking = 0;
00208
00209
00210 #define DEPEND_SET_FILE 1
00211 #define DEPEND_ENABLE 2
00212 #define DEPEND_TARGET_SET 4
00213 #define DEPEND_FILE_ALREADY_SET 8
00214
00215 #undef LANG_HOOKS_NAME
00216 #define LANG_HOOKS_NAME "GNU Java"
00217 #undef LANG_HOOKS_INIT
00218 #define LANG_HOOKS_INIT java_init
00219 #undef LANG_HOOKS_FINISH
00220 #define LANG_HOOKS_FINISH java_finish
00221 #undef LANG_HOOKS_INIT_OPTIONS
00222 #define LANG_HOOKS_INIT_OPTIONS java_init_options
00223 #undef LANG_HOOKS_DECODE_OPTION
00224 #define LANG_HOOKS_DECODE_OPTION java_decode_option
00225 #undef LANG_HOOKS_POST_OPTIONS
00226 #define LANG_HOOKS_POST_OPTIONS java_post_options
00227 #undef LANG_HOOKS_SET_YYDEBUG
00228 #define LANG_HOOKS_SET_YYDEBUG java_set_yydebug
00229
00230
00231 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
00232
00233
00234
00235 static int
00236 process_option_with_no (p, table, table_size)
00237 const char *p;
00238 const struct string_option *table;
00239 int table_size;
00240 {
00241 int j;
00242
00243 for (j = 0; j < table_size; j++)
00244 {
00245 if (!strcmp (p, table[j].string))
00246 {
00247 *table[j].variable = table[j].on_value;
00248 return 1;
00249 }
00250 if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
00251 && ! strcmp (p+3, table[j].string))
00252 {
00253 *table[j].variable = ! table[j].on_value;
00254 return 1;
00255 }
00256 }
00257
00258 return 0;
00259 }
00260
00261
00262
00263
00264
00265 static int
00266 java_decode_option (argc, argv)
00267 int argc __attribute__ ((__unused__));
00268 char **argv;
00269 {
00270 char *p = argv[0];
00271
00272 jcf_path_init ();
00273
00274 if (strcmp (p, "-version") == 0)
00275 {
00276 version_flag = 1;
00277
00278 return 0;
00279 }
00280
00281 #define CLARG "-fcompile-resource="
00282 if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
00283 {
00284 resource_name = p + sizeof (CLARG) - 1;
00285 return 1;
00286 }
00287 #undef CLARG
00288 #define CLARG "-fassume-compiled="
00289 if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
00290 {
00291 add_assume_compiled (p + sizeof (CLARG) - 1, 0);
00292 return 1;
00293 }
00294 #undef CLARG
00295 #define CLARG "-fno-assume-compiled="
00296 if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
00297 {
00298 add_assume_compiled (p + sizeof (CLARG) - 1, 1);
00299 return 1;
00300 }
00301 #undef CLARG
00302 #define CLARG "-fassume-compiled"
00303 if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
00304 {
00305 add_assume_compiled ("", 0);
00306 return 1;
00307 }
00308 #undef CLARG
00309 #define CLARG "-fno-assume-compiled"
00310 if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
00311 {
00312 add_assume_compiled ("", 1);
00313 return 1;
00314 }
00315 #undef CLARG
00316 #define CLARG "-fCLASSPATH="
00317 if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
00318 {
00319 jcf_path_classpath_arg (p + sizeof (CLARG) - 1);
00320 return 1;
00321 }
00322 #undef CLARG
00323 #define CLARG "-fclasspath="
00324 if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
00325 {
00326 jcf_path_classpath_arg (p + sizeof (CLARG) - 1);
00327 return 1;
00328 }
00329 #undef CLARG
00330 #define CLARG "-fbootclasspath="
00331 if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
00332 {
00333 jcf_path_bootclasspath_arg (p + sizeof (CLARG) - 1);
00334 return 1;
00335 }
00336 #undef CLARG
00337 #define CLARG "-fextdirs="
00338 if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
00339 {
00340 jcf_path_extdirs_arg (p + sizeof (CLARG) - 1);
00341 return 1;
00342 }
00343 #undef CLARG
00344 else if (strncmp (p, "-I", 2) == 0)
00345 {
00346 jcf_path_include_arg (p + 2);
00347 return 1;
00348 }
00349
00350 #define ARG "-foutput-class-dir="
00351 if (strncmp (p, ARG, sizeof (ARG) - 1) == 0)
00352 {
00353 jcf_write_base_directory = p + sizeof (ARG) - 1;
00354 return 1;
00355 }
00356 #undef ARG
00357 #define ARG "-fencoding="
00358 if (strncmp (p, ARG, sizeof (ARG) - 1) == 0)
00359 {
00360 current_encoding = p + sizeof (ARG) - 1;
00361 return 1;
00362 }
00363 #undef ARG
00364 #define ARG "-finline-functions"
00365 if (strncmp (p, ARG, sizeof (ARG) - 1) == 0)
00366 {
00367 flag_inline_functions = 1;
00368 flag_really_inline = 1;
00369 return 1;
00370 }
00371 #undef ARG
00372
00373 if (p[0] == '-' && p[1] == 'f')
00374 {
00375
00376
00377
00378 p += 2;
00379 if (process_option_with_no (p, lang_f_options,
00380 ARRAY_SIZE (lang_f_options)))
00381 return 1;
00382 return dump_switch_p (p);
00383 }
00384
00385 if (strcmp (p, "-Wall") == 0)
00386 {
00387 flag_wall = 1;
00388 flag_redundant = 1;
00389 flag_extraneous_semicolon = 1;
00390
00391
00392 set_Wunused (1);
00393 return 1;
00394 }
00395
00396 if (p[0] == '-' && p[1] == 'W')
00397 {
00398
00399 p += 2;
00400 return process_option_with_no (p, lang_W_options,
00401 ARRAY_SIZE (lang_W_options));
00402 }
00403
00404 if (strcmp (p, "-MD") == 0)
00405 {
00406 jcf_dependency_init (1);
00407 dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
00408 return 1;
00409 }
00410 else if (strcmp (p, "-MMD") == 0)
00411 {
00412 jcf_dependency_init (0);
00413 dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
00414 return 1;
00415 }
00416 else if (strcmp (p, "-M") == 0)
00417 {
00418 jcf_dependency_init (1);
00419 dependency_tracking |= DEPEND_ENABLE;
00420 return 1;
00421 }
00422 else if (strcmp (p, "-MM") == 0)
00423 {
00424 jcf_dependency_init (0);
00425 dependency_tracking |= DEPEND_ENABLE;
00426 return 1;
00427 }
00428 else if (strcmp (p, "-MP") == 0)
00429 {
00430 jcf_dependency_print_dummies ();
00431 return 1;
00432 }
00433 else if (strcmp (p, "-MT") == 0)
00434 {
00435 jcf_dependency_set_target (argv[1]);
00436 dependency_tracking |= DEPEND_TARGET_SET;
00437 return 2;
00438 }
00439 else if (strcmp (p, "-MF") == 0)
00440 {
00441 jcf_dependency_set_dep_file (argv[1]);
00442 dependency_tracking |= DEPEND_FILE_ALREADY_SET;
00443 return 2;
00444 }
00445
00446 return 0;
00447 }
00448
00449
00450 FILE *finput;
00451
00452 static const char *
00453 java_init (filename)
00454 const char *filename;
00455 {
00456 #if 0
00457 extern int flag_minimal_debug;
00458 flag_minimal_debug = 0;
00459 #endif
00460
00461
00462
00463
00464 if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
00465 && force_align_functions_log < 1)
00466 force_align_functions_log = 1;
00467
00468
00469
00470 if (filename == 0 || !strcmp (filename, "-"))
00471 {
00472 finput = stdin;
00473 filename = "stdin";
00474
00475 if (dependency_tracking)
00476 error ("can't do dependency tracking with input from stdin");
00477 }
00478 else
00479 {
00480 if (dependency_tracking)
00481 {
00482 char *dot;
00483
00484
00485
00486
00487 if (! ((dependency_tracking & DEPEND_TARGET_SET)
00488 && (dependency_tracking & DEPEND_FILE_ALREADY_SET)))
00489 {
00490 dot = strrchr (filename, '.');
00491 if (dot == NULL)
00492 error ("couldn't determine target name for dependency tracking");
00493 else
00494 {
00495 char *buf = (char *) xmalloc (dot - filename +
00496 3 + sizeof (TARGET_OBJECT_SUFFIX));
00497 strncpy (buf, filename, dot - filename);
00498
00499
00500
00501
00502
00503 if ((dependency_tracking & DEPEND_TARGET_SET))
00504 ;
00505 else if (flag_emit_class_files)
00506 jcf_dependency_set_target (NULL);
00507 else
00508 {
00509 strcpy (buf + (dot - filename), TARGET_OBJECT_SUFFIX);
00510 jcf_dependency_set_target (buf);
00511 }
00512
00513 if ((dependency_tracking & DEPEND_FILE_ALREADY_SET))
00514 ;
00515 else if ((dependency_tracking & DEPEND_SET_FILE))
00516 {
00517 strcpy (buf + (dot - filename), ".d");
00518 jcf_dependency_set_dep_file (buf);
00519 }
00520 else
00521 jcf_dependency_set_dep_file ("-");
00522
00523 free (buf);
00524 }
00525 }
00526 }
00527 }
00528
00529 jcf_path_init ();
00530 jcf_path_seal (version_flag);
00531
00532 decl_printable_name = lang_printable_name;
00533 print_error_function = lang_print_error;
00534 lang_expand_expr = java_lang_expand_expr;
00535
00536
00537
00538 memcpy (tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
00539 java_tree_code_type,
00540 (int)LAST_JAVA_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE);
00541 memcpy (tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE,
00542 java_tree_code_length,
00543 (LAST_JAVA_TREE_CODE -
00544 (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int));
00545 memcpy (tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE,
00546 java_tree_code_name,
00547 (LAST_JAVA_TREE_CODE -
00548 (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
00549 java_init_decl_processing ();
00550
00551 using_eh_for_cleanups ();
00552
00553 return filename;
00554 }
00555
00556 static void
00557 java_finish ()
00558 {
00559 jcf_dependency_write ();
00560 }
00561
00562
00563 static char *decl_buf = NULL;
00564
00565
00566 static int decl_buflen = 0;
00567
00568
00569 static int decl_bufpos = 0;
00570
00571
00572
00573
00574 static void
00575 put_decl_string (str, len)
00576 const char *str;
00577 int len;
00578 {
00579 if (len < 0)
00580 len = strlen (str);
00581 if (decl_bufpos + len >= decl_buflen)
00582 {
00583 if (decl_buf == NULL)
00584 {
00585 decl_buflen = len + 100;
00586 decl_buf = (char *) xmalloc (decl_buflen);
00587 }
00588 else
00589 {
00590 decl_buflen *= 2;
00591 decl_buf = (char *) xrealloc (decl_buf, decl_buflen);
00592 }
00593 }
00594 strcpy (decl_buf + decl_bufpos, str);
00595 decl_bufpos += len;
00596 }
00597
00598
00599
00600 static void
00601 put_decl_node (node)
00602 tree node;
00603 {
00604 int was_pointer = 0;
00605 if (TREE_CODE (node) == POINTER_TYPE)
00606 {
00607 node = TREE_TYPE (node);
00608 was_pointer = 1;
00609 }
00610 if (TREE_CODE_CLASS (TREE_CODE (node)) == 'd'
00611 && DECL_NAME (node) != NULL_TREE)
00612 {
00613 if (TREE_CODE (node) == FUNCTION_DECL)
00614 {
00615
00616
00617 if (! DECL_CONSTRUCTOR_P (node)
00618 && ! DECL_ARTIFICIAL (node) && DECL_CONTEXT (node))
00619 {
00620 put_decl_node (TYPE_NAME (DECL_CONTEXT (node)));
00621 put_decl_string (".", 1);
00622 }
00623 if (! DECL_CONSTRUCTOR_P (node))
00624 put_decl_node (DECL_NAME (node));
00625 if (TREE_TYPE (node) != NULL_TREE)
00626 {
00627 int i = 0;
00628 tree args = TYPE_ARG_TYPES (TREE_TYPE (node));
00629 if (TREE_CODE (TREE_TYPE (node)) == METHOD_TYPE)
00630 args = TREE_CHAIN (args);
00631 put_decl_string ("(", 1);
00632 for ( ; args != end_params_node; args = TREE_CHAIN (args), i++)
00633 {
00634 if (i > 0)
00635 put_decl_string (",", 1);
00636 put_decl_node (TREE_VALUE (args));
00637 }
00638 put_decl_string (")", 1);
00639 }
00640 }
00641 else
00642 put_decl_node (DECL_NAME (node));
00643 }
00644 else if (TREE_CODE_CLASS (TREE_CODE (node)) == 't'
00645 && TYPE_NAME (node) != NULL_TREE)
00646 {
00647 if (TREE_CODE (node) == RECORD_TYPE && TYPE_ARRAY_P (node))
00648 {
00649 put_decl_node (TYPE_ARRAY_ELEMENT (node));
00650 put_decl_string("[]", 2);
00651 }
00652 else if (node == promoted_byte_type_node)
00653 put_decl_string ("byte", 4);
00654 else if (node == promoted_short_type_node)
00655 put_decl_string ("short", 5);
00656 else if (node == promoted_char_type_node)
00657 put_decl_string ("char", 4);
00658 else if (node == promoted_boolean_type_node)
00659 put_decl_string ("boolean", 7);
00660 else if (node == void_type_node && was_pointer)
00661 put_decl_string ("null", 4);
00662 else
00663 put_decl_node (TYPE_NAME (node));
00664 }
00665 else if (TREE_CODE (node) == IDENTIFIER_NODE)
00666 put_decl_string (IDENTIFIER_POINTER (node), IDENTIFIER_LENGTH (node));
00667 else
00668 put_decl_string ("<unknown>", -1);
00669 }
00670
00671
00672
00673
00674
00675
00676 const char *
00677 lang_printable_name (decl, v)
00678 tree decl;
00679 int v __attribute__ ((__unused__));
00680 {
00681 decl_bufpos = 0;
00682 put_decl_node (decl);
00683 put_decl_string ("", 1);
00684 return decl_buf;
00685 }
00686
00687
00688
00689
00690 const char *
00691 lang_printable_name_wls (decl, v)
00692 tree decl;
00693 int v __attribute__ ((__unused__));
00694 {
00695 decl_bufpos = 1;
00696 put_decl_node (decl);
00697 put_decl_string ("", 1);
00698 decl_buf [0] = ' ';
00699 return decl_buf;
00700 }
00701
00702
00703
00704
00705 static void
00706 lang_print_error (context, file)
00707 diagnostic_context *context __attribute__((__unused__));
00708 const char *file;
00709 {
00710 static tree last_error_function_context = NULL_TREE;
00711 static tree last_error_function = NULL;
00712 static int initialized_p;
00713
00714
00715
00716 if (!initialized_p)
00717 {
00718 ggc_add_tree_root (&last_error_function_context, 1);
00719 ggc_add_tree_root (&last_error_function, 1);
00720 initialized_p = 1;
00721 }
00722
00723 if (current_function_decl != NULL
00724 && DECL_CONTEXT (current_function_decl) != last_error_function_context)
00725 {
00726 if (file)
00727 fprintf (stderr, "%s: ", file);
00728
00729 last_error_function_context = DECL_CONTEXT (current_function_decl);
00730 fprintf (stderr, "In class `%s':\n",
00731 lang_printable_name (last_error_function_context, 0));
00732 }
00733 if (last_error_function != current_function_decl)
00734 {
00735 if (file)
00736 fprintf (stderr, "%s: ", file);
00737
00738 if (current_function_decl == NULL)
00739 fprintf (stderr, "At top level:\n");
00740 else
00741 {
00742 const char *name = lang_printable_name (current_function_decl, 2);
00743 fprintf (stderr, "In %s `%s':\n",
00744 (DECL_CONSTRUCTOR_P (current_function_decl) ? "constructor"
00745 : "method"),
00746 name);
00747 }
00748
00749 last_error_function = current_function_decl;
00750 }
00751
00752 }
00753
00754
00755
00756
00757
00758 static void
00759 java_dummy_print (c, s)
00760 diagnostic_context *c __attribute__ ((__unused__));
00761 const char *s __attribute__ ((__unused__));
00762 {
00763 }
00764
00765
00766
00767
00768
00769
00770
00771
00772 void lang_init_source (level)
00773 int level;
00774 {
00775 if (level == 1)
00776 print_error_function = java_dummy_print;
00777 else
00778 print_error_function = lang_print_error;
00779 }
00780
00781 static void
00782 java_init_options ()
00783 {
00784 flag_bounds_check = 1;
00785 flag_exceptions = 1;
00786 flag_non_call_exceptions = 1;
00787 }
00788
00789
00790 static void
00791 java_post_options ()
00792 {
00793
00794 if (flag_really_inline == 0)
00795 {
00796 flag_no_inline = 1;
00797 flag_inline_functions = 0;
00798 }
00799 }