1 /* expressions
2 
3    Copyright (C) 1994-1997 University of Dortmund
4    Department of Electrical Engineering, AG SIV
5 
6    VAUL is free software; you can redistribute it and/or modify it
7    under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10 
11    VAUL is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General
14    Public License for more details.
15 
16    You should have received a copy of the GNU Library General Public
17    License along with VAUL; see the file COPYING.LIB.  If not, write
18    to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19    Boston, MA 02111-1307 USA.
20 
21 
22 */
23 
24 #include <freehdl/vaul-parser.h>
25 #include <freehdl/vaul-chunk.h>
26 #include <freehdl/vaul-dunit.h>
27 #include <freehdl/vaul-util.h>
28 #include "vaulgens-chunk.h"
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <assert.h>
33 
34 #define psr vaul_parser
35 
36 static int aggregate_conversion_cost(pVAUL_AmbgAggregate, pIIR_Type t, IR_Kind k);
37 
38 pIIR_PhysicalLiteral
build_PhysicalLiteral(pIIR_AbstractLiteral lit,pIIR_Identifier unit)39 psr::build_PhysicalLiteral (pIIR_AbstractLiteral lit,
40 			    pIIR_Identifier unit)
41 {
42   pVAUL_Name u = mVAUL_SimpleName(lit->pos, unit);
43   pIIR_Declaration d = find_single_decl (u, IR_PHYSICAL_UNIT, "physical unit");
44   if (d == NULL)
45     return NULL;
46   pIIR_PhysicalUnit pu = pIIR_PhysicalUnit(d);
47   return mIIR_PhysicalLiteral(lit->pos, pu->type, lit, pu);
48 }
49 
50 pIIR_AbstractLiteralExpression
build_LiteralExpression(pIIR_PosInfo pos,pIIR_AbstractLiteral lit)51 psr::build_LiteralExpression (pIIR_PosInfo pos, pIIR_AbstractLiteral lit)
52 {
53   if (lit->is(IR_INTEGER_LITERAL))
54     return mIIR_AbstractLiteralExpression(pos, std->universal_integer, lit);
55   else if (lit->is(IR_FLOATING_POINT_LITERAL))
56     return mIIR_AbstractLiteralExpression(pos, std->universal_real, lit);
57   else
58     abort ();
59 }
60 
61 pIIR_AbstractLiteralExpression
build_LiteralExpression(int lineno,pIIR_AbstractLiteral lit)62 psr::build_LiteralExpression (int lineno, pIIR_AbstractLiteral lit)
63 {
64   return build_LiteralExpression (make_posinfo (lineno), lit);
65 }
66 
67 pIIR_Expression
build_QualifiedExpr(pVAUL_Name m,pIIR_Expression e)68 psr::build_QualifiedExpr(pVAUL_Name m, pIIR_Expression e)
69 {
70   pIIR_Type t = get_type(m);
71   if (t == NULL)
72     return NULL;
73   overload_resolution (e, t);
74   return mIIR_QualifiedExpression(m->pos, t, t, e);
75 }
76 
77 pIIR_Expression
build_TypeConversion(pIIR_PosInfo pos,pIIR_Type t,pIIR_Expression e)78 psr::build_TypeConversion (pIIR_PosInfo pos,
79 			   pIIR_Type t,
80 			   pIIR_Expression e)
81 {
82   overload_resolution(e, IR_TYPE);
83   // XXX - check for closely related types and stuff
84   // info("xxx - unchecked conversion from %n to %n", expr_type(e), t);
85   return mIIR_TypeConversion(pos, t, t, e);
86 }
87 
build_bcall(pIIR_Expression l,const char * op,pIIR_Expression r)88 pIIR_Expression psr::build_bcall(pIIR_Expression l, const char *op, pIIR_Expression r)
89 {
90   // XXX - reincarnate lno parm.
91 
92   pIIR_PosInfo pos = l? l->pos : make_posinfo(0);
93   pVAUL_Name n =
94     mVAUL_IftsName(pos,
95 		   mVAUL_SimpleName(pos, make_opid(op)),
96 		   mVAUL_NamedAssocElem(pos,
97 					r? mVAUL_NamedAssocElem(pos,
98 								NULL,
99 								NULL,
100 								r) : NULL,
101 					NULL, l));
102   return build_Expr(n);
103 }
104 
105 static void
iterate_for_kind(pIIR_Declaration d,void * cl)106 iterate_for_kind (pIIR_Declaration d, void *cl)
107 {
108   IR_Kind &basic_k = *(IR_Kind *)cl;
109   IR_Kind this_k = d->kind();
110 
111   if (basic_k == IR_INVALID)
112     basic_k = this_k;
113   else if (basic_k != this_k && !tree_is (this_k, basic_k))
114     {
115       while (!tree_is(basic_k, this_k))
116 	this_k = tree_base (this_k);
117       basic_k = this_k;
118     }
119 }
120 
121 static int
filter_for_kind_ignore_funcs(pIIR_Declaration d,void * cl)122 filter_for_kind_ignore_funcs (pIIR_Declaration d, void *cl)
123 {
124   if (!d->is(IR_SUBPROGRAM_DECLARATION))
125     {
126       iterate_for_kind (d, cl);
127       return 0;
128     }
129   else
130     return -1;
131 }
132 
133 static int
filter_for_kind_ignore_enums(pIIR_Declaration d,void * cl)134 filter_for_kind_ignore_enums (pIIR_Declaration d, void *cl)
135 {
136   if (!d->is(IR_ENUMERATION_LITERAL))
137     {
138       iterate_for_kind (d, cl);
139       return 0;
140     }
141   else
142     return -1;
143 }
144 
145 pIIR
build_Expr_or_Attr(pVAUL_Name n)146 psr::build_Expr_or_Attr (pVAUL_Name n)
147 {
148   // A SimpleName with a StringLiteral as its id is really a string literal.
149 
150   if (n->is(VAUL_SIMPLE_NAME)
151       && pVAUL_SimpleName(n)->id->is(IR_STRING_LITERAL))
152     return mVAUL_AmbgArrayLitRef (n->pos, NULL,
153 				  pIIR_StringLiteral(pVAUL_SimpleName(n)->id));
154 
155   // see what declarations a prefix of the name matches
156 
157   vaul_decl_set *set = new vaul_decl_set(this);
158   find_decls(*set, n);
159 
160   if (!set->multi_decls (false))
161     {
162       delete set;
163       return mVAUL_UnresolvedName (n->pos, NULL, n);
164     }
165 
166   // recursivly resolve the rest of the name.
167 
168   return build_Expr_or_Attr (n, set, IR_INVALID);
169 }
170 
171 static pVAUL_SimpleName
get_simple_name(pVAUL_Name n)172 get_simple_name (pVAUL_Name n)
173 {
174   if (n->is(VAUL_SIMPLE_NAME))
175     return pVAUL_SimpleName(n);
176   else if (n->is(VAUL_SEL_NAME))
177     return get_simple_name(pVAUL_SelName(n)->prefix);
178   else if (n->is(VAUL_IFTS_NAME))
179     return get_simple_name(pVAUL_IftsName(n)->prefix);
180   else
181     return NULL;
182 }
183 
184 pIIR_Expression
build_formal_Expr(pIIR_InterfaceDeclaration formal,pVAUL_Name n)185 psr::build_formal_Expr (pIIR_InterfaceDeclaration formal, pVAUL_Name n)
186 {
187   // construct a decl_set that has found the given formal
188 
189   vaul_decl_set *set = new vaul_decl_set(this);
190   set->add (formal);
191   set->name = get_simple_name (n);
192 
193   // recursivly resolve the rest of the name.
194 
195   pIIR ea = build_Expr_or_Attr (n, set, IR_INVALID);
196   return validate_Expr (ea);
197 }
198 
199 pIIR_Expression
validate_Expr(pIIR ea)200 psr::validate_Expr (pIIR ea)
201 {
202   if (ea == NULL)
203     return NULL;
204   if (ea->is(IR_EXPRESSION))
205     return pIIR_Expression(ea);
206   if (ea->is(IR_ARRAY_RANGE))
207     error ("%:%n can not be used in an expression", ea, ea);
208   else
209     error ("%:%n can only be used as the prefix of another attribute",
210 	   ea, ea);
211   return NULL;
212 }
213 
214 pIIR_Expression
build_Expr(pVAUL_Name n)215 psr::build_Expr (pVAUL_Name n)
216 {
217   pIIR ea = build_Expr_or_Attr (n);
218   return validate_Expr (ea);
219 }
220 
make_appropriate(pIIR_Expression e)221 pIIR_Expression psr::make_appropriate(pIIR_Expression e)
222 {
223   if (e && try_overload_resolution(e, NULL, IR_ACCESS_TYPE))
224     {
225       overload_resolution (e, IR_ACCESS_TYPE);
226       pIIR_Type at = expr_type (e);
227       if (at == NULL)
228 	return NULL;
229       at = vaul_get_base (at);
230       assert (at->is(IR_ACCESS_TYPE));
231       e = mIIR_AccessReference (e->pos, pIIR_AccessType(at)->designated_type,
232 				e);
233     }
234   return e;
235 }
236 
237 pIIR
build_Expr_or_Attr(pVAUL_Name n,vaul_decl_set * set,IR_Kind basic_k)238 psr::build_Expr_or_Attr (pVAUL_Name n, vaul_decl_set *set, IR_Kind basic_k)
239 {
240   if (basic_k == IR_INVALID)
241     set->iterate (iterate_for_kind, &basic_k);
242 
243   if (n->is(VAUL_IFTS_NAME)
244       || (set->name == n && tree_is(basic_k, IR_SUBPROGRAM_DECLARATION)))
245     {
246 
247       // An array subscription, a function call (maybe without
248       // arguments), a type conversion, or an array slicing.
249 
250       pVAUL_Name pfx = n;
251       pVAUL_GenAssocElem a = NULL;
252 
253       if (n->is(VAUL_IFTS_NAME))
254 	{
255 	  pfx = pVAUL_IftsName(n)->prefix;
256 	  a = pVAUL_IftsName(n)->assoc;
257 	}
258 
259       // Now PFX is the function to be called, the array to be
260       // subscripted or sliced, or the target type of the conversion.
261       // A is the list of arguments, or NULL if there are none.
262 
263       if (a && (a->is(VAUL_RANGE_ASSOC_ELEM)
264 		|| a->is(VAUL_SUBTYPE_ASSOC_ELEM)))
265 	{
266 	  // An array slice.
267 
268 	  pIIR_Expression prefix =
269 	    make_appropriate (build_Expr (pfx, set, basic_k));
270 	  overload_resolution (prefix, NULL, IR_ARRAY_TYPE, false, false);
271 	  return build_SliceReference (prefix, a);
272 	}
273       else if (set->name == pfx
274 	       && tree_is (basic_k, IR_SUBPROGRAM_DECLARATION))
275 	{
276 	  // A function call.
277 
278 	  if (prepare_named_assocs(a))
279 	    {
280 	      pVAUL_AmbgCall e = mVAUL_AmbgCall (pfx->pos, NULL,
281 						 pVAUL_NamedAssocElem(a));
282 	      e->set = set;
283 
284 	      int c = pre_constrain (e);
285 	      if (c < 0)
286 		{
287 		  report_mismatched_subprog (pfx, set,
288 					     pVAUL_NamedAssocElem(a));
289 		  delete set;
290 		  return NULL;
291 		}
292 
293 	      e->set->invalidate_pot_invalids();
294 
295 	      // When we have more than one member, they must be enum
296 	      // literals or be distinguishable by their return type.
297 
298 	      // XXX -- check this.
299 
300 	      return e;
301 	    }
302 	}
303       else
304 	{
305 	  if (set->name == pfx && tree_is (basic_k, IR_TYPE_DECLARATION))
306 	    {
307 	      // A type conversion.
308 
309 	      if (a == NULL || a->next != NULL)
310 		error ("%:type conversions must have exactly one argument",
311 		       pfx);
312 	      else if (!a->is(VAUL_NAMED_ASSOC_ELEM)
313 		       || pVAUL_NamedAssocElem(a)->formal)
314 		error ("%:argument of type conversion must be a simple "
315 		       "expression", pfx);
316 	      else
317 		{
318 		  pIIR_Declaration d = set->single_decl ();
319 		  delete set;
320 		  assert (d
321 			  && d->is(IR_TYPE_DECLARATION)
322 			  && a->is(VAUL_NAMED_ASSOC_ELEM));
323 		  pIIR_Expression e = pVAUL_NamedAssocElem(a)->actual;
324 		  return build_TypeConversion (pfx->pos,
325 					       pIIR_TypeDeclaration(d)->type,
326 					       e);
327 		}
328 	    }
329 	  else
330 	    {
331 	      assert(n->is(VAUL_IFTS_NAME));
332 	      // An array subscription.
333 
334 	      pIIR_Expression prefix =
335 		make_appropriate (build_Expr (pfx, set, basic_k));
336 	      overload_resolution (prefix, NULL, IR_ARRAY_TYPE, false, false);
337 	      return build_ArrayReference (prefix, a);
338 	    }
339 	}
340 
341     }
342   else if (n == set->name)
343     {
344       if (tree_is (basic_k, IR_ENUMERATION_LITERAL)
345 	  || basic_k == IR_DECLARATION)
346 	{
347 	  /* We have basic_k == IR_DECLARATION when set contains both
348 	     enumeration literals and subprograms.  Overload
349 	     resolution will handle this special case.
350 	  */
351 	  pVAUL_AmbgEnumLitRef e = mVAUL_AmbgEnumLitRef(n->pos, NULL);
352 	  e->set = set;
353 	  return e;
354 	}
355 #if 0
356       else if (tree_is (basic_k, IR_ALIAS_DECLARATION))
357 	{
358 	  pIIR_Declaration d = set->single_decl();
359 	  delete set;
360 	  if (d == NULL)
361 	    return NULL;
362 	  assert (d->is(IR_ALIAS_DECLARATION));
363 	  return pIIR_AliasDeclaration(d)->initial_value;
364 	}
365 #endif
366       else if (!tree_is (basic_k, IR_OBJECT_DECLARATION)
367 	       && !tree_is(basic_k, IR_PHYSICAL_UNIT))
368 	{
369 	  delete set;
370 	  return mVAUL_UnresolvedName(n->pos, NULL, n);
371 	}
372 
373       pIIR_Declaration d = set->single_decl();
374       delete set;
375       if(d == NULL)
376 	return NULL;
377 
378       if (d->is(IR_OBJECT_DECLARATION))
379 	{
380 	  pIIR_ObjectDeclaration od = pIIR_ObjectDeclaration(d);
381 	  pIIR_SimpleReference sr =
382 	    mIIR_SimpleReference(n->pos, od->subtype, od);
383 	  simple_reference_name(sr) = n;
384 	  return sr;
385 	}
386       else if (d->is(IR_PHYSICAL_UNIT))
387 	{
388 	  pIIR_PhysicalUnit u = pIIR_PhysicalUnit(d);
389 	  return mIIR_PhysicalLiteral(n->pos, u->type, NULL, u);
390 	}
391       else
392 	assert (false);
393     }
394   else if (n->is(VAUL_ATTRIBUTE_NAME))
395     {
396       return build_AttrNode(pVAUL_AttributeName(n), set, basic_k);
397     }
398   else if (n->is(VAUL_SEL_NAME))
399     {
400       pIIR_TextLiteral suffix = pVAUL_SelName(n)->suffix;
401       pVAUL_Name pfx = pVAUL_SelName(n)->prefix;
402       pIIR_Expression orig_prefix = build_Expr (pfx, set, basic_k);
403       pIIR_Expression prefix = make_appropriate (orig_prefix);
404 
405       if (prefix != orig_prefix && vaul_name_eq (suffix, "all"))
406 	return prefix;
407       overload_resolution (prefix, NULL, IR_RECORD_TYPE, false, false);
408       if (prefix == NULL)
409 	return NULL;
410       pIIR_Type t = expr_type (prefix);
411       if (t == NULL || !t->base->is(IR_RECORD_TYPE))
412 	{
413 	  info ("XXX - not a record type %n", t);
414 	  return NULL;
415 	}
416       pIIR_RecordType rt = pIIR_RecordType(t->base);
417       for (pIIR_ElementDeclarationList elts = rt->element_declarations;
418 	   elts; elts = elts->rest)
419 	{
420 	  pIIR_ElementDeclaration re = elts->first;
421 	  if (vaul_name_eq (re->declarator, suffix))
422 	    return mIIR_RecordReference(n->pos, re->subtype, prefix, re);
423 	}
424       error("%:%n has no element named %n, it has", n, rt, suffix);
425       for (pIIR_ElementDeclarationList elts = rt->element_declarations;
426 	   elts; elts = elts->rest)
427 	{
428 	  pIIR_ElementDeclaration re = elts->first;
429 	  info("%: %n: %n", re, re->declarator, re->subtype);
430 	}
431       return NULL;
432 
433     }
434   else
435     {
436       info ("%:XXX - unimplemented partial expr name %n (%n)",
437 	    n, n, set->name);
438     }
439 
440   delete set;
441   return NULL;
442 }
443 
444 pIIR_Expression
build_Expr(pVAUL_Name n,vaul_decl_set * set,IR_Kind basic_k)445 psr::build_Expr (pVAUL_Name n, vaul_decl_set *set, IR_Kind basic_k)
446 {
447   pIIR ea = build_Expr_or_Attr (n, set, basic_k);
448   return validate_Expr (ea);
449 }
450 
451 void
report_mismatched_subprog(pVAUL_Name pfx,vaul_decl_set * set,pVAUL_NamedAssocElem assocs)452 psr::report_mismatched_subprog (pVAUL_Name pfx, vaul_decl_set *set,
453 				pVAUL_NamedAssocElem assocs)
454 {
455   bool obvious = true;
456   my_dynparray<pIIR_Type_vector> assoc_types;
457 
458   for (pVAUL_NamedAssocElem na = assocs; na;
459        na = pVAUL_NamedAssocElem(na->next))
460     {
461       assert (na->is(VAUL_NAMED_ASSOC_ELEM));
462       pIIR_Type_vector *tv = ambg_expr_types (na->actual);
463       assert (tv);
464       assoc_types.add (tv);
465       if (tv->size() > 5)
466 	obvious = false;
467     }
468   if (obvious || options.fullnames)
469     {
470       error ("%:no declaration matches use as %n(%~", pfx, pfx);
471       int i = 0;
472       for (pVAUL_NamedAssocElem na = assocs; na;
473 	   na = pVAUL_NamedAssocElem(na->next))
474 	{
475 	  assert (na->is(VAUL_NAMED_ASSOC_ELEM));
476 	  if (na->formal)
477 	    info ("%~%n => %~", na->formal);
478 	  pIIR_Type_vector *tv = assoc_types[i++];
479 	  if (tv->size() == 0)
480 	    info ("%~?%~");
481 	  if (tv->size() > 1)
482 	    info ("%~{ %~");
483 	  for (int j = 0; j < tv->size(); j++)
484 	    {
485 	      info ("%~%n%~", (*tv)[j]);
486 	      if (j < tv->size()-1)
487 		info("%~ | %~");
488 	    }
489 	  if (tv->size() > 1)
490 	    info ("%~ }%~");
491 	  if (na->next)
492 	    info ("%~, %~");
493 	}
494       info ("%~), candidates are");
495     }
496   else
497     error ("%:no declaration of %n matches this unobvious use, candidates are",
498 	   pfx, pfx);
499   for (int i = 0; i < assoc_types.size(); i++)
500     delete assoc_types[i];
501   set->show ();
502 }
503 
504 pIIR_ArrayReference
build_ArrayReference(pIIR_Expression prefix,pVAUL_GenAssocElem a)505 psr::build_ArrayReference (pIIR_Expression prefix, pVAUL_GenAssocElem a)
506 {
507   if (prefix == NULL || a == NULL)
508     return NULL;
509 
510   pIIR_Type t = expr_type (prefix);
511   if (t == NULL)
512     return NULL;
513 
514   if (!t->base->is(IR_ARRAY_TYPE))
515     {
516       error ("%:can't subscribe %n (not an array)", a, prefix);
517       return NULL;
518     }
519 
520   pIIR_ArrayType at = pIIR_ArrayType(t->base);
521   if (at->index_types == NULL)
522     return NULL;
523 
524   pIIR_ArrayReference aor = mIIR_ArrayReference (a->pos, at->element_type,
525 						 prefix, NULL);
526   pIIR_ExpressionList *ind_tail = &aor->indices;
527   for (pIIR_TypeList it = at->index_types; it; it = it->rest)
528     {
529       if (a == NULL)
530 	{
531 	  error ("%:too few subscripts for array %n", prefix, prefix);
532 	  return NULL;
533 	}
534       if (!a->is(VAUL_NAMED_ASSOC_ELEM) || pVAUL_NamedAssocElem(a)->formal)
535 	{
536 	  error("%:array subscripts must be simple expressions", a);
537 	  return NULL;
538 	}
539 
540       pVAUL_NamedAssocElem na = pVAUL_NamedAssocElem(a);
541       overload_resolution (na->actual, it->first);
542       *ind_tail = mIIR_ExpressionList (a->pos, na->actual, NULL);
543       ind_tail = &(*ind_tail)->rest;
544       a = a->next;
545     }
546 
547   if (a)
548     {
549       error ("%:too many subscripts for array %n", a, prefix);
550       return NULL;
551     }
552 
553   return aor;
554 }
555 
556 pIIR_SliceReference
build_SliceReference(pIIR_Expression prefix,pVAUL_GenAssocElem slice)557 psr::build_SliceReference (pIIR_Expression prefix, pVAUL_GenAssocElem slice)
558 {
559   if (prefix == NULL || slice == NULL)
560     return NULL;
561 
562   pIIR_Range r = range_from_assoc (slice);
563   pIIR_Type rt = ensure_range_type (r, NULL);
564 
565   if (rt == NULL)
566     return NULL;
567 
568   assert (slice->next == NULL);
569 
570   pIIR_Type t = expr_type (prefix);
571   if (t == NULL)
572     return NULL;
573 
574   if (!t->base->is(IR_ARRAY_TYPE))
575     {
576       error("%:can't take slice of %n (not an array)", slice, prefix);
577       return NULL;
578     }
579 
580   pIIR_ArrayType at = pIIR_ArrayType(t->base);
581   if (at->index_types && at->index_types->rest)
582     error ("%:sliced arrays must be one-dimensional", slice);
583 
584   if (rt && at->index_types && at->index_types->first
585       && rt->base != at->index_types->first->base)
586     {
587       error ("%:type of slice bounds does not match array index type", slice);
588       r = NULL;
589     }
590 
591   pIIR_ScalarSubtype it = mIIR_ScalarSubtype (slice->pos,
592 					      rt->base,
593 					      rt,
594 					      NULL,
595 					      r);
596   pIIR_ArraySubtype st = mIIR_ArraySubtype (slice->pos,
597 					    at,
598 					    t,
599 					    NULL,
600 					    mIIR_TypeList (slice->pos,
601 							   it,
602 							   NULL));
603 
604   return mIIR_SliceReference (slice->pos, st, prefix, r);
605 }
606 
607 int
try_one_association(pVAUL_NamedAssocElem a,pIIR_InterfaceDeclaration f)608 psr::try_one_association (pVAUL_NamedAssocElem a,
609 			  pIIR_InterfaceDeclaration f)
610 {
611   // XXX - what about formal and actual conversions?
612   return constrain (a->actual, f->subtype, IR_INVALID);
613 }
614 
615 static pIIR_InterfaceDeclaration
find_interface_by_id(pIIR_InterfaceList list,pIIR_TextLiteral id)616 find_interface_by_id (pIIR_InterfaceList list, pIIR_TextLiteral id)
617 {
618   if (!id->is(IR_IDENTIFIER))
619     return NULL;
620 
621   while (list)
622     {
623       if (vaul_name_eq (list->first->declarator, id))
624 	return list->first;
625       list = list->rest;
626     }
627   return NULL;
628 }
629 
630 pIIR_Declaration
grab_formal_conversion(pVAUL_NamedAssocElem assoc,pIIR_InterfaceList formals,int * formal_cost,pIIR_InterfaceDeclaration * converted_formal)631 psr::grab_formal_conversion (pVAUL_NamedAssocElem assoc,
632 			     pIIR_InterfaceList formals,
633 			     int *formal_cost,
634 			     pIIR_InterfaceDeclaration *converted_formal)
635 {
636     if (assoc->ifts_decls == NULL)
637 	return NULL;
638 
639     // We have either function(ifc) or type(ifc) with ifc being
640     // the only argument.
641 
642     assert(assoc->formal->is(VAUL_IFTS_NAME));
643     pVAUL_IftsName ifts = pVAUL_IftsName(assoc->formal);
644     assert(ifts->assoc && ifts->assoc->is(VAUL_NAMED_ASSOC_ELEM));
645     pVAUL_NamedAssocElem arg = pVAUL_NamedAssocElem(ifts->assoc);
646     assert(arg->next == NULL);
647     IR_Kind kind = assoc->ifts_kind;
648     pVAUL_SimpleName sn = assoc->ifts_arg_name;
649     assert(sn);
650 
651     if (pIIR_InterfaceDeclaration f = find_interface_by_id (formals, sn->id))
652       {
653 	pIIR_Declaration conversion = NULL;
654 	int fcost;
655 	if (tree_is(kind, IR_FUNCTION_DECLARATION))
656 	  {
657 	    // See if we can resolve the function.
658 
659 	    pIIR_SimpleReference mor = mIIR_SimpleReference (assoc->pos,
660 							    f->subtype,
661 							    f);
662 	    simple_reference_name(mor) = sn;
663 	    pVAUL_NamedAssocElem na = mVAUL_NamedAssocElem (assoc->pos,
664 						  NULL,
665 						  arg->formal,
666 						  mor);
667 	    pVAUL_AmbgCall ac = mVAUL_AmbgCall (assoc->pos, NULL, na);
668 	    ac->set = assoc->ifts_decls;
669 	    // XXX - should this be based on the actual type?
670 	    fcost = constrain(ac, NULL, IR_TYPE);
671 	    if(fcost >= 0) {
672 		conversion = assoc->ifts_decls->single_decl(false);
673 		assert(conversion && conversion->is(IR_FUNCTION_DECLARATION));
674 	    }
675 	} else if(tree_is(kind, IR_TYPE_DECLARATION)) {
676 	  conversion = assoc->ifts_decls->single_decl(false);
677 	  assert(conversion && conversion->is(IR_TYPE_DECLARATION));
678 	  fcost = 0;
679 	} else
680 	    assert(false);
681 
682 	info("+++ - %n converted by %n (cost %d)", f, conversion, fcost);
683 
684 	if(formal_cost)
685 	    *formal_cost = fcost;
686 	if(converted_formal)
687 	    *converted_formal = f;
688 	return conversion;
689     }
690 
691     return NULL;
692 }
693 
694 static pIIR_Type
get_partial_formal_type(pVAUL_Name name,pIIR_InterfaceDeclaration formal,pVAUL_SubarrayType subarray_storage=NULL)695 get_partial_formal_type (pVAUL_Name name, pIIR_InterfaceDeclaration formal,
696 			 pVAUL_SubarrayType subarray_storage = NULL)
697 {
698   if (name->is(VAUL_SIMPLE_NAME))
699     return formal->subtype;
700   else if (name->is(VAUL_SEL_NAME))
701     {
702       pIIR_Type ptype =
703 	get_partial_formal_type (pVAUL_SelName(name)->prefix, formal);
704       if (!ptype || !ptype->is(IR_RECORD_TYPE))
705 	return NULL;
706 
707       for (pIIR_ElementDeclarationList elts =
708 	     pIIR_RecordType(ptype)->element_declarations;
709 	   elts; elts = elts->rest)
710 	{
711 	  pIIR_ElementDeclaration re = elts->first;
712 	  if (vaul_name_eq (re->declarator, pVAUL_SelName(name)->suffix))
713 	    return re->subtype;
714 	}
715       return NULL;
716     }
717   else if (name->is(VAUL_IFTS_NAME))
718     {
719       pIIR_Type ptype =
720 	get_partial_formal_type (pVAUL_IftsName(name)->prefix, formal);
721       if (!ptype)
722 	return NULL;
723 
724       ptype = ptype->base;
725       if (!ptype->is(IR_ARRAY_TYPE))
726 	return NULL;
727 
728       pVAUL_GenAssocElem arg = pVAUL_IftsName(name)->assoc;
729       if (arg == NULL)
730 	return NULL;
731       if (arg->is(VAUL_NAMED_ASSOC_ELEM))
732 	{
733 	  pIIR_ArrayType at = pIIR_ArrayType(ptype);
734 	  pIIR_TypeList it = at->index_types;
735 	  while (it && arg)
736 	    {
737 	      assert (arg->is(VAUL_NAMED_ASSOC_ELEM));
738 	      arg = arg->next;
739 	      it = it->rest;
740 	    }
741 	  if (arg)
742 	    return NULL;
743 	  if (it)
744 	    {
745 	      if (subarray_storage)
746 		{
747 		  subarray_storage->pos = at->pos;
748 		  subarray_storage->static_level = at->static_level;
749 		  subarray_storage->declaration = NULL;
750 		  subarray_storage->index_types = it;
751 		  subarray_storage->element_type = at->element_type;
752 		  subarray_storage->complete_type = at;
753 		  return subarray_storage;
754 		}
755 	      else
756 		return NULL;
757 	    }
758 	  else
759 	    ptype = pIIR_ArrayType(ptype)->element_type;
760 	}
761       else
762 	{
763 	  // slices must be one-dimensional, this has already been checked
764 	  assert (arg->next == NULL);
765 	}
766       return ptype;
767     }
768   else
769     assert (false);
770 }
771 
772 int
try_association(pVAUL_NamedAssocElem actuals,pIIR_InterfaceList formals)773 psr::try_association (pVAUL_NamedAssocElem actuals, pIIR_InterfaceList formals)
774 {
775   int cost = 0;
776   pIIR_InterfaceList formal;
777   pVAUL_NamedAssocElem a;
778   my_dynarray<pIIR_InterfaceDeclaration> associated_formals;
779 
780   // quick check to avoid unecessary recursion for the most common cases
781 
782   int n_formals = 0, n_opt_formals = 0;
783   for (pIIR_InterfaceList f = formals; f; f = f->rest)
784     {
785       n_formals++;
786       if (f->first->initial_value)
787 	n_opt_formals++;
788     }
789 
790   int n_actuals = 0;
791   bool valid = true;
792   for (pVAUL_NamedAssocElem ae = actuals; ae; ae = pVAUL_NamedAssocElem(ae->next))
793     {
794       assert (ae->is(VAUL_NAMED_ASSOC_ELEM));
795       if (ae->formal && !ae->formal->is(VAUL_SIMPLE_NAME))
796 	{
797 	  valid = false;
798 	  break;
799 	}
800       n_actuals++;
801       if (n_actuals > n_formals)
802 	break;
803     }
804 
805   if (valid && (n_actuals > n_formals
806 		|| n_actuals < n_formals - n_opt_formals))
807     {
808       // info("+++ - shortcut");
809       return -1;
810     }
811 
812   // first, the unnamed ones
813 
814   formal = formals;
815   a = actuals;
816   while (formal && a && a->formal == NULL)
817     {
818       assert(a->is(VAUL_NAMED_ASSOC_ELEM));
819 
820       int c = try_one_association (a, formal->first);
821       if (c < 0)
822 	return c;
823       cost += c;
824       associated_formals.add (formal->first);
825       a = pVAUL_NamedAssocElem(a->next);
826       formal = formal->rest;
827     }
828 
829   if (formal == NULL && a != NULL)
830     return -1;
831 
832   // and now the named ones
833 
834   while (a)
835     {
836       assert (a->is(VAUL_NAMED_ASSOC_ELEM));
837       if (a->formal == NULL)
838 	break;
839 
840       info ("+++ - on %n", a->formal);
841 
842       // There are several cases here for the formal:
843       //
844       // interface_name
845       // function(interface_name)
846       // type(interface_name)
847       //
848       // interface_name.record_item
849       // interface_name(array_index, ...)
850       //   and combinations
851       //
852       // we try all cases and if more than one is valid, it's an error
853 
854       int formal_cost = -1;
855       pIIR_InterfaceDeclaration converted_formal = NULL;
856 
857       pIIR_Declaration conv = grab_formal_conversion (a, formals,
858 						      &formal_cost,
859 						      &converted_formal);
860       if (conv)
861 	{
862 	  pIIR_Type actual_type;
863 	  if (conv->is(IR_FUNCTION_DECLARATION))
864 	    actual_type = pIIR_FunctionDeclaration(conv)->return_type;
865 	  else if (conv->is(IR_TYPE_DECLARATION))
866 	    actual_type = pIIR_TypeDeclaration(conv)->type;
867 	  else
868 	    assert (false);
869 	  formal_cost += constrain (a->actual, actual_type, IR_INVALID);
870 	  associated_formals.add (converted_formal);
871 	}
872 
873       pVAUL_SimpleName sn = get_simple_name (a->formal);
874       assert (sn);
875       if (pIIR_InterfaceDeclaration f =
876 	  find_interface_by_id (formals, sn->id))
877 	{
878 	  if (converted_formal)
879 	    {
880 #if 0
881 	      error("%:%n is ambigous as a formal name",
882 		    a->formal, a->formal);
883 	      info("%: it could apply to both %n and %n",
884 		   a->formal, converted_formal, f);
885 #endif
886 	      return -1;
887 	    }
888 
889 	  assert (formal_cost < 0);
890 
891 	  pVAUL_SubarrayType sat = mVAUL_SubarrayType ((IIR_PosInfo *)NULL,
892 						       NULL,
893 						       NULL,
894 						       NULL);
895 	  pIIR_Type atype = get_partial_formal_type (a->formal, f, sat);
896 	  if (atype)
897 	    {
898 	      info("+++ - type of %n is %n", a->formal, atype);
899 	      formal_cost = constrain (a->actual, atype, IR_INVALID);
900 	      associated_formals.add (f);
901 	    }
902 	  else
903 	    return -1;
904 	}
905 
906       if (formal_cost < 0)
907 	return formal_cost;
908       cost += formal_cost;
909       a = pVAUL_NamedAssocElem (a->next);
910     }
911 
912   for (pIIR_InterfaceList f = formals; f; f = f->rest)
913     {
914       if (!f->first->initial_value && !associated_formals.contains(f->first))
915 	return -1;
916     }
917 
918   return cost;
919 }
920 
921 int
try_array_subscription(pIIR_ArrayType at,pVAUL_GenAssocElem a)922 psr::try_array_subscription (pIIR_ArrayType at, pVAUL_GenAssocElem a)
923 {
924   int cost = 0;
925   for (pIIR_TypeList it = at->index_types; it; it = it->rest)
926     {
927       if (a == NULL || !a->is(VAUL_NAMED_ASSOC_ELEM) ||
928 	  pVAUL_NamedAssocElem(a)->formal)
929 	return -1;
930       int c = constrain (pVAUL_NamedAssocElem(a)->actual, it->first,
931 			 IR_INVALID);
932       if (c < 0)
933 	return -1;
934       cost += c;
935       a = a->next;
936     }
937   if (a)
938     return -1;
939   return cost;
940 }
941 
942 static const char *
mode_name(IR_Mode m)943 mode_name (IR_Mode m)
944 {
945   switch (m)
946     {
947     case IR_UNKNOWN_MODE:
948       return "<unknown>";
949     case IR_IN_MODE:
950       return "in";
951     case IR_OUT_MODE:
952       return "out";
953     case IR_INOUT_MODE:
954       return "inout";
955     case IR_BUFFER_MODE:
956       return "buffer";
957     case IR_LINKAGE_MODE:
958       return "linkage";
959     }
960   return NULL;
961 }
962 
963 // Check whether the expression E can be read.
964 
965 void
check_for_read(pIIR_Expression e)966 psr::check_for_read (pIIR_Expression e)
967 {
968 
969   // All objects except those of mode out can be read.  References to
970   // objects with unknown declarations (such as the return value of a
971   // function call) are OK, too.
972   //
973   if (e->is(IR_OBJECT_REFERENCE))
974     {
975       pIIR_ObjectDeclaration obj = vaul_get_object_declaration (e);
976       IR_Mode m = vaul_get_mode (e);
977       if (obj && m == IR_OUT_MODE)
978 	error ("%:%n (of mode out) can not be read", e, obj);
979     }
980 
981   // The attributes 'STABLE, 'QUIET, 'DELAYED and 'TRANSACTION of a
982   // signal that is a interface object of mode inout, or out can not
983   // be read.  For mode in, they can not be read when the interface
984   // object is a subprogram parameter.  Else they can be read.
985   //
986   else if (e->is(IR_ATTR_STABLE)
987 	   || e->is(IR_ATTR_QUIET)
988 	   || e->is(IR_ATTR_DELAYED)
989 	   || e->is(IR_ATTR_TRANSACTION))
990     {
991       pIIR_ObjectDeclaration obj =
992 	vaul_get_object_declaration (pIIR_SignalAttr(e)->signal);
993       IR_Mode m = vaul_get_mode (obj);
994 
995       if (obj == NULL || !obj->is(IR_INTERFACE_DECLARATION))
996 	return;
997 
998       if (m == IR_IN_MODE)
999 	{
1000 	  if (obj->declarative_region->is(IR_SUBPROGRAM_DECLARATION))
1001 	    error ("%:%n can not be accessed since %n is a subprogram"
1002 		   " parameter of mode `in'", e, e, obj);
1003 	}
1004       else if (m == IR_INOUT_MODE || m == IR_OUT_MODE)
1005 	{
1006 	  error ("%:%n can not be accessed since %n has mode `%s'",
1007 		 e, e, obj, mode_name (m));
1008 	}
1009     }
1010 
1011   // The attributes 'EVENT, 'ACTIVE, 'LAST_EVENT, 'LAST_ACTIVE, and
1012   // 'LAST_VALUE of a interface object of mode out can not be read.
1013 
1014   else if (e->is(IR_ATTR_EVENT)
1015 	   || e->is(IR_ATTR_ACTIVE)
1016 	   || e->is(IR_ATTR_LAST_EVENT)
1017 	   || e->is(IR_ATTR_LAST_ACTIVE)
1018 	   || e->is(IR_ATTR_LAST_VALUE))
1019     {
1020       pIIR_ObjectDeclaration obj =
1021 	vaul_get_object_declaration (pIIR_SignalAttr(e)->signal);
1022       IR_Mode m = vaul_get_mode (obj);
1023 
1024       if (obj == NULL || !obj->is(IR_INTERFACE_DECLARATION))
1025 	return;
1026 
1027       if (m == IR_OUT_MODE)
1028 	{
1029 	  error ("%:%n can not be accessed since %n has mode `out'",
1030 		 e, e, obj);
1031 	}
1032 
1033     }
1034 
1035   // For aggregates, check all elements.
1036 
1037   else if (e->is(IR_RECORD_AGGREGATE))
1038     {
1039       for (pIIR_ElementAssociationList eal =
1040 	     pIIR_RecordAggregate(e)->element_association_list;
1041 	   eal; eal = eal->rest)
1042 	check_for_read (eal->first->value);
1043     }
1044   else if (e->is(IR_ARRAY_AGGREGATE))
1045     {
1046       for (pIIR_IndexedAssociationList ial =
1047 	     pIIR_ArrayAggregate(e)->indexed_association_list;
1048 	   ial; ial = ial->rest)
1049 	check_for_read (ial->first->value);
1050     }
1051 
1052   // Everything else can be read.
1053 }
1054 
1055 // Check whether the expression E can be updated.
1056 
1057 void
check_for_update(pIIR_Expression e)1058 psr::check_for_update (pIIR_Expression e)
1059 {
1060   if (e->is(IR_OBJECT_REFERENCE))
1061     {
1062       pIIR_ObjectDeclaration obj = vaul_get_object_declaration (e);
1063       IR_Mode m = vaul_get_mode (e);
1064       if (obj && m == IR_IN_MODE)
1065 	error ("%:%n (of mode in) can not be updated", e, obj);
1066     }
1067 
1068   // For aggregates, check all elements.
1069 
1070   else if (e->is(IR_RECORD_AGGREGATE))
1071     {
1072       for (pIIR_ElementAssociationList eal =
1073 	     pIIR_RecordAggregate(e)->element_association_list;
1074 	   eal; eal = eal->rest)
1075 	check_for_update (eal->first->value);
1076     }
1077   else if (e->is(IR_ARRAY_AGGREGATE))
1078     {
1079       for (pIIR_IndexedAssociationList ial =
1080 	     pIIR_ArrayAggregate(e)->indexed_association_list;
1081 	   ial; ial = ial->rest)
1082 	check_for_update (ial->first->value);
1083     }
1084 
1085   // "open" associations can be updated
1086   //
1087   else if (e->is(IR_OPEN_EXPRESSION))
1088     {
1089       return;
1090     }
1091 
1092   else
1093     error ("%:%n can not be updated", e, e);
1094 }
1095 
1096 bool
associate_one(pIIR_AssociationList & tail,pIIR_ObjectReference f,pIIR_Declaration fconv,pIIR_Expression a,pIIR_Declaration aconv,bool need_overload_resolution)1097 psr::associate_one (pIIR_AssociationList &tail,
1098 		    pIIR_ObjectReference f,
1099 		    pIIR_Declaration fconv,
1100 		    pIIR_Expression a,
1101 		    pIIR_Declaration aconv,
1102 		    bool need_overload_resolution)
1103 {
1104   if (f == NULL || a == NULL)
1105     return false;
1106 
1107   if (a->is(VAUL_UNRESOLVED_NAME))
1108     {
1109       pVAUL_UnresolvedName un = pVAUL_UnresolvedName(a);
1110       pIIR_Declaration d = find_single_decl(un->name, IR_DECLARATION, "");
1111       if(d)
1112 	error("%:%n can not be used in an expression", un->name, d);
1113       return false;
1114     }
1115 
1116 #if 0
1117   for (pIIR_AssociationList asl = tail; asl; asl = asl->rest)
1118     if (asl->first && asl->first->formal == f)
1119       {
1120 	error ("%:multiple actuals for formal %n", a, f);
1121 	return false;
1122       }
1123 #endif
1124 
1125   pIIR_Type actual_type;
1126   if (fconv)
1127     {
1128       if (fconv->is(IR_FUNCTION_DECLARATION))
1129 	actual_type = pIIR_FunctionDeclaration(fconv)->return_type;
1130       else if (fconv->is(IR_TYPE_DECLARATION))
1131 	actual_type = pIIR_TypeDeclaration(fconv)->type;
1132       else
1133 	assert (false);
1134     }
1135   else
1136     actual_type = f->subtype;
1137 
1138   if (need_overload_resolution)
1139     overload_resolution_not_for_read (a, actual_type);
1140   else
1141     {
1142       /* disambiguation is good enough because this expression tree
1143 	 has already been subject to overload resolution. */
1144       a = disambiguate_expr (a, actual_type, false);
1145     }
1146 
1147   if (a == NULL)
1148     return false;
1149 
1150   if (aconv)
1151     info ("%: +++ - actual of %n converted by %n", a, f, aconv);
1152 
1153   pIIR_InterfaceDeclaration fi =
1154     pIIR_InterfaceDeclaration (vaul_get_object_declaration (f));
1155   if (fi && (fi->mode == IR_IN_MODE || fi->mode == IR_INOUT_MODE
1156 	     || fi->mode == IR_LINKAGE_MODE))
1157     check_for_read (a);
1158   if (fi && (fi->mode == IR_OUT_MODE || fi->mode == IR_INOUT_MODE
1159 	     || fi->mode == IR_BUFFER_MODE || fi->mode == IR_LINKAGE_MODE))
1160     check_for_update (a);
1161 
1162   pIIR_AssociationElement assoc;
1163   if (a->is(IR_OPEN_EXPRESSION))
1164     assoc = mIIR_AssociationElementOpen (a->pos, f, fi, fconv, a, aconv);
1165   else
1166     assoc = mIIR_AssociationElementByExpression (a->pos, f, fi, fconv, a, aconv);
1167 
1168   tail = mIIR_AssociationList (assoc->pos, assoc, tail);
1169   return true;
1170 }
1171 
1172 pIIR_Expression
add_partial_choice(pIIR_Expression & pactual,pVAUL_Name formal,pIIR_Expression actual)1173 psr::add_partial_choice (pIIR_Expression &pactual,
1174 			 pVAUL_Name formal,
1175 			 pIIR_Expression actual)
1176 {
1177   pIIR_PosInfo pos = formal->pos;
1178   pIIR_Expression *ep = NULL;
1179 
1180   if (formal->is(VAUL_SIMPLE_NAME))
1181     ep = &pactual;
1182 
1183   else if(formal->is(VAUL_SEL_NAME))
1184     {
1185       pIIR_Expression px = add_partial_choice (pactual,
1186 					       pVAUL_SelName(formal)->prefix,
1187 					       NULL);
1188       if (px == NULL)
1189 	return NULL;
1190       assert (px->is(VAUL_ARTIFICIAL_AMBG_AGGREGATE));
1191       pVAUL_AmbgAggregate aggr = pVAUL_AmbgAggregate(px);
1192       pIIR_TextLiteral sfx = pVAUL_SelName(formal)->suffix;
1193       pVAUL_ElemAssoc ea;
1194       for (ea = aggr->first_assoc; ea; ea = ea->next)
1195 	{
1196 	  if (ea->choices && ea->choices->rest == NULL
1197 	      && ea->choices && ea->choices->first->is(VAUL_CHOICE_BY_NAME))
1198 	    {
1199 	      pVAUL_ChoiceByName nc = pVAUL_ChoiceByName (ea->choices->first);
1200 	      if (nc->name && nc->name->is(VAUL_SIMPLE_NAME)
1201 		  && vaul_name_eq(pVAUL_SimpleName(nc->name)->id, sfx))
1202 		break;
1203 	    }
1204 	}
1205       if (ea == NULL)
1206 	{
1207 	  pIIR_Choice c = mVAUL_ChoiceByName (pos, mVAUL_SimpleName(pos, sfx));
1208 	  ea = mVAUL_ElemAssoc (pos, aggr->first_assoc,
1209 			   mIIR_ChoiceList (pos, c, NULL), NULL);
1210 	  aggr->first_assoc = ea;
1211 	}
1212       ep = &ea->actual;
1213 
1214     }
1215 
1216   else if (formal->is(VAUL_IFTS_NAME))
1217     {
1218       pVAUL_GenAssocElem arg = pVAUL_IftsName(formal)->assoc;
1219       if (arg == NULL)
1220 	return NULL;
1221 
1222       pIIR_Expression px = add_partial_choice (pactual,
1223 					       pVAUL_IftsName(formal)->prefix,
1224 					       NULL);
1225       if (px == NULL)
1226 	return NULL;
1227       assert (px->is(VAUL_ARTIFICIAL_AMBG_AGGREGATE));
1228       pVAUL_AmbgAggregate aggr = pVAUL_AmbgAggregate(px);
1229 
1230       while (arg)
1231 	{
1232 	  pIIR_Choice c;
1233 	  if (arg->is(VAUL_NAMED_ASSOC_ELEM))
1234 	    c = mIIR_ChoiceByExpression (pos, pVAUL_NamedAssocElem(arg)->actual);
1235 	  else
1236 	    {
1237 	      c = mIIR_ChoiceByRange (pos, range_from_assoc (arg));
1238 	      actual_is_slice(pIIR_ChoiceByRange(c)) = true;
1239 	    }
1240 	  pVAUL_ElemAssoc ea = mVAUL_ElemAssoc (pos, aggr->first_assoc,
1241 				      mIIR_ChoiceList (pos, c, NULL),
1242 				      NULL);
1243 	  aggr->first_assoc = ea;
1244 	  ep = &ea->actual;
1245 
1246 	  arg = arg->next;
1247 	  if(arg)
1248 	    {
1249 	      aggr = mVAUL_ArtificialAmbgAggregate(pos, NULL, NULL);
1250 	      *ep = aggr;
1251 	    }
1252 	}
1253 
1254     }
1255   else
1256     assert(false);
1257 
1258   if (*ep)
1259     {
1260       if (actual || !(*ep)->is(VAUL_ARTIFICIAL_AMBG_AGGREGATE))
1261 	{
1262 	  error ("%:multiple actuals for %n", formal, formal);
1263 	  return NULL;
1264 	}
1265     }
1266   else
1267     *ep = actual? actual : mVAUL_ArtificialAmbgAggregate (pos, NULL, NULL);
1268 
1269   return *ep;
1270 }
1271 
1272 pIIR_AssociationList
associate(pVAUL_NamedAssocElem actuals,pIIR_InterfaceList formals,bool complete,bool need_overload_resolution)1273 psr::associate (pVAUL_NamedAssocElem actuals,
1274 		pIIR_InterfaceList formals,
1275 		bool complete,
1276 		bool need_overload_resolution)
1277 {
1278   pIIR_AssociationList tail = NULL;
1279   pVAUL_NamedAssocElem a;
1280   pIIR_InterfaceList formal;
1281 
1282   formal = formals;
1283   a = actuals;
1284   while (formal && a && a->formal == NULL)
1285     {
1286       assert (a->is(VAUL_NAMED_ASSOC_ELEM));
1287 
1288       pIIR_InterfaceDeclaration f = formal->first;
1289       pIIR_Expression f_exp = mIIR_SimpleReference (a->pos,
1290 						    f->subtype,
1291 						    f);
1292       overload_resolution_not_for_read (f_exp, pIIR_Type(NULL));
1293 
1294       if (a->actual
1295 	  && !associate_one (tail,
1296 			     pIIR_ObjectReference (f_exp), NULL,
1297 			     a->actual, NULL,
1298 			     need_overload_resolution))
1299 	return NULL;
1300       a = pVAUL_NamedAssocElem (a->next);
1301       formal = formal->rest;
1302     }
1303 
1304   if (formal == NULL && a != NULL)
1305     {
1306       error("%:too many actuals", a);
1307       return NULL;
1308     }
1309 
1310   while (a)
1311     {
1312       assert (a->is(VAUL_NAMED_ASSOC_ELEM) && a->formal);
1313 
1314       if (a->actual == NULL)
1315 	{
1316 	  a = pVAUL_NamedAssocElem(a->next);
1317 	  continue;
1318 	}
1319 
1320       pIIR_InterfaceDeclaration f;
1321       pIIR_Declaration fconv = grab_formal_conversion (a, formals, NULL, &f);
1322       pIIR_Expression f_exp;
1323       if (fconv)
1324 	f_exp = mIIR_SimpleReference (a->pos, f->subtype, f);
1325       else
1326 	{
1327 	  pVAUL_SimpleName sn = get_simple_name (a->formal);
1328 	  f = find_interface_by_id (formals, sn->id);
1329 	  if (f == NULL)
1330 	    {
1331 	      error ("%:no formal with name %n", sn, sn);
1332 	      f_exp = NULL;
1333 	    }
1334 	  else
1335 	    f_exp = build_formal_Expr (f, a->formal);
1336 	}
1337       overload_resolution_not_for_read (f_exp, pIIR_Type(NULL));
1338 
1339       if (f_exp == NULL
1340 	  || !associate_one(tail,
1341 			    pIIR_ObjectReference (f_exp), fconv,
1342 			    a->actual, NULL,
1343 			    need_overload_resolution))
1344 	return NULL;
1345 
1346       a = pVAUL_NamedAssocElem(a->next);
1347     }
1348 
1349 #if 0
1350   if (complete)
1351     {
1352       bool success = true;
1353       for (pIIR_InterfaceList f = formals; f; f = f->rest)
1354 	{
1355 	  if (f->first->initial_value)
1356 	    continue;
1357 	  pIIR_AssociationList asl;
1358 	  for (asl = tail; asl; asl = asl->rest)
1359 	    if(asl->first && asl->first->formal == f->first)
1360 	      break;
1361 	  if (asl == NULL)
1362 	    {
1363 	      error ("%:formal %n has not been associated",
1364 		     actuals, f->first);
1365 	      success = false;
1366 	    }
1367 	}
1368       if (!success)
1369 	return NULL;
1370     }
1371 #endif
1372 
1373   return reverse (tail);
1374 }
1375 
1376 pIIR_AssociationList
associate_ports(pVAUL_NamedAssocElem actuals,pIIR_InterfaceList formals)1377 psr::associate_ports (pVAUL_NamedAssocElem actuals,
1378 		      pIIR_InterfaceList formals)
1379 {
1380   pIIR_AssociationList map = associate (actuals, formals, false);
1381 
1382   for (pIIR_AssociationList al = map; al; al = al->rest)
1383     {
1384       pIIR_AssociationElement a = al->first;
1385       pIIR_SignalInterfaceDeclaration p =
1386 	pIIR_SignalInterfaceDeclaration (a->formal_declaration);  // fixed: ... (a->formal)
1387 
1388       if (a->actual->is (IR_OBJECT_REFERENCE))
1389 	{
1390 	  pIIR_ObjectDeclaration obj = vaul_get_object_declaration (a->actual);
1391 	  if (obj)
1392 	    {
1393 	      IR_Mode peer_mode = vaul_get_mode (obj);
1394 	      const char *allowed = NULL;
1395 	      switch (p->mode)
1396 		{
1397 		case IR_IN_MODE:
1398 		  if (peer_mode != IR_IN_MODE
1399 		      && peer_mode != IR_INOUT_MODE
1400 		      && peer_mode != IR_BUFFER_MODE)
1401 		    allowed = "in, inout or buffer";
1402 		  break;
1403 		case IR_OUT_MODE:
1404 		  if (peer_mode != IR_OUT_MODE
1405 		      && peer_mode != IR_INOUT_MODE
1406 		      && peer_mode != IR_BUFFER_MODE)
1407 		    allowed = "out, inout or buffer";
1408 		  break;
1409 		case IR_INOUT_MODE:
1410 		  if (peer_mode != IR_INOUT_MODE
1411 		      && peer_mode != IR_BUFFER_MODE)
1412 		    allowed = "inout or buffer";
1413 		  break;
1414 		case IR_BUFFER_MODE:
1415 		  if (peer_mode != IR_OUT_MODE
1416 		      && peer_mode != IR_INOUT_MODE
1417 		      && peer_mode != IR_BUFFER_MODE)
1418 		    allowed = "out, inout or buffer";
1419 		  break;
1420 		}
1421 	      if (allowed)
1422 		error ("%:port %n of mode %s can only be connected "
1423 		       "to ports of mode %s.",
1424 		       a, p, mode_name (p->mode), allowed);
1425 	    }
1426 	}
1427     }
1428 
1429   return map;
1430 }
1431 
1432 struct psr::filter_return_closure {
1433   vaul_parser *self;
1434   pIIR_Type t;
1435   IR_Kind k;
1436   pVAUL_NamedAssocElem a;
1437 };
1438 
1439 int
filter_return_stub(pIIR_Declaration d,void * cl)1440 psr::filter_return_stub (pIIR_Declaration d, void *cl)
1441 {
1442   filter_return_closure *rc = (filter_return_closure *)cl;
1443   return rc->self->filter_return (d, rc);
1444 }
1445 
1446 pIIR_Type
expr_type(pIIR_Expression e)1447 psr::expr_type (pIIR_Expression e)
1448 {
1449   if (e == NULL)
1450     return NULL;
1451 
1452   if (e->subtype == NULL && !e->is(IR_OPEN_EXPRESSION) && options.debug)
1453     info("%:XXX - %n (%s) has no type", e, e, e->kind_name());
1454 
1455   return e->subtype;
1456 }
1457 
1458 
1459 static void
get_ambg_types(pIIR_Declaration d,void * cl)1460 get_ambg_types (pIIR_Declaration d, void *cl)
1461 {
1462   pIIR_Type_vector *vc = (pIIR_Type_vector *)cl;
1463   if (d->is(IR_FUNCTION_DECLARATION)
1464       && pIIR_FunctionDeclaration(d)->return_type)
1465     vc->add_uniq (pIIR_FunctionDeclaration(d)->return_type);
1466   else if (d->is(IR_ENUMERATION_LITERAL)
1467 	   && pIIR_EnumerationLiteral(d)->subtype)
1468     vc->add_uniq (pIIR_EnumerationLiteral(d)->subtype);
1469 #if 0
1470   else
1471     fprintf (stderr,  "XXX - %n (%s) has no ambg_type\n", d, d->type_id());
1472 #endif
1473 }
1474 
1475 struct psr::cat_closure {
1476     vaul_parser *self;
1477     pIIR_Type_vector *types;
1478     pIIR_Expression expr;
1479 };
1480 
1481 static bool
is_interesting_array_type(pIIR_Type t)1482 is_interesting_array_type (pIIR_Type t)
1483 {
1484   return
1485     t->is(IR_ARRAY_TYPE) && pIIR_ArrayType(t)->declaration != NULL
1486     || (t->is(IR_ARRAY_SUBTYPE)
1487 	&& (pIIR_ArraySubtype(t)->immediate_base->declaration ==
1488 	    t->declaration));
1489 }
1490 
1491 void
collect_ambg_types_stub(pIIR_Declaration d,void * _cl)1492 psr::collect_ambg_types_stub (pIIR_Declaration d, void *_cl)
1493 {
1494   cat_closure *cl = (cat_closure *)_cl;
1495   cl->self->collect_ambg_types (d, cl);
1496 }
1497 
1498 void
collect_ambg_types(pIIR_Declaration d,cat_closure * cl)1499 psr::collect_ambg_types (pIIR_Declaration d, cat_closure *cl)
1500 {
1501   if (!d->is(IR_TYPE_DECLARATION))
1502     return;
1503 
1504   pIIR_Type t = pIIR_TypeDeclaration(d)->type;
1505 
1506   if (cl->expr->is(VAUL_AMBG_ARRAY_LIT_REF))
1507     {
1508       pVAUL_AmbgArrayLitRef alit = pVAUL_AmbgArrayLitRef(cl->expr);
1509 
1510       if (is_interesting_array_type (t)
1511 	  && array_literal_conversion_cost (alit, t, IR_INVALID) >= 0)
1512 	cl->types->add_uniq (t);
1513     }
1514   else if (cl->expr->is(VAUL_AMBG_AGGREGATE))
1515     {
1516       pVAUL_AmbgAggregate aggr = pVAUL_AmbgAggregate(cl->expr);
1517 
1518       if ((is_interesting_array_type (t) || t->is(IR_RECORD_TYPE))
1519 	  && aggregate_conversion_cost (aggr, t, IR_INVALID) >= 0)
1520 	cl->types->add_uniq (t);
1521     }
1522   else if(cl->expr->is(VAUL_AMBG_NULL_EXPR))
1523     {
1524       if (t->is(IR_ACCESS_TYPE))
1525 	cl->types->add_uniq (t);
1526     }
1527   else
1528     assert (false);
1529 }
1530 
ambg_expr_types(pIIR_Expression e)1531 pIIR_Type_vector *psr::ambg_expr_types(pIIR_Expression e)
1532 {
1533     pIIR_Type_vector *types = new pIIR_Type_vector;
1534 
1535     if (e == NULL)
1536       return types;
1537 
1538     if(e->is(VAUL_AMBG_CALL) || e->is(VAUL_AMBG_ENUM_LIT_REF)) {
1539 	vaul_decl_set *d = e->is(VAUL_AMBG_CALL)? pVAUL_AmbgCall(e)->set :
1540 	                                      pVAUL_AmbgEnumLitRef(e)->set;
1541 	d->refresh();
1542 	d->iterate(get_ambg_types, types);
1543     } else if(e->is(VAUL_AMBG_ARRAY_LIT_REF) || e->is(VAUL_AMBG_AGGREGATE)
1544 	      || e->is(VAUL_AMBG_NULL_EXPR)) {
1545 	// brute force, what else?
1546 	cat_closure cl = { this, types, e };
1547 	visit_decls (collect_ambg_types_stub, &cl);
1548 	// info("+++ - collected %d types", types->size());
1549     } else if(e->is(VAUL_UNRESOLVED_NAME)) {
1550       // just for the error message
1551       overload_resolution(e, IR_TYPE);
1552     } else if(pIIR_Type t = expr_type(e))
1553 	types->add(t);
1554 
1555     if (types->size() == 0 && e)
1556       error ("%:%n not valid here", e, e);
1557 
1558     return types;
1559 }
1560 
1561 int
conversion_cost(pIIR target,pIIR_Type should_t,IR_Kind should_k)1562 psr::conversion_cost (pIIR target, pIIR_Type should_t, IR_Kind should_k)
1563 {
1564   if (target == NULL)
1565     return 0;
1566 
1567   if (should_t)
1568     {
1569       should_t = vaul_get_base (should_t);
1570       should_k = should_t->kind();
1571     }
1572 
1573   bool impl_conv = false;
1574   pIIR_Type is_t = NULL;
1575 
1576   IR_Kind target_k = target->kind ();  // Optimization
1577 #define TARGET_IS(k) (tree_is ((target_k), (k)))
1578 
1579   if (TARGET_IS(IR_FUNCTION_DECLARATION))
1580     {
1581       pIIR_FunctionDeclaration f = pIIR_FunctionDeclaration(target);
1582       is_t = f->return_type;
1583       pIIR_InterfaceList parm1 = f->interface_declarations;
1584       pIIR_InterfaceList parm2 = parm1? parm1->rest : NULL;
1585       if (f->is(IR_PREDEFINED_FUNCTION_DECLARATION)
1586 	  && vaul_name_eq("\"/\"", f->declarator)
1587 	  && parm1 && parm1->first && parm2->first
1588 	  && parm1->first->subtype->base->is(IR_PHYSICAL_TYPE)
1589 	  && parm2->first->subtype->base->is(IR_PHYSICAL_TYPE))
1590 	impl_conv = true;
1591     }
1592   else if (TARGET_IS(IR_ABSTRACT_LITERAL_EXPRESSION))
1593     {
1594       is_t = expr_type (pIIR_AbstractLiteralExpression(target));
1595       if (is_t == std->universal_integer || is_t == std->universal_real)
1596 	impl_conv = true;
1597     }
1598   else if (TARGET_IS(VAUL_AMBG_ARRAY_LIT_REF))
1599     {
1600       return array_literal_conversion_cost (pVAUL_AmbgArrayLitRef(target),
1601 					    should_t, should_k,
1602 					    false);
1603     }
1604   else if (TARGET_IS(IR_ATTR_ARRAY_LENGTH))
1605     {
1606       is_t = pIIR_Attr_ArrayLENGTH(target)->subtype;
1607       impl_conv = true;
1608     }
1609 #if 0
1610   else if (TARGET_IS(IR_ATTR_LENGTH))
1611     {
1612       is_t = pIIR_Attr_LENGTH(target)->subtype;
1613       impl_conv = true;
1614     }
1615 #endif
1616   else if (TARGET_IS(IR_ATTR_POS))
1617     {
1618       is_t = pIIR_Attr_POS(target)->subtype;
1619       impl_conv = true;
1620     }
1621   else if (TARGET_IS(VAUL_AMBG_NULL_EXPR))
1622     {
1623       return tree_is(IR_ACCESS_TYPE, should_k)? 0 : -1;
1624     }
1625   else if (TARGET_IS(IR_ALLOCATOR)
1626 	   && should_t && should_t->is(IR_ACCESS_TYPE))
1627     {
1628       pIIR_Type new_type = pIIR_Allocator(target)->type_mark;
1629       assert (new_type->is(IR_ACCESS_TYPE));
1630       return conversion_cost (pIIR_AccessType(new_type)->designated_type,
1631 			      pIIR_AccessType(should_t)->designated_type,
1632 			      IR_INVALID);
1633     }
1634   else if (TARGET_IS(IR_EXPRESSION))
1635     {
1636       is_t = expr_type(pIIR_Expression(target));
1637     }
1638   else
1639     {
1640       assert(TARGET_IS(IR_TYPE));
1641       is_t = pIIR_Type(target);
1642     }
1643 
1644   if (is_t == NULL)
1645     return 0;
1646 
1647   is_t = vaul_get_base (is_t);
1648 
1649   // exact match
1650   if (should_t? is_t == should_t : is_t->is(should_k))
1651     return 0;
1652 
1653   // implicit conversion from universal types
1654   if (impl_conv)
1655     {
1656       if (should_t)
1657 	should_k = should_t->kind();
1658       if ((is_t == std->universal_integer
1659 	   && tree_is(should_k, IR_INTEGER_TYPE))
1660 	  || (is_t == std->universal_real
1661 	      && tree_is(should_k, IR_FLOATING_TYPE)))
1662 	return 1;
1663     }
1664 
1665   // no match
1666   return -1;
1667 }
1668 
1669 int
array_literal_conversion_cost(pVAUL_AmbgArrayLitRef l,pIIR_Type t,IR_Kind k,bool look_inside)1670 psr::array_literal_conversion_cost (pVAUL_AmbgArrayLitRef l,
1671 				    pIIR_Type t,
1672 				    IR_Kind k,
1673 				    bool look_inside)
1674 {
1675   if (t == 0)
1676     return (tree_is(IR_ARRAY_TYPE, k) || tree_is(k, IR_ARRAY_TYPE)) ? 0 : -1;
1677 
1678   t = t->base;
1679 
1680   if (!t->is(IR_ARRAY_TYPE))
1681     return -1;
1682 
1683   pIIR_ArrayType at = pIIR_ArrayType(t);
1684   if (at->index_types && at->index_types->rest)
1685     return -1;
1686   pIIR_Type et = at->element_type;
1687   if (et == NULL)
1688     return -1;
1689   et = et->base;
1690   if (!et->is(IR_ENUMERATION_TYPE))
1691     return -1;
1692   if (et == std->predef_CHARACTER)
1693     return 0;
1694 
1695   if (!look_inside)
1696     {
1697       pIIR_EnumerationLiteralList el;
1698       for (el = pIIR_EnumerationType(et)->enumeration_literals;
1699 	   el; el = el->rest)
1700 	{
1701 	  if (el->first->declarator
1702 	      && el->first->declarator->is(IR_CHARACTER_LITERAL))
1703 	    return 0;
1704 	}
1705       return -1;
1706     }
1707 
1708     {
1709       IR_String &val = l->value->text;
1710       for (int i = 1; i < val.len()-1; i++)
1711 	{
1712 	  pIIR_EnumerationLiteralList el;
1713 	  for (el = pIIR_EnumerationType(et)->enumeration_literals;
1714 	       el; el = el->rest)
1715 	    {
1716 	      if (el->first->declarator
1717 		  && el->first->declarator->is(IR_CHARACTER_LITERAL)
1718 		  && el->first->declarator->text[1] == val[i])
1719 		break;
1720 	    }
1721 	  if (el == NULL)
1722 	    return -1;
1723 	}
1724       return 0;
1725     }
1726 }
1727 
1728 static pVAUL_SimpleName
choice_simple_name(pIIR_Choice c)1729 choice_simple_name (pIIR_Choice c)
1730 {
1731   pVAUL_Name n = NULL;
1732   if (c->is(VAUL_CHOICE_BY_NAME))
1733     n = pVAUL_ChoiceByName(c)->name;
1734   else if (c->is(IR_CHOICE_BY_EXPRESSION))
1735     {
1736       if(pIIR_Expression e = pIIR_ChoiceByExpression(c)->value)
1737 	{
1738 	  if (e->is(VAUL_UNRESOLVED_NAME))
1739 	    n = pVAUL_UnresolvedName(e)->name;
1740 	  else if (e->is(IR_SIMPLE_REFERENCE))
1741 	    n = simple_reference_name(pIIR_SimpleReference(e));
1742 	  else
1743 	    return NULL;
1744 	}
1745     }
1746   if (n == NULL || !n->is(VAUL_SIMPLE_NAME))
1747     return NULL;
1748   return pVAUL_SimpleName(n);
1749 }
1750 
1751 static pIIR_ElementDeclaration
choice_elem(pIIR_RecordType t,pIIR_Choice c)1752 choice_elem (pIIR_RecordType t, pIIR_Choice c)
1753 {
1754   pVAUL_SimpleName n = choice_simple_name (c);
1755   if (n == NULL)
1756     return NULL;
1757   for (pIIR_ElementDeclarationList elts = t->element_declarations;
1758        elts; elts = elts->rest)
1759     {
1760       pIIR_ElementDeclaration re = elts->first;
1761       if (vaul_name_eq (re->declarator, n->id))
1762 	return re;
1763     }
1764   return NULL;
1765 }
1766 
1767 int
choice_conversion_cost(pIIR_Choice c,pIIR_Expression actual,pIIR_Type t,IR_Kind k)1768 psr::choice_conversion_cost (pIIR_Choice c, pIIR_Expression actual,
1769 			     pIIR_Type t, IR_Kind k)
1770 {
1771   if (tree_is (k, IR_ARRAY_TYPE))
1772     {
1773       int c1 = 0, c2 = 0;
1774       pIIR_ArrayType at = NULL;
1775       if (t)
1776 	{
1777 	  assert (t->is(IR_ARRAY_TYPE));
1778 	  pIIR_ArrayType at = pIIR_ArrayType(t);
1779 	  c1 = constrain (actual, at->element_type, IR_INVALID);
1780 	  if (c1 < 0)
1781 	    return c1;
1782 	}
1783       if (c != NULL)
1784 	{
1785 	  if (!c->is(IR_CHOICE_BY_EXPRESSION))
1786 	    return -1;
1787 	  pIIR_Expression e = pIIR_ChoiceByExpression(c)->value;
1788 	  if (e == NULL)
1789 	    return c1;
1790 	  if (at)
1791 	    {
1792 	      if (at->index_types == NULL)
1793 		return -1;
1794 	      c2 = constrain (e, at->index_types->first, IR_INVALID);
1795 	      if (c2 < 0)
1796 		return c2;
1797 	      return c1 + c2;
1798 	    }
1799 	  else
1800 	    return e->is(VAUL_UNRESOLVED_NAME)? -1 : c1;
1801 	}
1802     }
1803   else if (tree_is(k, IR_RECORD_TYPE))
1804     {
1805       pVAUL_SimpleName n = choice_simple_name(c);
1806       if (n == NULL)
1807 	return -1;
1808       if (t)
1809 	{
1810 	  assert (t->is(IR_RECORD_TYPE));
1811 	  pIIR_RecordType rt = pIIR_RecordType(t);
1812 	  for (pIIR_ElementDeclarationList elts = rt->element_declarations;
1813 	       elts; elts = elts->rest)
1814 	    {
1815 	      pIIR_ElementDeclaration re = elts->first;
1816 	      if (vaul_name_eq(re->declarator, n->id))
1817 		return constrain(actual, re->subtype, IR_INVALID);
1818 	    }
1819 	  return -1;
1820 	}
1821       else
1822 	return 0;
1823     }
1824 
1825   return -1;
1826 }
1827 
1828 static int
aggregate_conversion_cost(pVAUL_AmbgAggregate a,pIIR_Type t,IR_Kind k)1829 aggregate_conversion_cost (pVAUL_AmbgAggregate a, pIIR_Type t, IR_Kind k)
1830 {
1831     if(t) {
1832 	t = vaul_get_base (t);
1833 	k = t->kind();
1834     }
1835 
1836 #if 1
1837     return tree_is(k, IR_COMPOSITE_TYPE)? 0 : -1;
1838 #else // no need to be this clever.
1839     int cost = 0;
1840 
1841     for(pVAUL_ElemAssoc ea = a->first_assoc; ea; ea = ea->next)
1842 	for(nChoice c = ea->first_choice; c; c = c->next) {
1843 	    int cc = choice_conversion_cost(c, ea->actual, t, k);
1844 	    if(cc < 0)
1845 		return cc;
1846 	    cost += cc;
1847 	}
1848     return cost;
1849 #endif
1850 }
1851 
1852 pIIR_Aggregate
build_Aggregate(pVAUL_AmbgAggregate aggr,pIIR_Type t)1853 psr::build_Aggregate (pVAUL_AmbgAggregate aggr, pIIR_Type t)
1854 {
1855   if (aggr == NULL || t == NULL)
1856     return NULL;
1857 
1858   pIIR_Type bt = vaul_get_base (t);
1859 
1860   if (bt->is(IR_RECORD_TYPE))
1861     {
1862       pIIR_RecordType rt = pIIR_RecordType(bt);
1863       pIIR_RecordAggregate ra;
1864       if (aggr->is (VAUL_ARTIFICIAL_AMBG_AGGREGATE))
1865 	ra = mIIR_ArtificialRecordAggregate (aggr->pos, rt, NULL);
1866       else
1867 	ra = mIIR_RecordAggregate (aggr->pos, rt, NULL);
1868       pIIR_ElementAssociationList *al_tail = &ra->element_association_list;
1869 
1870       // associations without choice
1871       //
1872       pVAUL_ElemAssoc ea = aggr->first_assoc;
1873       pIIR_ElementDeclarationList elts = rt->element_declarations;
1874       while (ea && ea->choices == NULL && elts)
1875 	{
1876 	  pIIR_ElementDeclaration re = elts->first;
1877 	  pIIR_ElementAssociation ela =
1878 	    mIIR_ElementAssociation (ea->pos, re, ea->actual);
1879 	  *al_tail = mIIR_ElementAssociationList (ea->pos, ela, NULL);
1880 	  overload_resolution (ela->value, re->subtype);
1881 	  al_tail = &(*al_tail)->rest;
1882 	  elts = elts->rest;
1883 	  ea = ea->next;
1884 	}
1885 
1886       if (elts == NULL && ea != NULL)
1887 	{
1888 	  error("%:too many elements in record aggregate of type %n",
1889 		ea, rt);
1890 	  return ra;
1891 	}
1892 
1893       // associations with choices
1894       //
1895       while (ea && ea->choices)
1896 	{
1897 	  // find all choosen elements
1898 	  pIIR_DeclarationList elts = NULL;
1899 	  for (pIIR_ChoiceList cl = ea->choices; cl; cl = cl->rest)
1900 	    {
1901 	      pIIR_Choice c = cl->first;
1902 	      if (c->is(IR_CHOICE_BY_OTHERS))
1903 		{
1904 		  for (pIIR_ElementDeclarationList elts2 =
1905 			 rt->element_declarations;
1906 		       elts2; elts2 = elts2->rest)
1907 		    {
1908 		      pIIR_ElementDeclaration re = elts2->first;
1909 		      bool found = false;
1910 		      for (pIIR_ElementAssociationList al =
1911 			     ra->element_association_list;
1912 			   al; al = al->rest)
1913 			if (al->first->element == re)
1914 			  {
1915 			    found = true;
1916 			    break;
1917 			  }
1918 		      if (!found)
1919 			elts = mIIR_DeclarationList (c->pos, re, elts);
1920 		    }
1921 		}
1922 	      else
1923 		{
1924 		  pIIR_ElementDeclaration re = choice_elem (rt, c);
1925 		  if (re)
1926 		    elts = mIIR_DeclarationList (c->pos, re, elts);
1927 		  else
1928 		    {
1929 		      error ("%:%n has no element named %n, it has:",
1930 			     c, rt, c);
1931 		      for (pIIR_ElementDeclarationList elts2 =
1932 			     rt->element_declarations;
1933 			   elts2; elts2 = elts2->rest)
1934 			{
1935 			  pIIR_ElementDeclaration re = elts2->first;
1936 			  info ("%: %n: %n",
1937 				re, re->declarator, re->subtype);
1938 			}
1939 		    }
1940 		}
1941 	    }
1942 
1943 	  // find the type of all choosen elements
1944 	  pIIR_Type elem_type = NULL;
1945 	  for (pIIR_DeclarationList elt = elts; elt; elt = elt->rest)
1946 	    {
1947 	      pIIR_ElementDeclaration re = pIIR_ElementDeclaration(elt->first);
1948 	      for (pIIR_ElementAssociationList al =
1949 		     ra->element_association_list;
1950 		   al; al = al->rest)
1951 		{
1952 		  pIIR_ElementAssociation a = al->first;
1953 		  if (a->element == re)
1954 		    {
1955 		      error ("%:%n::%n has already been associated",
1956 			     elt, rt, re->declarator);
1957 		      if (!vaul_pos_eq (a->pos, elt->pos))
1958 			info ("%: here", a);
1959 		      continue;
1960 		    }
1961 		}
1962 
1963 	      if (elem_type && elem_type != re->subtype)
1964 		error ("%:all elements selected by a choice must be of"
1965 		       " the same type", elt);
1966 	      elem_type = re->subtype;
1967 	    }
1968 
1969 	  if (elem_type)
1970 	    {
1971 	      overload_resolution (ea->actual, elem_type);
1972 	      for (pIIR_DeclarationList elt = elts; elt; elt = elt->rest)
1973 		{
1974 		  pIIR_ElementDeclaration re =
1975 		    pIIR_ElementDeclaration(elt->first);
1976 		  pIIR_ElementAssociation ela =
1977 		    mIIR_ElementAssociation (elt->pos, re, ea->actual);
1978 		  *al_tail = mIIR_ElementAssociationList (elt->pos, ela, NULL);
1979 		  al_tail = &(*al_tail)->rest;
1980 		}
1981 	    }
1982 
1983 	  ea = ea->next;
1984 	}
1985 
1986       if (ea)
1987 	error ("%:associations without choices must precede all the others",
1988 	       ea);
1989 
1990       // check that all elements have been choosen
1991       //
1992       for (pIIR_ElementDeclarationList elts2 = rt->element_declarations;
1993 	   elts2; elts2 = elts2->rest)
1994 	{
1995 	  pIIR_ElementDeclaration re = elts2->first;
1996 	  bool found = false;
1997 	  for (pIIR_ElementAssociationList al = ra->element_association_list;
1998 	       al; al = al->rest)
1999 	    if (al->first->element == re)
2000 	      {
2001 		found = true;
2002 		break;
2003 	      }
2004 	  if (!found)
2005 	    error ("%:%n::%n has not been associated", aggr, rt,
2006 		   re->declarator);
2007 	}
2008 
2009       return ra;
2010 
2011     }
2012   else if (bt->is(IR_ARRAY_TYPE))
2013     {
2014       pIIR_ArrayType at = pIIR_ArrayType(bt);
2015 
2016       if (at->index_types == NULL)
2017 	return NULL;
2018 
2019       pIIR_ArrayAggregate aa;
2020       if (aggr->is(VAUL_ARTIFICIAL_AMBG_AGGREGATE))
2021 	aa = mIIR_ArtificialArrayAggregate(aggr->pos, t, NULL);
2022       else
2023 	aa = mIIR_ArrayAggregate(aggr->pos, t, NULL);
2024       pIIR_IndexedAssociationList *al_tail = &aa->indexed_association_list;
2025 
2026       pIIR_Type actual_type;
2027       if (at->index_types->rest == NULL)
2028 	actual_type = at->element_type;
2029       else
2030 	{
2031 	  pIIR_ArrayType base = (at->is(VAUL_SUBARRAY_TYPE)?
2032 				 pVAUL_SubarrayType(at)->complete_type : at);
2033 	  actual_type = mVAUL_SubarrayType (at->pos,
2034 					    at->index_types->rest,
2035 					    at->element_type,
2036 					    base);
2037 	}
2038 
2039       pVAUL_ElemAssoc ea = aggr->first_assoc;
2040       while (ea && ea->choices == NULL)
2041 	{
2042 	  overload_resolution (ea->actual, actual_type);
2043 	  pIIR_SingleIndexedAssociation ia =
2044 	    mIIR_SingleIndexedAssociation(ea->pos, ea->actual, NULL);
2045 	  *al_tail = mIIR_IndexedAssociationList(ea->pos, ia, NULL);
2046 	  al_tail = &(*al_tail)->rest;
2047 	  ea = ea->next;
2048 	}
2049 
2050       while (ea && ea->choices)
2051 	{
2052 	  pIIR_ChoiceList cl = ea->choices;
2053 	  pIIR_Choice c = cl->first;
2054 	  pIIR_Type atype;
2055 	  if (c->is(IR_CHOICE_BY_RANGE) &&
2056 	      actual_is_slice(pIIR_ChoiceByRange(c)))
2057 	    atype = at;
2058 	  else
2059 	    atype = actual_type;
2060 
2061 	  overload_resolution_not_for_read (ea->actual, atype);
2062 	  for (; cl; cl = cl->rest)
2063 	    {
2064 	      pIIR_Choice c = cl->first;
2065 	      pIIR_IndexedAssociation ia = NULL;
2066 
2067 	      if (c->is(IR_CHOICE_BY_EXPRESSION))
2068 		{
2069 		  assert (atype == actual_type);
2070 		  pIIR_Expression e = pIIR_ChoiceByExpression(c)->value;
2071 		  overload_resolution (e, at->index_types->first);
2072 		  ia = mIIR_SingleIndexedAssociation(ea->pos, ea->actual, e);
2073 		}
2074 	      else if (c->is(IR_CHOICE_BY_RANGE))
2075 		{
2076 		  assert (atype == (actual_is_slice(pIIR_ChoiceByRange(c))?
2077 				    at : actual_type));
2078 		  pIIR_Range range = pIIR_ChoiceByRange(c)->range;
2079 		  ensure_range_type (range, NULL);
2080 		  if (actual_is_slice(pIIR_ChoiceByRange(c)))
2081 		    ia = mIIR_SliceIndexedAssociation (ea->pos, ea->actual,
2082 						       range);
2083 		  else
2084 		    ia = mIIR_RangeIndexedAssociation (ea->pos, ea->actual,
2085 						       range);
2086 		}
2087 	      else if (c->is(IR_CHOICE_BY_OTHERS))
2088 		ia = mIIR_OthersIndexedAssociation (ea->pos, ea->actual);
2089 	      else
2090 		error ("%:%n invalid as array aggregate choice", c, c);
2091 
2092 	      *al_tail = mIIR_IndexedAssociationList(ea->pos, ia, NULL);
2093 	      al_tail = &(*al_tail)->rest;
2094 	    }
2095 	  ea = ea->next;
2096 	}
2097 
2098       if (ea)
2099 	error("%:associations without choices must precede all the others",
2100 	      ea);
2101 
2102       return aa;
2103 
2104     }
2105   else
2106     error ("%n is not a composite type", t);
2107   return NULL;
2108 }
2109 
2110 static bool
is_array_func(pIIR_FunctionDeclaration f,pVAUL_NamedAssocElem a)2111 is_array_func (pIIR_FunctionDeclaration f, pVAUL_NamedAssocElem a)
2112 {
2113     return f->return_type && f->return_type->is(IR_ARRAY_TYPE)
2114 	&& f->interface_declarations == NULL && a != NULL;
2115 }
2116 
2117 int
filter_return(pIIR_Declaration d,filter_return_closure * rc)2118 psr::filter_return (pIIR_Declaration d, filter_return_closure *rc)
2119 {
2120   if (d->is(IR_FUNCTION_DECLARATION))
2121     {
2122       pIIR_FunctionDeclaration f = pIIR_FunctionDeclaration(d);
2123       int c1, c2;
2124       if (is_array_func(f, rc->a))
2125 	{
2126 	  c1 = conversion_cost (pIIR_ArrayType(f->return_type)->element_type,
2127 				rc->t, rc->k);
2128 	  if(c1 >= 0)
2129 	    c2 = try_array_subscription (pIIR_ArrayType(f->return_type),
2130 					 rc->a);
2131 	}
2132       else
2133 	{
2134 	  c1 = conversion_cost (f, rc->t, rc->k);
2135 	  if (c1 >= 0)
2136 	    c2 = try_association (rc->a, f->interface_declarations);
2137 	}
2138       if (c1 < 0 || c2 < 0)
2139 	return -1;
2140       return c1+c2;
2141     }
2142   else if (d->is(IR_PROCEDURE_DECLARATION))
2143     {
2144       pIIR_ProcedureDeclaration pd = pIIR_ProcedureDeclaration(d);
2145       if (!tree_is (VAUL_VOID_TYPE, rc->k))
2146 	return -1;
2147       return try_association (rc->a, pd->interface_declarations);
2148     }
2149   else if (d->is(IR_ENUMERATION_LITERAL))
2150     {
2151       pIIR_EnumerationLiteral el = pIIR_EnumerationLiteral(d);
2152       return conversion_cost (el->subtype, rc->t, rc->k);
2153     }
2154   else
2155     return -1;
2156 }
2157 
2158 static pVAUL_Name
expr_name(pIIR_Expression e)2159 expr_name (pIIR_Expression e)
2160 {
2161   if (e->is(VAUL_UNRESOLVED_NAME))
2162     return pVAUL_UnresolvedName(e)->name;
2163   else if (e->is(IR_SIMPLE_REFERENCE))
2164     return simple_reference_name (pIIR_SimpleReference(e));
2165   else if(e->is(VAUL_AMBG_CALL))
2166     {
2167       vaul_decl_set *set = pVAUL_AmbgCall(e)->set;
2168       return set? set->name : NULL;
2169     }
2170   else
2171     return NULL;
2172 }
2173 
prepare_named_assocs(pVAUL_GenAssocElem gen)2174 bool psr::prepare_named_assocs(pVAUL_GenAssocElem gen)
2175 {
2176     bool named = false;
2177     bool success = true;
2178 
2179     for(pVAUL_GenAssocElem a = gen; a; a = a->next) {
2180 	if(a->is(VAUL_NAMED_ASSOC_ELEM)) {
2181 	    pVAUL_NamedAssocElem na = pVAUL_NamedAssocElem(a);
2182 
2183 	    if(na->formal)
2184 		named = true;
2185 	    else if(named) {
2186 		error("%:unnamed associations must preced the named ones", na);
2187 		return false;
2188 	    }
2189 
2190 	    if(na->formal) {
2191 		pVAUL_Name f = na->formal;
2192 
2193 		na->ifts_decls = NULL;
2194 		if(f->is(VAUL_IFTS_NAME)) {
2195 		    pVAUL_IftsName in = pVAUL_IftsName(f);
2196 		    //info("%:+++ - function/type/array element", f);
2197 		    na->ifts_arg_name = NULL;
2198 		    if(in->assoc && in->assoc->next == NULL
2199 		       && in->assoc->is(VAUL_NAMED_ASSOC_ELEM)) {
2200 			pIIR_Expression a = pVAUL_NamedAssocElem(in->assoc)->actual;
2201 			if(a) {
2202 			    pVAUL_Name an = expr_name(a);
2203 			    if(an && an->is(VAUL_SIMPLE_NAME))
2204 				na->ifts_arg_name = pVAUL_SimpleName(an);
2205 			}
2206 		    }
2207 
2208 		    if(na->ifts_arg_name) {
2209 			na->ifts_decls = new vaul_decl_set(this);
2210 			find_decls(*(na->ifts_decls), f);
2211 
2212 			if(!na->ifts_decls->multi_decls(false)) {
2213 			    //info("      but no matches (which is fine)", f);
2214 			    delete na->ifts_decls;
2215 			    na->ifts_decls = NULL;
2216 			} else {
2217 			    na->ifts_kind = IR_INVALID;
2218 			    na->ifts_decls->iterate(iterate_for_kind,
2219 						    &na->ifts_kind);
2220 			    if (!tree_is (na->ifts_kind,
2221 					  IR_FUNCTION_DECLARATION)
2222 				&& !tree_is (na->ifts_kind,
2223 					     IR_TYPE_DECLARATION))
2224 			      {
2225 				// info("%:      but not a function/type (%s)",
2226 				//     f, tree_kind_name(na->ifts_kind));
2227 				delete na->ifts_decls;
2228 				na->ifts_decls = NULL;
2229 			      }
2230 			}
2231 		    } else
2232 		      // info("%:      but not exactly one simple argument", f)
2233 		      ;
2234 		}
2235 
2236 		if(get_simple_name(f) == NULL) {
2237 		    error("%:%n does not contain an interface name",
2238 			  na->formal, na->formal);
2239 		    success = false;
2240 		}
2241 	    }
2242 
2243 	} else {
2244 	    error("%:%n can not be used in an association", a, a);
2245 	    success = false;
2246 	}
2247     }
2248 
2249     return success;
2250 }
2251 
validate_gen_assocs(pVAUL_GenAssocElem assocs)2252 void psr::validate_gen_assocs(pVAUL_GenAssocElem assocs)
2253 {
2254     for(pVAUL_GenAssocElem a = assocs; a; a = a->next) {
2255 	if(!a->is(VAUL_NAMED_ASSOC_ELEM)) {
2256 	    if(a != assocs || a->next != NULL) {
2257 		error("%:slices must be one-dimensional", a);
2258 		a->next = NULL;
2259 	    }
2260 	}
2261     }
2262 }
2263 
2264 int
pre_constrain(pIIR_Expression e)2265 psr::pre_constrain (pIIR_Expression e)
2266 {
2267   max_constrain_depth = 2;
2268   constrain_depth = 0;
2269   int res = constrain (e, NULL, IR_TYPE);
2270   max_constrain_depth = -1;
2271   return res;
2272 }
2273 
2274 int
constrain(pIIR_Expression e,pIIR_Type t,IR_Kind k)2275 psr::constrain (pIIR_Expression e, pIIR_Type t, IR_Kind k)
2276 {
2277   if (max_constrain_depth >= 0) {
2278     if (constrain_depth >= max_constrain_depth)
2279       return 0;
2280     constrain_depth += 1;
2281   }
2282 
2283   int res = constrain1 (e, t, k);
2284 
2285   if (max_constrain_depth >= 0)
2286     constrain_depth -= 1;
2287   return res;
2288 }
2289 
2290 int
constrain1(pIIR_Expression e,pIIR_Type t,IR_Kind k)2291 psr::constrain1 (pIIR_Expression e, pIIR_Type t, IR_Kind k)
2292 {
2293     if(e == NULL || (t == NULL && k == IR_INVALID))
2294         return 0;
2295 
2296     if(e->is(VAUL_AMBG_CALL)) {
2297 	vaul_decl_set *s = pVAUL_AmbgCall(e)->set;
2298 	s->refresh();
2299 	filter_return_closure rc = { this, t, k, pVAUL_AmbgCall(e)->first_actual };
2300 	s->filter(filter_return_stub, &rc);
2301 	if(max_constrain_depth >= 0 && constrain_depth == 1) {
2302 	    s->invalidate_pot_invalids();
2303 	    return s->multi_decls(false)? 0 : -1;
2304 	} else
2305 	    return s->retain_lowcost();
2306     } else if(e->is(VAUL_AMBG_ENUM_LIT_REF)) {
2307 	vaul_decl_set *s = pVAUL_AmbgEnumLitRef(e)->set;
2308 	s->refresh();
2309 	filter_return_closure rc = { this, t, k, NULL };
2310 	s->filter (filter_return_stub, &rc);
2311 	return s->retain_lowcost();
2312     } else if(e->is(VAUL_AMBG_AGGREGATE))
2313 	return aggregate_conversion_cost(pVAUL_AmbgAggregate(e), t, k);
2314     else if(e->is(VAUL_UNRESOLVED_NAME))
2315 	return 0;
2316     else
2317 	return conversion_cost(e, t, k);
2318 }
2319 
try_overload_resolution(pIIR_Expression e,pIIR_Type t,IR_Kind k)2320 bool psr::try_overload_resolution(pIIR_Expression e, pIIR_Type t, IR_Kind k)
2321 {
2322     return constrain(e, t, k) >= 0;
2323 }
2324 
type_string(IR_Kind k)2325 static const char *type_string(IR_Kind k)
2326 {
2327   if (k == IR_INTEGER_TYPE)
2328     return "an integer";
2329   if (k == IR_FLOATING_TYPE)
2330     return "a floating point";
2331   if (k == IR_PHYSICAL_TYPE)
2332     return "a physical";
2333   if (k == IR_ARRAY_TYPE)
2334     return "an array";
2335   if (k == IR_RECORD_TYPE)
2336     return "a record";
2337   if (k == IR_COMPOSITE_TYPE)
2338     return "a composite";
2339   if (k == IR_ACCESS_TYPE)
2340     return "an access";
2341   if (k == IR_TYPE)
2342     return "a";
2343   return "an unspeakable";
2344 }
2345 
2346 pIIR_Expression
disambiguate_expr(pIIR_Expression e,pIIR_Type t,bool procs)2347 psr::disambiguate_expr (pIIR_Expression e, pIIR_Type t, bool procs)
2348 {
2349   e = disambiguate_expr1 (e, t, procs);
2350   if (e)
2351     e->static_level = vaul_compute_static_level (e);
2352   return e;
2353 }
2354 
2355 pIIR_Expression
disambiguate_expr1(pIIR_Expression e,pIIR_Type t,bool procs)2356 psr::disambiguate_expr1 (pIIR_Expression e, pIIR_Type t, bool procs)
2357 {
2358   if (e->is(VAUL_AMBG_CALL))
2359     {
2360       for (pVAUL_NamedAssocElem ne = pVAUL_AmbgCall(e)->first_actual; ne;
2361 	   ne = pVAUL_NamedAssocElem(ne->next))
2362 	{
2363 	  assert(ne->is(VAUL_NAMED_ASSOC_ELEM));
2364 	  if (ne->actual == NULL)
2365 	    {
2366 	      info("%:+++ - found NULL actual in %n", e, e);
2367 	      return NULL;
2368 	    }
2369 	}
2370 
2371       pVAUL_AmbgCall(e)->set->invalidate_pot_invalids ();
2372       pIIR_Declaration d = pVAUL_AmbgCall(e)->set->single_decl ();
2373       if (d == NULL)
2374 	{
2375 #if 0
2376 	  // give more info about `e'
2377 	  info ("+++ - assocs:");
2378 	  for (pVAUL_GenAssocElem ge = pVAUL_AmbgCall(e)->first_actual; ge;
2379 	       ge = ge->next)
2380 	    {
2381 	      info ("+++ -  %n", ge);
2382 	      if (ge->is(VAUL_NAMED_ASSOC_ELEM))
2383 		{
2384 		  pIIR_Expression e = pVAUL_NamedAssocElem(ge)->actual;
2385 		  pIIR_Type_vector *types = ambg_expr_types(e);
2386 		  for (int i = 0; i < types->size(); i++)
2387 		    if (try_overload_resolution(e, (*types)[i], IR_INVALID))
2388 		      info ("+++ --  %n", (*types)[i]);
2389 		}
2390 	    }
2391 #endif
2392 	}
2393 
2394       if (d && d->is(IR_FUNCTION_DECLARATION))
2395 	{
2396 	  pVAUL_AmbgCall ac = pVAUL_AmbgCall (e);
2397 	  if (is_array_func(pIIR_FunctionDeclaration(d), ac->first_actual))
2398 	    {
2399 	      pIIR_FunctionDeclaration fd = pIIR_FunctionDeclaration(d);
2400 	      e = mIIR_FunctionCall (ac->pos, fd->return_type, fd, NULL);
2401 	      return build_ArrayReference (e, ac->first_actual);
2402 	    }
2403 	  else
2404 	    {
2405 	      pIIR_FunctionDeclaration fd = pIIR_FunctionDeclaration(d);
2406 	      pIIR_AssociationList al =
2407 		associate (pVAUL_AmbgCall(e)->first_actual,
2408 			   fd->interface_declarations, true, false);
2409 	      return mIIR_FunctionCall (e->pos, fd->return_type, fd, al);
2410 	    }
2411 	}
2412       else if (d && d->is(IR_PROCEDURE_DECLARATION))
2413 	{
2414 	  if (!procs)
2415 	    {
2416 	      error ("%:%n is a procedure, not a function", e, d);
2417 	      return NULL;
2418 	    }
2419 	  else
2420 	    {
2421 	      pIIR_ProcedureDeclaration pd = pIIR_ProcedureDeclaration(d);
2422 	      pIIR_AssociationList al =
2423 		associate (pVAUL_AmbgCall(e)->first_actual,
2424 			   pd->interface_declarations, true, false);
2425 	      return mVAUL_ProcedureCall (e->pos, NULL, pd, al);
2426 	    }
2427 	}
2428 
2429     }
2430   else if(e->is(VAUL_AMBG_ENUM_LIT_REF))
2431     {
2432       /* In addition to enum literals, we might also happen upon
2433 	 subprograms without parameters here.
2434       */
2435 
2436       pVAUL_AmbgEnumLitRef(e)->set->invalidate_pot_invalids();
2437       pIIR_Declaration d = pVAUL_AmbgEnumLitRef(e)->set->single_decl();
2438       if(d == 0)
2439 	return NULL;
2440       if (d->is(IR_ENUMERATION_LITERAL))
2441 	{
2442 	  pIIR_EnumerationLiteral el = pIIR_EnumerationLiteral(d);
2443 	  return mIIR_EnumLiteralReference(e->pos, el->subtype, el);
2444 	}
2445       else if (d->is(IR_FUNCTION_DECLARATION))
2446 	{
2447 	  pIIR_FunctionDeclaration fd = pIIR_FunctionDeclaration(d);
2448 	  return mIIR_FunctionCall (e->pos, fd->return_type, fd, NULL);
2449 	}
2450       else if (d->is(IR_PROCEDURE_DECLARATION))
2451 	{
2452 	  if (!procs)
2453 	    {
2454 	      error ("%:%n is a procedure, not a function", e, d);
2455 	      return NULL;
2456 	    }
2457 	  return mVAUL_ProcedureCall (e->pos, NULL,
2458 				      pIIR_ProcedureDeclaration(d),
2459 				      NULL);
2460 	}
2461       else
2462 	abort ();
2463     }
2464   else if (e->is(VAUL_AMBG_ARRAY_LIT_REF))
2465     {
2466       pVAUL_AmbgArrayLitRef l = pVAUL_AmbgArrayLitRef(e);
2467       if (t == NULL)
2468 	error ("%:can't determine string literal type", l);
2469       else if (array_literal_conversion_cost (l, t, IR_INVALID) >= 0)
2470 	return mIIR_ArrayLiteralExpression (l->pos, t, l->value);
2471       else
2472 	report_type_mismatch (e, t, IR_INVALID);
2473     }
2474   else if (e->is(VAUL_AMBG_AGGREGATE))
2475     {
2476       if (t == NULL)
2477 	error("%:can't determine aggregate type", e);
2478       else
2479 	return build_Aggregate(pVAUL_AmbgAggregate(e), t);
2480     }
2481   else if (e->is(VAUL_AMBG_NULL_EXPR))
2482     {
2483       if (t == NULL)
2484 	error("%:can't determine null constant type", e);
2485       else
2486 	return mIIR_NullExpression(e->pos, t);
2487     }
2488 #if 0 // This is wrong to do in general.
2489   else if (e->is(IR_ALLOCATOR))
2490     {
2491       if (t == NULL)
2492 	error ("%:can't determine type of new object", e);
2493       else
2494 	{
2495 	  pIIR_Allocator(e)->type_mark = t;
2496 	  return e;
2497 	}
2498     }
2499 #endif
2500   else
2501     return e;
2502 
2503   return NULL;
2504 }
2505 
check_for_unresolved_names(pIIR_Expression e)2506 bool psr::check_for_unresolved_names (pIIR_Expression e)
2507 {
2508   if (e == NULL)
2509     return true;
2510 
2511   if(e->is (VAUL_UNRESOLVED_NAME))
2512     {
2513       pVAUL_UnresolvedName un = pVAUL_UnresolvedName(e);
2514       pIIR_Declaration d = find_single_decl(un->name, IR_DECLARATION, "");
2515       if(d)
2516 	error("%:%n can not be used in an expression", un->name, d);
2517       return false;
2518     }
2519 
2520   bool ret = true;
2521 
2522   if (e->is (VAUL_AMBG_CALL))
2523     {
2524       for(pVAUL_NamedAssocElem ne = pVAUL_AmbgCall(e)->first_actual; ne;
2525 	  ne = pVAUL_NamedAssocElem(ne->next))
2526 	{
2527 	  assert(ne->is(VAUL_NAMED_ASSOC_ELEM));
2528 	  if(!check_for_unresolved_names (ne->actual))
2529 	    ret = false;
2530 	}
2531     }
2532   else if (e->is (VAUL_AMBG_AGGREGATE))
2533     {
2534       // build_Aggregate does it for us.  It still uses
2535       // overload_resolution.
2536     }
2537 
2538   return ret;
2539 }
2540 
2541 void
report_type_mismatch(pIIR_Expression e,pIIR_Type t,IR_Kind k)2542 psr::report_type_mismatch (pIIR_Expression e, pIIR_Type t, IR_Kind k)
2543 {
2544   pIIR_Type_vector *types = ambg_expr_types(e);
2545   if (t)
2546     error ("%:%n does not match required type %n, its type could be:",
2547 	   e, e, t);
2548   else
2549     error ("%:type of %n is not %s type, its type could be:", e, e,
2550 	   type_string(k));
2551   for (int i = 0; i < types->size(); i++)
2552     {
2553       pIIR_Type t = (*types)[i];
2554       if (try_overload_resolution(e, t, IR_INVALID))
2555 	info("%:   %n", (*types)[i], (*types)[i]);
2556     }
2557   delete types;
2558 }
2559 
2560 static bool
is_time_type(pIIR_Type t)2561 is_time_type (pIIR_Type t)
2562 {
2563   pIIR_Declaration d = t->declaration;
2564   return t->is(IR_PHYSICAL_TYPE) &&
2565     d && d->declarative_region
2566     && d->declarative_region->is(VAUL_STANDARD_PACKAGE)
2567     && vaul_name_eq ("time", d->declarator);
2568 }
2569 
2570 IR_StaticLevel
vaul_merge_levels(IR_StaticLevel l1,IR_StaticLevel l2)2571 vaul_merge_levels (IR_StaticLevel l1, IR_StaticLevel l2)
2572 {
2573   return (l1 < l2)? l1 : l2;
2574 }
2575 
2576 IR_StaticLevel
m_vaul_compute_static_level(pIIR_AbstractLiteralExpression e)2577 m_vaul_compute_static_level (pIIR_AbstractLiteralExpression e)
2578 {
2579   return is_time_type (e->subtype)? IR_GLOBALLY_STATIC : IR_LOCALLY_STATIC;
2580 }
2581 
2582 IR_StaticLevel
m_vaul_compute_static_level(pIIR_EnumLiteralReference e)2583 m_vaul_compute_static_level (pIIR_EnumLiteralReference e)
2584 {
2585   return IR_LOCALLY_STATIC;
2586 }
2587 
2588 IR_StaticLevel
m_vaul_compute_static_level(pIIR_ArrayLiteralExpression e)2589 m_vaul_compute_static_level (pIIR_ArrayLiteralExpression e)
2590 {
2591   return IR_LOCALLY_STATIC;
2592 }
2593 
2594 IR_StaticLevel
m_vaul_compute_static_level(pIIR_SimpleReference e)2595 m_vaul_compute_static_level (pIIR_SimpleReference e)
2596 {
2597   return vaul_compute_static_level (e->object);
2598 }
2599 
2600 IR_StaticLevel
m_vaul_compute_static_level(pIIR_RecordReference e)2601 m_vaul_compute_static_level (pIIR_RecordReference e)
2602 {
2603   return e->record->static_level;
2604 }
2605 
2606 IR_StaticLevel
m_vaul_compute_static_level(pIIR_Declaration d)2607 m_vaul_compute_static_level (pIIR_Declaration d)
2608 {
2609   return IR_NOT_STATIC;
2610 }
2611 
2612 IR_StaticLevel
m_vaul_compute_static_level(pIIR_ConstantDeclaration d)2613 m_vaul_compute_static_level (pIIR_ConstantDeclaration d)
2614 {
2615   // Constants in a loop are not static, but everywhere else they are
2616   // at least globally static, including in generate statements.  When
2617   // the constant is initialized with a locally static expression, it
2618   // is also locally static.
2619 
2620   if (d->declarative_region->is (IR_LOOP_DECLARATIVE_REGION))
2621     return IR_NOT_STATIC;
2622 
2623   return ((d->initial_value &&
2624 	   d->initial_value->static_level == IR_LOCALLY_STATIC)?
2625 	  IR_LOCALLY_STATIC : IR_GLOBALLY_STATIC);
2626 }
2627 
2628 IR_StaticLevel
m_vaul_compute_static_level(pIIR_ConstantInterfaceDeclaration d)2629 m_vaul_compute_static_level (pIIR_ConstantInterfaceDeclaration d)
2630 {
2631   // XXX - every constant interface thing expect in a subprogram is a
2632   // generic?
2633 
2634   if (!d->declarative_region->is (IR_SUBPROGRAM_DECLARATION))
2635     return IR_GLOBALLY_STATIC;
2636   return IR_NOT_STATIC;
2637 }
2638 
2639 IR_StaticLevel
m_vaul_compute_static_level(pIIR_FunctionCall e)2640 m_vaul_compute_static_level (pIIR_FunctionCall e)
2641 {
2642   IR_StaticLevel lev;
2643 
2644   // initialize LEV to the maximal level possible
2645 
2646   if (e->function->is (IR_PREDEFINED_FUNCTION_DECLARATION))
2647     lev = IR_LOCALLY_STATIC;
2648   else if (e->function->pure)
2649     lev = IR_GLOBALLY_STATIC;
2650   else
2651     return IR_NOT_STATIC;
2652 
2653   // adjust for actuals
2654 
2655   for (pIIR_AssociationList al = e->parameter_association_list;
2656        al; al = al->rest)
2657     lev = vaul_merge_levels (lev, al->first->actual->static_level);
2658 
2659   return lev;
2660 }
2661 
2662 IR_StaticLevel
m_vaul_compute_static_level(pIIR_ExplicitRange e)2663 m_vaul_compute_static_level (pIIR_ExplicitRange e)
2664 {
2665   IR_StaticLevel lev_left = (e->left
2666 			     ? e->left->static_level
2667 			     : IR_GLOBALLY_STATIC);
2668   IR_StaticLevel lev_right = (e->right
2669 			      ? e->right->static_level
2670 			      : IR_GLOBALLY_STATIC);
2671 
2672   return vaul_merge_levels (lev_left, lev_right);
2673 }
2674 
2675 IR_StaticLevel
m_vaul_compute_static_level(pIIR_ArrayRange a)2676 m_vaul_compute_static_level (pIIR_ArrayRange a)
2677 {
2678   return a->array_type->static_level;
2679 }
2680 
2681 IR_StaticLevel
m_vaul_compute_static_level(pIIR_ArrayAggregate e)2682 m_vaul_compute_static_level (pIIR_ArrayAggregate e)
2683 {
2684   // Array aggregates are eithe globally static or non-static.  They
2685   // are never locally static.
2686 
2687   for (pIIR_IndexedAssociationList ial = e->indexed_association_list;
2688        ial; ial = ial->rest)
2689     {
2690       pIIR_IndexedAssociation ia = ial->first;
2691       if (ia->value && ia->value->static_level < IR_GLOBALLY_STATIC)
2692 	return IR_NOT_STATIC;
2693       if (ia->is(IR_RANGE_INDEXED_ASSOCIATION)
2694 	  && (vaul_compute_static_level (pIIR_RangeIndexedAssociation(ia)->index_range)
2695 	      < IR_GLOBALLY_STATIC))
2696 	return IR_NOT_STATIC;
2697       if (ia->is(IR_SINGLE_INDEXED_ASSOCIATION)
2698 	  && pIIR_SingleIndexedAssociation(ia)->index
2699 	  && (pIIR_SingleIndexedAssociation(ia)->index->static_level
2700 	      < IR_GLOBALLY_STATIC))
2701 	return IR_NOT_STATIC;
2702     }
2703   return IR_GLOBALLY_STATIC;
2704 }
2705 
2706 IR_StaticLevel
m_vaul_compute_static_level(pIIR_RecordAggregate e)2707 m_vaul_compute_static_level (pIIR_RecordAggregate e)
2708 {
2709   // Record aggregates are eithe globally static or non-static.  They
2710   // are never locally static.
2711 
2712   for (pIIR_ElementAssociationList eal = e->element_association_list;
2713        eal; eal = eal->rest)
2714     {
2715       if (eal->first->value &&
2716 	  eal->first->value->static_level < IR_GLOBALLY_STATIC)
2717 	return IR_NOT_STATIC;
2718     }
2719   return IR_GLOBALLY_STATIC;
2720 }
2721 
2722 IR_StaticLevel
m_vaul_compute_static_level(pIIR_AttrTypeValue e)2723 m_vaul_compute_static_level (pIIR_AttrTypeValue e)
2724 {
2725   return vaul_compute_static_level (e->prefix);
2726 }
2727 
2728 IR_StaticLevel
m_vaul_compute_static_level(pIIR_AttrTypeFunc e)2729 m_vaul_compute_static_level (pIIR_AttrTypeFunc e)
2730 {
2731   IR_StaticLevel lev1 = vaul_compute_static_level (e->prefix);
2732   IR_StaticLevel lev2 = e->argument->static_level;
2733 
2734   return vaul_merge_levels (lev1, lev2);
2735 }
2736 
2737 IR_StaticLevel
m_vaul_compute_static_level(pIIR_AttrArrayFunc e)2738 m_vaul_compute_static_level (pIIR_AttrArrayFunc e)
2739 {
2740   return e->array_type->static_level;
2741 }
2742 
2743 IR_StaticLevel
m_vaul_compute_static_level(pIIR_AttrSigFunc a)2744 m_vaul_compute_static_level (pIIR_AttrSigFunc a)
2745 {
2746   return a->signal->static_level;
2747 }
2748 
2749 IR_StaticLevel
m_vaul_compute_static_level(pIIR_QualifiedExpression e)2750 m_vaul_compute_static_level (pIIR_QualifiedExpression e)
2751 {
2752   return e->static_level;
2753 }
2754 
2755 IR_StaticLevel
m_vaul_compute_static_level(pIIR_TypeConversion e)2756 m_vaul_compute_static_level (pIIR_TypeConversion e)
2757 {
2758   return e->static_level;
2759 }
2760 
2761 IR_StaticLevel
m_vaul_compute_static_level(pIIR_Allocator a)2762 m_vaul_compute_static_level (pIIR_Allocator a)
2763 {
2764   IR_StaticLevel lev;
2765   if (a->value)
2766     lev = a->value->static_level;
2767   else
2768     lev = a->type_mark->static_level;
2769   // A allocator is at most globally static
2770   return vaul_merge_levels (lev, IR_GLOBALLY_STATIC);
2771 }
2772 
2773 IR_StaticLevel
m_vaul_compute_static_level(pIIR_Expression e)2774 m_vaul_compute_static_level (pIIR_Expression e)
2775 {
2776   return IR_NOT_STATIC;
2777 }
2778 
2779 void
overload_resolution(pIIR_Expression & e,pIIR_Type t,IR_Kind k,bool procs,bool for_read)2780 psr::overload_resolution (pIIR_Expression &e, pIIR_Type t, IR_Kind k,
2781 			  bool procs, bool for_read)
2782 {
2783   if (e == NULL)
2784     return;
2785 
2786   if (!check_for_unresolved_names (e))
2787     {
2788       e = NULL;
2789       return;
2790     }
2791 
2792   bool valid = try_overload_resolution (e, t, k);
2793 
2794   if (!valid)
2795     {
2796       report_type_mismatch (e, t, k);
2797       e = NULL;
2798     }
2799   else
2800     e = disambiguate_expr (e, t, procs);
2801 
2802   if (e && for_read)
2803     check_for_read (e);
2804 }
2805 
2806 void
check_static_level(pIIR_Expression e,IR_StaticLevel l)2807 psr::check_static_level (pIIR_Expression e, IR_StaticLevel l)
2808 {
2809   static const char *level_name[] = { "not(?)", "globally", "locally" };
2810 
2811   // XXX - turn this into an error when the determination of the
2812   // static level of expressions is complete.
2813 
2814   if (e && e->static_level < l && options.debug)
2815     info ("%:warning: %n is not known to be %s static", e, e, level_name[l]);
2816 }
2817 
2818 pIIR_Range
range_from_assoc(pVAUL_GenAssocElem assoc)2819 psr::range_from_assoc (pVAUL_GenAssocElem assoc)
2820 {
2821   if (assoc->is(VAUL_RANGE_ASSOC_ELEM))
2822     return pVAUL_RangeAssocElem(assoc)->range;
2823   else if (assoc->is(VAUL_SUBTYPE_ASSOC_ELEM))
2824     {
2825       pIIR_Type type = pVAUL_SubtypeAssocElem(assoc)->type;
2826       if (type == NULL)
2827 	return NULL;
2828       else if (!type->is(IR_SCALAR_SUBTYPE))
2829 	{
2830 	  error ("%:%n cannot be used as range", assoc, type);
2831 	  return NULL;
2832 	}
2833       else
2834 	return pIIR_ScalarSubtype(type)->range;
2835     }
2836   else
2837     info ("XXX - no `%s' ranges", assoc->kind_name());
2838   return NULL;
2839 }
2840 
2841 pIIR_Type
ensure_range_type(pIIR_Range range,pIIR_Type type)2842 psr::ensure_range_type (pIIR_Range range, pIIR_Type type)
2843 {
2844   if (range->is(IR_EXPLICIT_RANGE))
2845     {
2846       pIIR_ExplicitRange er = pIIR_ExplicitRange(range);
2847       if (type == NULL)
2848 	type = find_index_range_type (er);
2849       if (type == NULL)
2850 	return NULL;
2851       overload_resolution(er->left, type);
2852       overload_resolution(er->right, type);
2853     }
2854   else if (range->is(IR_ARRAY_RANGE))
2855     {
2856       if (type)
2857 	{
2858 	  pIIR_Type t = pIIR_ArrayRange(range)->type;
2859 	  if (vaul_get_base (t) != type)
2860 	    error ("%:%n is not a base type of %n", t, t, type);
2861 	}
2862     }
2863   else
2864     assert(false);
2865 
2866   return type;
2867 }
2868 
2869 VAUL_ObjectClass
m_vaul_get_class(pIIR_Expression e)2870 m_vaul_get_class (pIIR_Expression e)
2871 {
2872   return VAUL_ObjClass_None;
2873 }
2874 
2875 VAUL_ObjectClass
m_vaul_get_class(pIIR_RecordReference ror)2876 m_vaul_get_class (pIIR_RecordReference ror)
2877 {
2878   if (ror->record)
2879     return vaul_get_class (ror->record);
2880   else
2881     return VAUL_ObjClass_None;
2882 }
2883 
2884 VAUL_ObjectClass
m_vaul_get_class(pIIR_GenericArrayReference aor)2885 m_vaul_get_class (pIIR_GenericArrayReference aor)
2886 {
2887   if (aor->array)
2888     return vaul_get_class (aor->array);
2889   else
2890     return VAUL_ObjClass_None;
2891 }
2892 
2893 VAUL_ObjectClass
m_vaul_get_class(pIIR_SignalAttr asr)2894 m_vaul_get_class (pIIR_SignalAttr asr)
2895 {
2896   return VAUL_ObjClass_None;
2897 }
2898 
2899 VAUL_ObjectClass
m_vaul_get_class(pIIR_SimpleReference so)2900 m_vaul_get_class (pIIR_SimpleReference so)
2901 {
2902   return so->object? vaul_get_class (so->object) : VAUL_ObjClass_None;
2903 }
2904 
2905 VAUL_ObjectClass
m_vaul_get_class(pIIR_AccessReference)2906 m_vaul_get_class (pIIR_AccessReference)
2907 {
2908   return VAUL_ObjClass_Variable;
2909 }
2910 
2911 VAUL_ObjectClass
m_vaul_get_class(pIIR_ConstantInterfaceDeclaration i)2912 m_vaul_get_class (pIIR_ConstantInterfaceDeclaration i)
2913 {
2914   return VAUL_ObjClass_Constant;
2915 }
2916 
2917 VAUL_ObjectClass
m_vaul_get_class(pIIR_VariableInterfaceDeclaration i)2918 m_vaul_get_class (pIIR_VariableInterfaceDeclaration i)
2919 {
2920   return VAUL_ObjClass_Variable;
2921 }
2922 
2923 VAUL_ObjectClass
m_vaul_get_class(pIIR_SignalInterfaceDeclaration i)2924 m_vaul_get_class (pIIR_SignalInterfaceDeclaration i)
2925 {
2926   return VAUL_ObjClass_Signal;
2927 }
2928 
2929 VAUL_ObjectClass
m_vaul_get_class(pIIR_FileInterfaceDeclaration i)2930 m_vaul_get_class (pIIR_FileInterfaceDeclaration i)
2931 {
2932   return VAUL_ObjClass_File;
2933 }
2934 
2935 VAUL_ObjectClass
m_vaul_get_class(pIIR_ConstantDeclaration)2936 m_vaul_get_class (pIIR_ConstantDeclaration)
2937 {
2938   return VAUL_ObjClass_Constant;
2939 }
2940 
2941 VAUL_ObjectClass
m_vaul_get_class(pIIR_VariableDeclaration)2942 m_vaul_get_class (pIIR_VariableDeclaration)
2943 {
2944   return VAUL_ObjClass_Variable;
2945 }
2946 
2947 VAUL_ObjectClass
m_vaul_get_class(pIIR_SignalDeclaration)2948 m_vaul_get_class (pIIR_SignalDeclaration)
2949 {
2950   return VAUL_ObjClass_Signal;
2951 }
2952 
2953 VAUL_ObjectClass
m_vaul_get_class(pIIR_FileDeclaration)2954 m_vaul_get_class (pIIR_FileDeclaration)
2955 {
2956   return VAUL_ObjClass_File;
2957 }
2958 
2959 IR_Mode
m_vaul_get_mode(pIIR_Expression e)2960 m_vaul_get_mode (pIIR_Expression e)
2961 {
2962   return IR_IN_MODE;
2963 }
2964 
2965 IR_Mode
m_vaul_get_mode(pIIR_RecordReference ror)2966 m_vaul_get_mode (pIIR_RecordReference ror)
2967 {
2968   return ror->record? vaul_get_mode (ror->record) : IR_IN_MODE;
2969 }
2970 
2971 IR_Mode
m_vaul_get_mode(pIIR_GenericArrayReference aor)2972 m_vaul_get_mode (pIIR_GenericArrayReference aor)
2973 {
2974   return aor->array? vaul_get_mode (aor->array) : IR_IN_MODE;
2975 }
2976 
2977 IR_Mode
m_vaul_get_mode(pIIR_SignalAttr)2978 m_vaul_get_mode (pIIR_SignalAttr)
2979 {
2980   return IR_IN_MODE;
2981 }
2982 
2983 IR_Mode
m_vaul_get_mode(pIIR_SimpleReference so)2984 m_vaul_get_mode (pIIR_SimpleReference so)
2985 {
2986   return so->object? vaul_get_mode (so->object) : IR_IN_MODE;
2987 }
2988 
2989 IR_Mode
m_vaul_get_mode(pIIR_AccessReference)2990 m_vaul_get_mode (pIIR_AccessReference)
2991 {
2992   return IR_INOUT_MODE; // XXX - guessed
2993 }
2994 
2995 IR_Mode
m_vaul_get_mode(pIIR_InterfaceDeclaration i)2996 m_vaul_get_mode (pIIR_InterfaceDeclaration i)
2997 {
2998   return i->mode;
2999 }
3000 
3001 IR_Mode
m_vaul_get_mode(pIIR_ConstantDeclaration)3002 m_vaul_get_mode (pIIR_ConstantDeclaration)
3003 {
3004   return IR_IN_MODE;
3005 }
3006 
3007 IR_Mode
m_vaul_get_mode(pIIR_VariableDeclaration)3008 m_vaul_get_mode (pIIR_VariableDeclaration)
3009 {
3010   return IR_INOUT_MODE;
3011 }
3012 
3013 IR_Mode
m_vaul_get_mode(pIIR_SignalDeclaration)3014 m_vaul_get_mode (pIIR_SignalDeclaration)
3015 {
3016   return IR_INOUT_MODE;
3017 }
3018 
3019 IR_Mode
m_vaul_get_mode(pIIR_FileDeclaration)3020 m_vaul_get_mode (pIIR_FileDeclaration)
3021 {
3022   return IR_UNKNOWN_MODE;
3023 }
3024 
3025 pIIR_Type
m_vaul_get_type(pIIR_RecordReference ror)3026 m_vaul_get_type (pIIR_RecordReference ror)
3027 {
3028   return ror->subtype;
3029 }
3030 
3031 pIIR_Type
m_vaul_get_type(pIIR_ArrayReference aor)3032 m_vaul_get_type (pIIR_ArrayReference aor)
3033 {
3034   return aor->subtype;
3035 }
3036 
3037 pIIR_Type
m_vaul_get_type(pIIR_SliceReference sor)3038 m_vaul_get_type (pIIR_SliceReference sor)
3039 {
3040   return sor->subtype;
3041 }
3042 
3043 pIIR_Type
m_vaul_get_type(pIIR_SignalAttr asr)3044 m_vaul_get_type (pIIR_SignalAttr asr)
3045 {
3046   return asr->subtype;
3047 }
3048 
3049 pIIR_Type
m_vaul_get_type(pIIR_SimpleReference so)3050 m_vaul_get_type (pIIR_SimpleReference so)
3051 {
3052   return so->subtype;
3053 }
3054 
3055 pIIR_Type
m_vaul_get_type(pIIR_AccessReference aor)3056 m_vaul_get_type (pIIR_AccessReference aor)
3057 {
3058   return aor->subtype;
3059 }
3060 
3061 pIIR_ObjectDeclaration
m_vaul_get_object_declaration(pIIR_Expression exp)3062 m_vaul_get_object_declaration (pIIR_Expression exp)
3063 {
3064   return NULL;
3065 }
3066 
3067 pIIR_ObjectDeclaration
m_vaul_get_object_declaration(pIIR_RecordReference ror)3068 m_vaul_get_object_declaration (pIIR_RecordReference ror)
3069 {
3070   return vaul_get_object_declaration (ror->record);
3071 }
3072 
3073 pIIR_ObjectDeclaration
m_vaul_get_object_declaration(pIIR_GenericArrayReference aor)3074 m_vaul_get_object_declaration (pIIR_GenericArrayReference aor)
3075 {
3076   return vaul_get_object_declaration (aor->array);
3077 }
3078 
3079 pIIR_ObjectDeclaration
m_vaul_get_object_declaration(pIIR_SignalAttr asr)3080 m_vaul_get_object_declaration (pIIR_SignalAttr asr)
3081 {
3082   return vaul_get_object_declaration (asr->signal);
3083 }
3084 
3085 pIIR_ObjectDeclaration
m_vaul_get_object_declaration(pIIR_SimpleReference so)3086 m_vaul_get_object_declaration (pIIR_SimpleReference so)
3087 {
3088   return so->object;
3089 }
3090 
3091 pIIR_ObjectDeclaration
m_vaul_get_object_declaration(pIIR_AccessReference aor)3092 m_vaul_get_object_declaration (pIIR_AccessReference aor)
3093 {
3094   return vaul_get_object_declaration (aor->access);
3095 }
3096