OSDN Git Service

2001-10-15 Alexandre Petit-Bianco <apbianco@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / java / lang.c
1 /* Java(TM) language-specific utility routines.
2    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
3    Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC 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 GNU CC 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 GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, 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 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
27
28 #include "config.h"
29 #include "system.h"
30 #include "tree.h"
31 #include "input.h"
32 #include "rtl.h"
33 #include "expr.h"
34 #include "java-tree.h"
35 #include "jcf.h"
36 #include "toplev.h"
37 #include "langhooks.h"
38 #include "flags.h"
39 #include "xref.h"
40 #include "ggc.h"
41 #include "diagnostic.h"
42
43 struct string_option
44 {
45   const char *string;
46   int *variable;
47   int on_value;
48 };
49
50 static void java_init PARAMS ((void));
51 static void java_init_options PARAMS ((void));
52 static int java_decode_option PARAMS ((int, char **));
53 static void put_decl_string PARAMS ((const char *, int));
54 static void put_decl_node PARAMS ((tree));
55 static void java_dummy_print PARAMS ((diagnostic_context *, const char *));
56 static void lang_print_error PARAMS ((diagnostic_context *, const char *));
57 static int process_option_with_no PARAMS ((char *,
58                                            struct string_option *,
59                                            int));
60
61 #ifndef TARGET_OBJECT_SUFFIX
62 # define TARGET_OBJECT_SUFFIX ".o"
63 #endif
64
65 /* Table indexed by tree code giving a string containing a character
66    classifying the tree code.  Possibilities are
67    t, d, s, c, r, <, 1 and 2.  See java/java-tree.def for details.  */
68
69 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
70
71 static const char java_tree_code_type[] = {
72   'x',
73 #include "java-tree.def"
74 };
75 #undef DEFTREECODE
76
77 /* Table indexed by tree code giving number of expression
78    operands beyond the fixed part of the node structure.
79    Not used for types or decls.  */
80
81 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
82
83 static const int java_tree_code_length[] = {
84   0,
85 #include "java-tree.def"
86 };
87 #undef DEFTREECODE
88
89 /* Names of tree components.
90    Used for printing out the tree and error messages.  */
91 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
92
93 static const char *const java_tree_code_name[] = {
94   "@@dummy",
95 #include "java-tree.def"
96 };
97 #undef DEFTREECODE
98
99 int compiling_from_source;
100
101 const char * const language_string = "GNU Java";
102
103 char * resource_name;
104
105 int flag_emit_class_files = 0;
106
107 /* Nonzero if input file is a file with a list of filenames to compile. */
108
109 int flag_filelist_file = 0;
110
111 /* When non zero, we emit xref strings. Values of the flag for xref
112    backends are defined in xref_flag_table, xref.c.  */
113
114 int flag_emit_xref = 0;
115
116 /* When non zero, -Wall was turned on.  */
117 int flag_wall = 0;
118
119 /* When non zero, check for redundant modifier uses.  */
120 int flag_redundant = 0;
121
122 /* When non zero, call a library routine to do integer divisions. */
123 int flag_use_divide_subroutine = 1;
124
125 /* When non zero, generate code for the Boehm GC.  */
126 int flag_use_boehm_gc = 0;
127
128 /* When non zero, assume the runtime uses a hash table to map an
129    object to its synchronization structure.  */
130 int flag_hash_synchronization;
131
132 /* When non zero, assume all native functions are implemented with
133    JNI, not CNI.  */
134 int flag_jni = 0;
135
136 /* When non zero, warn when source file is newer than matching class
137    file.  */
138 int flag_newer = 1;
139
140 /* When non zero, generate checks for references to NULL.  */
141 int flag_check_references = 0;
142
143 /* The encoding of the source file.  */
144 const char *current_encoding = NULL;
145
146 /* When non zero, report the now deprecated empty statements.  */
147 int flag_extraneous_semicolon;
148
149 /* When non zero, always check for a non gcj generated classes archive.  */
150 int flag_force_classes_archive_check;
151
152 /* When zero, don't optimize static class initialization. This flag shouldn't
153    be tested alone, use STATIC_CLASS_INITIALIZATION_OPTIMIZATION_P instead.  */
154 int flag_optimize_sci = 1;
155
156 /* When non zero, print extra version information.  */
157 static int version_flag = 0;
158
159 /* Table of language-dependent -f options.
160    STRING is the option name.  VARIABLE is the address of the variable.
161    ON_VALUE is the value to store in VARIABLE
162     if `-fSTRING' is seen as an option.
163    (If `-fno-STRING' is seen as an option, the opposite value is stored.)  */
164
165 static struct string_option
166 lang_f_options[] =
167 {
168   {"emit-class-file", &flag_emit_class_files, 1},
169   {"emit-class-files", &flag_emit_class_files, 1},
170   {"filelist-file", &flag_filelist_file, 1},
171   {"use-divide-subroutine", &flag_use_divide_subroutine, 1},
172   {"use-boehm-gc", &flag_use_boehm_gc, 1},
173   {"hash-synchronization", &flag_hash_synchronization, 1},
174   {"jni", &flag_jni, 1},
175   {"check-references", &flag_check_references, 1},
176   {"force-classes-archive-check", &flag_force_classes_archive_check, 1}
177 };
178
179 static struct string_option
180 lang_W_options[] =
181 {
182   { "redundant-modifiers", &flag_redundant, 1 },
183   { "extraneous-semicolon", &flag_extraneous_semicolon, 1 },
184   { "out-of-date", &flag_newer, 1 }
185 };
186
187 JCF *current_jcf;
188
189 /* Variable controlling how dependency tracking is enabled in
190    init_parse.  */
191 static int dependency_tracking = 0;
192
193 /* Flag values for DEPENDENCY_TRACKING.  */
194 #define DEPEND_SET_FILE 1
195 #define DEPEND_ENABLE   2
196 #define DEPEND_TARGET_SET 4
197 #define DEPEND_FILE_ALREADY_SET 8
198
199 #undef LANG_HOOKS_INIT
200 #define LANG_HOOKS_INIT java_init
201 #undef LANG_HOOKS_INIT_OPTIONS
202 #define LANG_HOOKS_INIT_OPTIONS java_init_options
203 #undef LANG_HOOKS_DECODE_OPTION
204 #define LANG_HOOKS_DECODE_OPTION java_decode_option
205
206 /* Each front end provides its own.  */
207 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
208
209 /* Process an option that can accept a `no-' form.
210    Return 1 if option found, 0 otherwise.  */
211 static int
212 process_option_with_no (p, table, table_size)
213      char *p;
214      struct string_option *table;
215      int table_size;
216 {
217   int j;
218
219   for (j = 0; j < table_size; j++)
220     {
221       if (!strcmp (p, table[j].string))
222         {
223           *table[j].variable = table[j].on_value;
224           return 1;
225         }
226       if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
227           && ! strcmp (p+3, table[j].string))
228         {
229           *table[j].variable = ! table[j].on_value;
230           return 1;
231         }
232     }
233
234   return 0;
235 }
236
237 /*
238  * process java-specific compiler command-line options
239  * return 0, but do not complain if the option is not recognised.
240  */
241 static int
242 java_decode_option (argc, argv)
243      int argc __attribute__ ((__unused__));
244      char **argv;
245 {
246   char *p = argv[0];
247
248   if (strcmp (p, "-version") == 0)
249     {
250       version_flag = 1;
251       /* We return 0 so that the caller can process this.  */
252       return 0;
253     }
254
255 #define CLARG "-fcompile-resource="
256   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
257     {
258       resource_name = p + sizeof (CLARG) - 1;
259       return 1;
260     }
261 #undef CLARG
262 #define CLARG "-fassume-compiled="
263   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
264     {
265       add_assume_compiled (p + sizeof (CLARG) - 1, 0);
266       return 1;
267     }
268 #undef CLARG
269 #define CLARG "-fno-assume-compiled="
270   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
271     {
272       add_assume_compiled (p + sizeof (CLARG) - 1, 1);
273       return 1;
274     }
275 #undef CLARG
276 #define CLARG "-fassume-compiled"
277   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
278     {
279       add_assume_compiled ("", 0);
280       return 1;
281     }
282 #undef CLARG
283 #define CLARG "-fno-assume-compiled"
284   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
285     {
286       add_assume_compiled ("", 1);
287       return 1;
288     }
289 #undef CLARG
290 #define CLARG "-fclasspath="
291   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
292     {
293       jcf_path_classpath_arg (p + sizeof (CLARG) - 1);
294       return 1;
295     }
296 #undef CLARG
297 #define CLARG "-fCLASSPATH="
298   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
299     {
300       jcf_path_CLASSPATH_arg (p + sizeof (CLARG) - 1);
301       return 1;
302     }
303 #undef CLARG
304   else if (strncmp (p, "-I", 2) == 0)
305     {
306       jcf_path_include_arg (p + 2);
307       return 1;
308     }
309
310 #define ARG "-foutput-class-dir="
311   if (strncmp (p, ARG, sizeof (ARG) - 1) == 0)
312     {
313       jcf_write_base_directory = p + sizeof (ARG) - 1;
314       return 1;
315     }
316 #undef ARG
317 #define ARG "-fencoding="
318   if (strncmp (p, ARG, sizeof (ARG) - 1) == 0)
319     {
320       current_encoding = p + sizeof (ARG) - 1;
321       return 1;
322     }
323 #undef ARG
324
325 #undef ARG
326 #define ARG "-fno-optimize-static-class-initialization"
327   if (strncmp (p, ARG, sizeof (ARG) - 1) == 0)
328     {
329       flag_optimize_sci = 0;
330       return 1;
331     }
332 #undef ARG
333
334   if (p[0] == '-' && p[1] == 'f')
335     {
336       /* Some kind of -f option.
337          P's value is the option sans `-f'.
338          Search for it in the table of options.  */
339       p += 2;
340       return process_option_with_no (p, lang_f_options,
341                                      ARRAY_SIZE (lang_f_options));
342     }
343
344   if (strcmp (p, "-Wall") == 0)
345     {
346       flag_wall = 1;
347       flag_redundant = 1;
348       flag_extraneous_semicolon = 1;
349       /* When -Wall given, enable -Wunused.  We do this because the C
350          compiler does it, and people expect it.  */
351       set_Wunused (1);
352       return 1;
353     }
354
355   if (p[0] == '-' && p[1] == 'W')
356     {
357       /* Skip `-W' and see if we accept the option or its `no-' form.  */
358       p += 2;
359       return process_option_with_no (p, lang_W_options,
360                                      ARRAY_SIZE (lang_W_options));
361     }
362
363   if (strcmp (p, "-MD") == 0)
364     {
365       jcf_dependency_init (1);
366       dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
367       return 1;
368     }
369   else if (strcmp (p, "-MMD") == 0)
370     {
371       jcf_dependency_init (0);
372       dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
373       return 1;
374     }
375   else if (strcmp (p, "-M") == 0)
376     {
377       jcf_dependency_init (1);
378       dependency_tracking |= DEPEND_ENABLE;
379       return 1;
380     }
381   else if (strcmp (p, "-MM") == 0)
382     {
383       jcf_dependency_init (0);
384       dependency_tracking |= DEPEND_ENABLE;
385       return 1;
386     }
387   else if (strcmp (p, "-MP") == 0)
388     {
389       jcf_dependency_print_dummies ();
390       return 1;
391     }
392   else if (strcmp (p, "-MT") == 0)
393     {
394       jcf_dependency_set_target (argv[1]);
395       dependency_tracking |= DEPEND_TARGET_SET;
396       return 2;
397     }
398   else if (strcmp (p, "-MF") == 0)
399     {
400       jcf_dependency_set_dep_file (argv[1]);
401       dependency_tracking |= DEPEND_FILE_ALREADY_SET;
402       return 2;
403     }
404
405   return 0;
406 }
407
408 /* Global open file.  */
409 FILE *finput;
410
411 const char *
412 init_parse (filename)
413      const char *filename;
414 {
415   /* Open input file.  */
416
417   if (filename == 0 || !strcmp (filename, "-"))
418     {
419       finput = stdin;
420       filename = "stdin";
421
422       if (dependency_tracking)
423         error ("can't do dependency tracking with input from stdin");
424     }
425   else
426     {
427       if (dependency_tracking)
428         {
429           char *dot;
430
431           /* If the target is set and the output filename is set, then
432              there's no processing to do here.  Otherwise we must
433              compute one or the other.  */
434           if (! ((dependency_tracking & DEPEND_TARGET_SET)
435                  && (dependency_tracking & DEPEND_FILE_ALREADY_SET)))
436             {
437               dot = strrchr (filename, '.');
438               if (dot == NULL)
439                 error ("couldn't determine target name for dependency tracking");
440               else
441                 {
442                   char *buf = (char *) xmalloc (dot - filename +
443                                                 3 + sizeof (TARGET_OBJECT_SUFFIX));
444                   strncpy (buf, filename, dot - filename);
445
446                   /* If emitting class files, we might have multiple
447                      targets.  The class generation code takes care of
448                      registering them.  Otherwise we compute the
449                      target name here.  */
450                   if ((dependency_tracking & DEPEND_TARGET_SET))
451                     ; /* Nothing.  */
452                   else if (flag_emit_class_files)
453                     jcf_dependency_set_target (NULL);
454                   else
455                     {
456                       strcpy (buf + (dot - filename), TARGET_OBJECT_SUFFIX);
457                       jcf_dependency_set_target (buf);
458                     }
459
460                   if ((dependency_tracking & DEPEND_FILE_ALREADY_SET))
461                     ; /* Nothing.  */
462                   else if ((dependency_tracking & DEPEND_SET_FILE))
463                     {
464                       strcpy (buf + (dot - filename), ".d");
465                       jcf_dependency_set_dep_file (buf);
466                     }
467                   else
468                     jcf_dependency_set_dep_file ("-");
469
470                   free (buf);
471                 }
472             }
473         }
474     }
475
476   init_lex ();
477
478   return filename;
479 }
480
481 void
482 finish_parse ()
483 {
484   jcf_dependency_write ();
485 }
486
487 /* Buffer used by lang_printable_name. */
488 static char *decl_buf = NULL;
489
490 /* Allocated size of decl_buf. */
491 static int decl_buflen = 0;
492
493 /* Length of used part of decl_buf;  position for next character. */
494 static int decl_bufpos = 0;
495
496 /* Append the string STR to decl_buf.
497    It length is given by LEN;  -1 means the string is nul-terminated. */
498
499 static void
500 put_decl_string (str, len)
501      const char *str;
502      int len;
503 {
504   if (len < 0)
505     len = strlen (str);
506   if (decl_bufpos + len >= decl_buflen)
507     {
508       if (decl_buf == NULL)
509         {
510           decl_buflen = len + 100;
511           decl_buf = (char *) xmalloc (decl_buflen);
512         }
513       else
514         {
515           decl_buflen *= 2;
516           decl_buf = (char *) xrealloc (decl_buf, decl_buflen);
517         }
518     }
519   strcpy (decl_buf + decl_bufpos, str);
520   decl_bufpos += len;
521 }
522
523 /* Append to decl_buf a printable name for NODE. */
524
525 static void
526 put_decl_node (node)
527      tree node;
528 {
529   int was_pointer = 0;
530   if (TREE_CODE (node) == POINTER_TYPE)
531     {
532       node = TREE_TYPE (node);
533       was_pointer = 1;
534     }
535   if (TREE_CODE_CLASS (TREE_CODE (node)) == 'd'
536       && DECL_NAME (node) != NULL_TREE)
537     {
538       if (TREE_CODE (node) == FUNCTION_DECL)
539         {
540           /* We want to print the type the DECL belongs to. We don't do
541              that when we handle constructors. */
542           if (! DECL_CONSTRUCTOR_P (node)
543               && ! DECL_ARTIFICIAL (node) && DECL_CONTEXT (node))
544             {
545               put_decl_node (TYPE_NAME (DECL_CONTEXT (node)));
546               put_decl_string (".", 1);
547             }
548           if (! DECL_CONSTRUCTOR_P (node))
549             put_decl_node (DECL_NAME (node));
550           if (TREE_TYPE (node) != NULL_TREE)
551             {
552               int i = 0;
553               tree args = TYPE_ARG_TYPES (TREE_TYPE (node));
554               if (TREE_CODE (TREE_TYPE (node)) == METHOD_TYPE)
555                 args = TREE_CHAIN (args);
556               put_decl_string ("(", 1);
557               for ( ; args != end_params_node;  args = TREE_CHAIN (args), i++)
558                 {
559                   if (i > 0)
560                     put_decl_string (",", 1);
561                   put_decl_node (TREE_VALUE (args));
562                 }
563               put_decl_string (")", 1);
564             }
565         }
566       else
567         put_decl_node (DECL_NAME (node));
568     }
569   else if (TREE_CODE_CLASS (TREE_CODE (node)) == 't'
570       && TYPE_NAME (node) != NULL_TREE)
571     {
572       if (TREE_CODE (node) == RECORD_TYPE && TYPE_ARRAY_P (node))
573         {
574           put_decl_node (TYPE_ARRAY_ELEMENT (node));
575           put_decl_string("[]", 2);
576         }
577       else if (node == promoted_byte_type_node)
578         put_decl_string ("byte", 4);
579       else if (node == promoted_short_type_node)
580         put_decl_string ("short", 5);
581       else if (node == promoted_char_type_node)
582         put_decl_string ("char", 4);
583       else if (node == promoted_boolean_type_node)
584         put_decl_string ("boolean", 7);
585       else if (node == void_type_node && was_pointer)
586         put_decl_string ("null", 4);
587       else
588         put_decl_node (TYPE_NAME (node));
589     }
590   else if (TREE_CODE (node) == IDENTIFIER_NODE)
591     put_decl_string (IDENTIFIER_POINTER (node), IDENTIFIER_LENGTH (node));
592   else
593     put_decl_string ("<unknown>", -1);
594 }
595
596 /* Return a user-friendly name for DECL.
597    The resulting string is only valid until the next call.
598    The value of the hook decl_printable_name is this function,
599    which is also called directly by lang_print_error. */
600
601 const char *
602 lang_printable_name (decl, v)
603      tree decl;
604      int v  __attribute__ ((__unused__));
605 {
606   decl_bufpos = 0;
607   put_decl_node (decl);
608   put_decl_string ("", 1);
609   return decl_buf;
610 }
611
612 /* Does the same thing that lang_printable_name, but add a leading
613    space to the DECL name string -- With Leading Space.  */
614
615 const char *
616 lang_printable_name_wls (decl, v)
617      tree decl;
618      int v  __attribute__ ((__unused__));
619 {
620   decl_bufpos = 1;
621   put_decl_node (decl);
622   put_decl_string ("", 1);
623   decl_buf [0] = ' ';
624   return decl_buf;
625 }
626
627 /* Print on stderr the current class and method context.  This function
628    is the value of the hook print_error_function, called from toplev.c. */
629
630 static void
631 lang_print_error (context, file)
632      diagnostic_context *context __attribute__((__unused__));
633      const char *file;
634 {
635   static tree last_error_function_context = NULL_TREE;
636   static tree last_error_function = NULL;
637   static int initialized_p;
638
639   /* Register LAST_ERROR_FUNCTION_CONTEXT and LAST_ERROR_FUNCTION with
640      the garbage collector.  */
641   if (!initialized_p)
642     {
643       ggc_add_tree_root (&last_error_function_context, 1);
644       ggc_add_tree_root (&last_error_function, 1);
645       initialized_p = 1;
646     }
647
648   if (current_function_decl != NULL
649       && DECL_CONTEXT (current_function_decl) != last_error_function_context)
650     {
651       if (file)
652         fprintf (stderr, "%s: ", file);
653
654       last_error_function_context = DECL_CONTEXT (current_function_decl);
655       fprintf (stderr, "In class `%s':\n",
656                lang_printable_name (last_error_function_context, 0));
657     }
658   if (last_error_function != current_function_decl)
659     {
660       if (file)
661         fprintf (stderr, "%s: ", file);
662
663       if (current_function_decl == NULL)
664         fprintf (stderr, "At top level:\n");
665       else
666         {
667           const char *name = lang_printable_name (current_function_decl, 2);
668           fprintf (stderr, "In %s `%s':\n",
669                    (DECL_CONSTRUCTOR_P (current_function_decl) ? "constructor" 
670                     : "method"),
671                    name);
672         }
673
674       last_error_function = current_function_decl;
675     }
676
677 }
678
679 static void
680 java_init ()
681 {
682 #if 0
683   extern int flag_minimal_debug;
684   flag_minimal_debug = 0;
685 #endif
686
687   jcf_path_init ();
688   jcf_path_seal (version_flag);
689
690   decl_printable_name = lang_printable_name;
691   print_error_function = lang_print_error;
692   lang_expand_expr = java_lang_expand_expr;
693
694   /* Append to Gcc tree node definition arrays */
695
696   memcpy (tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
697           java_tree_code_type,
698           (int)LAST_JAVA_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE);
699   memcpy (tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE,
700           java_tree_code_length,
701           (LAST_JAVA_TREE_CODE - 
702            (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int));
703   memcpy (tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE,
704           java_tree_code_name,
705           (LAST_JAVA_TREE_CODE - 
706            (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
707
708   using_eh_for_cleanups ();
709 }
710
711 /* This doesn't do anything on purpose. It's used to satisfy the
712    print_error_function hook we don't print error messages with bogus
713    function prototypes.  */
714
715 static void
716 java_dummy_print (c, s)
717      diagnostic_context *c __attribute__ ((__unused__));
718      const char *s __attribute__ ((__unused__));
719 {
720 }
721
722 /* Called to install the PRINT_ERROR_FUNCTION hook differently
723    according to LEVEL. LEVEL is 1 during early parsing, when function
724    prototypes aren't fully resolved. print_error_function is set so it
725    doesn't print incomplete function prototypes. When LEVEL is 2,
726    function prototypes are fully resolved and can be printed when
727    reporting errors.  */
728
729 void lang_init_source (level)
730      int level;
731 {
732   if (level == 1)
733     print_error_function = java_dummy_print;
734   else 
735     print_error_function = lang_print_error;
736 }
737
738 static void
739 java_init_options ()
740 {
741   flag_bounds_check = 1;
742   flag_exceptions = 1;
743   flag_non_call_exceptions = 1;
744 }
745
746 const char *
747 lang_identify ()
748 {
749   return "Java";
750 }
751
752 /* Hooks for print_node.  */
753
754 void
755 print_lang_decl (file, node, indent)
756      FILE *file __attribute ((__unused__));
757      tree node __attribute ((__unused__));
758      int indent __attribute ((__unused__));
759 {
760 }
761
762 void
763 print_lang_type (file, node, indent)
764      FILE *file __attribute ((__unused__));
765      tree node __attribute ((__unused__));
766      int indent __attribute ((__unused__));
767 {
768 }
769
770 void
771 print_lang_identifier (file, node, indent)
772      FILE *file __attribute ((__unused__));
773      tree node __attribute ((__unused__));
774      int indent __attribute ((__unused__));
775 {
776 }
777
778 void
779 print_lang_statistics ()
780 {
781 }
782
783 /* used by print-tree.c */
784
785 void
786 lang_print_xnode (file, node, indent)
787      FILE *file __attribute ((__unused__));
788      tree node __attribute ((__unused__));
789      int indent __attribute ((__unused__));
790 {
791 }
792
793 /* Return the typed-based alias set for T, which may be an expression
794    or a type.  Return -1 if we don't do anything special.  */
795
796 HOST_WIDE_INT
797 lang_get_alias_set (t)
798      tree t ATTRIBUTE_UNUSED;
799 {
800   return -1;
801 }