1 
2 
3 /*
4  * This software was developed by U.S. Government employees as part of
5  * their official duties and is not subject to copyright.
6  *
7  * $Log: resolve.c,v $
8  * Revision 1.14  1997/01/21 19:19:51  dar
9  * made C++ compatible
10  *
11  * Revision 1.13  1995/06/08  22:59:59  clark
12  * bug fixes
13  *
14  * Revision 1.12  1995/05/17  14:28:07  libes
15  * Fixed bug in WHEREresolve return value.
16  *
17  * Revision 1.11  1995/04/08  20:54:18  clark
18  * WHERE rule resolution bug fixes
19  *
20  * Revision 1.11  1995/04/08  20:49:50  clark
21  * WHERE
22  *
23  * Revision 1.10  1995/03/09  18:44:02  clark
24  * various fixes for caddetc - before interface clause changes
25  *
26  * Revision 1.9  1994/11/22  18:32:39  clark
27  * Part 11 IS; group reference
28  *
29  * Revision 1.8  1994/11/10  19:20:03  clark
30  * Update to IS
31  *
32  * Revision 1.7  1994/05/11  19:51:24  libes
33  * numerous fixes
34  *
35  * Revision 1.6  1993/10/15  18:48:48  libes
36  * CADDETC certified
37  *
38  * Revision 1.4  1993/02/16  03:24:37  libes
39  * fixed numerous type botches (see comment in expparse.y)
40  * fixed statement handling botches
41  * completed implicit sub/supertypes
42  * misc other fixeds
43  *
44  * Revision 1.3  1993/01/19  22:17:27  libes
45  * *** empty log message ***
46  *
47  * Revision 1.2  1992/09/16  18:23:08  libes
48  * fixed bug in TYPEresolve connecting reference types back to using types
49  *
50  * Revision 1.1  1992/08/18  17:13:43  libes
51  * Initial revision
52  *
53  * Revision 1.4  1992/06/08  18:06:57  libes
54  * prettied up interface to print_objects_when_running
55  *
56  */
57 
58 #include <assert.h>
59 #include <sc_memmgr.h>
60 #include <stdlib.h>
61 #include "express/resolve.h"
62 #include "stack.h"
63 #include "express/schema.h"
64 #include "express/express.h"
65 
66 int print_objects_while_running = 0;
67 
68 Error ERROR_undefined_attribute = ERROR_none;
69 Error ERROR_undefined_type = ERROR_none;
70 Error ERROR_undefined_schema = ERROR_none;
71 Error ERROR_unknown_attr_in_entity = ERROR_none;
72 Error ERROR_unknown_subtype = ERROR_none;
73 Error ERROR_unknown_supertype = ERROR_none;
74 Error ERROR_circular_reference = ERROR_none;
75 Error ERROR_ambiguous_attribute = ERROR_none;
76 Error ERROR_ambiguous_group = ERROR_none;
77 Error WARNING_fn_skip_branch = ERROR_none;
78 Error WARNING_case_skip_label = ERROR_none;
79 
80 
81 static void ENTITYresolve_subtypes PROTO( ( Schema ) );
82 static void ENTITYresolve_supertypes PROTO( ( Entity ) );
83 static void TYPEresolve_expressions PROTO( ( Type, Scope ) );
84 
85 static Error ERROR_wrong_arg_count;
86 static Error ERROR_supertype_resolve;
87 static Error ERROR_subtype_resolve;
88 static Error ERROR_not_a_type;
89 static Error ERROR_funcall_not_a_function;
90 static Error ERROR_undefined_func;
91 static Error ERROR_undefined;
92 static Error ERROR_expected_proc;
93 static Error ERROR_no_such_procedure;
94 static Error ERROR_query_requires_aggregate;
95 static Error ERROR_self_is_unknown;
96 static Error ERROR_inverse_bad_attribute;
97 static Error ERROR_inverse_bad_entity;
98 static Error ERROR_missing_supertype;
99 static Error ERROR_subsuper_loop;
100 static Error ERROR_subsuper_continuation;
101 static Error ERROR_select_loop;
102 static Error ERROR_select_continuation;
103 static Error ERROR_type_is_entity;
104 static Error ERROR_overloaded_attribute;
105 static Error ERROR_redecl_no_such_attribute;
106 static Error ERROR_redecl_no_such_supertype;
107 static Error ERROR_missing_self;
108 static Error WARNING_unique_qual_redecl;
109 
110 static Type self = 0;   /**< always points to current value of SELF or 0 if none */
111 
112 static bool found_self;  /**< remember whether we've seen a SELF in a WHERE clause */
113 
114 /***********************/
115 /* function prototypes */
116 /***********************/
117 
118 static int WHEREresolve PROTO( ( Linked_List, Scope, int ) );
119 extern void VAR_resolve_expressions PROTO( ( Variable, Entity ) );
120 extern void VAR_resolve_types PROTO( ( Variable v ) );
121 
122 /** Initialize the Fed-X second pass. */
RESOLVEinitialize(void)123 void RESOLVEinitialize( void ) {
124     ERROR_undefined = ERRORcreate(
125                           "Reference to undefined object %s.", SEVERITY_ERROR );
126 
127     ERROR_undefined_attribute = ERRORcreate(
128                                     "Reference to undefined attribute %s.", SEVERITY_ERROR );
129 
130     ERROR_undefined_type = ERRORcreate(
131                                "Reference to undefined type %s.", SEVERITY_ERROR );
132 
133     ERROR_undefined_schema = ERRORcreate(
134                                  "Reference to undefined schema %s.", SEVERITY_ERROR );
135 
136     ERROR_unknown_attr_in_entity = ERRORcreate(
137                                        "Unknown attribute %s in entity %s.", SEVERITY_ERROR );
138 
139     ERROR_unknown_subtype = ERRORcreate(
140                                 "Unknown subtype %s for entity %s.", SEVERITY_EXIT );
141     /*"Unknown subtype %s for entity %s.", SEVERITY_WARNING);*/
142 
143     ERROR_unknown_supertype = ERRORcreate(
144                                   "Unknown supertype %s for entity %s.", SEVERITY_ERROR );
145 
146     ERROR_circular_reference = ERRORcreate(
147                                    "Circularity: definition of %s references itself.", SEVERITY_ERROR );
148     /*"Circular definition: schema %s referenced schema %s.",SEVERITY_ERROR);*/
149 
150     ERROR_subsuper_loop = ERRORcreate(
151                               "Entity %s is a subtype of itself", SEVERITY_ERROR );
152     ERROR_subsuper_continuation = ERRORcreate(
153                                       "  (via supertype entity %s)", SEVERITY_ERROR );
154 
155     ERROR_select_loop = ERRORcreate(
156                             "Select type %s selects itself", SEVERITY_ERROR );
157     ERROR_select_continuation = ERRORcreate(
158                                     "  (via select type %s)", SEVERITY_ERROR );
159 
160     ERROR_supertype_resolve = ERRORcreate(
161                                   "Supertype %s is not an entity (line %d).", SEVERITY_ERROR );
162 
163     ERROR_subtype_resolve = ERRORcreate(
164                                 "Subtype %s resolves to non-entity %s on line %d.", SEVERITY_ERROR );
165 
166     ERROR_not_a_type = ERRORcreate(
167                            "Expected a type (or entity) but %s is %s.", SEVERITY_ERROR );
168 
169     ERROR_funcall_not_a_function = ERRORcreate(
170                                        "Function call of %s which is not a function.", SEVERITY_ERROR );
171 
172     ERROR_undefined_func = ERRORcreate(
173                                "Function %s undefined.", SEVERITY_ERROR );
174 
175     ERROR_expected_proc = ERRORcreate(
176                               "%s is used as a procedure call but is not defined as one (line %d).", SEVERITY_ERROR );
177 
178     ERROR_no_such_procedure = ERRORcreate(
179                                   "No such procedure as %s.", SEVERITY_ERROR );
180 
181     ERROR_wrong_arg_count = ERRORcreate(
182                                 "Call to %s uses %d arguments, but expected %d.", SEVERITY_WARNING );
183 
184     ERROR_query_requires_aggregate = ERRORcreate(
185                                          "Query expression source must be an aggregate.", SEVERITY_ERROR );
186 
187     ERROR_self_is_unknown = ERRORcreate(
188                                 "SELF is not within an entity declaration.", SEVERITY_ERROR );
189 
190     ERROR_inverse_bad_entity = ERRORcreate(
191                                    "Attribute %s is referenced from non-entity-inheriting type.", SEVERITY_ERROR );
192 
193     ERROR_inverse_bad_attribute = ERRORcreate(
194                                       "Unknown attribute %s in entity %s in inverse.", SEVERITY_ERROR );
195 
196     ERROR_missing_supertype = ERRORcreate(
197                                   "Entity %s missing from supertype list for subtype %s.", SEVERITY_ERROR );
198 
199     ERROR_type_is_entity = ERRORcreate(
200                                "An entity (%s) is not acceptable as an underlying type.", SEVERITY_ERROR );
201 
202     ERROR_ambiguous_attribute = ERRORcreate(
203                                     "Ambiguous attribute reference %s.", SEVERITY_WARNING );
204 
205     ERROR_ambiguous_group = ERRORcreate(
206                                 "Ambiguous group reference %s.", SEVERITY_WARNING );
207 
208     ERROR_overloaded_attribute = ERRORcreate(
209                                      "Attribute %s already inherited via supertype %s.", SEVERITY_ERROR );
210 
211     ERROR_redecl_no_such_attribute = ERRORcreate(
212                                          "Redeclared attribute %s not declared in supertype %s.", SEVERITY_ERROR );
213 
214     ERROR_redecl_no_such_supertype = ERRORcreate(
215                                          "No such supertype %s for redeclaration of attribute %s.", SEVERITY_ERROR );
216 
217     ERROR_missing_self = ERRORcreate(
218                              "Domain rule %s must refer to SELF or attribute.", SEVERITY_ERROR );
219 
220     WARNING_fn_skip_branch = ERRORcreate(
221                                  "IF statement condition is always %s. Ignoring branch that is never taken.", SEVERITY_WARNING );
222 
223     WARNING_case_skip_label = ERRORcreate( "CASE label %s cannot be matched. Ignoring its statements.", SEVERITY_WARNING );
224 
225     WARNING_unique_qual_redecl = ERRORcreate( "Possibly unnecessary qualifiers on redeclared attr '%s' in a uniqueness rule of entity '%s'.", SEVERITY_WARNING );
226 
227     ERRORcreate_warning( "circular_subtype", ERROR_subsuper_loop );
228     ERRORcreate_warning( "circular_select", ERROR_select_loop );
229     ERRORcreate_warning( "entity_as_type", ERROR_type_is_entity );
230     ERRORcreate_warning( "invariant_condition", WARNING_fn_skip_branch );
231     ERRORcreate_warning( "invalid_case", WARNING_case_skip_label );
232     ERRORcreate_warning( "unnecessary_qualifiers", WARNING_unique_qual_redecl );
233 }
234 
235 /** Clean up the Fed-X second pass */
RESOLVEcleanup(void)236 void RESOLVEcleanup( void ) {
237     ERRORdestroy( ERROR_undefined );
238     ERRORdestroy( ERROR_undefined_attribute );
239     ERRORdestroy( ERROR_undefined_type );
240     ERRORdestroy( ERROR_undefined_schema );
241     ERRORdestroy( ERROR_unknown_attr_in_entity );
242     ERRORdestroy( ERROR_unknown_subtype );
243     ERRORdestroy( ERROR_unknown_supertype );
244     ERRORdestroy( ERROR_circular_reference );
245     ERRORdestroy( ERROR_subsuper_loop );
246     ERRORdestroy( ERROR_subsuper_continuation );
247     ERRORdestroy( ERROR_select_loop );
248     ERRORdestroy( ERROR_select_continuation );
249     ERRORdestroy( ERROR_supertype_resolve );
250     ERRORdestroy( ERROR_subtype_resolve );
251     ERRORdestroy( ERROR_not_a_type );
252     ERRORdestroy( ERROR_funcall_not_a_function );
253     ERRORdestroy( ERROR_undefined_func );
254     ERRORdestroy( ERROR_expected_proc );
255     ERRORdestroy( ERROR_no_such_procedure );
256     ERRORdestroy( ERROR_wrong_arg_count );
257     ERRORdestroy( ERROR_query_requires_aggregate );
258     ERRORdestroy( ERROR_self_is_unknown );
259     ERRORdestroy( ERROR_inverse_bad_entity );
260     ERRORdestroy( ERROR_inverse_bad_attribute );
261     ERRORdestroy( ERROR_missing_supertype );
262     ERRORdestroy( ERROR_type_is_entity );
263     ERRORdestroy( ERROR_ambiguous_attribute );
264     ERRORdestroy( ERROR_ambiguous_group );
265     ERRORdestroy( ERROR_overloaded_attribute );
266     ERRORdestroy( ERROR_redecl_no_such_attribute );
267     ERRORdestroy( ERROR_redecl_no_such_supertype );
268     ERRORdestroy( ERROR_missing_self );
269     ERRORdestroy( WARNING_case_skip_label );
270     ERRORdestroy( WARNING_fn_skip_branch );
271     ERRORdestroy( WARNING_unique_qual_redecl );
272 }
273 
274 /**
275 ** Retrieve the aggregate type from the underlying types of the select type t_select
276 ** \param t_select the select type to retrieve the aggregate type from
277 ** \param t_agg the current aggregate type
278 ** \return the aggregate type
279 */
TYPE_retrieve_aggregate(Type t_select,Type t_agg)280 Type TYPE_retrieve_aggregate( Type t_select, Type t_agg ) {
281     if( TYPEis_select( t_select ) ) {
282         /* parse the underlying types */
283         LISTdo_links( t_select->u.type->body->list, link )
284         /* the current underlying type */
285         Type t = ( Type ) link->data;
286         if( TYPEis_select( t ) ) {
287             t_agg = TYPE_retrieve_aggregate( t, t_agg );
288         } else if( TYPEis_aggregate( t ) ) {
289             if( t_agg ) {
290                 if( t_agg != t->u.type->body->base ) {
291                     /* 2 underlying types do not have to the same base */
292                     return 0;
293                 }
294             } else {
295                 t_agg = t->u.type->body->base;
296             }
297         } else {
298             /* the underlying type is neither a select nor an aggregate */
299             return 0;
300         }
301 
302         LISTod;
303     }
304 
305     return t_agg;
306 }
307 
308 /**
309 ** \param expr expression to resolve
310 ** \param scope scope in which to resolve
311 ** \param typecheck type to verify against (?)
312 **
313 ** Resolve all references in an expression.
314 ** \note the macro 'EXPresolve' calls this function after checking if expr is already resolved
315 */
EXP_resolve(Expression expr,Scope scope,Type typecheck)316 void EXP_resolve( Expression expr, Scope scope, Type typecheck ) {
317     Function f = 0;
318     Symbol * sym;
319     Generic x;
320     Entity e;
321     Type t;
322     bool func_args_checked = false;
323 
324     /*  if (expr == EXPRESSION_NULL)
325             return;
326     */
327     switch( expr->type->u.type->body->type ) {
328         case funcall_:
329             /* functions with no arguments get handled elsewhere */
330             /* because the parser sees them just like attributes */
331 
332             x = SCOPEfind( scope, expr->symbol.name,
333                            SCOPE_FIND_FUNCTION | SCOPE_FIND_ENTITY );
334             if( !x ) {
335                 ERRORreport_with_symbol( ERROR_undefined_func,
336                                          &expr->symbol, expr->symbol.name );
337                 resolve_failed( expr );
338                 break;
339             }
340             if( ( DICT_type != OBJ_FUNCTION ) && ( DICT_type != OBJ_ENTITY ) ) {
341                 sym = OBJget_symbol( x, DICT_type );
342                 ERRORreport_with_symbol( ERROR_funcall_not_a_function,
343                                          &expr->symbol, sym->name );
344                 resolve_failed( expr );
345                 break;
346             }
347             /* original code accepted rules, too? */
348 
349             /* entities are treated like implicit constructor functions */
350             if( DICT_type == OBJ_ENTITY ) {
351                 Type self_old = self; /* save previous in the unlikely but possible case that
352                                        * SELF is in a derived initialization of an entity */
353                 e = ( Entity )x;
354                 self = e->u.entity->type;
355                 /* skip parameter resolution for now */
356                 /*          ARGresolve();*/
357                 expr->return_type = e->u.entity->type;
358                 self = self_old;    /* restore old SELF */
359             } else {
360                 f = ( Function )x;
361                 expr->return_type = f->u.func->return_type;
362 
363                 /* do argument typechecking here if requested */
364                 /* currently, we just check arg count; necesary */
365                 /* to NVL code later which assumes args are present */
366                 if( LISTget_length( expr->u.funcall.list ) !=
367                         f->u.func->pcount ) {
368                     ERRORreport_with_symbol( ERROR_wrong_arg_count,
369                                              &expr->symbol, expr->symbol.name,
370                                              LISTget_length( expr->u.funcall.list ),
371                                              f->u.func->pcount );
372                 }
373 
374 #ifdef future_work
375                 if( EXPRESS_lint ) {
376                     /* verify parameters match function call */
377                 }
378 #endif
379 
380                 /* should make this data-driven! */
381                 if( f == FUNC_NVL ) {
382                     EXPresolve( ( Expression )LISTget_first( expr->u.funcall.list ), scope, typecheck );
383                     EXPresolve( ( Expression )LISTget_second( expr->u.funcall.list ), scope, typecheck );
384                     func_args_checked = true;
385                 }
386 
387                 /* why is this here?  (snc) */
388                 if( f == FUNC_USEDIN ) {
389                     expr->return_type = Type_Bag_Of_Generic;
390                 }
391             }
392             if( !func_args_checked ) {
393                 LISTdo( expr->u.funcall.list, param, Expression )
394                 EXPresolve( param, scope, Type_Dont_Care );
395                 if( is_resolve_failed( param ) ) {
396                     resolve_failed( expr );
397                     break;
398                 }
399                 LISTod;
400             }
401 
402 #if 0
403             /* add function or entity as first element of list */
404             LISTadd_first( expr->u.list, x );
405 #endif
406             expr->u.funcall.function = ( struct Scope_ * ) x;
407 
408             resolved_all( expr );
409             break;
410         case aggregate_:
411             LISTdo( expr->u.list, elt, Expression )
412             EXPresolve( elt, scope, Type_Dont_Care );
413             if( is_resolve_failed( elt ) ) {
414                 resolve_failed( expr );
415                 break;
416             }
417             LISTod;
418 
419             /* may have to do more work here! */
420             expr->return_type = expr->type;
421             resolved_all( expr );
422             break;
423         case identifier_:
424 
425             x = 0;
426 
427             /* assume it's a variable/attribute */
428             if( !x ) {
429                 x = ( Generic )VARfind( scope, expr->symbol.name, 0 );
430             }
431             /* if not found as a variable, try as function, etc ... */
432             if( !x ) {
433                 x = SCOPEfind( scope, expr->symbol.name,
434                                SCOPE_FIND_ANYTHING );
435             }
436             /* Not all enums have `typecheck->u.type->body->type` == `enumeration_` - ?! */
437             if( !x ) {
438                 Scope enumscope = scope;
439                 while( 1 ) {
440                     /* look up locally, then go through the superscopes */
441                     x = DICTlookup( enumscope->enum_table, expr->symbol.name );
442                     if( x ) {
443                         break;
444                     }
445                     if( enumscope->type == OBJ_SCHEMA ) {
446                         /* if we get here, this means that we've looked through all scopes */
447                         x = 0;
448                         break;
449                     }
450                     enumscope = enumscope->superscope;
451                 }
452             }
453 
454             if( !x ) {
455                 if( typecheck == Type_Unknown ) {
456                     return;
457                 } else {
458                     ERRORreport_with_symbol( ERROR_undefined,
459                                              &expr->symbol, expr->symbol.name );
460                     resolve_failed( expr );
461                     break;
462                 }
463             }
464             switch( DICT_type ) {
465                 case OBJ_VARIABLE:
466                     expr->u.variable = ( Variable )x;
467 #if 0
468                     /* gee, I don't see what variables have to go through this right here */
469                     VARresolve_expressions( expr->u.variable, scope );
470                     if( is_resolve_failed( expr->u.variable->name ) ) {
471                         resolve_failed( expr );
472                         break;
473                     }
474 #endif
475                     /* Geez, don't wipe out original type! */
476                     expr->return_type = expr->u.variable->type;
477                     if( expr->u.variable->flags.attribute ) {
478                         found_self = true;
479                     }
480                     resolved_all( expr );
481                     break;
482                 case OBJ_ENTITY:
483                     expr->return_type = expr->type = ( ( Entity )x )->u.entity->type;
484                     /* entity may not actually be resolved by now */
485                     /* but I don't think that's a problem */
486                     resolved_all( expr );
487                     break;
488                 case OBJ_EXPRESSION:
489                     /* so far only enumerations get returned this way */
490                     expr->u.expression = ( Expression )x;
491                     expr->type = expr->return_type = ( ( Expression )x )->type;
492                     resolved_all( expr );
493                     break;
494                 case OBJ_FUNCTION:
495                     /* functions with no args end up here because the */
496                     /* parser doesn't know any better */
497                     expr->u.list = LISTcreate();
498                     LISTadd_last( expr->u.list, x );
499                     expr->type = Type_Funcall;
500                     expr->return_type = ( ( Function )x )->u.func->return_type;
501                     /* function may not actually be resolved by now */
502                     /* but I don't think that's a problem */
503 
504                     if( ( ( Function )x )->u.func->pcount != 0 ) {
505                         ERRORreport_with_symbol( ERROR_wrong_arg_count,
506                                                  &expr->symbol, expr->symbol.name, 0,
507                                                  f->u.func->pcount );
508                         resolve_failed( expr );
509                     } else {
510                         resolved_all( expr );
511                     }
512                     break;
513                 case OBJ_TYPE:
514                     /* enumerations can appear here, I don't know about others */
515                     expr->type = ( Type )x;
516                     expr->return_type = ( Type )x;
517                     expr->symbol.resolved = expr->type->symbol.resolved;
518                     break;
519                 default:
520                     fprintf( stderr, "ERROR: unexpected type in EXPresolve.\n" );
521                     break;
522             }
523             break;
524         case op_:
525             expr->return_type = ( *EXPop_table[expr->e.op_code].resolve )( expr, scope );
526             break;
527         case entity_:           /* only 'self' is seen this way */
528         case self_:
529             if( self ) {
530                 expr->return_type = self;
531                 /* we can't really call ourselves resolved, but we */
532                 /* will be by the time we return, and besides, */
533                 /* there's no way this will be accessed if the true */
534                 /* entity fails resolution */
535                 found_self = true;
536                 resolved_all( expr );
537             } else {
538                 ERRORreport_with_symbol( ERROR_self_is_unknown, &scope->symbol );
539                 resolve_failed( expr );
540             }
541             break;
542         case query_:
543             EXPresolve( expr->u.query->aggregate, expr->u.query->scope, Type_Dont_Care );
544             expr->return_type = expr->u.query->aggregate->return_type;
545 
546             /* verify that it's an aggregate */
547             if( is_resolve_failed( expr->u.query->aggregate ) ) {
548                 resolve_failed( expr );
549                 break;
550             }
551             if( TYPEis_aggregate( expr->return_type ) ) {
552                 t = expr->u.query->aggregate->return_type->u.type->body->base;
553             } else if( TYPEis_select( expr->return_type ) ) {
554                 /* retrieve the common aggregate type */
555                 t = TYPE_retrieve_aggregate( expr->return_type, 0 );
556                 if( !t ) {
557                     ERRORreport_with_symbol( ERROR_query_requires_aggregate, &expr->u.query->aggregate->symbol );
558                     resolve_failed( expr );
559                     break;
560                 }
561             } else if( TYPEis_runtime( expr->return_type ) ) {
562                 t = Type_Runtime;
563             } else {
564                 ERRORreport_with_symbol( ERROR_query_requires_aggregate, &expr->u.query->aggregate->symbol );
565                 resolve_failed( expr );
566                 break;
567             }
568             expr->u.query->local->type = t;
569             expr->u.query->local->name->return_type = t;
570             EXPresolve( expr->u.query->expression, expr->u.query->scope, Type_Dont_Care );
571             expr->symbol.resolved = expr->u.query->expression->symbol.resolved;
572             break;
573         case integer_:
574         case real_:
575         case string_:
576         case binary_:
577         case boolean_:
578         case logical_:
579         case number_:
580             expr->return_type = expr->type;
581             resolved_all( expr );
582             break;
583         case attribute_:
584             expr->return_type = expr->type;
585             resolved_all( expr );
586             break;
587         default:
588             fprintf( stderr, "ERROR: unexpected type in EXPresolve.\n" );
589     }
590 }
591 
ENTITYresolve_subtype_expression(Expression expr,Entity ent,Linked_List * flat)592 int ENTITYresolve_subtype_expression( Expression expr, Entity ent/*was scope*/, Linked_List * flat ) {
593     Entity ent_ref;
594     int i = UNRESOLVED;
595 
596     if( !expr ) {
597         return ( RESOLVED );
598     } else if( TYPEis_expression( expr->type ) ) {
599         i = ENTITYresolve_subtype_expression( expr->e.op1, ent, flat );
600         i |= ENTITYresolve_subtype_expression( expr->e.op2, ent, flat );
601     } else if( TYPEis_oneof( expr->type ) ) {
602         LISTdo( expr->u.list, sel, Expression )
603         i |= ENTITYresolve_subtype_expression( sel, ent, flat );
604         LISTod;
605     } else {
606         /* must be a simple entity reference */
607         ent_ref = ( Entity )SCOPEfind( ent->superscope, expr->symbol.name, SCOPE_FIND_ENTITY );
608         if( !ent_ref ) {
609             ERRORreport_with_symbol( ERROR_unknown_subtype, &ent->symbol,
610                                      expr->symbol.name, ent->symbol.name );
611             i = RESOLVE_FAILED;
612         } else if( DICT_type != OBJ_ENTITY ) {
613             Symbol * sym = OBJget_symbol( ent_ref, DICT_type );
614             /* line number should really be on supertype name, */
615             /* but all we have easily is the entity line number */
616             ERRORreport_with_symbol( ERROR_subtype_resolve, &ent->symbol,
617                                      expr->symbol.name, sym->line );
618             i = RESOLVE_FAILED;
619         } else {
620             bool found = false;
621 
622             /* link in to flat list */
623             if( !*flat ) {
624                 *flat = LISTcreate();
625             }
626 
627             LISTdo( *flat, sub, Entity )
628             if( sub == ent_ref ) {
629                 found = true;
630                 break;
631             }
632             LISTod
633 
634             if( !found ) {
635                 LISTadd_last( *flat, ( Generic )ent_ref );
636             }
637 
638             /* link in to expression */
639             expr->type = ent_ref->u.entity->type;
640             i = RESOLVED;
641 
642 #if 0
643             /* If the user said there was a subtype relationship but */
644             /* did not mention the reverse supertype relationship, */
645             /* complain (IS p. 44) */
646             LISTdo( ent_ref->u.entity->supertypes, sup, Entity )
647             if( sup == ent ) {
648                 found = true;
649                 break;
650             }
651             LISTod
652             if( !found ) {
653                 if( !ent_ref->u.entity->supertypes ) {
654                     ent_ref->u.entity->supertypes = LISTcreate();
655                 }
656                 LISTadd_last( ent_ref->u.entity->supertypes, ( Generic )ent );
657             }
658 #endif
659         }
660     }
661     return( i );
662 }
663 
664 /**
665 ** \param typeaddr type to resolve
666 ** \returns true type
667 **
668 ** Resolve all references in a type.
669 */
TYPE_resolve(Type * typeaddr)670 void TYPE_resolve( Type * typeaddr /*, Scope scope*/ ) {
671     Type type = *typeaddr;
672     Type ref_type;
673     TypeBody body = type->u.type->body;
674     Scope scope = type->superscope;
675 
676     if( body ) {
677         /* complex type definition such as aggregates, enums, ... */
678 
679         resolve_in_progress( type );
680 
681         if( TYPEis_aggregate( type ) ) {
682             TYPEresolve( &body->base );
683             /* only really critical failure point for future use */
684             /* of this type is the base type, ignore others (above) */
685             type->symbol.resolved = body->base->symbol.resolved;
686         } else if( TYPEis_select( type ) ) {
687             LISTdo_links( body->list, link )
688             TYPEresolve( ( Type * )&link->data );
689             if( is_resolve_failed( ( Type )link->data ) ) {
690                 resolve_failed( type );
691                 break;
692             }
693             LISTod;
694         }
695     } else if( type->u.type->head ) {
696         /* simple type definition such as "TYPE T = U" */
697         resolve_in_progress( type );
698 
699         TYPEresolve( &type->u.type->head );
700 
701         if( !is_resolve_failed( type->u.type->head ) ) {
702             if( ERRORis_enabled( ERROR_type_is_entity ) ) {
703                 if( TYPEis_entity( type->u.type->head ) ) {
704                     ERRORreport_with_symbol( ERROR_type_is_entity, &type->symbol, type->u.type->head->u.type->body->entity->symbol.name );
705                     resolve_failed( type );
706                 }
707             }
708             /* allow type ref's to be bypassed by caching true type */
709             type->u.type->body = type->u.type->head->u.type->body;
710         }
711     } else {
712         /* simple type reference such as "T" */
713         /* this really is a hack.  masking out only variables from */
714         /* the search is to support the (allowed) circumstance of */
715         /* an attribute or formal parameter whose name is the same */
716         /* as its type, i.e. "foo : foo".  unfortunately, babys like */
717         /* local variables get thrown out with the bathwater.  -snc */
718         ref_type = ( Type )SCOPEfind( scope, type->symbol.name,
719                                       SCOPE_FIND_ANYTHING ^ SCOPE_FIND_VARIABLE );
720         /*              SCOPE_FIND_TYPE | SCOPE_FIND_ENTITY);*/
721         if( !ref_type ) {
722             ERRORreport_with_symbol( ERROR_undefined_type, &type->symbol, type->symbol.name );
723             *typeaddr = Type_Bad; /* just in case */
724             resolve_failed( type );
725         } else if( DICT_type == OBJ_TYPE ) {
726             /* due to declarations of multiple attributes off of a */
727             /* single type ref, we have to use reference counts */
728             /* to safely deallocate the TypeHead.  It's trivial to do */
729             /* but gaining back the memory isn't worth the CPU time. */
730             /* if (type->refcount--) TYPE_destroy(type); */
731 
732             type = *typeaddr = ref_type;
733             TYPEresolve( typeaddr ); /* addr doesn't matter here */
734             /* it will not be written through */
735         } else if( DICT_type == OBJ_ENTITY ) {
736             /* if (type->refcount--) TYPE_destroy(type); see above */
737 
738             type = *typeaddr = ( ( Entity )ref_type )->u.entity->type;
739         } else {
740             ERRORreport_with_symbol( ERROR_not_a_type, &type->symbol, type->symbol.name,
741                                      OBJget_type( DICT_type ) );
742             resolve_failed( type );
743         }
744     }
745 
746     if( !is_resolve_failed( type ) ) {
747         resolved_all( type );
748     }
749     return;
750 }
751 
752 /**
753 ** \param v variable to resolve
754 ** \param entity entity in which to resolve
755 **
756 ** Resolve all references in a variable definition.
757 */
VAR_resolve_expressions(Variable v,Entity entity)758 void VAR_resolve_expressions( Variable v, Entity entity /* was scope */ ) {
759     EXPresolve( v->name, entity, Type_Dont_Care ); /* new!! */
760 
761     if( v->initializer ) {
762         EXPresolve( v->initializer, entity, v->type );
763 
764         if( is_resolve_failed( v->initializer ) ) {
765             resolve_failed( v->name );
766         }
767     }
768 }
769 
770 /**
771 ** \param v variable to resolve
772 **
773 ** Resolve all references in a variable definition.
774 */
VAR_resolve_types(Variable v)775 void VAR_resolve_types( Variable v ) {
776     int failed = 0;
777 
778     TYPEresolve( &v->type );
779     failed = is_resolve_failed( v->type );
780 
781     if( v->inverse_symbol && ( !v->inverse_attribute ) ) {
782         /* resolve inverse */
783         Variable attr;
784         Type type = v->type;
785 
786         if( TYPEis_aggregate( type ) ) {
787             /* pull entity out of aggregate type defn for ... */
788             /* inverse var: set (or bag) of entity for ...; */
789             type = type->u.type->body->base;
790         }
791         if( type->u.type->body->type != entity_ ) {
792             ERRORreport_with_symbol( ERROR_inverse_bad_entity,
793                                      &v->name->symbol, v->inverse_symbol->name );
794         } else {
795             attr = VARfind( type->u.type->body->entity, v->inverse_symbol->name, 1 );
796             if( attr ) {
797                 v->inverse_attribute = attr;
798                 failed |= is_resolve_failed( attr->name );
799             } else {
800                 ERRORreport_with_symbol( ERROR_inverse_bad_attribute,
801                                          v->inverse_symbol, v->inverse_symbol->name, type->u.type->body->entity->symbol.name );
802             }
803         }
804         /* symbol is no longer used here and could be gc'd */
805         /* but keep around anyway for ease in later reconstruction */
806     }
807 
808     if( failed ) {
809         resolve_failed( v->name );
810     }
811 
812     /* note: cannot set resolved bit since it has to be resolved again */
813     /* by VAR_resolve_expressions later on */
814 #if 0
815     else {
816         resolved_all( v->name );
817     }
818 #endif
819 }
820 
821 /**
822 ** \param statement statement to resolve
823 ** \param scope scope in which to resolve
824 **
825 ** Resolve all references in a statement.
826 */
827 void STMTresolve( Statement statement, Scope scope );
828 
STMTlist_resolve(Linked_List list,Scope scope)829 void STMTlist_resolve( Linked_List list, Scope scope ) {
830     LISTdo( list, s, Statement )
831     STMTresolve( s, scope );
832     LISTod;
833 }
834 
835 /**
836  * \param item case item to resolve
837  * \param scope scope in which to resolve
838  * \param statement the CASE statement (for return type, etc)
839  *
840  * Resolve all references in a case item
841  */
CASE_ITresolve(Case_Item item,Scope scope,Statement statement)842 void CASE_ITresolve( Case_Item item, Scope scope, Statement statement ) {
843     int validLabels = 0;
844     LISTdo( item->labels, e, Expression ) {
845         EXPresolve( e, scope, statement->u.Case->selector->return_type );
846         if( e->return_type != Type_Bad ) {
847             validLabels++;
848         }
849     }
850     LISTod;
851     if( validLabels ) {
852         STMTresolve( item->action, scope );
853     }
854 }
855 
STMTresolve(Statement statement,Scope scope)856 void STMTresolve( Statement statement, Scope scope ) {
857     /* scope is always the function/procedure/rule from SCOPEresolve_expressions_statements(); */
858     Scope proc;
859 
860     if( !statement ) {
861         return;    /* could be null statement */
862     }
863 
864     switch( statement->type ) {
865         case STMT_ALIAS:
866             EXPresolve( statement->u.alias->variable->initializer, scope, Type_Dont_Care );
867             statement->u.alias->variable->type =
868                 statement->u.alias->variable->initializer->type;
869             if( !is_resolve_failed( statement->u.alias->variable->initializer ) ) {
870                 STMTlist_resolve( statement->u.alias->statements, statement->u.alias->scope );
871             }
872             break;
873         case STMT_ASSIGN:
874             EXPresolve( statement->u.assign->lhs, scope, Type_Dont_Care );
875             EXPresolve( statement->u.assign->rhs, scope, statement->u.assign->lhs->type );
876             break;
877         case STMT_CASE:
878             EXPresolve( statement->u.Case->selector, scope, Type_Dont_Care );
879             LISTdo( statement->u.Case->cases, c, Case_Item ) {
880                 CASE_ITresolve( c, scope, statement );
881             }
882             LISTod;
883             break;
884         case STMT_COMPOUND:
885             STMTlist_resolve( statement->u.compound->statements, scope );
886             break;
887         case STMT_COND:
888             EXPresolve( statement->u.cond->test, scope, Type_Dont_Care );
889             STMTlist_resolve( statement->u.cond->code, scope );
890             if( statement->u.cond->otherwise ) {
891                 STMTlist_resolve( statement->u.cond->otherwise, scope );
892             }
893             break;
894         case STMT_PCALL:
895 #define proc_name statement->symbol.name
896             proc = ( Scope )SCOPEfind( scope, proc_name,
897                                        SCOPE_FIND_PROCEDURE );
898             if( proc ) {
899                 if( DICT_type != OBJ_PROCEDURE ) {
900                     Symbol * newsym = OBJget_symbol( proc, DICT_type );
901                     ERRORreport_with_symbol( ERROR_expected_proc, &statement->symbol, proc_name, newsym->line );
902                 } else {
903                     statement->u.proc->procedure = proc;
904                 }
905             } else {
906                 ERRORreport_with_symbol( ERROR_no_such_procedure, &statement->symbol, proc_name );
907             }
908             LISTdo( statement->u.proc->parameters, e, Expression )
909             EXPresolve( e, scope, Type_Dont_Care );
910             LISTod;
911             break;
912         case STMT_LOOP:
913             if( statement->u.loop->scope ) {
914                 /* resolve increment with old scope */
915                 EXPresolve( statement->u.loop->scope->u.incr->init, scope, Type_Dont_Care );
916                 EXPresolve( statement->u.loop->scope->u.incr->end, scope, Type_Dont_Care );
917                 EXPresolve( statement->u.loop->scope->u.incr->increment, scope, Type_Dont_Care );
918                 /* resolve others with new scope! */
919                 scope = statement->u.loop->scope;
920             }
921             if( statement->u.loop->while_expr ) {
922                 EXPresolve( statement->u.loop->while_expr, scope, Type_Dont_Care );
923             }
924 
925             if( statement->u.loop->until_expr ) {
926                 EXPresolve( statement->u.loop->until_expr, scope, Type_Dont_Care );
927             }
928 
929             STMTlist_resolve( statement->u.loop->statements, scope );
930             break;
931         case STMT_RETURN:
932             if( statement->u.ret->value ) {
933                 EXPresolve( statement->u.ret->value, scope, Type_Dont_Care );
934             }
935             break;
936         case STMT_SKIP:
937         case STMT_ESCAPE:
938             /* do nothing */ /* WARNING should we really *not* do anything for these? */
939             ;
940     }
941 }
942 
ALGresolve_expressions_statements(Scope s,Linked_List statements)943 void ALGresolve_expressions_statements( Scope s, Linked_List statements ) {
944     int status = 0;
945 
946     if( print_objects_while_running & OBJ_ALGORITHM_BITS &
947             OBJget_bits( s->type ) ) {
948         fprintf( stderr, "pass %d: %s (%s)\n", EXPRESSpass,
949                  s->symbol.name, OBJget_type( s->type ) );
950     }
951 
952     SCOPEresolve_expressions_statements( s );
953     STMTlist_resolve( statements, s );
954 
955     s->symbol.resolved = status;
956 }
957 
ENTITY_get_local_attribute(Entity e,char * name)958 static Variable ENTITY_get_local_attribute( Entity e, char * name ) {
959     LISTdo( e->u.entity->attributes, a, Variable )
960     if( streq( VARget_simple_name( a ), name ) ) {
961         return a;
962     }
963     LISTod;
964     return 0;
965 }
966 
ENTITYresolve_expressions(Entity e)967 void ENTITYresolve_expressions( Entity e ) {
968     Variable v;
969     int status = 0;
970     DictionaryEntry de;
971     char * sname;
972     Entity sup;
973 
974     if( print_objects_while_running & OBJ_ENTITY_BITS ) {
975         fprintf( stderr, "pass %d: %s (entity)\n", EXPRESSpass,
976                  e->symbol.name );
977     }
978 
979     self = e->u.entity->type;
980 
981     LISTdo( e->u.entity->attributes, attr, Variable ) {
982         if( attr->name->type->u.type->body->type == op_ ) {
983             /* attribute redeclaration */
984             sname = attr->name->e.op1->e.op2->symbol.name;
985             if( streq( sname, e->symbol.name ) ||
986                     !( sup = ENTITYfind_inherited_entity( e, sname, 0 ) ) ) {
987                 ERRORreport_with_symbol( ERROR_redecl_no_such_supertype,
988                                         &attr->name->e.op1->e.op2->symbol,
989                                         attr->name->e.op1->e.op2->symbol.name,
990                                         VARget_simple_name( attr ) );
991                 resolve_failed( attr->name );
992             } else {
993                 sname = VARget_simple_name( attr );
994                 if( !ENTITY_get_local_attribute( sup, sname ) ) {
995                     ERRORreport_with_symbol( ERROR_redecl_no_such_attribute,
996                                             &attr->name->e.op2->symbol,
997                                             sname,
998                                             sup->symbol.name );
999                     resolve_failed( attr->name );
1000                 }
1001                 /* should be ok to share this ptr */
1002                 attr->name->symbol.name = sname;
1003             }
1004         } else {
1005             /* new attribute declaration */
1006             LISTdo_n( e->u.entity->supertypes, supr, Entity, b ) {
1007                     if( ENTITYget_named_attribute( supr,
1008                                                 attr->name->symbol.name ) ) {
1009                         ERRORreport_with_symbol( ERROR_overloaded_attribute,
1010                                                 &attr->name->symbol,
1011                                                 attr->name->symbol.name,
1012                                                 supr->symbol.name );
1013                         resolve_failed( attr->name );
1014                     }
1015             } LISTod;
1016         }
1017         VARresolve_expressions( attr, e );
1018         status |= is_resolve_failed( attr->name );
1019     } LISTod;
1020 
1021     DICTdo_type_init( e->symbol_table, &de, OBJ_VARIABLE );
1022     while( 0 != ( v = ( Variable )DICTdo( &de ) ) ) {
1023         if( !is_resolve_failed( v->name ) ) {
1024             TYPEresolve_expressions( v->type, e );
1025             if( v->initializer ) {
1026                 EXPresolve( v->initializer, e, v->type );
1027                 status |= is_resolve_failed( v->initializer );
1028             }
1029         } else {
1030             status = RESOLVE_FAILED;
1031         }
1032     }
1033 
1034     if( !WHEREresolve( e->where, e, 1 ) ) {
1035         status = RESOLVE_FAILED;
1036     }
1037 
1038     self = 0;
1039 
1040     e->symbol.resolved = status;
1041 }
1042 
1043 
1044 
ENTITYcheck_missing_supertypes(Entity ent)1045 void ENTITYcheck_missing_supertypes( Entity ent ) {
1046     int found;
1047 
1048     /* Make sure each of my subtypes lists me as a supertype */
1049     LISTdo( ent->u.entity->subtypes, sub, Entity ) {
1050         found = false;
1051         LISTdo_n( sub->u.entity->supertypes, sup, Entity, b ) {
1052             if( sup == ent ) {
1053                 found = true;
1054                 break;
1055             }
1056         } LISTod;
1057         if( !found ) {
1058             ERRORreport_with_symbol( ERROR_missing_supertype, &sub->symbol, ent->symbol.name, sub->symbol.name );
1059             resolve_failed( sub );
1060         }
1061     } LISTod;
1062 }
1063 
1064 /** calculate number of attributes inheritance, following up superclass chain */
ENTITYcalculate_inheritance(Entity e)1065 void ENTITYcalculate_inheritance( Entity e ) {
1066     e->u.entity->inheritance = 0;
1067 
1068     LISTdo( e->u.entity->supertypes, super, Entity ) {
1069         if( super->u.entity->inheritance == ENTITY_INHERITANCE_UNINITIALIZED ) {
1070             ENTITYcalculate_inheritance( super );
1071         }
1072         e->u.entity->inheritance += ENTITYget_size( super );
1073     }
1074     LISTod
1075 }
1076 
1077 /** returns 1 if entity is involved in circularity, else 0 */
ENTITY_check_subsuper_cyclicity(Entity e,Entity enew)1078 int ENTITY_check_subsuper_cyclicity( Entity e, Entity enew ) {
1079     /* just check subtypes - this implicitly checks supertypes */
1080     /* as well */
1081     LISTdo( enew->u.entity->subtypes, sub, Entity )
1082     if( e == sub ) {
1083         ERRORreport_with_symbol( ERROR_subsuper_loop, &sub->symbol, e->symbol.name );
1084         return 1;
1085     }
1086     if( sub->search_id == __SCOPE_search_id ) {
1087         return 0;
1088     }
1089     sub->search_id = __SCOPE_search_id;
1090     if( ENTITY_check_subsuper_cyclicity( e, sub ) ) {
1091         ERRORreport_with_symbol( ERROR_subsuper_continuation, &sub->symbol, sub->symbol.name );
1092         return 1;
1093     }
1094     LISTod;
1095     return 0;
1096 }
1097 
ENTITYcheck_subsuper_cyclicity(Entity e)1098 void ENTITYcheck_subsuper_cyclicity( Entity e ) {
1099     __SCOPE_search_id++;
1100     ( void ) ENTITY_check_subsuper_cyclicity( e, e );
1101 }
1102 
1103 /** returns 1 if select type is involved in circularity, else 0 */
TYPE_check_select_cyclicity(TypeBody tb,Type tnew)1104 int TYPE_check_select_cyclicity( TypeBody tb, Type tnew ) {
1105     LISTdo( tnew->u.type->body->list, item, Type )
1106     if( item->u.type->body->type == select_ ) {
1107         if( tb == item->u.type->body ) {
1108             ERRORreport_with_symbol( ERROR_select_loop,
1109                                      &item->symbol, item->symbol.name );
1110             return 1;
1111         }
1112         if( item->search_id == __SCOPE_search_id ) {
1113             return 0;
1114         }
1115         item->search_id = __SCOPE_search_id;
1116         if( TYPE_check_select_cyclicity( tb, item ) ) {
1117             ERRORreport_with_symbol( ERROR_select_continuation,
1118                                      &item->symbol, item->symbol.name );
1119             return 1;
1120         }
1121     }
1122     LISTod;
1123     return 0;
1124 }
1125 
TYPEcheck_select_cyclicity(Type t)1126 void TYPEcheck_select_cyclicity( Type t ) {
1127     if( t->u.type->body->type == select_ ) {
1128         __SCOPE_search_id++;
1129         ( void ) TYPE_check_select_cyclicity( t->u.type->body, t );
1130     }
1131 }
1132 
1133 void ENTITYresolve_types( Entity e );
1134 
1135 /** also resolves inheritance counts and sub/super consistency */
SCOPEresolve_types(Scope s)1136 void SCOPEresolve_types( Scope s ) {
1137     Variable var;
1138     DictionaryEntry de;
1139     Generic x;
1140 
1141     if( print_objects_while_running & OBJ_SCOPE_BITS &
1142             OBJget_bits( s->type ) ) {
1143         fprintf( stderr, "pass %d: %s (%s)\n", EXPRESSpass,
1144                  s->symbol.name, OBJget_type( s->type ) );
1145     }
1146 
1147     DICTdo_init( s->symbol_table, &de );
1148     while( 0 != ( x = DICTdo( &de ) ) ) {
1149         switch( DICT_type ) {
1150             case OBJ_TYPE:
1151                 if( ERRORis_enabled( ERROR_select_loop ) ) {
1152                     TYPEcheck_select_cyclicity( ( Type )x );
1153                 }
1154                 break;
1155             case OBJ_VARIABLE:  /* really constants */
1156                 var = ( Variable )x;
1157                 /* before OBJ_BITS hack, we looked in s->superscope */
1158                 TYPEresolve( &var->type );
1159                 if( is_resolve_failed( var->type ) ) {
1160                     resolve_failed( var->name );
1161                     resolve_failed( s );
1162                 }
1163                 break;
1164             case OBJ_ENTITY:
1165                 ENTITYcheck_missing_supertypes( ( Entity )x );
1166                 ENTITYresolve_types( ( Entity )x );
1167                 ENTITYcalculate_inheritance( ( Entity )x );
1168                 if( ERRORis_enabled( ERROR_subsuper_loop ) ) {
1169                     ENTITYcheck_subsuper_cyclicity( ( Entity )x );
1170                 }
1171                 if( is_resolve_failed( ( Entity )x ) ) {
1172                     resolve_failed( s );
1173                 }
1174                 break;
1175             case OBJ_SCHEMA:
1176                 if( is_not_resolvable( ( Schema )x ) ) {
1177                     break;
1178                 }
1179                 /*FALLTHRU*/
1180             case OBJ_PROCEDURE:
1181             case OBJ_RULE:
1182             case OBJ_FUNCTION:
1183                 SCOPEresolve_types( ( Scope )x );
1184                 if( is_resolve_failed( ( Scope )x ) ) {
1185                     resolve_failed( s );
1186                 }
1187                 break;
1188             default:
1189                 break;
1190         }
1191     }
1192     if( s->type == OBJ_FUNCTION ) {
1193         TYPEresolve( &s->u.func->return_type );
1194     }
1195 }
1196 
1197 
1198 
1199 /********************************new****************************************/
1200 
SCOPEresolve_subsupers(Scope scope)1201 void SCOPEresolve_subsupers( Scope scope ) {
1202     DictionaryEntry de;
1203     Generic x;
1204     char type;
1205     Symbol * sym;
1206     Type t;
1207 
1208     if( print_objects_while_running & OBJ_SCOPE_BITS &
1209             OBJget_bits( scope->type ) ) {
1210         fprintf( stderr, "pass %d: %s (%s)\n", EXPRESSpass,
1211                  scope->symbol.name, OBJget_type( scope->type ) );
1212     }
1213 
1214     DICTdo_init( scope->symbol_table, &de );
1215     while( 0 != ( x = DICTdo( &de ) ) ) {
1216         switch( type = DICT_type ) {
1217             case OBJ_ENTITY:
1218                 ENTITYresolve_supertypes( ( Entity )x );
1219                 ENTITYresolve_subtypes( ( Entity )x );
1220                 break;
1221             case OBJ_FUNCTION:
1222             case OBJ_PROCEDURE:
1223             case OBJ_RULE:
1224                 SCOPEresolve_subsupers( ( Scope )x );
1225                 break;
1226             case OBJ_TYPE:
1227                 t = ( Type )x;
1228                 TYPEresolve( &t );
1229                 break;
1230             default:
1231                 /* ignored everything else */
1232                 break;
1233         }
1234         sym = OBJget_symbol( x, type );
1235         if( is_resolve_failed_raw( sym ) ) {
1236             resolve_failed( scope );
1237         }
1238     }
1239 }
1240 
1241 /** for each supertype, find the entity it refs to */
ENTITYresolve_supertypes(Entity e)1242 static void ENTITYresolve_supertypes( Entity e ) {
1243     Entity ref_entity;
1244 
1245     if( print_objects_while_running & OBJ_ENTITY_BITS ) {
1246         fprintf( stderr, "pass %d: %s (entity)\n", EXPRESSpass,
1247                  e->symbol.name );
1248     }
1249 
1250     if( e->u.entity->supertype_symbols ) {
1251         e->u.entity->supertypes = LISTcreate();
1252     }
1253 #if 0
1254     if( e->u.entity->supertype_symbols && !e->u.entity->supertypes ) {
1255         e->u.entity->supertypes = LISTcreate();
1256     }
1257 #endif
1258 
1259     LISTdo( e->u.entity->supertype_symbols, sym, Symbol * ) {
1260         ref_entity = ( Entity )SCOPEfind( e->superscope, sym->name, SCOPE_FIND_ENTITY );
1261         if( !ref_entity ) {
1262             ERRORreport_with_symbol( ERROR_unknown_supertype, sym, sym->name, e->symbol.name );
1263             /*          ENTITY_resolve_failed = 1;*/
1264             resolve_failed( e );
1265         } else if( DICT_type != OBJ_ENTITY ) {
1266             Symbol * newsym = OBJget_symbol( ref_entity, DICT_type );
1267             ERRORreport_with_symbol( ERROR_supertype_resolve, sym, sym->name, newsym->line );
1268             /*          ENTITY_resolve_failed = 1;*/
1269             resolve_failed( e );
1270         } else {
1271             bool found = false;
1272 
1273             LISTadd_last( e->u.entity->supertypes, ( Generic )ref_entity );
1274             if( is_resolve_failed( ref_entity ) ) {
1275                 resolve_failed( e );
1276             }
1277 
1278             /* If the user said there was a supertype relationship but */
1279             /* did not mentioned the reverse subtype relationship */
1280             /* force it to be explicitly known by listing this entity */
1281             /* in the ref'd entity's subtype list */
1282 
1283             LISTdo_n( ref_entity->u.entity->subtypes, sub, Entity, b ) {
1284                 if( sub == e ) {
1285                     found = true;
1286                     break;
1287                 }
1288             } LISTod
1289             if( !found ) {
1290                 if( !ref_entity->u.entity->subtypes ) {
1291                     ref_entity->u.entity->subtypes = LISTcreate();
1292                 }
1293                 LISTadd_last( ref_entity->u.entity->subtypes, ( Generic )e );
1294             }
1295         }
1296     } LISTod;
1297 }
1298 
ENTITYresolve_subtypes(Entity e)1299 static void ENTITYresolve_subtypes( Entity e ) {
1300     int i;
1301 
1302     if( print_objects_while_running & OBJ_ENTITY_BITS ) {
1303         fprintf( stderr, "pass %d: %s (entity)\n", EXPRESSpass,
1304                  e->symbol.name );
1305     }
1306 
1307     i = ENTITYresolve_subtype_expression( e->u.entity->subtype_expression, e, &e->u.entity->subtypes );
1308     if( i & RESOLVE_FAILED ) {
1309         resolve_failed( e );
1310     }
1311 }
1312 
1313 /** resolve the 'unique' list
1314  * these are lists of lists
1315  * the sublists are: label, ref'd_attr, ref'd attr, ref'd attr, etc.
1316  * where ref'd_attrs are either simple ids or SELF\entity.attr
1317  * where "entity" represents a supertype (only, I believe)
1318 */
ENTITYresolve_uniques(Entity e)1319 void ENTITYresolve_uniques( Entity e ) {
1320     Variable attr, attr2 = 0;
1321     int failed = 0;
1322     LISTdo( e->u.entity->unique, unique, Linked_List ) {
1323         int i = 0;
1324         LISTdo_links( unique, reflink ) {
1325             Type old_self = self;
1326             Expression expr;
1327             /* skip first which is always the label (or NULL if no label) */
1328             i++;
1329             if( i == 1 ) {
1330                 continue;
1331             }
1332             expr = ( Expression ) reflink->data;
1333             assert( expr );
1334 
1335             self = e->u.entity->type;
1336             EXPresolve( expr, e, Type_Dont_Care );
1337             self = old_self;
1338 
1339             /* SELF\entity.attr, or just an attr name? */
1340             if( ( expr->e.op_code == OP_DOT ) &&
1341                     ( expr->e.op1->e.op_code == OP_GROUP ) &&
1342                     ( expr->e.op1->e.op1->type == Type_Self ) ) {
1343                 attr = ENTITYresolve_attr_ref( e, &( expr->e.op1->e.op2->symbol ), &( expr->e.op2->symbol ) );
1344                 attr2 = ENTITYresolve_attr_ref( e, 0, &( expr->e.op2->symbol ) );
1345             } else {
1346                 attr = ENTITYresolve_attr_ref( e, 0, &( expr->symbol ) );
1347             }
1348             if( ( attr2 ) && ( attr != attr2 ) && ( ENTITYdeclares_variable( e, attr2 ) ) ) {
1349                 /* attr exists in type + supertype - it's a redeclaration.
1350                  * in this case, qualifiers are unnecessary; print a warning */
1351                 ERRORreport_with_symbol( WARNING_unique_qual_redecl, &( expr->e.op2->symbol ), expr->e.op2->symbol.name, e->symbol.name );
1352             }
1353             if( !attr ) {
1354                 /*      ERRORreport_with_symbol(ERROR_unknown_attr_in_entity,*/
1355                 /*                  aref->attribute, aref->attribute->name,*/
1356                 /*                  e->symbol.name);*/
1357                 failed = RESOLVE_FAILED;
1358                 continue;
1359             }
1360             if( ENTITYdeclares_variable( e, attr ) ) {
1361                 attr->flags.unique = 1;
1362             }
1363         } LISTod;
1364     } LISTod;
1365     e->symbol.resolved |= failed;
1366 }
1367 
ENTITYresolve_types(Entity e)1368 void ENTITYresolve_types( Entity e ) {
1369     int failed = 0;
1370 
1371     if( print_objects_while_running & OBJ_ENTITY_BITS ) {
1372         fprintf( stderr, "pass %d: %s (entity)\n", EXPRESSpass,
1373                  e->symbol.name );
1374     }
1375 
1376     LISTdo( e->u.entity->attributes, att, Variable ) {
1377         /* resolve in context of superscope to allow "X : X;" */
1378         VARresolve_types( att );
1379         failed |= is_resolve_failed( att->name );
1380     } LISTod;
1381 
1382     /*
1383      * resolve the 'unique' list
1384      */
1385     ENTITYresolve_uniques( e );
1386 
1387     /* don't wipe out any previous failure stat */
1388     e->symbol.resolved |= failed;
1389 }
1390 
1391 /** resolve all expressions in type definitions */
TYPEresolve_expressions(Type t,Scope s)1392 static void TYPEresolve_expressions( Type t, Scope s ) {
1393     TypeBody body;
1394 
1395     /* meaning of self in a type declaration refers to the type itself, so */
1396     /* temporary redirect "self" to ourselves to allow this */
1397     Type self_old = self;
1398     self = t;
1399 
1400     /* recurse through base types */
1401     for( ;; t = body->base ) {
1402         if( t->where ) {
1403             ( void )WHEREresolve( t->where, s, 1 );
1404         }
1405 
1406         /* reached an indirect type definition, resolved elsewhere */
1407         if( t->u.type->head ) {
1408             break;
1409         }
1410 
1411         if( !TYPEis_aggregate( t ) ) {
1412             break;
1413         }
1414 
1415         body = t->u.type->body;
1416         if( body->upper ) {
1417             EXPresolve( body->upper, s, Type_Dont_Care );
1418         }
1419         if( body->lower ) {
1420             EXPresolve( body->lower, s, Type_Dont_Care );
1421         }
1422         if( body->precision ) {
1423             EXPresolve( body->precision, s, Type_Dont_Care );
1424         }
1425     }
1426 
1427     self = self_old;
1428 }
1429 
SCOPEresolve_expressions_statements(Scope s)1430 void SCOPEresolve_expressions_statements( Scope s ) {
1431     DictionaryEntry de;
1432     Generic x;
1433     Variable v;
1434 
1435     if( print_objects_while_running & OBJ_SCOPE_BITS &
1436             OBJget_bits( s->type ) ) {
1437         fprintf( stderr, "pass %d: %s (%s)\n", EXPRESSpass,
1438                  s->symbol.name, OBJget_type( s->type ) );
1439     }
1440 
1441     DICTdo_init( s->symbol_table, &de );
1442     while( 0 != ( x = DICTdo( &de ) ) ) {
1443         switch( DICT_type ) {
1444             case OBJ_SCHEMA:
1445                 if( is_not_resolvable( ( Schema )x ) ) {
1446                     break;
1447                 }
1448                 SCOPEresolve_expressions_statements( ( Scope )x );
1449                 break;
1450             case OBJ_ENTITY:
1451                 ENTITYresolve_expressions( ( Entity )x );
1452                 break;
1453             case OBJ_FUNCTION:
1454                 ALGresolve_expressions_statements( ( Scope )x, ( ( Scope )x )->u.func->body );
1455                 break;
1456             case OBJ_PROCEDURE:
1457                 ALGresolve_expressions_statements( ( Scope )x, ( ( Scope )x )->u.proc->body );
1458                 break;
1459             case OBJ_RULE:
1460                 ALGresolve_expressions_statements( ( Scope )x, ( ( Scope )x )->u.rule->body );
1461 
1462                 WHEREresolve( RULEget_where( ( Scope )x ), ( Scope )x, 0 );
1463                 break;
1464             case OBJ_VARIABLE:
1465                 v = ( Variable )x;
1466                 TYPEresolve_expressions( v->type, s );
1467                 if( v->initializer ) {
1468                     EXPresolve( v->initializer, s, v->type );
1469                 }
1470                 break;
1471             case OBJ_TYPE:
1472                 TYPEresolve_expressions( ( Type )x, s );
1473                 break;
1474             default:
1475                 /* ignored everything else */
1476                 break;
1477         }
1478     }
1479 }
1480 
WHEREresolve(Linked_List list,Scope scope,int need_self)1481 static int WHEREresolve( Linked_List list, Scope scope, int need_self ) {
1482     int status = 0;
1483 
1484     LISTdo( list, w, Where )
1485     /* check if we've been here before */
1486     /* i'm not sure why, but it happens */
1487     status |= w->label->resolved;
1488     if( w->label->resolved & ( RESOLVED | RESOLVE_FAILED ) ) {
1489         break;
1490     }
1491 
1492     found_self = false;
1493     EXPresolve( w->expr, scope, Type_Dont_Care );
1494     if( need_self && ! found_self ) {
1495         ERRORreport_with_symbol( ERROR_missing_self,
1496                                  w->label,
1497                                  w->label->name );
1498         w->label->resolved = RESOLVE_FAILED;
1499     } else {
1500         w->label->resolved = RESOLVED;
1501     }
1502     status |= w->label->resolved;
1503     LISTod
1504     if( status == RESOLVE_FAILED ) {
1505         return 0;
1506     } else {
1507         return 1;
1508     }
1509 }
1510 
TAGcreate_tags()1511 struct tag * TAGcreate_tags() {
1512     extern int tag_count;
1513 
1514     return( ( struct tag * )calloc( tag_count, sizeof( struct tag ) ) );
1515 }
1516