1 /* declarations
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-dunit.h>
26 #include <freehdl/vaul-pool.h>
27 #include <freehdl/vaul-util.h>
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <assert.h>
32 #include <limits.h>
33 
34 #include "vaulgens-chunk.h"
35 
36 #define psr vaul_parser
37 
38 pIIR_Identifier
make_id(const char * id)39 psr::make_id (const char *id)
40 {
41   return mIIR_Identifier (int(0), (IR_Character *)id, strlen (id));
42 }
43 
44 pIIR_StringLiteral
make_strlit(const char * str)45 psr::make_strlit (const char *str)
46 {
47   return mIIR_StringLiteral (int(0), (IR_Character *)str, strlen (str));
48 }
49 
50 pIIR_StringLiteral
make_opid(const char * op)51 psr::make_opid (const char *op)
52 {
53   char *opidstr = vaul_aprintf ("\"%s\"", op);
54   pIIR_StringLiteral l = make_strlit (opidstr);
55   free (opidstr);
56   return l;
57 }
58 
59 char *
id_to_chars(pIIR_TextLiteral id)60 psr::id_to_chars (pIIR_TextLiteral id)
61 {
62   return id->text.to_chars ();
63 }
64 
65 void
init()66 psr::init ()
67 {
68   decl_cache = NULL;
69   cstat_tail = NULL;
70   cur_scope = NULL;
71   cur_body = NULL;
72   cur_du = new vaul_design_unit (pool->get_work_library(),
73 				 NULL, lex->filename);
74 
75   tree_protect_loc ((tree_base_node **)&decl_cache);
76 
77   next_decl_seqno = 0;
78 
79   int l = lex->lineno;
80   push_scope (mVAUL_TopScope(l, NULL));
81   add_decl (mIIR_LibraryClause (l, make_id("work")));
82   add_decl (mIIR_LibraryClause (l, make_id("std")));
83 
84   std = NULL;
85 
86   announced_scope = NULL;
87   n_errors = 0;
88 
89   max_constrain_depth = -1;
90 }
91 
92 void
start(pIIR_LibraryUnit u)93 psr::start (pIIR_LibraryUnit u)
94 {
95   if(u->is(VAUL_STANDARD_PACKAGE))
96     std = pVAUL_StandardPackage(u);
97   else
98     {
99       int l = lex->lineno;
100       pVAUL_SelName sn = mVAUL_SelName (l, mVAUL_SimpleName(l, make_id("std")),
101 			      make_id("standard"));
102       pIIR_Declaration d = find_single_decl (sn, VAUL_STANDARD_PACKAGE,
103 					     "(the) standard package");
104       if (d == NULL)
105 	std = mVAUL_StandardPackage (l, make_id("pseudo-standard"));
106       else
107 	{
108 	  std = pVAUL_StandardPackage(d);
109 	  add_decl (mIIR_UseClause (l, NULL, std));
110 	}
111     }
112 
113   u->context_items = cur_scope->declarations;
114   u->library_name = make_id (cur_du->get_library ());
115 
116   cur_du->set_tree (u);
117   add_decl (u);
118   push_scope (u);
119 
120   char *name;
121   if (u->is(IR_ARCHITECTURE_DECLARATION) && u->continued)
122     name = pool->architecture_name (id_to_chars (u->continued->declarator),
123 				    id_to_chars (u->declarator));
124   else if (u->is(IR_PACKAGE_BODY_DECLARATION))
125     name = pool->package_body_name (id_to_chars (u->declarator));
126   else
127     name = id_to_chars (u->declarator);
128   cur_du->set_name (name);
129 }
130 
131 vaul_design_unit *
finish()132 psr::finish ()
133 {
134   if (cur_scope && cur_scope->is(VAUL_TOP_SCOPE))
135     pop_scope (cur_scope);
136 
137   if (eof)
138     {
139       release_ref (cur_du);
140       cur_du = NULL;
141     }
142 
143   if (cur_du && cur_du->get_tree ())
144     {
145       /* Copy list of used units into LibraryUnit node for easy
146 	 access.
147       */
148       vaul_design_unit *u = cur_du->query_used_dus (NULL);
149       pIIR_LibraryUnitList n = NULL, *nt = &n;
150       while (u)
151 	{
152 	  *nt = mIIR_LibraryUnitList (-1, u->get_tree (), NULL);
153 	  nt = &(*nt)->rest;
154 	  u = cur_du->query_used_dus (u);
155 	}
156       cur_du->get_tree()->used_units = n;
157     }
158 
159   closing_label = NULL;
160   cur_scope = NULL;
161 
162   decl_cache = NULL;
163   tree_unprotect_loc ((tree_base_node **)&decl_cache);
164 
165   return cur_du;
166 }
167 
168 void
add_libs(pIIR_IdentifierList ids)169 psr::add_libs (pIIR_IdentifierList ids)
170 {
171   while (ids)
172     {
173       add_decl (mIIR_LibraryClause (ids->pos, ids->first));
174       ids = ids->rest;
175     }
176 }
177 
use(pVAUL_SelNameList snl)178 void psr::use (pVAUL_SelNameList snl)
179 {
180   for (; snl; snl = snl->link)
181     {
182       pVAUL_SelName sn = snl->name;
183       pIIR_Declaration d = find_single_decl (sn->prefix, IR_DECLARATION, "");
184       if (d == NULL)
185 	continue;
186       if (!d->is(IR_LIBRARY_CLAUSE) && !d->is(IR_PACKAGE_DECLARATION)) {
187 	error ("%:%n should be a library or a package", sn, sn);
188 	continue;
189       }
190 
191       pIIR_TextLiteral id = vaul_name_eq(sn->suffix, "all")? NULL : sn->suffix;
192       add_decl (mIIR_UseClause (sn->pos, id, d));
193       if (id && d->is (IR_DECLARATIVE_REGION))
194 	{
195 	  vaul_decl_set dset(this);
196 	  find_decls (dset, id, pIIR_DeclarativeRegion(d), true);
197 	  if (dset.found_none())
198 	    info ("%:warning: %n is not declared in %n", sn, id, d);
199 	}
200     }
201 }
202 
203 void
use_unit(vaul_design_unit * du)204 psr::use_unit (vaul_design_unit *du)
205 {
206   cur_du->uses (du);
207 }
208 
209 static void
visit_scope(pIIR_DeclarativeRegion s,void f (pIIR_Declaration,void *),void * cl)210 visit_scope (pIIR_DeclarativeRegion s,
211 	     void f(pIIR_Declaration, void *),
212 	     void *cl)
213 {
214   for (pIIR_DeclarationList dl = first(s); dl; dl = next(dl))
215     {
216       pIIR_Declaration d = dl->first;
217       if (d->is(IR_USE_CLAUSE))
218 	{
219 	  pIIR_Declaration uu = pIIR_UseClause(d)->used_unit;
220 	  if (uu->is(IR_DECLARATIVE_REGION))
221 	    visit_scope (pIIR_DeclarativeRegion(uu), f, cl);
222 	  else
223 	    f (d, cl);
224 	}
225       else if (d->is(IR_DECLARATIVE_REGION))
226 	visit_scope (pIIR_DeclarativeRegion(d), f, cl);
227       else
228 	f (d, cl);
229     }
230 }
231 
232 void
visit_decls(void f (pIIR_Declaration,void *),void * cl)233 psr::visit_decls (void f (pIIR_Declaration, void *), void *cl)
234 {
235   pIIR_DeclarativeRegion s = cur_scope;
236   while (s && !s->is(VAUL_TOP_SCOPE))
237     s = s->declarative_region;
238   assert(s);
239 
240   visit_scope (s, f, cl);
241 }
242 
243 void
push_scope(pIIR_DeclarativeRegion s)244 psr::push_scope (pIIR_DeclarativeRegion s)
245 {
246   s->declarative_region = cur_scope;
247   cur_scope = s;
248 
249   decls_in_flight(s).init();
250 
251   if (s->is(IR_SUBPROGRAM_DECLARATION))
252     cur_body = pIIR_SubprogramDeclaration(s);
253 }
254 
255 void
pop_scope(pIIR_DeclarativeRegion s)256 psr::pop_scope (pIIR_DeclarativeRegion s)
257 {
258   assert (cur_scope && cur_scope == s);
259 
260   decls_in_flight(s).init();
261 
262   // check incomplete types
263   for (pIIR_DeclarationList dl = s->declarations; dl; dl = dl->rest)
264     {
265       pIIR_Declaration d = dl->first;
266       if (d->is(VAUL_INCOMPLETE_TYPE))
267 	{
268 	  error ("%n is still incomplete", d);
269 	  info ("%:here is the incomplete declaration", d);
270 	}
271     }
272 
273   // check unitialized constants
274   if (s->is(IR_PACKAGE_BODY_DECLARATION)
275       && s->continued && s->continued->is(IR_PACKAGE_DECLARATION))
276     {
277       pIIR_PackageDeclaration p = pIIR_PackageDeclaration (s->continued);
278       for (pIIR_DeclarationList dl = p->declarations; dl; dl = dl->rest)
279 	{
280 	  pIIR_Declaration d = dl->first;
281 	  if (!d->is(IR_CONSTANT_DECLARATION)
282 	      || pIIR_ConstantDeclaration(d)->initial_value != NULL)
283 	    continue;
284 
285 	  pIIR_Declaration d2 = NULL;
286 	  for (pIIR_DeclarationList dl2 = s->declarations; dl2;
287 	       dl2 = dl2->rest)
288 	    {
289 	      d2 = dl2->first;
290 	      if (d2->declarator == d->declarator
291 		  && d2->is(IR_CONSTANT_DECLARATION))
292 		break;
293 	    }
294 	  if(d2 == NULL)
295 	    {
296 	      error ("%n is still not initialized", d);
297 	      info ("%:here is the declaration", d);
298 	    }
299 	}
300     }
301 
302 #if 0
303   if (s->is(IR_BLOCK_STATEMENT))
304     bind_specs (pIIR_BlockStatement(s));
305 #endif
306 
307   cur_scope = s->declarative_region;
308   if (s->is (IR_SUBPROGRAM_DECLARATION))
309     {
310       pIIR_DeclarativeRegion b;
311       for (b = cur_scope; b && !b->is(IR_SUBPROGRAM_DECLARATION);
312 	   b = b->declarative_region)
313 	;
314       cur_body = pIIR_SubprogramDeclaration(b);
315     }
316 }
317 
318 static bool
top_can_contain(pIIR_Declaration d)319 top_can_contain (pIIR_Declaration d)
320 {
321   return d->is(IR_LIBRARY_CLAUSE)
322     || d->is(IR_USE_CLAUSE)
323     || d->is(IR_DECLARATIVE_REGION);
324 }
325 
326 pIIR_DeclarationList
next(pIIR_DeclarationList dl)327 next (pIIR_DeclarationList dl)
328 {
329     if (dl->rest)
330       return dl->rest;
331     else
332       {
333 	pIIR_Declaration d = dl->first;
334 	if (d->declarative_region->continued)
335 	  return first (d->declarative_region->continued);
336 	else
337 	  return NULL;
338       }
339 }
340 
341 pIIR_DeclarationList
first(pIIR_DeclarativeRegion s)342 first (pIIR_DeclarativeRegion s)
343 {
344   for (; s; s = s->continued)
345     if (s->declarations)
346       return s->declarations;
347   return NULL;
348 }
349 
350 static inline bool
overloadable(pIIR_Declaration d)351 overloadable (pIIR_Declaration d)
352 {
353   return d->is(IR_ENUMERATION_LITERAL) || d->is(IR_SUBPROGRAM_DECLARATION);
354 }
355 
356 static bool
homograph(pIIR_Declaration d1,pIIR_Declaration d2)357 homograph (pIIR_Declaration d1, pIIR_Declaration d2)
358 {
359   if (!vaul_name_eq (d1->declarator, d2->declarator))
360     return false;
361 
362   pIIR_InterfaceList p1l =
363     (d1->is(IR_SUBPROGRAM_DECLARATION)?
364      pIIR_SubprogramDeclaration(d1)->interface_declarations : NULL);
365   pIIR_InterfaceList p2l =
366     (d2->is(IR_SUBPROGRAM_DECLARATION)?
367      pIIR_SubprogramDeclaration(d2)->interface_declarations : NULL);
368 
369   while (p1l && p2l)
370     {
371       pIIR_InterfaceDeclaration p1 = p1l->first;
372       pIIR_InterfaceDeclaration p2 = p2l->first;
373       if (p1->subtype == NULL || p2->subtype == NULL
374 	  || vaul_get_base (p1->subtype) != vaul_get_base (p2->subtype))
375 	return false;
376       p1l = p1l->rest;
377       p2l = p2l->rest;
378     }
379   if (p1l || p2l)
380     return false;
381 
382   pIIR_Type t1 = (d1->is(IR_FUNCTION_DECLARATION)?
383 		  pIIR_FunctionDeclaration(d1)->return_type :
384 		  (d1->is(IR_ENUMERATION_LITERAL) ?
385 		   pIIR_EnumerationLiteral(d1)->subtype : NULL));
386   pIIR_Type t2 = (d2->is(IR_FUNCTION_DECLARATION) ?
387 		  pIIR_FunctionDeclaration(d2)->return_type :
388 		  (d2->is(IR_ENUMERATION_LITERAL) ?
389 		   pIIR_EnumerationLiteral(d2)->subtype : NULL));
390 
391   if (t1 && t2)
392     return vaul_get_base (t1) == vaul_get_base (t2);
393   return t1 == t2;
394 }
395 
396 /* XXX all this same_* stuff should be done by ctree
397 */
398 
399 static bool
same_literal(pIIR_Literal l1,pIIR_Literal l2)400 same_literal (pIIR_Literal l1, pIIR_Literal l2)
401 {
402   return true;
403 }
404 
405 static bool
same_expr(pIIR_Expression e1,pIIR_Expression e2)406 same_expr (pIIR_Expression e1, pIIR_Expression e2)
407 {
408   if (e1 == e2)
409     return true;
410   if (!e1 || !e2)
411     return false;
412   if (e1->kind () != e2->kind ())
413     return false;
414 
415   if (e1->is(IR_ABSTRACT_LITERAL_EXPRESSION))
416     return same_literal (pIIR_AbstractLiteralExpression(e1)->value,
417 			 pIIR_AbstractLiteralExpression(e2)->value);
418   else if (e1->is(IR_SIMPLE_REFERENCE))
419     return (pIIR_SimpleReference(e1)->object ==
420 	    pIIR_SimpleReference(e2)->object);
421   else
422     {
423       fprintf (stderr, "xxx - can't compare expressions for sameness.\n");
424       return true;
425     }
426 }
427 
428 static bool same_type(pIIR_Type t1, pIIR_Type t2);
429 
430 static bool
same_range(pIIR_Range r1,pIIR_Range r2)431 same_range (pIIR_Range r1, pIIR_Range r2)
432 {
433   if (r1 == r2)
434     return true;
435   if (!r1 || !r2)
436     return false;
437   if (r1->kind() != r2->kind())
438     return false;
439   if (r1->is(IR_EXPLICIT_RANGE))
440     {
441       pIIR_ExplicitRange er1 = pIIR_ExplicitRange(r1);
442       pIIR_ExplicitRange er2 = pIIR_ExplicitRange(r2);
443       return er1->direction == er2->direction
444 	&& same_expr (er1->left, er2->left)
445 	&& same_expr (er1->right, er2->right);
446     }
447   else if (r1->is(IR_ARRAY_RANGE))
448     {
449       pIIR_ArrayRange ar1 = pIIR_ArrayRange(r1);
450       pIIR_ArrayRange ar2 = pIIR_ArrayRange(r2);
451       return ar1->array == ar2->array
452 	&& same_expr (ar1->index, ar2->index);
453     }
454   else
455     return true;
456 }
457 
458 static bool
same_index_constraint(pIIR_TypeList c1,pIIR_TypeList c2)459 same_index_constraint (pIIR_TypeList c1,
460 		       pIIR_TypeList c2)
461 {
462   if (c1 == c2)
463     return true;
464   if (!c1 || !c2)
465     return false;
466 
467   while (c1 && c2)
468     {
469       if (!same_type (c1->first, c2->first))
470 	return false;
471       c1 = c1->rest;
472       c2 = c2->rest;
473     }
474 
475   return c1 == NULL && c2 == NULL;
476 }
477 
478 static bool
same_type(pIIR_Type t1,pIIR_Type t2)479 same_type (pIIR_Type t1, pIIR_Type t2)
480 {
481   if (t1 == t2)
482     return true;
483   if (!t1 || !t2)
484     return false;
485   if (vaul_get_base (t1) != vaul_get_base (t2))
486     return false;
487 
488   if (t1->is(IR_SCALAR_SUBTYPE)
489       && t2->is(IR_SCALAR_SUBTYPE))
490     {
491       return same_range (pIIR_ScalarSubtype(t1)->range,
492 			 pIIR_ScalarSubtype(t2)->range);
493     }
494   else if (t1->is(IR_ARRAY_SUBTYPE) && t2->is(IR_ARRAY_SUBTYPE))
495     {
496       return same_index_constraint (pIIR_ArraySubtype(t1)->constraint,
497 				    pIIR_ArraySubtype(t2)->constraint);
498     }
499   return false;
500 }
501 
502 static bool
conforming(pIIR_Declaration d1,pIIR_Declaration d2)503 conforming (pIIR_Declaration d1, pIIR_Declaration d2)
504 {
505   if (d1->is(IR_SUBPROGRAM_DECLARATION))
506     {
507       if ((d1->is(IR_FUNCTION_DECLARATION)
508 	   && !d2->is(IR_FUNCTION_DECLARATION))
509 	  || (d1->is(IR_PROCEDURE_DECLARATION)
510 	      && !d2->is(IR_PROCEDURE_DECLARATION)))
511 	return false;
512 
513       pIIR_InterfaceList p1l =
514 	pIIR_SubprogramDeclaration(d1)->interface_declarations;
515       pIIR_InterfaceList p2l =
516 	pIIR_SubprogramDeclaration(d2)->interface_declarations;
517 
518       while (p1l && p2l)
519 	{
520 	  pIIR_InterfaceDeclaration p1 = p1l->first;
521 	  pIIR_InterfaceDeclaration p2 = p2l->first;
522 
523 	  if (p1->mode != p2->mode
524 	      || vaul_get_class (p1) != vaul_get_class (p2)
525 	      || p1->bus != p2->bus
526 	      || !same_type(p1->subtype, p2->subtype))
527 	    return false;
528 	  p1l = p1l->rest;
529 	  p2l = p2l->rest;
530 	}
531 
532       if (d1->is(IR_FUNCTION_DECLARATION))
533 	return same_type(pIIR_FunctionDeclaration(d1)->return_type,
534 			 pIIR_FunctionDeclaration(d2)->return_type);
535       return true;
536     }
537   return false;
538 }
539 
540 static bool
immediate_scope(pIIR_Declaration d,pIIR_DeclarativeRegion s)541 immediate_scope (pIIR_Declaration d, pIIR_DeclarativeRegion s)
542 {
543   while (s)
544     {
545       if (d->declarative_region == s)
546 	return true;
547       s = s->continued;
548     }
549   return false;
550 }
551 
552 pIIR_Declaration
add_decl(pIIR_DeclarativeRegion region,pIIR_Declaration decl,pIIR_TextLiteral id)553 psr::add_decl (pIIR_DeclarativeRegion region, pIIR_Declaration decl,
554 	       pIIR_TextLiteral id)
555 {
556   unselect_scope ();
557 
558   if (decl == NULL)
559     return NULL;
560 
561   assert (!region->is(VAUL_TOP_SCOPE) || top_can_contain(decl));
562 
563   if (id)
564     {
565       decl->pos = id->pos;
566       decl->declarator = id;
567     }
568 
569   decl->seqno = next_decl_seqno++;
570 
571   if (decl->declarator)
572     invalidate_decl_cache (decl->declarator);
573 
574   if (decl->declarator && !decl->is(IR_USE_CLAUSE))
575     {
576       decls_in_flight(region).remove(decl->declarator);
577 
578       /* deal with redeclarations
579        */
580       pIIR_Declaration prev = NULL;
581       pIIR_DeclarationList dl;
582       for (dl = first(region); dl; dl = next(dl))
583 	{
584 	  if (homograph (dl->first, decl))
585 	    {
586 	      prev = dl->first;
587 	      break;
588 	    }
589 	}
590 
591       while (prev)          // "while" so that we can break out of it
592 	{
593 	  if (decl->is(IR_TYPE_DECLARATION)
594 	      && prev->is(IR_TYPE_DECLARATION))
595 	    {
596 	      pIIR_Type pt = pIIR_TypeDeclaration(prev)->type;
597 	      pIIR_Type dt = pIIR_TypeDeclaration(decl)->type;
598 	      if (pt->is(VAUL_INCOMPLETE_TYPE) && !dt->is(VAUL_INCOMPLETE_TYPE))
599 		{
600 		  vaul_complete_incomplete_type (pVAUL_IncompleteType(pt), dt);
601 		  rem_decl (region, prev);
602 		  break;
603 		}
604 	      else if (dt->is(VAUL_INCOMPLETE_TYPE))
605 		return prev;
606 	    }
607 	  else if (decl->is(IR_CONSTANT_DECLARATION)
608 		   && prev->is(IR_CONSTANT_DECLARATION))
609 	    {
610 	      if (pIIR_ConstantDeclaration(prev)->initial_value == NULL)
611 		{
612 		  add_decl_plain (region,
613 				  mIIR_ConstantDeclaration (decl->pos,
614 							    prev->declarator,
615 							    pIIR_ConstantDeclaration(prev)->subtype,
616 							    pIIR_ConstantDeclaration(decl)->initial_value));
617 		  return prev;
618 		}
619 	    }
620 	  else if (decl->is(IR_LIBRARY_CLAUSE)
621 		   && prev->is(IR_LIBRARY_CLAUSE))
622 	    return prev;
623 	  else if (conforming(prev, decl))
624 	    {
625 	      if (prev->is(IR_PREDEFINED_FUNCTION_DECLARATION)
626 		  || prev->is(IR_PREDEFINED_PROCEDURE_DECLARATION))
627 		{
628 		  if (prev->declarative_region == region)
629 		    {
630 		      rem_decl (region, prev);
631 		      break;
632 		    }
633 		  else
634 		    {
635 		      error ("%:sorry, you must declare builtin operators"
636 			     " along with their types", decl);
637 		      decl->declarative_region = region;
638 		      return decl;
639 		    }
640 		}
641 	      return prev;
642 	    }
643 
644 	  error ("%:redeclaration of %n", decl, prev);
645 	  info ("%: previously declared here", prev);
646 
647 	  // point redecl to its 'wannabe' scope, but don't link it
648 	  // into scope's list, so that it can't be found.
649 	  //
650 	  decl->declarative_region = region;
651 	  return decl;
652 	}
653     }
654 
655   add_decl_plain (region, decl);
656 
657   if (region->is(VAUL_STANDARD_PACKAGE) && decl->is(IR_TYPE_DECLARATION))
658     {
659       pVAUL_StandardPackage std = pVAUL_StandardPackage(region);
660       pIIR_Type t = pIIR_TypeDeclaration(decl)->type;
661       if (vaul_name_eq (decl->declarator, "bit"))
662 	std->predef_BIT = t;
663       else if (vaul_name_eq (decl->declarator, "boolean"))
664 	std->predef_BOOLEAN = t;
665       else if (vaul_name_eq (decl->declarator, "integer"))
666 	std->predef_INTEGER = t;
667       else if (vaul_name_eq (decl->declarator, "real"))
668 	std->predef_REAL = t;
669       else if (vaul_name_eq (decl->declarator, "time"))
670 	std->predef_TIME = t;
671       else if (vaul_name_eq (decl->declarator, "character"))
672 	std->predef_CHARACTER = t;
673       else if (vaul_name_eq (decl->declarator, "string"))
674 	std->predef_STRING = t;
675       else if (vaul_name_eq (decl->declarator, "bit_vector"))
676 	std->predef_BIT_VECTOR = t;
677       else if (vaul_name_eq (decl->declarator, "severity_level"))
678 	std->predef_SEVERITY_LEVEL = t;
679       else if (vaul_name_eq (decl->declarator, "file_open_kind"))
680 	std->predef_FILE_OPEN_KIND = t;
681       else if (vaul_name_eq (decl->declarator, "file_open_status"))
682 	std->predef_FILE_OPEN_STATUS = t;
683     }
684 
685   if (decl->is(IR_DECLARATIVE_REGION)
686       && pIIR_DeclarativeRegion(decl)->continued
687       && region->is(VAUL_TOP_SCOPE))
688     {
689       region->continued =
690 	pIIR_DeclarativeRegion(decl)->continued->declarative_region;
691     }
692 
693   /* Call out to the code generator when we are in a package body.
694      Subprograms are handled specially.  Enumeration literals and
695      physical units are not handed to the consumer at all. */
696 
697   if (!decl->is(IR_SUBPROGRAM_DECLARATION)
698       && !decl->is(IR_ENUMERATION_LITERAL)
699       && !decl->is(IR_PHYSICAL_UNIT)
700       && region->is(IR_PACKAGE_BODY_DECLARATION))
701     {
702       if (consumer)
703 	consumer->consume_pbody_decl (decl);
704       collect ();
705     }
706 
707   return decl;
708 }
709 
710 void
add_decl_plain(pIIR_DeclarativeRegion region,pIIR_Declaration decl)711 psr::add_decl_plain (pIIR_DeclarativeRegion region, pIIR_Declaration decl)
712 {
713   decl->declarative_region = region;
714   pIIR_DeclarationList dl = mIIR_DeclarationList(decl->pos, decl, NULL);
715   if (pIIR_DeclarationList t = tail(region))
716     t->rest = dl;
717   else
718     region->declarations = dl;
719   tail(region) = dl;
720 }
721 
722 void
rem_decl(pIIR_DeclarativeRegion region,pIIR_Declaration decl)723 psr::rem_decl (pIIR_DeclarativeRegion region, pIIR_Declaration decl)
724 {
725   pIIR_DeclarationList prev = NULL;
726   for (pIIR_DeclarationList dl = region->declarations; dl;
727        prev = dl, dl = dl->rest)
728     {
729       if (dl->first == decl)
730 	{
731 	  if (prev)
732 	    prev->rest = dl->rest;
733 	  else
734 	    region->declarations = dl->rest;
735 	  if (dl == tail(region))
736 	    tail(region) = prev;
737 	  return;
738 	}
739     }
740   assert(false);
741 }
742 
743 pIIR_TypeDeclaration
add_type_decl(pIIR_DeclarativeRegion region,pIIR_Type type,pIIR_TextLiteral name)744 psr::add_type_decl (pIIR_DeclarativeRegion region,
745 		    pIIR_Type type,
746 		    pIIR_TextLiteral name)
747 {
748   if (type == NULL)
749     return NULL;
750 
751   pIIR_TypeDeclaration decl = mIIR_TypeDeclaration(name->pos, name, type);
752   decl = pIIR_TypeDeclaration (add_decl (region, decl));
753   while (type && type->declaration == NULL)
754     {
755       type->declaration = decl;
756       if (type->is (IR_SUBTYPE))
757 	type = pIIR_Subtype(type)->immediate_base;
758       else
759 	type = NULL;
760     }
761   return decl;
762 }
763 
764 void
start_decl(pIIR_TextLiteral id)765 psr::start_decl (pIIR_TextLiteral id)
766 {
767   assert (cur_scope != NULL);
768   decls_in_flight(cur_scope).add (id);
769 }
770 
vaul_decl_set(vaul_parser * p)771 vaul_decl_set::vaul_decl_set (vaul_parser *p)
772 {
773   pr = p;
774   decls = NULL;
775   filter_func = NULL;
776   filter_data = NULL;
777 
778   reset ();
779 }
780 
~vaul_decl_set()781 vaul_decl_set::~vaul_decl_set ()
782 {
783   reset ();
784 }
785 
786 void
reset()787 vaul_decl_set::reset ()
788 {
789   free (decls);
790 
791   decls = NULL;
792   n_decls = 0;
793   doing_indirects = false;
794   not_overloadable = false;
795   name = NULL;
796 }
797 
798 void
copy_from(vaul_decl_set * set)799 vaul_decl_set::copy_from (vaul_decl_set *set)
800 {
801   reset ();
802   n_decls = set->n_decls;
803   decls = (item*) vaul_xmalloc (n_decls*sizeof(item));
804   for (int i = 0; i < n_decls; i++)
805     decls[i] = set->decls[i];
806 }
807 
808 void
set_filter(bool (* func)(pIIR_Declaration,void *),void * data)809 vaul_decl_set::set_filter (bool (*func)(pIIR_Declaration, void*), void *data)
810 {
811   filter_func = func;
812   filter_data = data;
813 }
814 
815 bool
has_filter()816 vaul_decl_set::has_filter ()
817 {
818   return filter_func != NULL;
819 }
820 
821 bool
use_cache()822 vaul_decl_set::use_cache ()
823 {
824   return !has_filter ();
825 }
826 
827 void
add(pIIR_Declaration d)828 vaul_decl_set::add (pIIR_Declaration d)
829 {
830   // if we have a filter and it rejects D, don't add it.
831 
832   if (filter_func && !filter_func (d, filter_data))
833     return;
834 
835   // filter out hidden decls
836 
837   if (!doing_indirects)
838     {
839       if (not_overloadable)
840 	return;
841       if (!overloadable(d))
842 	not_overloadable = true;
843       for (int i = 0; i < n_decls; i++)
844 	if (decls[i].state == valid && homograph (decls[i].d, d))
845 	  {
846 	    if(name && pr)
847 	      pr->info("%:%n hides %n", name, decls[i].d, d); // XXX
848 	    return;
849 	  }
850     }
851   else
852     {
853       // Only add indirect declarations D when the set is either empty
854       // or D is overloadable.
855 
856       if (n_decls > 0  && !overloadable (d))
857 	return;
858     }
859 
860 
861   for (int i = 0; i < n_decls; i++)
862     if (decls[i].d == d)
863       return;
864 
865   decls = (item *)vaul_xrealloc(decls, (n_decls+1) * sizeof(item));
866   decls[n_decls].d = d;
867   decls[n_decls].state = doing_indirects? pot_valid : valid;
868   decls[n_decls].cost = 0;
869   n_decls++;
870 }
871 
872 bool
finish_scope(pIIR_DeclarativeRegion s)873 vaul_decl_set::finish_scope (pIIR_DeclarativeRegion s)
874 {
875   if (doing_indirects)
876     return true;
877 
878   int i;
879 
880   // if there is more than one !overloadable pot_valid, remove all
881   // !overloadable pot_valids.
882 
883   int n_simple_pot_valids = 0;
884   for (i = 0; i < n_decls; i++)
885     if (decls[i].state == pot_valid && !overloadable(decls[i].d))
886       n_simple_pot_valids++;
887 
888   if (n_simple_pot_valids > 1)
889     for (i = 0; i < n_decls; i++)
890       if (decls[i].state == pot_valid && !overloadable(decls[i].d))
891 	decls[i].state = invalid;
892 
893   // filter out pot_valids that have a homograph in immediate scope S
894 
895   for (i = 0; i < n_decls; i++)
896     if (decls[i].state == valid && immediate_scope(decls[i].d, s))
897       for (int j = 0; j < n_decls; j++)
898 	if (decls[j].state == pot_valid
899 	    && homograph (decls[i].d, decls[j].d))
900 	  decls[j].state = invalid;
901 
902   // all pot_valids that remain become valids
903 
904   for (i = 0; i < n_decls; i++)
905     if (decls[i].state == pot_valid)
906       {
907 	decls[i].state = valid;
908 	if(!overloadable(decls[i].d))
909 	  not_overloadable = true;
910       }
911 
912   // if there are physical units and something else, remove the
913   // physical units.
914 
915   int n_others = 0;
916   for (i = 0; i < n_decls; i++)
917     if (decls[i].state == valid && !decls[i].d->is(IR_PHYSICAL_UNIT))
918       n_others++;
919 
920   if (n_others > 0)
921     {
922       for (i = 0; i < n_decls; i++)
923 	if (decls[i].d->is(IR_PHYSICAL_UNIT))
924 	  decls[i].state = invalid;
925     }
926 
927   // figure out if no more decls can possibly be accepted
928   return not_overloadable;
929 }
930 
931 void
begin_indirects()932 vaul_decl_set::begin_indirects ()
933 {
934   doing_indirects = true;
935 }
936 
937 void
end_indirects()938 vaul_decl_set::end_indirects ()
939 {
940   doing_indirects = false;
941 }
942 
943 void
refresh()944 vaul_decl_set::refresh ()
945 {
946   for (int i = 0; i < n_decls; i++)
947     {
948       if (decls[i].state == pot_invalid)
949 	decls[i].state = valid;
950       decls[i].cost = 0;
951     }
952 }
953 
954 void
invalidate_pot_invalids()955 vaul_decl_set::invalidate_pot_invalids ()
956 {
957   for (int i = 0; i < n_decls; i++)
958     if (decls[i].state == pot_invalid)
959       decls[i].state = invalid;
960 }
961 
962 void
filter(int (* f)(pIIR_Declaration,void *),void * cl)963 vaul_decl_set::filter (int (*f) (pIIR_Declaration, void *), void *cl)
964 {
965   for (int i = 0; i < n_decls; i++)
966     if (decls[i].state == valid)
967       {
968 	int c = f (decls[i].d, cl);
969 	if (c < 0)
970 	  decls[i].state = pot_invalid;
971 	else
972 	  decls[i].cost = c;
973       }
974 }
975 
976 void
iterate(void (* f)(pIIR_Declaration,void *),void * cl)977 vaul_decl_set::iterate (void (*f) (pIIR_Declaration, void *), void *cl)
978 {
979   for (int i = 0; i < n_decls; i++)
980     if (decls[i].state == valid)
981       f (decls[i].d, cl);
982 }
983 
984 int
retain_lowcost()985 vaul_decl_set::retain_lowcost ()
986 {
987   int i, lc = INT_MAX;
988 
989   for (i = 0; i < n_decls; i++)
990     if (decls[i].state == valid && decls[i].cost < lc)
991       lc = decls[i].cost;
992   for (i = 0; i < n_decls; i++)
993     if (decls[i].state == valid && decls[i].cost > lc)
994       decls[i].state = pot_invalid;
995   return lc == INT_MAX ? -1 : lc;
996 }
997 
998 static const char *item_state[] = {
999   "invalid",
1000   "pot. invalid",
1001   "pot. valid",
1002   "valid"
1003 };
1004 
1005 pIIR_Declaration
single_decl(bool print)1006 vaul_decl_set::single_decl (bool print)
1007 {
1008   // see if a single valid decl remains
1009 
1010   pIIR_Declaration d = NULL;
1011   int lc;
1012   int i;
1013   for (i = 0; i < n_decls; i++)
1014     if (decls[i].state == valid)
1015       {
1016 	if (d)
1017 	  break;
1018 	d = decls[i].d;
1019 	lc = decls[i].cost;
1020       }
1021 
1022   if (i == n_decls && d)
1023     {
1024       // if (print && name && pr && n_decls > 1)
1025       //   pr->info ("%:%n resolved to %n (%d)", name, name, d, lc);
1026 
1027       // Add D to list of external decls if it comes from another
1028       // library unit and is not already on the list.
1029 
1030       pIIR_LibraryUnit cur_lu = pr->cur_du->get_tree ();
1031       for (pIIR_DeclarativeRegion dr = d->declarative_region;
1032 	   dr;
1033 	   dr = dr->declarative_region)
1034 	{
1035 
1036 	  if (dr->is (IR_LIBRARY_UNIT) && dr != cur_lu)
1037 	    {
1038 	      for (pIIR_DeclarationList dl = cur_lu->external_decls;
1039 		   dl;
1040 		   dl = dl->rest)
1041 		if (dl->first == d)
1042 		  return d;
1043 	      // pr->info ("+++ - external %n", d);
1044 	      cur_lu->external_decls =
1045 		pr->mIIR_DeclarationList (d->pos,
1046 					  d,
1047 					  cur_lu->external_decls);
1048 	      break;
1049 	    }
1050 	}
1051 
1052       return d;
1053     }
1054 
1055   if (print && name && pr)
1056     {
1057       // report why not
1058       if (n_decls == 0)
1059 	pr->error ("%:%n is undeclared", name, name);
1060       else
1061 	{
1062 	  // XXX - introduce different kinds of 'invalid'
1063 	  //       to disambiguate between different causes
1064 	  pr->error ("%:use of %n is ambigous, candidates are", name, name);
1065 	  show (!(pr && pr->options.debug));
1066 	}
1067     }
1068   return NULL;
1069 }
1070 
1071 bool
multi_decls(bool print)1072 vaul_decl_set::multi_decls (bool print)
1073 {
1074   // see if at least one valid decl remains
1075 
1076   pIIR_Declaration d = NULL;
1077   for (int i = 0; i < n_decls; i++)
1078     if (decls[i].state == valid)
1079       return true;
1080 
1081   if (print && name && pr)
1082     {
1083       // report why not
1084       if (n_decls == 0)
1085 	pr->error ("%:%n is undeclared", name, name);
1086       else
1087 	{
1088 	  // XXX - introduce different kinds of 'invalid'.
1089 	  pr->error ("%:use of %n is ambigous, candidates are", name, name);
1090 	  show (!(pr && pr->options.debug));
1091 	}
1092     }
1093   return false;
1094 }
1095 
1096 void
show(bool only_valids)1097 vaul_decl_set::show (bool only_valids)
1098 {
1099   if (pr == NULL)
1100     return;
1101 
1102   for (int j = 0; j < n_decls; j++) {
1103     if (!only_valids || decls[j].state == valid)
1104       {
1105 	if (only_valids)
1106 	  pr->info ("%: %n", decls[j].d, decls[j].d);
1107 	else
1108 	  pr->info ("%: %n (%s %d)", decls[j].d,
1109 		    decls[j].d, item_state[decls[j].state],
1110 		    decls[j].cost);
1111       }
1112   }
1113 }
1114 
1115 bool
found_none()1116 vaul_decl_set::found_none()
1117 {
1118   return n_decls == 0;
1119 }
1120 
1121 /* XXX - needs to get a lot cleverer, for example, avoid copy of
1122    decl_set. */
1123 
1124 void
invalidate_decl_cache(pIIR_TextLiteral id)1125 psr::invalidate_decl_cache (pIIR_TextLiteral id)
1126 {
1127   pVAUL_DeclCache *cp;
1128   for (cp = &decl_cache; *cp;)
1129     if (vaul_name_eq (id, (*cp)->id))
1130       *cp = (*cp)->next;
1131     else
1132       cp = &(*cp)->next;
1133 }
1134 
1135 
1136 bool
find_in_decl_cache(vaul_decl_set & dset,pIIR_TextLiteral id,pIIR_Declaration scope,bool by_sel)1137 psr::find_in_decl_cache (vaul_decl_set &dset, pIIR_TextLiteral id,
1138 			 pIIR_Declaration scope, bool by_sel)
1139 {
1140   if (options.nocache)
1141     return false;
1142   pVAUL_DeclCache c, p;
1143   for (c = decl_cache, p = NULL; c; p = c, c = c->next)
1144     {
1145       if (vaul_name_eq (id, c->id)
1146 	  && scope == c->scope
1147 	  && by_sel == c->by_sel)
1148 	{
1149 	  // bring cache entry to front of list?
1150 #if 0
1151 	  if (p)
1152 	    {
1153 	      p->next = c->next;
1154 	      c->next = decl_cache;
1155 	      decl_cache = c;
1156 	    }
1157 #endif
1158 	  dset.copy_from (c->set);
1159 	  // info ("found %n in cache", id);
1160 	  return true;
1161 	}
1162     }
1163 
1164   return false;
1165 }
1166 
1167 void
add_to_decl_cache(vaul_decl_set & dset,pIIR_TextLiteral id,pIIR_Declaration scope,bool by_sel)1168 psr::add_to_decl_cache (vaul_decl_set &dset,  pIIR_TextLiteral id,
1169 			pIIR_Declaration scope, bool by_sel)
1170 {
1171   if (options.nocache)
1172     return;
1173   // info ("adding %n to cache", id);
1174   vaul_decl_set *set = new vaul_decl_set(this);
1175   set->copy_from (&dset);
1176   pVAUL_DeclCache c = mVAUL_DeclCache (set, id, scope, by_sel);
1177   c->next = decl_cache;
1178   decl_cache = c;
1179 }
1180 
1181 void
find_decls(vaul_decl_set & ds,pIIR_TextLiteral id,pIIR_Declaration scope_or_lib,bool by_sel)1182 psr::find_decls (vaul_decl_set &ds, pIIR_TextLiteral id,
1183 		 pIIR_Declaration scope_or_lib, bool by_sel)
1184 {
1185   if (scope_or_lib->is(IR_LIBRARY_CLAUSE))
1186     {
1187       char *library = id_to_chars (scope_or_lib->declarator);
1188       if (vaul_name_eq (library, "work"))
1189 	library = pool->get_work_library ();
1190 
1191       vaul_design_unit *du = pool->get (library, id_to_chars (id));
1192       if (du)
1193 	{
1194 	  if (du->is_error ())
1195 	    error("%n: %s", id, du->get_error_desc());
1196 	  else
1197 	    {
1198 	      use_unit (du);
1199 	      ds.add (du->get_tree ());
1200 	    }
1201 	}
1202       release_ref(du);
1203       return;
1204     }
1205 
1206   assert (scope_or_lib->is(IR_DECLARATIVE_REGION));
1207   pIIR_DeclarativeRegion scope = pIIR_DeclarativeRegion (scope_or_lib);
1208 
1209   if (decls_in_flight(scope).contains (id))
1210     return;
1211 
1212   for (pIIR_DeclarationList dl = first(scope); dl; dl = next(dl))
1213     {
1214       pIIR_Declaration d = dl->first;
1215       if (d->is(IR_USE_CLAUSE))
1216 	{
1217 	  if (by_sel)
1218 	    continue;
1219 	  if (d->declarator != NULL && !vaul_name_eq (d->declarator, id))
1220 	    continue;
1221 
1222 	  /* declarations reached thru use-clauses must be visible by
1223 	     selection inside their own scope. */
1224 
1225 	  ds.begin_indirects ();
1226 	  find_decls (ds, id, pIIR_UseClause(d)->used_unit, true);
1227 	  ds.end_indirects ();
1228 	}
1229       else if (vaul_name_eq (d->declarator, id))
1230 	ds.add (d);
1231     }
1232 
1233   if (!ds.finish_scope (scope) && !by_sel && scope->declarative_region)
1234     find_decls (ds, id, scope->declarative_region, by_sel);
1235 }
1236 
1237 void
find_decls(vaul_decl_set & dset,pVAUL_Name n,pIIR_Declaration scope,bool by_sel)1238 psr::find_decls (vaul_decl_set &dset, pVAUL_Name n,
1239 		 pIIR_Declaration scope, bool by_sel)
1240 {
1241   if (n->is(VAUL_SIMPLE_NAME))
1242     {
1243       pIIR_TextLiteral id = pVAUL_SimpleName(n)->id;
1244       if (!dset.use_cache ())
1245 	find_decls (dset, id, scope, by_sel);
1246       else if(!find_in_decl_cache (dset, id, scope, by_sel))
1247 	{
1248 	  find_decls (dset, pVAUL_SimpleName(n)->id, scope, by_sel);
1249 	  add_to_decl_cache (dset, id, scope, by_sel);
1250 	}
1251       dset.name = n;
1252     }
1253   else if (n->is(VAUL_SEL_NAME))
1254     {
1255       // If we have a filter, look up the prefix with a fresh decl_set
1256       // and throw an error when the prefix could not be resolved.
1257       // Otherwise, use dset for looking up the prefix and allow
1258       // partial lookups, ie. for selected names that refer to record
1259       // components.
1260 
1261       pIIR_Declaration d;
1262 
1263       if (dset.has_filter ())
1264 	{
1265 	  vaul_decl_set prefix_dset (this);
1266 	  find_decls (prefix_dset, pVAUL_SelName(n)->prefix, scope, by_sel);
1267 	  d = prefix_dset.single_decl ();
1268 	}
1269       else
1270 	{
1271 	  find_decls (dset, pVAUL_SelName(n)->prefix, scope, by_sel);
1272 	  d = dset.single_decl (false);
1273 	}
1274 
1275       if (d == NULL)
1276 	return;
1277 
1278       if (!d->is(IR_DECLARATIVE_REGION) && !d->is(IR_LIBRARY_CLAUSE))
1279 	{
1280 	  // its probably a record reference. build_Expr will
1281 	  // handle all errors.
1282 	  return;
1283 	}
1284 
1285       if (!d->is(IR_PACKAGE_DECLARATION) && !d->is(IR_LIBRARY_CLAUSE))
1286 	{
1287 	  error ("%:declarations in %n are not visible here", n,
1288 		 pVAUL_SelName(n)->prefix);
1289 	  return;
1290 	}
1291 
1292       dset.reset ();
1293 
1294       find_decls (dset, pVAUL_SelName(n)->suffix, d, true);
1295       dset.name = n;
1296     }
1297   else if (n->is(VAUL_IFTS_NAME))
1298     {
1299       find_decls (dset, pVAUL_IftsName(n)->prefix, scope, by_sel);
1300     }
1301   else if (n->is(VAUL_ATTRIBUTE_NAME))
1302     {
1303       find_decls (dset, pVAUL_AttributeName(n)->prefix, scope, by_sel);
1304     }
1305   else
1306     {
1307       info("XXX - can't look up a %s", n->kind_name());
1308       dset.name = n;
1309     }
1310 }
1311 
1312 void
find_decls(vaul_decl_set & ds,pVAUL_Name n)1313 psr::find_decls (vaul_decl_set &ds, pVAUL_Name n)
1314 {
1315   if (selected_scope)
1316     find_decls(ds, n, selected_scope, true);
1317   find_decls (ds, n, cur_scope, false);
1318 }
1319 
1320 void
select_scope(pIIR_DeclarativeRegion s)1321 psr::select_scope (pIIR_DeclarativeRegion s)
1322 {
1323   selected_scope = s;
1324 }
1325 
1326 void
unselect_scope()1327 psr::unselect_scope()
1328 {
1329   selected_scope = NULL;
1330 }
1331 
1332 pIIR_Declaration
find_single_decl(pVAUL_Name name,IR_Kind exp_k,const char * kind_name)1333 psr::find_single_decl (pVAUL_Name name, IR_Kind exp_k, const char *kind_name)
1334 {
1335   vaul_decl_set ds(this);
1336   find_decls (ds, name);
1337   pIIR_Declaration d = ds.single_decl (kind_name != NULL);
1338   if (d && (!d->is(exp_k) || ds.name != name))
1339     {
1340       if (kind_name)
1341 	error ("%:%n is not a %s", name, name, kind_name);
1342       d = NULL;
1343     }
1344   return d;
1345 }
1346 
1347 pIIR_EntityDeclaration
get_entity(pIIR_Identifier n)1348 psr::get_entity (pIIR_Identifier n)
1349 {
1350   pIIR_EntityDeclaration entity = NULL;
1351 
1352   vaul_design_unit *du = pool->get (pool->get_work_library(),
1353 				    id_to_chars (n));
1354   if (du == NULL)
1355     error ("unknown entity %n", n);
1356   else if (du->is_error())
1357     error ("%n: %s", n, du->get_error_desc());
1358   else if (du->get_tree() == NULL
1359 	   || !du->get_tree()->is(IR_ENTITY_DECLARATION))
1360     error ("%n is not an entity", n);
1361   else
1362     {
1363       use_unit (du);
1364       entity = pIIR_EntityDeclaration(du->get_tree());
1365     }
1366   release_ref(du);
1367   return entity;
1368 }
1369 
1370 pIIR_PackageDeclaration
get_package(pIIR_Identifier n)1371 psr::get_package (pIIR_Identifier n)
1372 {
1373   pIIR_PackageDeclaration package = NULL;
1374 
1375   vaul_design_unit *du = pool->get (pool->get_work_library(),
1376 				    id_to_chars (n));
1377   if (du == NULL)
1378     error ("unknown package %n", n);
1379   else if (du->is_error())
1380     error ("%n: %s", n, du->get_error_desc());
1381   else if (du->get_tree() == NULL
1382 	   || !du->get_tree()->is(IR_PACKAGE_DECLARATION))
1383     error ("%n is not a package", n);
1384   else
1385     {
1386       use_unit (du);
1387       package = pIIR_PackageDeclaration (du->get_tree());
1388     }
1389   release_ref(du);
1390   return package;
1391 }
1392 
1393 pIIR_ConfigurationDeclaration
get_configuration(pVAUL_Name c)1394 psr::get_configuration (pVAUL_Name c)
1395 {
1396   return pIIR_ConfigurationDeclaration(
1397 	  find_single_decl(c, IR_CONFIGURATION_DECLARATION, "configuration"));
1398 }
1399 
1400 pIIR_Declaration
add_Alias(pIIR_Identifier id,pIIR_Type type,pVAUL_Name thing)1401 psr::add_Alias (pIIR_Identifier id, pIIR_Type type, pVAUL_Name thing)
1402 {
1403   if (id == NULL || type == NULL || thing == NULL)
1404     return NULL;
1405 
1406   pIIR_Expression base = build_Expr (thing);
1407   overload_resolution_not_for_read (base, type);
1408   if (base == NULL)
1409     return NULL;
1410 
1411   // Clone `base', which is an ObjectReference.
1412 
1413   pIIR_ObjectDeclaration object = vaul_get_object_declaration (base);
1414   pIIR_ObjectDeclaration alias;
1415 
1416   if (object == NULL)
1417     return NULL;
1418 
1419   if (object->is(IR_SIGNAL_DECLARATION))
1420     {
1421       pIIR_SignalDeclaration d = pIIR_SignalDeclaration (object);
1422       alias = mIIR_SignalDeclaration (id->pos,
1423 				      id, type,
1424 				      d->initial_value,
1425 				      d->signal_kind);
1426     }
1427   else if (object->is(IR_VARIABLE_DECLARATION))
1428     {
1429       pIIR_VariableDeclaration d = pIIR_VariableDeclaration (object);
1430       alias = mIIR_VariableDeclaration (id->pos,
1431 					id, type,
1432 					d->initial_value);
1433     }
1434   else if (object->is(IR_CONSTANT_DECLARATION))
1435     {
1436       pIIR_ConstantDeclaration d = pIIR_ConstantDeclaration (object);
1437       alias = mIIR_ConstantDeclaration (id->pos,
1438 					id, type,
1439 					d->initial_value);
1440     }
1441   else if (object->is(IR_FILE_DECLARATION))
1442     {
1443       pIIR_FileDeclaration d = pIIR_FileDeclaration (object);
1444       alias = mIIR_FileDeclaration (id->pos,
1445 				    id, type,
1446 				    NULL,
1447 				    d->file_open_expression,
1448 				    d->file_logical_name);
1449     }
1450   else if (object->is(IR_SIGNAL_INTERFACE_DECLARATION))
1451     {
1452       pIIR_SignalInterfaceDeclaration d =
1453 	pIIR_SignalInterfaceDeclaration (object);
1454       alias = mIIR_SignalInterfaceDeclaration (id->pos,
1455 					       id, type,
1456 					       d->initial_value,
1457 					       d->mode,
1458 					       d->bus,
1459 					       d->signal_kind);
1460     }
1461   else if (object->is(IR_VARIABLE_INTERFACE_DECLARATION))
1462     {
1463       pIIR_VariableInterfaceDeclaration d =
1464 	pIIR_VariableInterfaceDeclaration (object);
1465       alias = mIIR_VariableInterfaceDeclaration (id->pos,
1466 						 id, type,
1467 						 d->initial_value,
1468 						 d->mode,
1469 						 d->bus);
1470     }
1471   else if (object->is(IR_CONSTANT_INTERFACE_DECLARATION))
1472     {
1473       pIIR_ConstantInterfaceDeclaration d =
1474 	pIIR_ConstantInterfaceDeclaration (object);
1475       alias = mIIR_ConstantInterfaceDeclaration (id->pos,
1476 						 id, type,
1477 						 d->initial_value,
1478 						 d->mode,
1479 						 d->bus);
1480     }
1481   else if (object->is(IR_FILE_INTERFACE_DECLARATION))
1482     {
1483       pIIR_FileInterfaceDeclaration d =
1484 	pIIR_FileInterfaceDeclaration (object);
1485       alias = mIIR_FileInterfaceDeclaration (id->pos,
1486 					     id, type,
1487 					     d->initial_value,
1488 					     d->mode,
1489 					     d->bus);
1490     }
1491   else
1492     {
1493       error ("XXX - don't know how to alias %n", object);
1494       return NULL;
1495     }
1496 
1497   alias->alias_base = pIIR_ObjectReference (base);
1498 
1499   return add_decl (alias);
1500 }
1501