Rune - Further Object abstraction work
[rune.git] / librune / decl.c
1 /*
2  * DECL.C
3  *
4  * (c)Copyright 1993-2014, Matthew Dillon, All Rights Reserved.  See the
5  * COPYRIGHT file at the base of the distribution.
6  */
7
8 #include "defs.h"
9 #include <dlfcn.h>
10
11 #define DHSIZE  4096
12 #define DHMASK  (DHSIZE - 1)
13
14 static Declaration * DeclHashAry[DHSIZE];
15 static Declaration * OperHashAry[DHSIZE];
16
17 void
18 InitDecls(void)
19 {
20 }
21
22 /*
23  * Allocate a declaration and add it to the tail of the sg's declaration
24  * list.
25  */
26 Declaration *
27 AllocDeclaration(SemGroup *sg, int dop, Scope *scope)
28 {
29     Parse  *p = sg->sg_Parse;
30     Declaration *d = zalloc(sizeof(Declaration));
31
32     /*
33      * Default to library scope.  If this is a refinement we default to no
34      * scope flags which causes the resolver to inherit the scope from the
35      * superclass.
36      *
37      * ResolveClasses() in librune/resolve.c will inherit the scope from the
38      * superclass if it is not set here, so do not set default scope for a
39      * 'refine' declaration.
40      */
41     if ((scope->s_Flags & (SCOPE_REFINE | SCOPE_ALL_VISIBLE)) == 0)
42         scope->s_Flags |= SCOPE_LIBRARY;
43
44     d->d_Parse = p;
45     d->d_Op = dop;
46     d->d_MyGroup = sg;
47     d->d_Index = sg->sg_DeclCount++;
48     d->d_Scope = *scope;
49     d->d_Level = sg;
50     d->d_Offset = -1;
51     d->d_DynIndex = -1;
52     d->d_BackendId = -1;
53     RUNE_INSERT_TAIL(&sg->sg_DeclList, d, d_Node);
54     if (p->p_Format == PFMT_SOURCE)
55         LexInitRef(&d->d_LexRef, &p->p_Token);
56     return (d);
57 }
58
59 void
60 FreeDeclaration(Parse *p __unused, Declaration *d)
61 {
62     /* XXX free the Type */
63     /* XXX free d_AssExp */
64     /* XXX free d_ProcBody */
65     /* XXX free d_OrigBody */
66     if (d->d_Id) {
67         UnHashDecl(d);
68         d->d_Id = 0;
69     }
70     if (d->d_Op == DOP_PROC && d->d_ProcDecl.ed_OperId != 0) {
71         UnHashOper(d);
72         d->d_Op = 0;
73     }
74     if (d->d_MyGroup) {
75         RUNE_REMOVE(&d->d_MyGroup->sg_DeclList, d, d_Node);
76         d->d_MyGroup = NULL;
77     }
78     zfree(d, sizeof(Declaration));
79 }
80
81 Declaration *
82 AllocImportDecl(Stmt *st, Scope *scope)
83 {
84     Declaration *d;
85
86     dassert(st->st_Op == ST_Import);
87     d = AllocDeclaration(st->st_MyGroup, DOP_IMPORT, scope);
88     LexDupRef(&st->st_LexRef, &d->d_LexRef);
89
90     /*
91      * st_MyGroup may be empty if the import is shared.  Use the SemGroup
92      * initialized by the parser.  (If the import is not shared es_SemGroup
93      * will be the same as st_MyGroup).
94      *
95      * Note that ParseModule() will handle the d->d_ImportDecl.ed_SemGroup
96      * and st->st_ImportStmt.es_SemGroup glue.
97      */
98     HashDecl(d, st->st_ImportStmt.es_AsId);
99     return (d);
100 }
101
102 Declaration *
103 AllocClassDecl(Stmt *st, runeid_t id, Type *super, Scope *scope)
104 {
105     Declaration *d;
106
107     dassert(st->st_Op == ST_Class);
108     d = AllocDeclaration(st->st_MyGroup->sg_Parent, DOP_CLASS, scope);
109     LexDupRef(&st->st_LexRef, &d->d_LexRef);
110     d->d_ClassDecl.ed_Super = super;
111     d->d_ClassDecl.ed_SemGroup = st->st_MyGroup;
112     HashDecl(d, id);
113     return (d);
114 }
115
116
117 SemGroup *
118 AllocSemGroup(sg_type_t type, Parse *p, SemGroup *par, Stmt *st)
119 {
120     SemGroup *sg = zalloc(sizeof(SemGroup));
121
122     if (par) {
123         sg->sg_Parent = par;
124         sg->sg_NestLevel = par->sg_NestLevel;
125         sg->sg_NestSize = par->sg_NestSize;
126         RUNE_INSERT_TAIL(&par->sg_SemList, sg, sg_Node);
127     }
128     sg->sg_Op = type;
129     sg->sg_Parse = p;
130     sg->sg_Stmt = st;
131     sg->sg_Level = -1;
132     RUNE_INIT(&sg->sg_SemList);
133     RUNE_INIT(&sg->sg_DeclList);
134     RUNE_INIT(&sg->sg_ClassList);
135
136     return (sg);
137 }
138
139 void
140 FreeSemGroup(SemGroup *sg)
141 {
142     if (sg->sg_Parent) {
143         RUNE_REMOVE(&sg->sg_Parent->sg_SemList, sg, sg_Node);
144         sg->sg_Parent = NULL;
145     }
146     dassert(RUNE_EMPTY(&sg->sg_DeclList));
147     /* XXX zfree? */
148 }
149
150 #if 0
151
152 /*
153  * Allocate a declaration block from a compound expression
154  */
155 SemGroup *
156 AllocSemGroupFromCompoundExp(SemGroup *par, Exp *exp)
157 {
158     SemGroup *sg;
159
160     sg = AllocSemGroup(SG_COMPOUND, par->sg_Parse, par, NULL);
161     while (exp) {
162         Declaration *d;
163         Scope   tscope = INIT_SCOPE(SCOPE_PUBLIC);
164
165         d = AllocDeclaration(sg, DOP_GROUP_STORAGE, &tscope);
166         LexDupRef(&exp->ex_LexRef, &d->d_LexRef);
167         d->d_StorDecl.ed_Type = exp->ex_Type;
168     }
169     return (sg);
170 }
171
172 #endif
173
174 /*
175  * DupSemGroup() - duplicate a semantic group
176  *
177  * Duplicate ssg.  sg is the new parent.
178  *
179  * This routine guarentees that the d_Index's and ordering will match up
180  * (because it forces it).
181  */
182 SemGroup *
183 DupSemGroup(SemGroup *sg, Stmt *st, SemGroup *ssg, int dupDecls)
184 {
185     Declaration *d;
186     SemGroup *nsg = AllocSemGroup(ssg->sg_Op, ssg->sg_Parse, sg, st);
187
188     dassert(RUNE_EMPTY(&nsg->sg_DeclList));
189
190     nsg->sg_Flags = ssg->sg_Flags & SGF_INHERIT_BASE;
191     if (dupDecls) {
192         int     hiindex = -1;
193
194         RUNE_FOREACH(d, &ssg->sg_DeclList, d_Node) {
195             Declaration *nd;
196
197             nd = DupDeclaration(nsg, d);
198             nd->d_Index = d->d_Index;
199             if (hiindex < d->d_Index)   /* sanity */
200                 hiindex = d->d_Index;   /* sanity */
201         }
202         dassert(hiindex == nsg->sg_DeclCount - 1);
203         nsg->sg_VarCount = ssg->sg_VarCount;
204     }
205     nsg->sg_NestLevel = ssg->sg_NestLevel;
206     nsg->sg_NestSize = ssg->sg_NestSize;
207     nsg->sg_AltContext = ssg->sg_AltContext;
208
209     return (nsg);
210 }
211
212 static int
213 hashid(SemGroup *sg, runeid_t id)
214 {
215     id += (uintptr_t)sg;
216     id ^= id >> 32;
217     id ^= id >> 16;
218
219     return ((int)(id & DHMASK));
220 }
221
222 /*
223  * findDecl() - find declaration relative to class level N
224  *
225  * FindDecl() will find the highest identifier less then or equal to the
226  * specified level.   When multple identifiers are found at the same
227  * (highest) level, FindDecl() will return the last, which is first entered.
228  * This allows us to bring certain types of declarations, such as superclass
229  * methods, into a subclass and only access them under special circumstances.
230  * See ResolveClasses().
231  */
232 static
233 Declaration *
234 findDecl(SemGroup *sg, runeid_t id, int visibility, int level, int *eno)
235 {
236     Declaration *d;
237
238     /*
239      * private visibility is usually lost first, then library, then public.
240      * But some searches want to initially restrict to within the current
241      * library or private space in which case we must still match against
242      * public declarations, etc.  This typically happens at parse time.
243      */
244     if (visibility & SCOPE_LIBRARY)
245         visibility |= SCOPE_PUBLIC;
246     if (visibility & SCOPE_PRIVATE)
247         visibility |= SCOPE_LIBRARY | SCOPE_PUBLIC;
248
249     for (d = DeclHashAry[hashid(sg, id)]; d; d = d->d_HNext) {
250         Declaration *bd;
251         int     scopeFlags;
252
253         if (d->d_MyGroup != sg || d->d_Id != id)
254             continue;
255         if (level >= 0 && d->d_Level->sg_Level > level)
256             continue;
257
258         /*
259          * Find the closest matching level.
260          */
261         if (level >= 0) {
262             bd = d;
263             for (d = d->d_HNext; d; d = d->d_HNext) {
264                 if (d->d_MyGroup != sg || d->d_Id != id)
265                     continue;
266                 if (d->d_Level->sg_Level <= level &&
267                     d->d_Level->sg_Level >= bd->d_Level->sg_Level)
268                 {
269                     bd = d;     /* first, highest id < level */
270                 }
271             }
272             d = bd;
273         }
274
275         /*
276          * Check visibility.  We may have to recurse through d_Super to be
277          * able to check visibility from the point of view of the superclass.
278          */
279         if (level >= 0) {
280             bd = d;
281             while (bd->d_MyGroup->sg_Level != level) {
282                 dassert(bd->d_Super != NULL);
283                 bd = bd->d_Super;
284             }
285             scopeFlags = bd->d_ScopeFlags;
286         } else {
287             bd = d;
288             scopeFlags = d->d_ScopeFlags;
289         }
290
291 #if 0
292         /*
293          * XXX not tied in yet?  so not relevant?
294          *
295          * If scope not yet resolved and not specified in the subclass,
296          * refinements inherit the scope from the superclass declaration.
297          */
298         while ((scopeFlags & SCOPE_ALL_VISIBLE) == 0) {
299             bd = bd->d_Super;
300             if (bd == NULL)
301                 break;
302             scopeFlags = bd->d_ScopeFlags;
303         }
304 #endif
305         if ((scopeFlags & visibility) == 0) {
306             *eno = TOK_ERR_SCOPE_NOT_VISIBLE;
307             break;
308         }
309
310         /*
311          * Yahh
312          */
313         *eno = 0;
314         return (d);
315     }
316     *eno = TOK_ERR_ID_NOT_FOUND;
317     return (NULL);
318 }
319
320 Declaration *
321 FindOperId(SemGroup *sg, runeid_t id, int args)
322 {
323     Declaration *d;
324
325     for (d = OperHashAry[hashid(sg, id)]; d; d = d->d_ONext) {
326         if (d->d_MyGroup == sg &&
327             d->d_Op == DOP_PROC &&
328             d->d_ProcDecl.ed_OperId == id) {
329             if (d->d_ProcDecl.ed_Type->ty_ProcType.et_ArgCount ==
330                 (urunesize_t)args)
331             {
332                 break;
333             }
334         }
335     }
336     return (d);
337 }
338
339 /*
340  * Associate an identifier with the declaration.  We eat the caller's
341  * reference to the identifier.
342  *
343  * Return 1 if a duplicate declaration has been detected.  Such detection is
344  * only useful during the parsing phase since we overload identifiers in the
345  * resolution phase.
346  *
347  * NOTE! we depend on inserting at the base of the hash chain.  See
348  * findDecl() for more information.
349  */
350 int
351 HashDecl(Declaration *d, runeid_t id)
352 {
353     Declaration **pd;
354     SemGroup *sg = d->d_MyGroup;
355
356     dassert(d != NULL);
357     dassert_decl(d, id != 0 && d->d_Id == 0 && d->d_MyGroup != NULL);
358     d->d_Id = id;
359     pd = &DeclHashAry[hashid(d->d_MyGroup, id)];
360     d->d_HNext = *pd;
361     *pd = d;
362     if (id != RUNEID_SELF) {
363         while ((d = d->d_HNext) != NULL) {
364             if (d->d_Id == id && d->d_MyGroup == sg)
365                 return (1);
366         }
367     }
368     return (0);
369 }
370
371 /*
372  * Remove the identifier associated with the declaration.
373  */
374 runeid_t
375 UnHashDecl(Declaration *d)
376 {
377     runeid_t id;
378
379     if ((id = d->d_Id) != 0) {
380         Declaration **pd;
381
382         pd = &DeclHashAry[hashid(d->d_MyGroup, id)];
383         while (*pd != d) {
384             dassert(*pd != NULL);
385             pd = &(*pd)->d_HNext;
386         }
387         *pd = d->d_HNext;
388         d->d_HNext = NULL;
389         d->d_Id = 0;
390     }
391     return (id);
392 }
393
394 void
395 HashOper(Declaration *d, runeid_t id)
396 {
397     Declaration **pd;
398
399     dassert(d != NULL);
400     dassert_decl(d, id && d->d_MyGroup != NULL &&
401                     d->d_Op == DOP_PROC && d->d_ProcDecl.ed_OperId == 0);
402     d->d_ProcDecl.ed_OperId = id;
403     pd = &OperHashAry[hashid(d->d_MyGroup, id)];
404     d->d_ONext = *pd;
405     *pd = d;
406 }
407
408 runeid_t
409 UnHashOper(Declaration *d)
410 {
411     runeid_t id;
412
413     dassert_decl(d, d->d_Op == DOP_PROC);
414     if ((id = d->d_ProcDecl.ed_OperId) != 0) {
415         Declaration **pd;
416         pd = &OperHashAry[hashid(d->d_MyGroup, id)];
417         while (*pd != d) {
418             dassert(*pd != NULL);
419             pd = &(*pd)->d_ONext;
420         }
421         *pd = d->d_ONext;
422         d->d_ONext = NULL;
423         d->d_ProcDecl.ed_OperId = 0;
424     }
425     return (id);
426 }
427
428 /*
429  * Rename a declaration, fixup the hash tables appropriately.  Used when
430  * making contextual declarations such 'Fd.setfd ...' outside the Fd class.
431  *
432  * NOTE: The original SemGroup will have holes in its index now.
433  */
434 void
435 RenameDecl(Declaration *d, SemGroup *nsg)
436 {
437     runeid_t id;
438     runeid_t operId;
439
440     id = UnHashDecl(d);
441     if (d->d_Op == DOP_PROC)
442         operId = UnHashOper(d);
443     else
444         operId = 0;
445
446     RUNE_REMOVE(&d->d_MyGroup->sg_DeclList, d, d_Node);
447     RUNE_INSERT_TAIL(&nsg->sg_DeclList, d, d_Node);
448     d->d_Index = nsg->sg_DeclCount++;
449     d->d_MyGroup = nsg;
450
451     if (id)
452         HashDecl(d, id);
453     if (operId)
454         HashOper(d, operId);
455 }
456
457 /*
458  * MatchOperatorTypes() - Match left and right hand types to the operator
459  * procedure.
460  *
461  * The op decl is a procedure definition.  Access the procedure arguments and
462  * match them against the Lhs and Rhs types of the exp, returning 0 on
463  * failure, 1 on match.
464  *
465  * If the op decl is an internal operator, match pointers to void against any
466  * pointer.
467  */
468 int
469 MatchOperatorTypes(Declaration *d, Type *ltype, Type *rtype)
470 {
471     Type   *type;
472     runeid_t id;
473     Type   *dltype;
474     Type   *drtype;
475     SemGroup *sg;
476     int     scope;
477     int     internal1;
478     int     internal2;
479
480     /*
481      * Pull the procedure argument type, which must be a compound type.
482      */
483     dassert_decl(d, d->d_Op == DOP_PROC &&
484                  d->d_ProcDecl.ed_Type->ty_Op == TY_PROC);
485     type = d->d_ProcDecl.ed_Type->ty_ProcType.et_ArgsType;
486     id = d->d_ProcDecl.ed_OperId;
487     id = id;
488     dassert_decl(d, type->ty_Op == TY_ARGS);
489     sg = type->ty_ArgsType.et_SemGroup;
490     scope = d->d_ScopeFlags;
491
492     //char buf[RUNE_IDTOSTR_LEN];
493     //printf("START %s\n", runeid_text(id, buf));
494
495     /*
496      * Obtain first argument
497      */
498     RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
499         if (d->d_Op == DOP_ARGS_STORAGE)
500             break;
501     }
502
503     /*
504      * Operators need at least one argument
505      */
506     if (d == NULL)
507         return (0);
508     dltype = d->d_StorDecl.ed_Type;
509
510     /*
511      * Match left argument (ltype) to first operator argument (decl)
512      *
513      * For an internal operator, void * in the operator declaration
514      * matches any pointer and void @ in the operator declaration matches
515      * any reference.
516      *
517      * Set the internal1 variable for either internal or internal2 scope
518      * when the first argument of the operator declaration is a void * or
519      * void @.
520      */
521     if ((scope & (SCOPE_INTERNAL | SCOPE_INTERNAL2)) &&
522         ltype->ty_Op == TY_PTRTO && SimilarType(&VoidPtrType, dltype))
523     {
524         /* ltype pointer matches against void * operator declaration */
525         internal1 = 1;
526     } else
527     if ((scope & (SCOPE_INTERNAL | SCOPE_INTERNAL2)) &&
528         ltype->ty_Op == TY_REFTO && SimilarType(&VoidRefType, dltype))
529     {
530         /* ltype pointer matches against void @ operator declaration */
531         internal1 = 1;
532     } else if (MatchType(dltype, ltype) >= SG_COMPAT_FAIL) {
533         /* normal match failed, return failure */
534         return (0);
535     } else {
536         /*
537          * Normal match succeeded and was not an internal-scoped pointer
538          * or reference.
539          */
540         internal1 = 0;
541     }
542
543     /*
544      * The left argument matched the declaration, now for the right hand
545      * side.
546      *
547      * Obtain the second argument, terminate unary operator, and fail if
548      * we have a unary operator against a binary expression or a binary
549      * operator against a unary expression.
550      */
551     while ((d = RUNE_NEXT(d, d_Node)) && d->d_Op != DOP_ARGS_STORAGE)
552         ;
553     if (rtype == NULL)
554         return d ? 0 : 1;
555     if (d == NULL)
556         return 0;
557     drtype = d->d_StorDecl.ed_Type;
558
559     /*
560      * Binary operator.
561      *
562      * If internal2 and the declaration's arg type is a pointer, rtype
563      * can be any pointer and does not have to match the ltype.  
564      *
565      * else if internal1 is active (meaning the left side was a pointer
566      * under internal1 guidelines), then the right and left sides must
567      * be the same type of pointer.
568      */
569     internal2 = (scope & SCOPE_INTERNAL2);
570
571     //printf("CHECK\n");
572     if (SimilarType(&VoidPtrType, drtype)) {
573         //printf("Q1\n");
574         if (internal2 && SimilarType(&VoidPtrType, rtype))
575             return 1;
576         //printf("Q2\n");
577         if (internal1 && MatchType(ltype, rtype) < SG_COMPAT_FAIL)
578             return 1;
579         //printf("Q3\n");
580     }
581     if (SimilarType(&VoidRefType, drtype)) {
582         //printf("Q4\n");
583         if (internal2 && SimilarType(&VoidRefType, rtype))
584             return 1;
585         //printf("Q5\n");
586         if (internal1 && MatchType(ltype, rtype) < SG_COMPAT_FAIL)
587             return 1;
588         //printf("Q6\n");
589     }
590
591     /*
592      * Otherwise no special deals are active, try to match the
593      * types directly.
594      */
595     if (MatchType(drtype, rtype) < SG_COMPAT_FAIL)
596         return 1;
597
598 #if 0
599     printf("END   OPERATOR %s internal1=%d internal2=%d\n",
600            runeid_text(id, buf), internal1, internal2);
601     printf("Expression types  %s\t", TypeToStr(ltype, NULL));
602     printf("%s\n", TypeToStr(rtype, NULL));
603     printf("Declaration types %s\t", TypeToStr(dltype, NULL));
604     printf("%s\n", TypeToStr(drtype, NULL));
605 #endif
606
607     return 0;
608 }
609
610 /*
611  * MatchCastTypes() - Match the return type and argument for a cast
612  *
613  * The cast decl is a procedure definition.  Access the procedure arguments
614  * and match them against the Lhs and Rhs types of the exp, returning 0 on
615  * failure, 1 on match.
616  *
617  * XXX allow internal bindings of subclasses to super classes.
618  */
619 int
620 MatchCastTypes(Declaration *d, Type *ltype, Type *rtype)
621 {
622     Declaration *d2;
623     Type   *type;
624     SemGroup *sg;
625     int     r;
626
627     dassert_decl(d, d->d_Op == DOP_PROC &&
628                  d->d_ProcDecl.ed_Type->ty_Op == TY_PROC);
629
630     /*
631      * Pull the procedure return type, which must match ltype
632      */
633     type = d->d_ProcDecl.ed_Type->ty_ProcType.et_RetType;
634     dassert(type->ty_Op != TY_UNRESOLVED);
635     if (MatchType(type, ltype) >= SG_COMPAT_FAIL)
636         return (0);
637
638     /*
639      * Pull the procedure argument type, which must be a compound type.
640      */
641     type = d->d_ProcDecl.ed_Type->ty_ProcType.et_ArgsType;
642     dassert_decl(d, type->ty_Op == TY_ARGS);
643     sg = type->ty_ArgsType.et_SemGroup;
644
645     /*
646      * Obtain first argument and match against the cast argument (rtype).
647      */
648     RUNE_FOREACH(d2, &sg->sg_DeclList, d_Node) {
649         if (d2->d_Op == DOP_ARGS_STORAGE)
650             break;
651     }
652
653     /*
654      * Match types.  Internal operators on pointers automatically
655      * match against void pointers, and internal operators on references
656      * automatically match against references.
657      */
658     if (d2 == NULL)
659         return (0);
660     if ((d->d_ScopeFlags & SCOPE_INTERNAL) &&
661         rtype->ty_Op == TY_PTRTO &&
662         SimilarType(&VoidPtrType, d2->d_StorDecl.ed_Type))
663     {
664         r = 0;
665     } else if ((d->d_ScopeFlags & SCOPE_INTERNAL) &&
666                rtype->ty_Op == TY_REFTO &&
667                SimilarType(&VoidRefType, d2->d_StorDecl.ed_Type))
668     {
669         r = 0;
670     } else {
671         r = MatchType(d2->d_StorDecl.ed_Type, rtype);
672     }
673     if (r >= SG_COMPAT_FAIL)
674         return (0);
675
676     /*
677      * Obtain the second argument .. that is, make sure there isn't a second
678      * argument.
679      */
680     while ((d2 = RUNE_NEXT(d2, d_Node)) && d->d_Op != DOP_ARGS_STORAGE)
681         ;
682     if (d2)
683         return (0);
684     return (1);
685 }
686
687 /*
688  * FindDLLSymbol()
689  *
690  * Find the requested DLL symbol by recursing through our SemGroup's looking
691  * for DLL imports.  If found, return its value.
692  */
693 void *
694 FindDLLSymbol(SemGroup *osg, SemGroup *sg, string_t str)
695 {
696     while (sg) {
697         /*
698          * Look for the declaration in this SemGroup
699          */
700         Declaration *d;
701
702         RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
703             if (d->d_Op == DOP_IMPORT) {
704                 Stmt   *st;
705                 void    (*func) (void);
706
707                 st = d->d_Stmt;
708                 dassert(st && st->st_Op == ST_Import);
709                 if (st->st_ImportStmt.es_DLL) {
710                     func = dlsym(st->st_ImportStmt.es_DLL, str);
711                     if (func)
712                         return (func);
713                 }
714             }
715         }
716         if (osg && sg->sg_Stmt && sg->sg_Stmt->st_Op == ST_Class) {
717             sg = osg;
718             osg = NULL;
719         } else {
720             if (sg->sg_Flags & SGF_SELFCONTAINED)
721                 break;
722             sg = sg->sg_Parent;
723         }
724     }
725     return (NULL);
726 }
727
728 /*
729  * FindDeclPath()
730  *
731  * Find the declaration associated with the array of identifiers representing
732  * id.id.id...
733  *
734  * We are allowed to recurse backwards in order to locate the first id in the
735  * array, and to recurse downwards through 'self' or explicitly named mounts.
736  * Once the first identifier matches, however, we can only recurse downwards.
737  * We do not try to overload our searches.
738  *
739  * When recursing backwards it is not possible to access non-global storage
740  * elements of a class, because there is no context in which to get at those
741  * variables (you have to go through "." or "->" via 'this' or something like
742  * that).  But it is ok to access globals and types.
743  *
744  * Note that typedef's do not match their own identifier, so something like
745  * 'typedef int int' works to create a qualified type that hides the
746  * original. XXX remove
747  *
748  * 'level' is used when resolving identifiers in a subclass that were pulled
749  * in from the superclass.  Also, if we have to go backwards (the identifier
750  * can't be found in the subclass), we have to switch to the original
751  * superclass's semgroup.  LEVEL IS ONLY USED WHEN RESOLVING IDENTIFIERS
752  * RELATIVE TO A "." OR "->" EXPRESSION, OR WHEN THE 'CURRENT' SEMGROUP IS
753  * THE CLASS ITSELF (I.E. DEFAULT ASSIGNMENTS AND THE DECLARATION ITSELF, BUT
754  * NOT A PROCEDURE BODY).
755  *
756  * On success *visibility will be set to the base visibility required if any
757  * further searches are made relative to the returned declaration.
758  *
759  * On failure *visibility is garbage.
760  */
761 Declaration *
762 FindDeclPath(LexRef *lexRef, SemGroup *osg,
763              SemGroup *sg, Type *nomatch,
764              runeid_t *ary, int mask,
765              int *visibility, int level, int *eno)
766 {
767     int     i;
768     int     noLocalStorage = 0;
769     Declaration *d = NULL;
770
771     i = 0;
772
773     while (ary[i] && sg) {
774         /*
775          * Look for the declaration in this SemGroup
776          */
777         d = findDecl(sg, ary[i], *visibility, level, eno);
778         if (d != NULL) {
779             if (nomatch &&
780                 d->d_Op == DOP_TYPEDEF &&
781                 nomatch == d->d_TypedefDecl.ed_Type)
782             {
783                 d = NULL;
784             }
785         }
786
787         /*
788          * Look for the declaration in the procedure arguments if this is the
789          * top level of a procedure.
790          */
791         if (d == NULL &&
792             sg->sg_Stmt &&
793             sg->sg_Stmt->st_Op == ST_Proc) {
794             Type   *argsType;
795             SemGroup *sg2;
796
797             d = sg->sg_Stmt->st_ProcStmt.es_Decl;
798             dassert_decl(d, d->d_Op == DOP_PROC);
799             argsType = d->d_ProcDecl.ed_Type->ty_ProcType.et_ArgsType;
800             dassert_decl(d, argsType->ty_Op == TY_ARGS);
801             sg2 = argsType->ty_ArgsType.et_SemGroup;
802             d = findDecl(sg2, ary[i], *visibility, level, eno);
803         }
804
805         /*
806          * Look for the declaration by recursing down into "self" imports. We
807          * do not overload on partial matches.. a partial match is considered
808          * to be a failure.
809          *
810          * If crossing a self-contained boundary only public scope can be
811          * searched.  Otherwise both public and library scope (but not
812          * private scope) can be searched.
813          */
814         if (d == NULL) {
815             d = findDecl(sg, RUNEID_SELF, *visibility, sg->sg_Level, eno);
816             while (d) {
817                 Declaration *d2;
818                 int     visibility2;
819
820                 if (d->d_MyGroup != sg || d->d_Id != RUNEID_SELF ||
821                     d->d_Op != DOP_IMPORT)
822                 {
823                     d = d->d_HNext;
824                     continue;
825                 }
826
827                 dassert_decl(d, d->d_ImportDecl.ed_SemGroup != NULL);
828
829                 if (d->d_ImportDecl.ed_SemGroup->sg_Flags &
830                     SGF_SELFCONTAINED) {
831                     visibility2 = *visibility &
832                                   ~(SCOPE_LIBRARY | SCOPE_PRIVATE);
833                 } else {
834                     visibility2 = *visibility & ~SCOPE_PRIVATE;
835                 }
836
837                 d2 = FindDeclPath(lexRef,
838                                   NULL,
839                                   d->d_ImportDecl.ed_SemGroup,
840                                   nomatch,
841                                   ary + i,
842                                   (mask & ~FDC_NULL) | FDC_NOBACK,
843                                   &visibility2,
844                                   -1,
845                                   eno);
846                 if (d2 == (void *)-1) {
847                     if (mask & FDC_NULL)
848                         d2 = NULL;
849                     return (d2);
850                 }
851
852                 /*
853                  * This was a complete search of all remaining array
854                  * elements, so return on success.
855                  */
856                 if (d2) {
857                     *visibility = visibility2;
858                     return (d2);
859                 }
860                 d = d->d_HNext;
861             }
862         }
863
864         /*
865          * If still not found then go back a level.  If we cross an import
866          * boundary we lose private-scope (and do not regain it even if we
867          * cross back into the same library).  If we cross a class boundary
868          * we may have to locate the superclass's SG.
869          */
870         if (d == NULL) {
871             /*
872              * If we are leaving a procedure context
873              */
874             if (sg &&
875                 sg->sg_Stmt &&
876                 sg->sg_Stmt->st_Op == ST_Proc) {
877                 if ((sg->sg_Stmt->st_Flags & STF_NESTED) == 0)
878                     noLocalStorage = 1;
879             }
880
881             /*
882              * If we are crossing a class statement boundary we have to jump
883              * to the original import semantic context.  For example, when a
884              * procedure is pulled in from a superclass we want to jump to
885              * its original semantic context, not the context our subclass is
886              * defined in.
887              *
888              * XXX I really wanted the 'original semantic context of the
889              * statement' but it's a mess.  This works just as well.
890              */
891             if (osg &&
892                 sg->sg_Stmt &&
893                 sg->sg_Stmt->st_Op == ST_Class) {
894                 sg = osg;
895                 osg = NULL;
896                 *visibility = SCOPE_ALL_VISIBLE;
897             } else {
898                 if ((mask & FDC_NOBACK) ||
899                     (sg->sg_Flags & SGF_SELFCONTAINED)) {
900                     return (NULL);
901                 }
902                 if (sg->sg_Flags & SGF_SEMTOP)
903                     *visibility &= ~SCOPE_PRIVATE;
904
905                 /*
906                  * If SGF_ALTPRIORITY is set this was an inlined procedure
907                  * and the sg_Parent link is not the proper semantic path (it
908                  * isn't visible namespace-wise).  In this situation the
909                  * inliner in resolve.c has set sg_Altcontext to the proper
910                  * group for searching.
911                  */
912                 if (sg->sg_Flags & SGF_ALTPRIORITY)
913                     sg = sg->sg_AltContext;
914                 else
915                     sg = sg->sg_Parent;
916             }
917
918             /*
919              * You can't back into a class's local storage (from a process).
920              */
921             if (sg && sg->sg_Stmt && sg->sg_Stmt->st_Op == ST_Class)
922                 noLocalStorage = 1;
923             continue;
924         }
925
926         /*
927          * FOUND!  No going backwards now, only recurse downwards through
928          * imports and classes from this point on.
929          *
930          * We lose private scope when we go through an import, and we loose
931          * library scope when we cross a selfcontained (library) boundary.
932          * Also, when pushing into a class semantically there is no context
933          * in which to access local storage.
934          */
935         mask |= FDC_NOBACK;
936
937         switch (d->d_Op) {
938         case DOP_IMPORT:
939             sg = d->d_ImportDecl.ed_SemGroup;
940             dassert_decl(d, sg != NULL);
941             if (sg->sg_Flags & SGF_SELFCONTAINED)
942                 *visibility &= ~(SCOPE_LIBRARY | SCOPE_PRIVATE);
943             else
944                 *visibility &= ~SCOPE_PRIVATE;
945             break;
946         case DOP_CLASS:
947             /*
948              * pushdown into a class.  Visibility remains the same.
949              */
950             sg = d->d_ClassDecl.ed_SemGroup;
951             noLocalStorage = 1;
952             break;
953         case DOP_GROUP_STORAGE:
954         case DOP_ARGS_STORAGE:
955         case DOP_STACK_STORAGE:
956             if (noLocalStorage) {
957                 fprintf(stderr,
958                         "You cannot access instantiated "
959                         "storage this way, there is "
960                         "no context.\n"
961                         "Perhaps you meant to "
962                         "use 'this.<id>'.\n");
963                 LexPrintRef(lexRef, 0);
964                 dpanic("");
965             }
966             /* fall through */
967         default:
968             dassert_decl(d, ary[i + 1] == 0);
969             sg = NULL;
970             break;
971         }
972         ++i;
973     }
974     return (d);
975 }
976
977 /*
978  * Look for the declaration via an alternative context.  sg_AltContext is
979  * temporarily set while resolving the expression tree, primarily to get more
980  * direct access to type globals when making method calls (otherwise the code
981  * has to prefix each one with the type or object which can be messy).
982  */
983 Declaration *
984 FindDeclPathAltContext(LexRef *lexRef, SemGroup *osg,
985                        SemGroup *sg, Type *nomatch,
986                        runeid_t *ary, int mask,
987                        int *visibility, int level, int *eno)
988 {
989     Declaration *d;
990
991     while (sg) {
992         if (sg->sg_AltContext) {
993             d = FindDeclPath(lexRef, osg, sg->sg_AltContext,
994                              nomatch, ary, mask,
995                              visibility, level, eno);
996             if (d && (d->d_ScopeFlags & SCOPE_GLOBAL))
997                 return d;
998         }
999         if ((sg->sg_Flags & (SGF_SEMTOP | SGF_NESTED)) == SGF_SEMTOP)
1000             break;
1001         sg = sg->sg_Parent;
1002     }
1003     return NULL;
1004 }
1005
1006 Declaration *
1007 FindDeclId(SemGroup *sg, runeid_t id, int *eno)
1008 {
1009     Declaration *d;
1010
1011     d = findDecl(sg, id, SCOPE_ALL_VISIBLE, sg->sg_Level, eno);
1012     return (d);
1013 }
1014
1015 /*
1016  * This version is used by the resolver to allow matches against refining
1017  * declarations to ignore scope.  Scope might not be assigned to such
1018  * declarations yet and will inherit the scope of the declaration in the
1019  * superclass that is being refined.
1020  */
1021 Declaration *
1022 FindDeclRefineId(SemGroup *sg, runeid_t id, int *eno)
1023 {
1024     Declaration *d;
1025
1026     d = findDecl(sg, id, SCOPE_REFINE | SCOPE_ALL_VISIBLE, sg->sg_Level, eno);
1027     return (d);
1028 }
1029
1030 Declaration *
1031 FindDeclIdLevel(SemGroup *sg, runeid_t id, int level, int *eno)
1032 {
1033     Declaration *d;
1034
1035     d = findDecl(sg, id, SCOPE_ALL_VISIBLE, level, eno);
1036     return (d);
1037 }
1038
1039 /*
1040  * RefineDeclaration()  - rd is a refinement of sd.  Fixup rd.
1041  *
1042  * sg is the semgroup representing our subclass (in the middle of being
1043  * built).  Refinements can be:
1044  *
1045  * - Completely compatible, such as a simple change in defaults
1046  *
1047  * - Partially compatible, such as compatible method overrides (means can
1048  * still be directly accessed via a superclass @ref).
1049  *
1050  * - Incompatible, when refinements change the underlying type, arguments, or
1051  * return values in incompatible ways.
1052  *
1053  * XXX YYY
1054  *
1055  * NOTE: May be called multiple times with the same argument.
1056  */
1057 void
1058 RefineDeclaration(SemGroup *sg, Declaration *sd, Declaration *rd)
1059 {
1060     int     compat = MatchDeclTypes(sd, rd);
1061
1062     if (compat < SG_COMPAT_PART && sd->d_Op == DOP_PROC)
1063         compat = SG_COMPAT_PART;
1064
1065     if (sg->sg_Compat < compat)
1066         sg->sg_Compat = compat;
1067     if (compat == SG_COMPAT_FAIL) {
1068         fprintf(stderr, "Refinement is illegal\n");
1069         dassert_decl(rd, 0);
1070     }
1071 }
1072
1073 /*
1074  * DupDeclaration() - duplicate a declaration (called during resolve)
1075  *
1076  * Note: When you dup a resolved declaration, it becomes unresolved. The
1077  * semGroup the decl's is being dup'd into must be resolved afterwords.  Note
1078  * that the d_Index's will not necessarily match up.
1079  *
1080  * Note: d_Level and d_Search are inherited from sd.  d_Level should be
1081  * non-NULL if sd is a declaration within a class, and NULL otherwise.
1082  * d_Search will be non-NULL when we integrate a declaration into a subclass
1083  * recursively.  That is, if you have class A and subclass B of A, and
1084  * subclass C of B, then when C pulls in a declaration from B that was
1085  * originally from A, it will see a non-NULL d_Search in b's version of the
1086  * declaration.
1087  */
1088 Declaration *
1089 DupDeclaration(SemGroup *sg, Declaration *sd)
1090 {
1091     Declaration *d = AllocDeclaration(sg, sd->d_Op, &sd->d_Scope);
1092     SemGroup *xsg;
1093
1094     LexDupRef(&sd->d_LexRef, &d->d_LexRef);
1095     if (sd->d_Id)
1096         HashDecl(d, sd->d_Id);
1097     d->d_Flags = sd->d_Flags & ~(DF_RESOLVED | DF_RESOLVING |
1098                                  DF_LAYOUT | DF_DIDPULLDOWN |
1099                                  DF_ONCLIST | DF_ONDLIST | DF_ONGLIST |
1100                                  DF_ONSRLIST | DF_ADDROF | DF_ADDRUSED);
1101     d->d_RState = 0;
1102     d->d_Level = sd->d_Level;
1103     d->d_Search = sd->d_Search;
1104     d->d_ImportSemGroup = sd->d_ImportSemGroup;
1105     d->d_Super = sd;
1106     d->d_Level = sd->d_Level;
1107     d->d_Stmt = sd->d_Stmt;
1108     /* do not dup d_DynIndex */
1109
1110     /*
1111      * We do not need to re-evaluate types for the new SemGroup unless the
1112      * change of venue would cause them to change (such as a refined
1113      * typedef).
1114      */
1115     switch (sg->sg_Op) {
1116     case SG_CLASS:
1117     case SG_COMPOUND:
1118     case SG_PROCARGS:
1119         xsg = sg;
1120         break;
1121     default:
1122         xsg = NULL;
1123         break;
1124     }
1125
1126     /*
1127      * XXX decl may be resolved if dup'ing a semgroup for a varargs call. See
1128      * libd/resolve.d 'Too many arg'
1129      */
1130 #if 0
1131     dassert_decl(d, (d->d_Flags & (DF_RESOLVED | DF_RESOLVING)) == 0);
1132 #endif
1133
1134     /*
1135      * Just reuse OrigAssExp.  The resolver will dup the epxression to
1136      * ed_AssExp later on.
1137      */
1138     switch (d->d_Op) {
1139     case DOP_CLASS:
1140     case DOP_IMPORT:
1141         /*
1142          * Only occurs inside import, so dup() should never be called on it.
1143          */
1144         dassert_decl(d, 0);
1145         break;
1146     case DOP_ARGS_STORAGE:
1147     case DOP_STACK_STORAGE:
1148     case DOP_GLOBAL_STORAGE:
1149     case DOP_GROUP_STORAGE:
1150         d->d_StorDecl.ed_Type = DupType(xsg, sd->d_StorDecl.ed_Type);
1151         d->d_StorDecl.ed_OrigAssExp = sd->d_StorDecl.ed_OrigAssExp;
1152         //d->d_StorDecl.ed_AssExp = NULL;
1153         break;
1154     case DOP_TYPEDEF:
1155         d->d_TypedefDecl.ed_Type = DupType(xsg, sd->d_TypedefDecl.ed_Type);
1156         d->d_TypedefDecl.ed_OrigAssExp = sd->d_TypedefDecl.ed_OrigAssExp;
1157         //d->d_TypedefDecl.ed_AssExp = NULL;
1158         break;
1159     case DOP_ALIAS:
1160         d->d_AliasDecl.ed_Type = DupType(xsg, sd->d_AliasDecl.ed_Type);
1161         d->d_AliasDecl.ed_OrigAssExp = sd->d_AliasDecl.ed_OrigAssExp;
1162         //d->d_AliasDecl.ed_AssExp = NULL;
1163         break;
1164     case DOP_PROC:
1165         /*
1166          * We do not duplicate the procedure body here.  If we were to it
1167          * would result in X*Y copies of the procedure whether they were used
1168          * or not.  Instead this is done at resolve time in resolveDecl().
1169          */
1170         d->d_ProcDecl.ed_Type = DupType(xsg, sd->d_ProcDecl.ed_Type);
1171         d->d_ProcDecl.ed_OrigBody = sd->d_ProcDecl.ed_OrigBody;
1172         if (sd->d_ProcDecl.ed_OperId)
1173             HashOper(d, sd->d_ProcDecl.ed_OperId);
1174         break;
1175     default:
1176         dassert_decl(d, 0);
1177     }
1178     return (d);
1179 }
1180
1181 void
1182 AdjustProcArgsNestingLevel(Declaration *d, SemGroup *fromSg)
1183 {
1184     Type   *type;
1185     SemGroup *sg;
1186
1187     dassert_decl(d, d->d_Op == DOP_PROC &&
1188                  d->d_ProcDecl.ed_Type->ty_Op == TY_PROC);
1189     type = d->d_ProcDecl.ed_Type->ty_ProcType.et_ArgsType;
1190     dassert_decl(d, type->ty_Op == TY_ARGS);
1191     sg = type->ty_ArgsType.et_SemGroup;
1192     sg->sg_NestLevel = fromSg->sg_NestLevel;
1193     sg->sg_NestSize = fromSg->sg_NestSize;
1194 }
1195
1196 void
1197 AdjustNestSize(SemGroup *sg, int size)
1198 {
1199     for (;;) {
1200         sg->sg_NestSize = size;
1201         if ((sg->sg_Flags & (SGF_SEMTOP | SGF_NESTED)) == SGF_SEMTOP)
1202             break;
1203         sg = sg->sg_Parent;
1204     }
1205 }
1206
1207 /*
1208  * Extra cacheability under certain circumstances.  Is not all-encompassing.
1209  * Used to determine if an inline procedure argument can be cached.
1210  */
1211 int
1212 DeclarationCacheable(Declaration *d)
1213 {
1214     Type   *type;
1215
1216     dassert_decl(d, d->d_Op & DOPF_STORAGE);
1217     type = d->d_StorDecl.ed_Type;
1218     if (d->d_Flags & DF_ADDRUSED)
1219         return 0;
1220     if (d->d_Scope.s_Flags & SCOPE_LVALUE)
1221         return 0;
1222     if (type->ty_Flags & (TF_ISINTEGER | TF_ISFLOATING | TF_ISBOOL))
1223         return 1;
1224     return 0;
1225 }