OSDN Git Service

Warning fixes:
[pf3gnuchains/gcc-fork.git] / gcc / ch / satisfy.c
1 /* Name-satisfaction for GNU Chill compiler.
2    Copyright (C) 1993 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "tree.h"
23 #include "flags.h"
24 #include "ch-tree.h"
25 #include "lex.h"
26 #include "toplev.h"
27
28 #define SATISFY(ARG) ((ARG) = satisfy(ARG, chain))
29
30 struct decl_chain
31 {
32   struct decl_chain *prev;
33   /* DECL can be a decl, or a POINTER_TYPE or a REFERENCE_TYPE. */
34   tree decl;
35 };
36
37 /* forward declaration */
38 tree satisfy PROTO((tree, struct decl_chain *));
39
40 static struct decl_chain dummy_chain;
41 #define LOOKUP_ONLY (chain==&dummy_chain)
42
43 /* Recursive helper routine to logically reverse the chain. */
44 static void
45 cycle_error_print (chain, decl)
46      struct decl_chain *chain;
47      tree decl;
48 {
49   if (chain->decl != decl)
50     {
51       cycle_error_print (chain->prev, decl);
52       if (TREE_CODE_CLASS (TREE_CODE (chain->decl)) == 'd')
53         error_with_decl (chain->decl, "  `%s', which depends on ...");
54     }
55 }
56
57 tree
58 safe_satisfy_decl (decl, prev_chain)
59      tree decl;
60      struct decl_chain *prev_chain;
61 {
62   struct decl_chain new_link;
63   struct decl_chain *link;
64   struct decl_chain *chain = prev_chain;
65   char *save_filename = input_filename;
66   int save_lineno = lineno;
67   tree result = decl;
68   
69   if (decl == NULL_TREE)
70     return decl;
71
72   if (!LOOKUP_ONLY)
73     {
74       int pointer_type_breaks_cycle = 0;
75       /* Look for a cycle.
76          We could do this test more efficiently by setting a flag.  FIXME */
77       for (link = prev_chain; link != NULL; link = link->prev)
78         {
79           if (TREE_CODE_CLASS (TREE_CODE (link->decl)) != 'd')
80             pointer_type_breaks_cycle = 1;
81           if (link->decl == decl)
82             {
83               if (!pointer_type_breaks_cycle)
84                 {
85                   error_with_decl (decl, "Cycle: `%s' depends on ...");
86                   cycle_error_print (prev_chain, decl);
87                   error_with_decl (decl, "  `%s'");
88                   return error_mark_node;
89                 }
90               /* There is a cycle, but it includes a pointer type,
91                  so we're OK.  However, we still have to continue
92                  the satisfy (for example in case this is a TYPE_DECL
93                  that points to a LANG_DECL).  The cycle-check for
94                  POINTER_TYPE/REFERENCE_TYPE should stop the recursion. */
95               break;
96             }
97         }
98
99       new_link.decl = decl;
100       new_link.prev = prev_chain;
101       chain = &new_link;
102     }
103
104   input_filename = DECL_SOURCE_FILE (decl);
105   lineno = DECL_SOURCE_LINE (decl);
106
107   switch ((enum chill_tree_code)TREE_CODE (decl))
108     {
109     case ALIAS_DECL:
110       if (!LOOKUP_ONLY && !DECL_POSTFIX_ALL(decl))
111         result = safe_satisfy_decl (DECL_ABSTRACT_ORIGIN (decl), chain);
112       break;
113     case BASED_DECL:
114       SATISFY (TREE_TYPE (decl));
115       SATISFY (DECL_ABSTRACT_ORIGIN (decl));
116       break;
117     case CONST_DECL:
118       SATISFY (TREE_TYPE (decl));
119       SATISFY (DECL_INITIAL (decl));
120       if (!LOOKUP_ONLY)
121         {
122           if (DECL_SIZE (decl) == 0)
123             {
124               tree init_expr = DECL_INITIAL (decl);
125               tree init_type;
126               tree specified_mode = TREE_TYPE (decl);
127
128               if (init_expr == NULL_TREE
129                   || TREE_CODE (init_expr) == ERROR_MARK)
130                 goto bad_const;
131               init_type = TREE_TYPE (init_expr);
132               if (specified_mode == NULL_TREE)
133                 {
134                   if (init_type == NULL_TREE)
135                     {
136                       check_have_mode (init_expr, "SYN without mode");
137                       goto bad_const;
138                     }
139                   TREE_TYPE (decl) = init_type;
140                   CH_DERIVED_FLAG (decl) = CH_DERIVED_FLAG (init_expr);
141                 }
142               else if (CH_IS_ASSOCIATION_MODE (specified_mode) ||
143                        CH_IS_ACCESS_MODE (specified_mode) || CH_IS_TEXT_MODE (specified_mode) ||
144                        CH_IS_BUFFER_MODE (specified_mode) || CH_IS_EVENT_MODE (specified_mode))
145                 {
146                   error ("SYN of this mode not allowed");
147                   goto bad_const;
148                 }
149               else if (!CH_COMPATIBLE (init_expr, specified_mode))
150                 {
151                   error ("mode of SYN incompatible with value");
152                   goto bad_const;
153                 } 
154               else if (discrete_type_p (specified_mode)
155                        && TREE_CODE (init_expr) == INTEGER_CST
156                        && (compare_int_csts (LT_EXPR, init_expr,
157                                              TYPE_MIN_VALUE (specified_mode))
158                            || compare_int_csts (GT_EXPR, init_expr,
159                                                 TYPE_MAX_VALUE(specified_mode))
160                            ))
161                 {
162                   error ("SYN value outside range of its mode");
163                   /* set an always-valid initial value to prevent 
164                      other errors. */
165                   DECL_INITIAL (decl) = TYPE_MIN_VALUE (specified_mode);
166                 }
167               else if (CH_STRING_TYPE_P (specified_mode) 
168                        && (init_type && CH_STRING_TYPE_P (init_type))
169                        && integer_zerop (string_assignment_condition (specified_mode, init_expr)))
170                 {
171                   error ("INIT string too large for mode");
172                   DECL_INITIAL (decl) = error_mark_node;
173                 }
174               else
175                 {
176                   struct ch_class class;
177                   class.mode = TREE_TYPE (decl);
178                   class.kind = CH_VALUE_CLASS;
179                   DECL_INITIAL (decl)
180                     = convert_to_class (class, DECL_INITIAL (decl));
181                 }
182               /* DECL_SIZE is set to prevent re-doing this stuff. */
183               DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (decl));
184               if (! TREE_CONSTANT (DECL_INITIAL (decl))
185                   && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK)
186                 {
187                   error_with_decl (decl,
188                                    "value of %s is not a valid constant");
189                   DECL_INITIAL (decl) = error_mark_node;
190                 }
191             }
192           result = DECL_INITIAL (decl);
193         }
194       break;
195     bad_const:
196       DECL_INITIAL (decl) = error_mark_node;
197       TREE_TYPE (decl) = error_mark_node;
198       return error_mark_node;
199     case FUNCTION_DECL:
200       SATISFY (TREE_TYPE (decl));
201       if (CH_DECL_PROCESS (decl))
202         safe_satisfy_decl (DECL_TASKING_CODE_DECL (decl), 
203                            prev_chain);
204       break;
205     case PARM_DECL:
206       SATISFY (TREE_TYPE (decl));
207       break;
208     /* RESULT_DECL doesn't need to be satisfied;  
209        it's only built internally in pass 2 */
210     case TYPE_DECL:
211       SATISFY (TREE_TYPE (decl));
212       if (CH_DECL_SIGNAL (decl))
213         safe_satisfy_decl (DECL_TASKING_CODE_DECL (decl), 
214                            prev_chain);
215       if (!LOOKUP_ONLY)
216         {
217           if (TYPE_NAME (TREE_TYPE (decl)) == NULL_TREE)
218             TYPE_NAME (TREE_TYPE (decl)) = decl;
219           layout_decl (decl, 0);
220           if (CH_DECL_SIGNAL (decl) && CH_TYPE_NONVALUE_P (TREE_TYPE (decl)))
221             error ("mode with non-value property in signal definition");
222           result = TREE_TYPE (decl);
223         }
224       break;
225     case VAR_DECL:
226       SATISFY (TREE_TYPE (decl));
227       if (!LOOKUP_ONLY)
228         {
229           layout_decl (decl, 0);
230           if (TREE_READONLY (TREE_TYPE (decl)))
231             TREE_READONLY (decl) = 1;
232         }
233       break;
234     default:
235       ;
236     }
237
238   /* Now set the DECL_RTL, if needed. */
239   if (!LOOKUP_ONLY && DECL_RTL (decl) == 0
240       && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL
241           || TREE_CODE (decl) == CONST_DECL))
242     {
243       if (TREE_CODE (decl) == FUNCTION_DECL && decl_function_context (decl))
244         make_function_rtl (decl);
245       else if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
246         expand_decl (decl);
247       else
248         { char * asm_name;
249           if (current_module == 0 || TREE_PUBLIC (decl)
250               || current_function_decl)
251             asm_name = NULL;
252           else
253             {
254               asm_name = (char*)
255                 alloca (IDENTIFIER_LENGTH (current_module->prefix_name)
256                         + IDENTIFIER_LENGTH (DECL_NAME (decl)) + 3);
257               sprintf (asm_name, "%s__%s",
258                        IDENTIFIER_POINTER (current_module->prefix_name),
259                        IDENTIFIER_POINTER (DECL_NAME (decl)));
260             }
261           make_decl_rtl (decl, asm_name, TREE_PUBLIC (decl));
262         }
263     }
264
265   input_filename = save_filename;
266   lineno = save_lineno;
267
268   return result;
269 }
270
271 tree
272 satisfy_decl (decl, lookup_only)
273      tree decl;
274      int lookup_only;
275 {
276   return safe_satisfy_decl (decl, lookup_only ? &dummy_chain : NULL);
277 }
278
279 static void
280 satisfy_list (exp, chain)
281      register tree exp;
282      struct decl_chain *chain;
283 {
284   for (; exp != NULL_TREE; exp = TREE_CHAIN (exp))
285     {
286       SATISFY (TREE_VALUE (exp));
287       SATISFY (TREE_PURPOSE (exp));
288     }
289 }
290
291 static void
292 satisfy_list_values (exp, chain)
293      register tree exp;
294      struct decl_chain *chain;
295 {
296   for (; exp != NULL_TREE; exp = TREE_CHAIN (exp))
297     {
298       SATISFY (TREE_VALUE (exp));
299     }
300 }
301
302 tree
303 satisfy (exp, chain)
304      tree exp;
305      struct decl_chain *chain;
306 {
307   int arg_length;
308   int i;
309   tree decl;
310
311   if (exp == NULL_TREE)
312     return NULL_TREE;
313
314 #if 0
315   if (!UNSATISFIED (exp))
316     return exp;
317 #endif
318
319   switch (TREE_CODE_CLASS (TREE_CODE (exp)))
320     {
321     case 'd':
322       if (!LOOKUP_ONLY)
323         return safe_satisfy_decl (exp, chain);
324       break;
325     case 'r':
326     case 's':
327     case '<':
328     case 'e':
329       switch ((enum chill_tree_code)TREE_CODE (exp))
330         {
331         case REPLICATE_EXPR:
332           goto binary_op;
333         case TRUTH_NOT_EXPR:
334           goto unary_op;
335         case COMPONENT_REF:
336           SATISFY (TREE_OPERAND (exp, 0));
337           if (!LOOKUP_ONLY && TREE_TYPE (exp) == NULL_TREE)
338             return resolve_component_ref (exp);
339           return exp;
340         case CALL_EXPR:
341           SATISFY (TREE_OPERAND (exp, 0));
342           SATISFY (TREE_OPERAND (exp, 1));
343           if (!LOOKUP_ONLY && TREE_TYPE (exp) == NULL_TREE)
344             return build_generalized_call (TREE_OPERAND (exp, 0),
345                                            TREE_OPERAND (exp, 1));
346           return exp;
347         case CONSTRUCTOR:
348           { tree link = TREE_OPERAND (exp, 1);
349             int expand_needed = TREE_TYPE (exp)
350               && TREE_CODE_CLASS (TREE_CODE (TREE_TYPE (exp))) != 't';
351             for (; link != NULL_TREE; link = TREE_CHAIN (link))
352               {
353                 SATISFY (TREE_VALUE (link));
354                 if (!TUPLE_NAMED_FIELD (link))
355                   SATISFY (TREE_PURPOSE (link));
356               }
357             SATISFY (TREE_TYPE (exp));
358             if (expand_needed && !LOOKUP_ONLY)
359               {
360                 tree type = TREE_TYPE (exp);
361                 TREE_TYPE (exp) = NULL_TREE; /* To force expansion. */
362                 return chill_expand_tuple (type, exp);
363               }
364             return exp;
365           }
366         default:
367           ;
368         }
369       arg_length = tree_code_length[TREE_CODE (exp)];
370       for (i = 0; i < arg_length; i++)
371         SATISFY (TREE_OPERAND (exp, i));
372       return exp;
373     case '1':
374     unary_op:
375       SATISFY (TREE_OPERAND (exp, 0));
376       if ((enum chill_tree_code)TREE_CODE (exp) == PAREN_EXPR)
377         return TREE_OPERAND (exp, 0);
378       if (!LOOKUP_ONLY)
379         return finish_chill_unary_op (exp);
380       break;
381     case '2':
382     binary_op:
383       SATISFY (TREE_OPERAND (exp, 0));
384       SATISFY (TREE_OPERAND (exp, 1));
385       if (!LOOKUP_ONLY && TREE_CODE (exp) != RANGE_EXPR)
386         return finish_chill_binary_op (exp);
387       break;
388     case 'x':
389       switch ((enum chill_tree_code)TREE_CODE (exp))
390         {
391         case IDENTIFIER_NODE:
392           decl = lookup_name (exp);
393           if (decl == NULL)
394             {
395               if (LOOKUP_ONLY)
396                 return exp;
397               error ("undeclared identifier `%s'", IDENTIFIER_POINTER (exp));
398               return error_mark_node;
399             }
400           if (LOOKUP_ONLY)
401             return decl;
402           return safe_satisfy_decl (decl, chain);
403         case TREE_LIST:
404           satisfy_list (exp, chain);
405           break;
406         default:
407           ;
408         }
409       break;
410     case 't':
411       /* If TYPE_SIZE is non-NULL, exp and its subfields has already been
412          satified and laid out.  The exception is pointer and reference types,
413          which we layout before we lay out their TREE_TYPE. */
414       if (TYPE_SIZE (exp) && TREE_CODE (exp) != POINTER_TYPE
415           && TREE_CODE (exp) != REFERENCE_TYPE)
416         return exp;
417       if (TYPE_MAIN_VARIANT (exp) != exp)
418         SATISFY (TYPE_MAIN_VARIANT (exp));
419       switch ((enum chill_tree_code)TREE_CODE (exp))
420         {
421         case LANG_TYPE:
422           {
423             tree d = TYPE_DOMAIN (exp);
424             tree t = satisfy (TREE_TYPE (exp), chain);
425             SATISFY (d);
426             /* It is possible that one of the above satisfy calls recursively
427                caused exp to be satisfied, in which case we're done. */
428             if (TREE_CODE (exp) != LANG_TYPE)
429               return exp;
430             TREE_TYPE (exp) = t;
431             TYPE_DOMAIN (exp) = d;
432             if (!LOOKUP_ONLY)
433               exp = smash_dummy_type (exp);
434           }
435           break;
436         case ARRAY_TYPE:
437           SATISFY (TREE_TYPE (exp));
438           SATISFY (TYPE_DOMAIN (exp));
439           SATISFY (TYPE_ATTRIBUTES (exp));
440           if (!LOOKUP_ONLY)
441             CH_TYPE_NONVALUE_P (exp) = CH_TYPE_NONVALUE_P (TREE_TYPE (exp));
442           if (!TYPE_SIZE (exp)  && !LOOKUP_ONLY)
443             exp = layout_chill_array_type (exp);
444           break;
445         case FUNCTION_TYPE:
446           SATISFY (TREE_TYPE (exp));
447           if (TREE_CODE_CLASS (TREE_CODE (TREE_TYPE (exp))) != 't'
448               && !LOOKUP_ONLY && TREE_CODE (TREE_TYPE (exp)) != ERROR_MARK)
449             {
450               error ("RETURNS spec with invalid mode");
451               TREE_TYPE (exp) = error_mark_node;
452             }
453           satisfy_list_values (TYPE_ARG_TYPES (exp), chain);
454           if (!TYPE_SIZE (exp)  && !LOOKUP_ONLY)
455             layout_type (exp);
456           break;
457         case ENUMERAL_TYPE:
458           if (TYPE_SIZE (exp) == NULL_TREE && !LOOKUP_ONLY)
459             { tree pair;
460               /* FIXME:  Should this use satisfy_decl? */
461               for (pair = TYPE_VALUES (exp); pair; pair = TREE_CHAIN (pair))
462                 SATISFY (DECL_INITIAL (TREE_VALUE (pair)));
463               layout_enum (exp);
464             }
465           break;
466         case INTEGER_TYPE:
467           SATISFY (TYPE_MIN_VALUE (exp));
468           SATISFY (TYPE_MAX_VALUE (exp));
469           if (TREE_TYPE (exp) != NULL_TREE)
470             { /* A range type */
471               if (TREE_TYPE (exp) != ridpointers[(int) RID_RANGE]
472                   && TREE_TYPE (exp) != ridpointers[(int) RID_BIN]
473                   && TREE_TYPE (exp) != string_index_type_dummy)
474                 SATISFY (TREE_TYPE (exp));
475               if (!TYPE_SIZE (exp)  && !LOOKUP_ONLY)
476                 exp = layout_chill_range_type (exp, 1);
477             }
478           break;
479         case POINTER_TYPE:
480         case REFERENCE_TYPE:
481           if (LOOKUP_ONLY)
482             SATISFY (TREE_TYPE (exp));
483           else
484             {
485               struct decl_chain *link;
486               int already_seen = 0;
487               for (link = chain; ; link = link->prev)
488                 {
489                   if (link == NULL)
490                     {   
491                       struct decl_chain new_link;
492                       new_link.decl = exp;
493                       new_link.prev = chain;
494                       TREE_TYPE (exp) = satisfy (TREE_TYPE (exp), &new_link);
495                       break;
496                     }
497                   else if (link->decl == exp)
498                     {
499                       already_seen = 1;
500                       break;
501                     }
502                 }
503               if (!TYPE_SIZE (exp))
504                 {
505                   layout_type (exp);
506                   if (TREE_CODE (exp) == REFERENCE_TYPE)
507                     CH_NOVELTY (exp) = CH_NOVELTY (TREE_TYPE (exp));
508                   if (! already_seen)
509                     {
510                       tree valtype = TREE_TYPE (exp);
511                       if (TREE_CODE_CLASS (TREE_CODE (valtype)) != 't')
512                         {
513                           if (TREE_CODE (valtype) != ERROR_MARK)
514                             error ("operand to REF is not a mode");
515                           TREE_TYPE (exp) = error_mark_node;
516                           return error_mark_node;
517                         }
518                       else if (TREE_CODE (exp) == POINTER_TYPE
519                                && TYPE_POINTER_TO (valtype) == NULL)
520                         TYPE_POINTER_TO (valtype) = exp;
521                     }
522                 }
523             }
524           break;
525         case RECORD_TYPE:
526           {
527             /* FIXME: detected errors in here will be printed as
528                often as this sequence runs. Find another way or
529                place to print the errors. */
530             /* if we have an ACCESS or TEXT mode we have to set
531                maximum_field_alignment to 0 to fit with runtime
532                system, even when we compile with -fpack. */
533             extern int maximum_field_alignment;
534             int save_maximum_field_alignment = maximum_field_alignment;
535
536             if (CH_IS_ACCESS_MODE (exp) || CH_IS_TEXT_MODE (exp))
537               maximum_field_alignment = 0;
538
539             for (decl = TYPE_FIELDS (exp); decl; decl = TREE_CHAIN (decl))
540               {
541                 SATISFY (TREE_TYPE (decl));
542                 if (!LOOKUP_ONLY)
543                   {
544                     /* if we have a UNION_TYPE here (variant structure), check for
545                        non-value mode in it. This is not allowed (Z.200/pg. 33) */
546                     if (TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE &&
547                         CH_TYPE_NONVALUE_P (TREE_TYPE (decl)))
548                       {
549                         error ("field with non-value mode in variant structure not allowed");
550                         TREE_TYPE (decl) = error_mark_node;
551                       }
552                     /* RECORD_TYPE gets the non-value property if one of the
553                        fields has the non-value property */
554                     CH_TYPE_NONVALUE_P (exp) |= CH_TYPE_NONVALUE_P (TREE_TYPE (decl));
555                   }
556                 if (TREE_CODE (decl) == CONST_DECL)
557                   {
558                     SATISFY (DECL_INITIAL (decl));
559                     if (!LOOKUP_ONLY)
560                       {
561                         if (CH_IS_BUFFER_MODE (exp) || CH_IS_EVENT_MODE (exp))
562                           DECL_INITIAL (decl)
563                             = check_queue_size (exp, DECL_INITIAL (decl));
564                         else if (CH_IS_TEXT_MODE (exp) &&
565                                  DECL_NAME (decl) == get_identifier ("__textlength"))
566                           DECL_INITIAL (decl)
567                             = check_text_length (DECL_INITIAL (decl));
568                       }
569                   }
570                 else if (TREE_CODE (decl) == FIELD_DECL)
571                   {
572                     SATISFY (DECL_INITIAL (decl));
573                   }
574               }
575             satisfy_list (TYPE_TAG_VALUES (exp), chain);
576             if (!TYPE_SIZE (exp)  && !LOOKUP_ONLY)
577               exp = layout_chill_struct_type (exp);
578             maximum_field_alignment = save_maximum_field_alignment;
579
580             /* perform some checks on nonvalue modes, they are record_mode's */
581             if (!LOOKUP_ONLY)
582               {
583                 if (CH_IS_BUFFER_MODE (exp))
584                   {
585                     tree elemmode = buffer_element_mode (exp);
586                     if (elemmode != NULL_TREE && CH_TYPE_NONVALUE_P (elemmode))
587                       {
588                         error ("buffer element mode must not have non-value property");
589                         invalidate_buffer_element_mode (exp);
590                       }
591                   }
592                 else if (CH_IS_ACCESS_MODE (exp))
593                   {
594                     tree recordmode = access_recordmode (exp);
595                     if (recordmode != NULL_TREE && CH_TYPE_NONVALUE_P (recordmode))
596                       {
597                         error ("recordmode must not have the non-value property");
598                         invalidate_access_recordmode (exp);
599                       }
600                   }
601               }
602           }
603           break;
604         case SET_TYPE:
605           SATISFY (TYPE_DOMAIN (exp));
606           if (!TYPE_SIZE (exp)  && !LOOKUP_ONLY)
607             exp = layout_powerset_type (exp);
608           break;
609         case UNION_TYPE:
610           for (decl = TYPE_FIELDS (exp); decl; decl = TREE_CHAIN (decl))
611             {
612               SATISFY (TREE_TYPE (decl));
613               if (!LOOKUP_ONLY)
614                 CH_TYPE_NONVALUE_P (exp) |= CH_TYPE_NONVALUE_P (TREE_TYPE (decl));
615             }
616           if (!TYPE_SIZE (exp)  && !LOOKUP_ONLY)
617             exp = layout_chill_variants (exp);
618           break;
619         default:
620           ;
621         }
622     }
623   return exp;
624 }