Rune - Generation work (now runs numerous tests)
[rune.git] / librune / type.c
1 /*
2  * TYPE.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
10 Type DynamicLValueType;
11 Type DynamicRValueType;
12
13 Type NumericType;       /* generic numeric placeholder */
14 Type IntegralType;      /* generic integral placeholder */
15 Type SIntegerType;      /* generic signed integer placeholder */
16 Type UIntegerType;      /* generic unsigned integer placeholder */
17
18 Type VoidType;
19 Type BoolType;
20 Type Int8Type;
21 Type UInt8Type;
22 Type Int16Type;
23 Type UInt16Type;
24 Type Int32Type;
25 Type UInt32Type;
26 Type Int64Type;
27 Type UInt64Type;
28 Type Int128Type;
29 Type UInt128Type;
30
31 Type IntPtrType;
32 Type UIntPtrType;
33 Type OffType;
34 Type SizeType;
35
36 Type FloatType;         /* generic float placeholder */
37 Type Float32Type;
38 Type Float64Type;
39 Type Float128Type;
40
41 Type PointerType;       /* generic pointer placeholder */
42 Type CCharType;         /* const char           */
43 Type StrType;           /* const char *         */
44 Type CharPtrType;       /* char *               */
45 Type CharPtrPtrType;    /* char **              */
46 Type VoidPtrType;       /* void *               */
47 Type VoidRefType;       /* void @               */
48 Type CVoidPtrType;      /* const void *         */
49 Type LVoidPtrType;      /* lvalue void *        */
50
51 Type LexRefType;        /* run-time access class tie-ins */
52 Type ScopeType;
53 Type DeclarationType;
54 Type SemGroupType;
55 Type TypeType;
56 Type FILLERTypeType;
57 Type FILLERDeclType;
58
59 typelist_t DynamicTypeList = RUNE_HEAD_INITIALIZER(DynamicTypeList);
60 typelist_t CompoundTypeList = RUNE_HEAD_INITIALIZER(CompoundTypeList);
61 typelist_t ArgsTypeList = RUNE_HEAD_INITIALIZER(ArgsTypeList);
62 typelist_t StorageTypeList = RUNE_HEAD_INITIALIZER(StorageTypeList);
63
64 static void initInternalClassType(Type *type, Declaration *d);
65
66 Type *BaseTypeAry[] = {
67                 &DynamicLValueType, &DynamicRValueType, &NumericType,
68                 &IntegralType, &SIntegerType, &UIntegerType,
69                 &VoidType, &BoolType, &Int8Type, &UInt8Type,
70                 &Int16Type, &UInt16Type, &Int32Type, &UInt32Type,
71                 &Int64Type, &UInt64Type, &Int128Type, &UInt128Type,
72
73                 &IntPtrType, &UIntPtrType, &OffType, &SizeType,
74
75                 &FloatType, &Float32Type, &Float64Type, &Float128Type,
76
77                 &PointerType, &CCharType, &StrType, &CharPtrType,
78                 &CharPtrPtrType, &VoidPtrType, &VoidRefType, &CVoidPtrType,
79                 &LVoidPtrType,
80
81                 &LexRefType, &ScopeType, &DeclarationType, &SemGroupType,
82                 &TypeType, &FILLERTypeType, &FILLERDeclType,
83                 NULL
84 };
85
86 void
87 initType(Type *type, typelist_t *list, int op)
88 {
89         type->ty_Op = op;
90         RUNE_INIT(&type->ty_QList);
91         if (list)
92                 RUNE_INSERT_TAIL(list, type, ty_Node);
93         type->ty_SQList = list;
94 }
95
96 void
97 initQualType(Type *type, typelist_t *list, int op, int sqflags)
98 {
99         initType(type, list, op);
100         type->ty_SQFlags = sqflags;
101 }
102
103 void
104 initPtrType(Type *type, Type *ptrto, int sqflags)
105 {
106         initQualType(type, &ptrto->ty_QList, TY_PTRTO, sqflags);
107         type->ty_PtrType.et_Type = ptrto;
108         /*type->ty_Bytes = sizeof(PointerStor);*/
109         type->ty_AlignMask = sizeof(void *) - 1;
110 }
111
112 void
113 initCPtrType(Type *type, Type *ptrto, int sqflags)
114 {
115         initQualType(type, &ptrto->ty_QList, TY_CPTRTO, sqflags);
116         type->ty_PtrType.et_Type = ptrto;
117         /*type->ty_Bytes = sizeof(void *);*/
118         type->ty_AlignMask = sizeof(void *) - 1;
119 }
120
121 static void
122 initRefType(Type *type, Type *refto, int sqflags)
123 {
124         initQualType(type, &refto->ty_QList, TY_REFTO, sqflags);
125         type->ty_RefType.et_Type = refto;
126         type->ty_AlignMask = sizeof(void *) - 1;
127         /*type->ty_Bytes = sizeof(PointerStor);*/
128 }
129
130 void
131 TypeInit(void)
132 {
133         int i;
134
135         initQualType(&DynamicLValueType, &DynamicTypeList,
136                      TY_DYNAMIC, SF_LVALUE);
137         initType(&DynamicRValueType, &DynamicTypeList, TY_DYNAMIC);
138         initType(&NumericType, NULL, TY_UNRESOLVED);
139         initType(&IntegralType, NULL, TY_UNRESOLVED);
140         initType(&SIntegerType, NULL, TY_UNRESOLVED);
141         initType(&UIntegerType, NULL, TY_UNRESOLVED);
142         initType(&FloatType, NULL, TY_UNRESOLVED);
143         initType(&PointerType, NULL, TY_UNRESOLVED);
144         PointerType.ty_AlignMask = sizeof(void *) - 1;
145
146         initType(&VoidType, NULL, TY_UNRESOLVED);
147         initType(&BoolType, NULL, TY_UNRESOLVED);
148         initType(&Int8Type, NULL, TY_UNRESOLVED);
149         initType(&UInt8Type, NULL, TY_UNRESOLVED);
150         initType(&Int16Type, NULL, TY_UNRESOLVED);
151         initType(&UInt16Type, NULL, TY_UNRESOLVED);
152         initType(&Int32Type, NULL, TY_UNRESOLVED);
153         initType(&UInt32Type, NULL, TY_UNRESOLVED);
154         initType(&Int64Type, NULL, TY_UNRESOLVED);
155         initType(&UInt64Type, NULL, TY_UNRESOLVED);
156
157         initType(&IntPtrType, NULL, TY_UNRESOLVED);
158         initType(&UIntPtrType, NULL, TY_UNRESOLVED);
159         initType(&OffType, NULL, TY_UNRESOLVED);
160         initType(&SizeType, NULL, TY_UNRESOLVED);
161
162         initType(&Float32Type, NULL, TY_UNRESOLVED);
163         initType(&Float64Type, NULL, TY_UNRESOLVED);
164         initType(&Float128Type, NULL, TY_UNRESOLVED);
165
166         initQualType(&CCharType, NULL, TY_UNRESOLVED, SF_CONST);
167         initPtrType(&StrType, &CCharType, 0);
168         initPtrType(&CharPtrType, &UInt8Type, 0);
169         initPtrType(&CharPtrPtrType, &CharPtrType, 0);
170         initPtrType(&VoidPtrType, &VoidType, 0);
171         initRefType(&VoidRefType, &VoidType, 0);
172         initCPtrType(&CVoidPtrType, &VoidType, SF_CONST);
173         initPtrType(&LVoidPtrType, &VoidType, SF_LVALUE);
174
175         /*
176          * Mark internal types (not all are bound to classes so it is
177          * easiest to just do it here).  This will prevent the collapse
178          * code from trying to collapse our base types.
179          */
180         for (i = 0; BaseTypeAry[i]; ++i)
181                 BaseTypeAry[i]->ty_Flags |= TF_ISINTERNAL;
182
183         StrTableAlloc("void", 4, SPECIAL_INTERNAL_VOID);
184         StrTableAlloc("bool", 4, SPECIAL_INTERNAL_BOOL);
185         StrTableAlloc("int8_t", 6, SPECIAL_INTERNAL_INT8);
186         StrTableAlloc("uint8_t", 7, SPECIAL_INTERNAL_UINT8);
187         StrTableAlloc("int16_t", 7, SPECIAL_INTERNAL_INT16);
188         StrTableAlloc("uint16_t", 8, SPECIAL_INTERNAL_UINT16);
189         StrTableAlloc("int32_t", 7, SPECIAL_INTERNAL_INT32);
190         StrTableAlloc("uint32_t", 8, SPECIAL_INTERNAL_UINT32);
191         StrTableAlloc("int64_t", 7, SPECIAL_INTERNAL_INT64);
192         StrTableAlloc("uint64_t", 8, SPECIAL_INTERNAL_UINT64);
193         StrTableAlloc("int128_t", 8, SPECIAL_INTERNAL_INT128);
194         StrTableAlloc("uint128_t", 9, SPECIAL_INTERNAL_UINT128);
195
196         StrTableAlloc("float32_t", 9, SPECIAL_INTERNAL_FLOAT32);
197         StrTableAlloc("float64_t", 9, SPECIAL_INTERNAL_FLOAT64);
198         StrTableAlloc("float128_t", 10, SPECIAL_INTERNAL_FLOAT128);
199
200         StrTableAlloc("intptr_t", 8, SPECIAL_INTERNAL_INTPTR);
201         StrTableAlloc("uintptr_t", 9, SPECIAL_INTERNAL_UINTPTR);
202         StrTableAlloc("size_t", 6, SPECIAL_INTERNAL_SIZE);
203         StrTableAlloc("off_t", 5, SPECIAL_INTERNAL_OFF);
204
205         StrTableAlloc("Float", 5, SPECIAL_INTERNAL_FLOAT);
206         StrTableAlloc("Pointer", 7, SPECIAL_INTERNAL_POINTER);
207         StrTableAlloc("Numeric", 7, SPECIAL_INTERNAL_NUMERIC);
208         StrTableAlloc("Integral", 8, SPECIAL_INTERNAL_INTEGRAL);
209         StrTableAlloc("SInteger", 8, SPECIAL_INTERNAL_SINTEGER);
210         StrTableAlloc("UInteger", 8, SPECIAL_INTERNAL_UINTEGER);
211
212         StrTableAlloc("LexRef", 6, SPECIAL_INTERNAL_LEXREF);
213         StrTableAlloc("Scope", 5, SPECIAL_INTERNAL_SCOPE);
214         StrTableAlloc("Declaration", 11, SPECIAL_INTERNAL_DECLARATION);
215         StrTableAlloc("SemGroup", 8, SPECIAL_INTERNAL_SEMGROUP);
216         StrTableAlloc("Type", 4, SPECIAL_INTERNAL_TYPE);
217         StrTableAlloc("FILLERType", 10, SPECIAL_INTERNAL_FILLERTYPE);
218         StrTableAlloc("FILLERDecl", 10, SPECIAL_INTERNAL_FILLERDECL);
219
220         StrTableAlloc("__count",        7,      SPECIAL_COUNT);
221         StrTableAlloc("__data",         6,      SPECIAL_DATA);
222         StrTableAlloc("__varcount",     10,     SPECIAL_VAR_COUNT);
223         StrTableAlloc("__vardata",      9,      SPECIAL_VAR_DATA);
224         StrTableAlloc("__typeid",       8,      SPECIAL_TYPEID);
225         StrTableAlloc("__typestr",      9,      SPECIAL_TYPESTR);
226         StrTableAlloc("NULL",           4,      SPECIAL_NULL);
227 }
228
229 /*
230  * Attach an internal class, creating a global summary type for it that
231  * allows our interpreter and code generator to make various assumptions.
232  */
233 int
234 InternalClassAttach(Parse *p __unused, int t, Declaration *d)
235 {
236         Type *itype = NULL;
237         int s;
238
239         dassert_decl(d, d->d_Op == DOP_CLASS);
240
241         if ((s = StrTableSpecial(d->d_Id)) & SPECIALF_INTERNAL) {
242                 switch(s) {
243                 case SPECIAL_INTERNAL_VOID:
244                         itype = &VoidType;
245                         break;
246                 case SPECIAL_INTERNAL_BOOL:
247                         /*
248                          * Special flag helper (resolver sets TF_ISBOOL in
249                          * in the type)
250                          */
251                         itype = &BoolType;
252                         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISBOOL;
253                         break;
254                 case SPECIAL_INTERNAL_INT8:
255                         itype = &Int8Type;
256                         break;
257                 case SPECIAL_INTERNAL_UINT8:
258                         itype = &UInt8Type;
259                         break;
260                 case SPECIAL_INTERNAL_INT16:
261                         itype = &Int16Type;
262                         break;
263                 case SPECIAL_INTERNAL_UINT16:
264                         itype = &UInt16Type;
265                         break;
266                 case SPECIAL_INTERNAL_INT32:
267                         itype = &Int32Type;
268                         break;
269                 case SPECIAL_INTERNAL_UINT32:
270                         itype = &UInt32Type;
271                         break;
272                 case SPECIAL_INTERNAL_INT64:
273                         itype = &Int64Type;
274                         break;
275                 case SPECIAL_INTERNAL_UINT64:
276                         itype = &UInt64Type;
277                         break;
278                 case SPECIAL_INTERNAL_INT128:
279                         itype = &Int128Type;
280                         break;
281                 case SPECIAL_INTERNAL_UINT128:
282                         itype = &UInt128Type;
283                         break;
284
285                 case SPECIAL_INTERNAL_FLOAT:
286                         /*
287                          * Special flag helper (resolver sets TF_ISFLOATING in
288                          * in the type)
289                          */
290                         itype = &FloatType;
291                         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISFLOATING;
292                         break;
293                 case SPECIAL_INTERNAL_FLOAT32:
294                         itype = &Float32Type;
295                         break;
296                 case SPECIAL_INTERNAL_FLOAT64:
297                         itype = &Float64Type;
298                         break;
299                 case SPECIAL_INTERNAL_FLOAT128:
300                         itype = &Float128Type;
301                         break;
302
303                 case SPECIAL_INTERNAL_INTPTR:
304                         itype = &IntPtrType;
305                         break;
306                 case SPECIAL_INTERNAL_UINTPTR:
307                         itype = &UIntPtrType;
308                         break;
309                 case SPECIAL_INTERNAL_OFF:
310                         itype = &OffType;
311                         break;
312                 case SPECIAL_INTERNAL_SIZE:
313                         itype = &SizeType;
314                         break;
315                 /* NOTE: There is no ssize_t in rune. size_t is signed */
316
317                 case SPECIAL_INTERNAL_POINTER:
318                         itype = &PointerType;
319                         break;
320                 case SPECIAL_INTERNAL_NUMERIC:
321                         itype = &NumericType;
322                         break;
323                 case SPECIAL_INTERNAL_INTEGRAL:
324                         itype = &IntegralType;
325                         break;
326                 case SPECIAL_INTERNAL_SINTEGER:
327                         /*
328                          * Special flag helper (resolver sets TF_ISINTEGER in
329                          * in the type)
330                          */
331                         itype = &SIntegerType;
332                         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISINTEGER;
333                         break;
334                 case SPECIAL_INTERNAL_UINTEGER:
335                         /*
336                          * Special flag helper (resolver sets TF_ISINTEGER
337                          * and TF_ISUNSIGNED in the type)
338                          */
339                         itype = &UIntegerType;
340                         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISUNSIGNED;
341                         d->d_ClassDecl.ed_SemGroup->sg_Flags |= SGF_ISINTEGER;
342                         break;
343
344                 case SPECIAL_INTERNAL_LEXREF:
345                         itype = &LexRefType;
346                         break;
347                 case SPECIAL_INTERNAL_SCOPE:
348                         itype = &ScopeType;
349                         break;
350                 case SPECIAL_INTERNAL_DECLARATION:
351                         itype = &DeclarationType;
352                         break;
353                 case SPECIAL_INTERNAL_SEMGROUP:
354                         itype = &SemGroupType;
355                         break;
356                 case SPECIAL_INTERNAL_TYPE:
357                         itype = &TypeType;
358                         break;
359                 case SPECIAL_INTERNAL_FILLERTYPE:
360                         itype = &FILLERTypeType;
361                         break;
362                 case SPECIAL_INTERNAL_FILLERDECL:
363                         itype = &FILLERDeclType;
364                         break;
365                 default:
366                         dassert(0);
367                         break;
368                 }
369         }
370         initInternalClassType(itype, d);
371
372         /*
373          * Fixup for const int8 pointers... we did not have
374          * a QList to put CCharType on until now.  It will
375          * wind up on the SemGroup's sg_ClassList.
376          */
377         if (itype == &UInt8Type) {
378                 TypeToQualType(itype, &CCharType,
379                                itype->ty_SQFlags | SF_CONST, NULL);
380         } 
381
382         return(t);
383 }
384
385 /*
386  * This is mostly deprecated except for official type aliases such as
387  * intptr_t.
388  */
389 int
390 InternalTypeAttach(Parse *p, int t, Declaration *d)
391 {
392         Type *itype = NULL;
393         int s;
394
395         dassert_decl(d, d->d_Op == DOP_TYPEDEF);
396
397         if ((s = StrTableSpecial(d->d_Id)) & SPECIALF_INTERNAL) {
398                 switch(s) {
399                 case SPECIAL_INTERNAL_VOID:
400                         itype = &VoidType;
401                         break;
402                 case SPECIAL_INTERNAL_BOOL:
403                         itype = &BoolType;
404                         break;
405                 case SPECIAL_INTERNAL_INT8:
406                         itype = &Int8Type;
407                         break;
408                 case SPECIAL_INTERNAL_UINT8:
409                         itype = &UInt8Type;
410                         break;
411                 case SPECIAL_INTERNAL_INT16:
412                         itype = &Int16Type;
413                         break;
414                 case SPECIAL_INTERNAL_UINT16:
415                         itype = &UInt16Type;
416                         break;
417                 case SPECIAL_INTERNAL_INT32:
418                         itype = &Int32Type;
419                         break;
420                 case SPECIAL_INTERNAL_UINT32:
421                         itype = &UInt32Type;
422                         break;
423                 case SPECIAL_INTERNAL_INT64:
424                         itype = &Int64Type;
425                         break;
426                 case SPECIAL_INTERNAL_UINT64:
427                         itype = &UInt64Type;
428                         break;
429
430                 case SPECIAL_INTERNAL_FLOAT32:
431                         itype = &Float32Type;
432                         break;
433                 case SPECIAL_INTERNAL_FLOAT64:
434                         itype = &Float64Type;
435                         break;
436                 case SPECIAL_INTERNAL_FLOAT128:
437                         itype = &Float128Type;
438                         break;
439
440                 case SPECIAL_INTERNAL_INTPTR:
441                         itype = &IntPtrType;
442                         break;
443                 case SPECIAL_INTERNAL_UINTPTR:
444                         itype = &UIntPtrType;
445                         break;
446                 case SPECIAL_INTERNAL_OFF:
447                         itype = &OffType;
448                         break;
449                 case SPECIAL_INTERNAL_SIZE:
450                         itype = &SizeType;
451                         break;
452                 /* NOTE: There is no ssize_t in rune. size_t is signed */
453
454                 case SPECIAL_INTERNAL_POINTER:
455                         itype = &PointerType;
456                         break;
457                 case SPECIAL_INTERNAL_NUMERIC:
458                         itype = &NumericType;
459                         break;
460                 case SPECIAL_INTERNAL_INTEGRAL:
461                         itype = &IntegralType;
462                         break;
463                 case SPECIAL_INTERNAL_SINTEGER:
464                         itype = &SIntegerType;
465                         break;
466                 case SPECIAL_INTERNAL_UINTEGER:
467                         itype = &UIntegerType;
468                         break;
469                 default:
470                         itype = InternalRegisteredTypeLookup(d->d_Id);
471                         if (itype == NULL)
472                                 dassert(0);
473                         break;
474                 }
475         }
476         if (itype) {
477                 if (itype->ty_Op != TY_UNRESOLVED) {
478                         t = LexError(&p->p_Token, TOK_ERR_DUPLICATE_ATTACH);
479                 } else {
480                         Type *ntype = d->d_TypedefDecl.ed_Type;
481
482                         TypeToQualType(ntype, itype, ntype->ty_SQFlags, NULL);
483                 }
484         } else {
485                 t = LexError(&p->p_Token, TOK_ERR_UNRECOGNIZED_ATTACH);
486         }
487         return(t);
488 }
489
490 Type *
491 AllocType(typelist_t *list, int op)
492 {
493         Type *type = zalloc(sizeof(Type));
494
495         initType(type, list, op);
496         return(type);
497 }
498
499 /*
500  * XXX match the compound type(s)
501  *
502  * May be used to generate a varargs compound type, in which case the
503  * semgroup may already be resolved.
504  */
505 Type *
506 AllocCompoundType(SemGroup *sg)
507 {
508         Type *type;
509
510         type = AllocType(&CompoundTypeList, TY_COMPOUND);
511         type->ty_CompType.et_SemGroup = sg;
512         dassert((sg->sg_Flags & SGF_RESOLVED) == 0);
513         return(type);
514 }
515
516 /*
517  * XXX match the compound type(s)
518  */
519 Type *
520 AllocArgsType(SemGroup *sg)
521 {
522         Type *type;
523
524         type = AllocType(&ArgsTypeList, TY_ARGS);
525         type->ty_ArgsType.et_SemGroup = sg;
526         return(type);
527 }
528
529 Type *
530 AllocStorageType(runesize_t bytes)
531 {
532         Type *type;
533
534         RUNE_FOREACH(type, &StorageTypeList, ty_Node) {
535                 if (type->ty_Op == TY_STORAGE &&
536                         type->ty_StorType.et_Bytes == bytes
537                 ) {
538                         return(type);
539                 }
540         }
541         type = AllocType(&StorageTypeList, TY_STORAGE);
542         type->ty_StorType.et_Bytes = bytes;
543         return(type);
544 }
545
546 Type *
547 AllocUnresolvedType(SemGroup *isg, SemGroup *sg, string_t *ary, int eatAry)
548 {
549         Type *type = NULL;
550
551         dassert_semgrp(sg, ary != NULL);
552
553         RUNE_FOREACH(type, &sg->sg_ClassList, ty_Node) {
554                 int i;
555
556                 if (type->ty_Op != TY_UNRESOLVED)
557                         continue;
558                 if (type->ty_UnresType.et_ImportSemGroup != isg)
559                         continue;
560
561                 for (i = 0; ary[i]; ++i) {
562                         if (ary[i] != type->ty_UnresType.et_DottedId[i])
563                                 break;
564                 }
565                 if (ary[i] == NULL &&
566                     type->ty_UnresType.et_DottedId[i] == NULL) {
567                         if (eatAry)
568                                 FreeDotIdAry(ary);
569                         return(type);
570                 }
571         }
572         type = AllocType((sg ? &sg->sg_ClassList : NULL), TY_UNRESOLVED);
573         type->ty_UnresType.et_DottedId = ary;
574         type->ty_UnresType.et_SemGroup = sg;            /* may be NULL */
575         type->ty_UnresType.et_ImportSemGroup = isg;     /* may be NULL */
576         return(type);
577 }
578
579 /*
580  * AllocClassType() - allocate a type representing a the semgroup which
581  *                      in turn represents (typically) a class.
582  */
583 Type *
584 AllocClassType(typelist_t *list, Type *super, SemGroup *sg, int visibility)
585 {
586         Type *type;
587
588         dassert(sg != NULL);
589         list = &sg->sg_ClassList;
590
591         RUNE_FOREACH(type, list, ty_Node) {
592                 if (type->ty_Op == TY_CLASS &&
593                     type->ty_ClassType.et_SemGroup == sg &&
594                     type->ty_ClassType.et_Super == super &&
595                     type->ty_Visibility == visibility
596                 ) {
597                         return(type);
598                 }
599         }
600         if (sg)
601                 dassert(&sg->sg_ClassList == list);
602         type = AllocType(list, TY_CLASS);
603         type->ty_ClassType.et_SemGroup = sg;
604         type->ty_ClassType.et_Super = super;
605         type->ty_Visibility = visibility;
606         return(type);
607 }
608
609 static
610 void
611 initInternalClassType(Type *type, Declaration *d)
612 {
613         SemGroup *sg = d->d_ClassDecl.ed_SemGroup;
614
615         initType(type, &sg->sg_ClassList, TY_CLASS);
616         RUNE_REMOVE(&sg->sg_ClassList, type, ty_Node);
617         RUNE_INSERT_HEAD(&sg->sg_ClassList, type, ty_Node);
618         type->ty_ClassType.et_SemGroup = d->d_ClassDecl.ed_SemGroup;
619         type->ty_ClassType.et_Super = d->d_ClassDecl.ed_Super;
620         type->ty_Visibility = d->d_ScopeFlags & SCOPE_ALL_VISIBLE;
621         type->ty_Flags |= TF_ISINTERNAL;
622 }
623
624 Type *
625 AllocImportType(typelist_t *list, SemGroup *sg, int visibility)
626 {
627         Type *type = AllocType(list, TY_IMPORT);
628
629         type->ty_ImportType.et_SemGroup = sg;
630         type->ty_Visibility = visibility;
631         return(type);
632 }
633
634 /*
635  * adjtype must be moved to type's QList because type is being modified
636  * such that that is where it is expected to be.
637  */
638 Type *
639 TypeAdjustQList(Type *type, Type *adjtype)
640 {
641         if (adjtype) {
642                 if (adjtype->ty_SQList)
643                         RUNE_REMOVE(adjtype->ty_SQList, adjtype, ty_Node);
644                 adjtype->ty_SQList = &type->ty_QList;
645                 RUNE_INSERT_TAIL(adjtype->ty_SQList, adjtype, ty_Node);
646         }
647         return type;
648 }
649
650 Type *
651 TypeToQualType(Type *otype, Type *ntype, int sqFlags, Exp *exp)
652 {
653         SemGroup *sg;
654
655         /*
656          * Combine with existing qualifiers, Shortcut if no changes made.
657          */
658         if (ntype == NULL && 
659             sqFlags == otype->ty_SQFlags &&
660             (exp == NULL || exp == otype->ty_AssExp)
661         ) {
662                 return(otype);
663         }
664
665         /*
666          * See if we already have a matching qualified type (only if storage
667          * for the new type is not being provided).  Note: the provided storage
668          * has already been initType()d
669          */
670         if (ntype == NULL) {
671                 RUNE_FOREACH(ntype, otype->ty_SQList, ty_Node) {
672                         if (ntype->ty_Op == otype->ty_Op && 
673                             ntype->ty_SQFlags == sqFlags &&
674                             (exp == NULL || ntype->ty_AssExp == exp)
675                         ) {
676                                 if (SameType(ntype, otype, sqFlags))
677                                         return(ntype);
678                         }
679                 }
680         }
681
682         /*
683          * Build a new qualified type and set its qualifiers, then duplicate
684          * appropriate sections of the old type.
685          *
686          * Default to the same SQList as otype.
687          */
688         if (ntype == NULL) {
689                 ntype = AllocType(otype->ty_SQList, otype->ty_Op);
690         } else {
691                 if (ntype->ty_SQList)
692                         RUNE_REMOVE(ntype->ty_SQList, ntype, ty_Node);
693                 ntype->ty_SQList = otype->ty_SQList;
694                 RUNE_INSERT_TAIL(ntype->ty_SQList, ntype, ty_Node);
695         }
696
697         /*
698          * Set the op and the expression.  Unlike SQFlags, if exp is passed as
699          * NULL we inherit the old type's default.
700          *
701          * The DupExp() call here is special, see DupExp()'s handling of
702          * ex_Decl.
703          *
704          * Normally DupExp() is called during resolution prior to ex_Decl
705          * being set.  This is the one case where it may be called with
706          * ex_Decl already set.
707          *
708          * WARNING! We do not try to resolve the type here.  Various resolve
709          *          related flags in ty_Flags will be resolved later.  This
710          *          includes TF_ISUNSIGNED and other TF_* flags.
711          */
712         ntype->ty_Op = otype->ty_Op;
713         if (exp)
714                 ntype->ty_AssExp = exp;
715         else if (otype->ty_AssExp)
716                 ntype->ty_AssExp = SetDupExp(NULL, otype->ty_AssExp);
717         ntype->ty_SQFlags = sqFlags;
718         ntype->ty_Visibility = otype->ty_Visibility;
719
720         switch(otype->ty_Op) {
721         case TY_CLASS:
722                 /*
723                  * When updating the class, alternative forms are collapsed
724                  * into it's SemGroup->sg_ClassList and not into some
725                  * potentially long recursive chain based on ty_QList.
726                  */
727                 sg = otype->ty_ClassType.et_SemGroup;
728
729                 dassert(ntype->ty_SQList == &sg->sg_ClassList);
730                 if (ntype->ty_ClassType.et_SemGroup != sg) {
731                         ntype->ty_ClassType.et_SemGroup = sg;
732                 }
733                 ntype->ty_ClassType.et_Super = otype->ty_ClassType.et_Super;
734                 break;
735         case TY_IMPORT:
736                 ntype->ty_Visibility = otype->ty_Visibility;
737                 ntype->ty_ImportType.et_SemGroup = otype->ty_ImportType.et_SemGroup;
738                 break;
739         case TY_CPTRTO:
740                 ntype->ty_CPtrType.et_Type = otype->ty_CPtrType.et_Type;
741                 break;
742         case TY_PTRTO:
743                 ntype->ty_PtrType.et_Type = otype->ty_PtrType.et_Type;
744                 break;
745         case TY_REFTO:
746                 ntype->ty_RefType.et_Type = otype->ty_RefType.et_Type;
747                 break;
748         case TY_ARYOF:
749                 /*
750                  * note: multiple type structures may share the same array size
751                  * expression in simple qualified-type cases.  YYY XXX bad bad.
752                  */
753                 ntype->ty_AryType.et_Type = otype->ty_AryType.et_Type;
754                 ntype->ty_AryType.et_ArySize = otype->ty_AryType.et_ArySize;
755                 ntype->ty_AryType.et_SemGroup = otype->ty_AryType.et_SemGroup;
756                 break;
757         case TY_COMPOUND:
758                 ntype->ty_CompType.et_SemGroup = otype->ty_CompType.et_SemGroup;
759                 break;
760         case TY_VAR:
761                 ntype->ty_VarType.et_Type = otype->ty_VarType.et_Type;
762                 ntype->ty_VarType.et_SemGroup = otype->ty_VarType.et_SemGroup;
763                 break;
764         case TY_ARGS:
765                 ntype->ty_ArgsType.et_SemGroup = otype->ty_ArgsType.et_SemGroup;
766                 break;
767         case TY_PROC:
768                 ntype->ty_ProcType.et_ArgsType = otype->ty_ProcType.et_ArgsType;
769                 ntype->ty_ProcType.et_RetType = otype->ty_ProcType.et_RetType;
770                 ntype->ty_ProcType.et_ArgCount = otype->ty_ProcType.et_ArgCount;
771                 dassert(ntype->ty_SQList ==
772                         &otype->ty_ProcType.et_RetType->ty_QList);
773                 break;
774         case TY_STORAGE:
775                 ntype->ty_StorType.et_Bytes = otype->ty_StorType.et_Bytes;
776                 break;
777         case TY_DYNAMIC:
778                 /*
779                  * It is not legal to qualify a dynamic type other then to
780                  * add or remove SF_LVALUE.
781                  */
782                 dassert(0);
783                 break;
784         case TY_UNRESOLVED:
785                 ntype->ty_UnresType.et_DottedId =
786                         otype->ty_UnresType.et_DottedId;
787                 ntype->ty_UnresType.et_SemGroup =
788                         otype->ty_UnresType.et_SemGroup;
789                 break;
790         default:
791                 dassert_type(otype, 0);
792         }
793         return(ntype);
794 }
795
796 /*
797  * XXX match the procedure type(s)
798  */
799 Type *
800 TypeToProcType(Type *rtype, Type *atype)
801 {
802         Type *type;
803         runesize_t count = 0;
804         Declaration *d;
805         SemGroup *sg;
806
807         dassert_type(atype, atype->ty_Op == TY_ARGS);
808         sg = atype->ty_CompType.et_SemGroup;
809
810         RUNE_FOREACH(d, &sg->sg_DeclList, d_Node) {
811                 ++count;
812         }
813         RUNE_FOREACH(type, &rtype->ty_QList, ty_Node) {
814                 if (type->ty_Op == TY_PROC) {
815                         if (type->ty_ProcType.et_ArgsType == atype &&
816                             type->ty_ProcType.et_RetType == rtype &&
817                             type->ty_ProcType.et_ArgCount == count
818                         ) {
819                                 puts("SG1"); /* YYY */
820                                 return(type);
821                         }
822                 }
823         }
824         type = AllocType(&rtype->ty_QList, TY_PROC);
825         type->ty_ProcType.et_ArgsType = AllocArgsType(sg);
826         type->ty_ProcType.et_RetType = rtype;
827         type->ty_ProcType.et_ArgCount = count;
828         return(type);
829 }
830
831 /*
832  * Convert type to pointer-to-type
833  */
834 Type *
835 TypeToPtrType(Type *otype)
836 {
837         Type *type;
838
839         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
840                 if (type->ty_Op == TY_PTRTO)
841                         return(type);
842         }
843         type = AllocType(&otype->ty_QList, TY_PTRTO);
844         type->ty_PtrType.et_Type = otype;
845         return(type);
846 }
847
848 /*
849  * Convert type to pointer-to-type
850  */
851 Type *
852 TypeToCPtrType(Type *otype)
853 {
854         Type *type;
855
856         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
857                 if (type->ty_Op == TY_CPTRTO)
858                         return(type);
859         }
860         type = AllocType(&otype->ty_QList, TY_CPTRTO);
861         type->ty_CPtrType.et_Type = otype;
862         return(type);
863 }
864
865 /*
866  * Convert type to ref-to-type
867  *
868  *      A reference type is similar to a pointer type except that the
869  *      resolver is not able to entirely know what it is pointing to.
870  *      The reference type is a superclass, but the actual type is 
871  *      stored in the run-time structure.
872  */
873 Type *
874 TypeToRefType(Type *otype)
875 {
876         Type *type;
877
878         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
879                 if (type->ty_Op == TY_REFTO)
880                         return(type);
881         }
882         type = AllocType(&otype->ty_QList, TY_REFTO);
883         type->ty_RefType.et_Type = otype;
884         return(type);
885 }
886
887 Type *
888 TypeToAryType(Type *otype, Exp *exp, SemGroup *sg)
889 {
890         Type *type;
891
892         /*
893          * XXX handle constant expression optimization for QList
894          * XXX handle qualifiers
895          */
896         type = AllocType(&otype->ty_QList, TY_ARYOF);
897         type->ty_AryType.et_ArySize = exp;
898         type->ty_AryType.et_Type = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
899         type->ty_AryType.et_SemGroup = sg;
900         type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
901         return(type);
902 }
903
904 #if 0
905
906 Type *
907 TypeToRunTimeAryType(Type *otype, int count)
908 {
909         Type *type;
910         Type *t2 = DelTypeQual(otype, SF_MASK_ARY_INHERIT);
911
912         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
913                 if (type->ty_Op == TY_ARYOF &&
914                         type->ty_AryType.et_Type == t2 &&
915                         type->ty_AryType.et_Count == count &&
916                         type->ty_SQFlags ==
917                          (otype->ty_SQFlags & SF_MASK_ARY_INHERIT)
918                 ) {
919                         return(type);
920                 }
921         }
922         type = AllocType(&otype->ty_QList, TY_ARYOF);
923         type->ty_AryType.et_Count = count;
924         type->ty_AryType.et_Type = t2;
925         type->ty_SQFlags |= otype->ty_SQFlags & SF_MASK_ARY_INHERIT;
926         return(type);
927 }
928
929 #endif
930
931 Type *
932 TypeToVarType(Type *otype, SemGroup *sg)
933 {
934         Type *type;
935
936         dassert(sg->sg_Flags & SGF_RESOLVED);
937         dassert(otype->ty_Flags & TF_RESOLVED);
938
939         RUNE_FOREACH(type, &otype->ty_QList, ty_Node) {
940                 if (type->ty_Op == TY_VAR &&
941                     type->ty_VarType.et_Type == otype &&
942                     type->ty_VarType.et_SemGroup == sg
943                 ) {
944                         puts("SG2"); /* YYY */
945                         return(type);
946                 }
947         }
948         type = AllocType(&otype->ty_QList, TY_VAR);
949         type->ty_VarType.et_Type = otype;
950         type->ty_VarType.et_SemGroup = sg;
951 #if 0
952         /* XXX doesn't work for var-args */
953         if (sg->sg_Flags & SGF_RESOLVED) {
954                 type->ty_Flags |= TF_RESOLVED;
955                 type->ty_Bytes = sg->sg_Bytes;
956                 type->ty_AlignMask = sg->sg_AlignMask;
957         }
958 #endif
959         return(type);
960 }
961
962 /*
963  * ChangeType() - given pointer, C pointer, or array of something,
964  *                return 'op' of something instead.
965  */
966 Type *
967 ChangeType(Type *type, int op)
968 {
969         switch(type->ty_Op) {
970         case TY_PTRTO:
971                 switch(op) {
972                 case TY_CPTRTO:
973                         type = TypeToCPtrType(type->ty_PtrType.et_Type);
974                         break;
975                 case TY_ARYOF:
976                         type = TypeToAryType(type->ty_PtrType.et_Type,
977                                              NULL, NULL);
978                         break;
979                 default:
980                         dassert(0);
981                 }
982                 break;
983         case TY_CPTRTO:
984                 switch(op) {
985                 case TY_PTRTO:
986                         type = TypeToPtrType(type->ty_CPtrType.et_Type);
987                         break;
988                 case TY_ARYOF:
989                         type = TypeToAryType(type->ty_CPtrType.et_Type,
990                                              NULL, NULL);
991                         break;
992                 default:
993                         dassert(0);
994                 }
995                 break;
996         case TY_ARYOF:
997                 switch(op) {
998                 case TY_PTRTO:
999                         type = TypeToPtrType(type->ty_AryType.et_Type);
1000                         break;
1001                 case TY_CPTRTO:
1002                         type = TypeToCPtrType(type->ty_AryType.et_Type);
1003                         break;
1004                 default:
1005                         dassert(0);
1006                 }
1007                 break;
1008         default:
1009                 dassert(0);
1010         }
1011         return(type);
1012 }
1013
1014 /*
1015  * BaseType() - return base type
1016  *
1017  *      Traverse the type to locate the base type.  Store the base type
1018  *      in *ptype and return the SemGroup, or return NULL if the base type
1019  *      does not have a SemGroup.
1020  */
1021 SemGroup *
1022 BaseType(Type **ptype)
1023 {
1024         Type *type = *ptype;
1025
1026         for (;;) {
1027                 switch(type->ty_Op) {
1028                 case TY_CPTRTO:
1029                         type = type->ty_CPtrType.et_Type;
1030                         continue;
1031                 case TY_PTRTO:
1032                         type = type->ty_PtrType.et_Type;
1033                         continue;
1034                 case TY_REFTO:
1035                         type = type->ty_RefType.et_Type;
1036                         continue;
1037                 case TY_ARYOF:
1038                         type = type->ty_AryType.et_Type;
1039                         continue;
1040                 }
1041                 break;
1042         }
1043
1044         *ptype = type;
1045
1046         switch(type->ty_Op) {
1047         case TY_CLASS:
1048                 return(type->ty_ClassType.et_SemGroup);
1049         case TY_COMPOUND:
1050                 return(type->ty_CompType.et_SemGroup);
1051         case TY_ARGS:
1052                 return(type->ty_ArgsType.et_SemGroup);
1053         case TY_PROC:
1054         case TY_VAR:
1055         case TY_DYNAMIC:
1056         case TY_STORAGE:
1057                 return(NULL);
1058         case TY_UNRESOLVED:
1059         default:
1060                 dassert_type(type, 0);
1061                 return(NULL);   /* avoid compiler complaints */
1062         }
1063 }
1064
1065 /*
1066  * DupType()     - create a duplicate of a type, possibly in a new SemGroup.
1067  *
1068  *      This code is used when duplicating procedures and other elements
1069  *      when merging a superclass into a subclass.
1070  *
1071  *      If sg is NULL, stype is simply returned.  The case is used when we
1072  *      try to duplciate an expression with DupExp()... in that case we
1073  *      want to dup the expression tree but use the same types.
1074  */
1075 Type *
1076 DupType(SemGroup *sg, Type *stype)
1077 {
1078         Type *type = NULL;
1079
1080         if (sg == NULL)
1081                 return(stype);
1082
1083         /*
1084          * XXX type may be resolved if it is part of a varargs dup
1085          */
1086 #if 0
1087         dassert_type(stype,
1088                      (stype->ty_Flags & (TF_RESOLVED|TF_RESOLVING)) == 0);
1089 #endif
1090
1091         switch(stype->ty_Op) {
1092         case TY_CLASS:
1093                 /*
1094                  * This only occurs because the resolver has resolved an
1095                  * unresolved type on the original SemGroup.  We duplicate
1096                  * that on the new SemGroup.
1097                  */
1098                 type = AllocClassType(&sg->sg_ClassList,
1099                                       stype->ty_ClassType.et_Super,
1100                                       stype->ty_ClassType.et_SemGroup,
1101                                       stype->ty_Visibility);
1102                 break;
1103         case TY_IMPORT:
1104         case TY_DYNAMIC:
1105                 type = stype;
1106                 break;
1107         case TY_CPTRTO:
1108                 type = TypeToCPtrType(DupType(sg, stype->ty_CPtrType.et_Type));
1109                 break;
1110         case TY_PTRTO:
1111                 type = TypeToPtrType(DupType(sg, stype->ty_PtrType.et_Type));
1112                 break;
1113         case TY_REFTO:
1114                 type = TypeToRefType(DupType(sg, stype->ty_RefType.et_Type));
1115                 break;
1116         case TY_ARYOF:
1117                 type = TypeToAryType(DupType(sg, stype->ty_AryType.et_Type),
1118                                 SetDupExp(sg, stype->ty_AryType.et_ArySize),
1119                                 stype->ty_AryType.et_SemGroup);
1120                 break;
1121         case TY_VAR:
1122                 type = TypeToVarType(DupType(sg, stype->ty_VarType.et_Type),
1123                                 DupSemGroup(sg, NULL,
1124                                             stype->ty_VarType.et_SemGroup, 1));
1125                 break;
1126         case TY_COMPOUND:
1127                 type = AllocCompoundType(
1128                                 DupSemGroup(sg, NULL,
1129                                             stype->ty_CompType.et_SemGroup, 1));
1130                 break;
1131         case TY_ARGS:
1132                 /*
1133                  * At the moment we always formally duplicate the arguments
1134                  * so we can modify them for methods below.
1135                  */
1136                 type = AllocArgsType(
1137                                 DupSemGroup(sg, NULL,
1138                                             stype->ty_CompType.et_SemGroup, 1));
1139                 break;
1140         case TY_PROC:
1141                 type = DupType(sg, stype->ty_ProcType.et_RetType);
1142                 type = TypeToProcType(type,
1143                                       DupType(sg,
1144                                               stype->ty_ProcType.et_ArgsType));
1145
1146                 /*
1147                  * If this is a method procedure, we have to change the
1148                  * first argument to point at our new subclass.  It was
1149                  * previously pointing at our superclass.   XXX the
1150                  * programmer can override the argument.  If it isn't a
1151                  * reference we have to assert.
1152                  */
1153                 if (stype->ty_SQFlags & SF_METHOD) {
1154                         SemGroup *asg = type->ty_ProcType.et_ArgsType->ty_ArgsType.et_SemGroup;
1155                         Declaration *d = RUNE_FIRST(&asg->sg_DeclList);
1156                         Type *thisType = d->d_StorDecl.ed_Type;
1157
1158                         dassert_decl(d, d->d_Id == String_This &&
1159                                         d->d_Op == DOP_ARGS_STORAGE);
1160                         dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1161                         if (thisType->ty_Op == TY_CLASS) {
1162                                 /* XXX sg_ClassList? right sg? */
1163                                 /* XXX correct visibility? */
1164                                 if (d->d_Search == NULL) {
1165                                         d->d_Search = d->d_StorDecl.ed_Type->
1166                                                       ty_ClassType.et_SemGroup;
1167                                 }
1168                                 d->d_StorDecl.ed_Type =
1169                                         AllocClassType(&sg->sg_ClassList,
1170                                                        sg->sg_Stmt->st_ClassStmt.es_Super,
1171                                                        sg->sg_Stmt->st_MyGroup,
1172                                                        SCOPE_ALL_VISIBLE);
1173                         } else {
1174                                 dassert_decl(d, thisType->ty_Op == TY_REFTO);
1175                         }
1176                 } else if (stype->ty_SQFlags & SF_GMETHOD) {
1177                         SemGroup *asg;
1178                         Declaration *d;
1179
1180                         asg = type->ty_ProcType.et_ArgsType->
1181                                 ty_ArgsType.et_SemGroup;
1182                         d = RUNE_FIRST(&asg->sg_DeclList);
1183
1184                         dassert_decl(d, d->d_Id == String_This &&
1185                                      d->d_Op == DOP_TYPEDEF);
1186                         dassert_decl(d, sg->sg_Stmt->st_Op == ST_Class);
1187                         dassert_decl(d, d->d_TypedefDecl.ed_Type->ty_Op ==
1188                                         TY_CLASS);
1189                         /* XXX sg_ClassList? right sg? */
1190                         /* XXX correct visibility? */
1191                         if (d->d_Search == NULL) {
1192                                 d->d_Search = d->d_TypedefDecl.ed_Type->
1193                                                ty_ClassType.et_SemGroup;
1194                         }
1195                         d->d_TypedefDecl.ed_Type =
1196                                 AllocClassType(&sg->sg_ClassList,
1197                                                sg->sg_Stmt->st_ClassStmt.es_Super,
1198                                                sg->sg_Stmt->st_MyGroup,
1199                                                SCOPE_ALL_VISIBLE);
1200                 }
1201                 break;
1202         case TY_STORAGE:
1203                 type = stype;
1204                 break;
1205         case TY_UNRESOLVED:
1206                 /*
1207                  * e.g. so elements in a superclass will see refined elements
1208                  * in the subclass.  Note that the original import semgroup
1209                  * is left intact so the semantic search mechanism uses it
1210                  * when the base sg (typically a subclass) fails.
1211                  */
1212                 type = AllocUnresolvedType(
1213                                 stype->ty_UnresType.et_ImportSemGroup,
1214                                 sg,
1215                                 stype->ty_UnresType.et_DottedId,
1216                                 0);
1217                 break;
1218         default:
1219                 dassert_type(stype, 0);
1220         }
1221
1222         if (type != stype) {
1223                 type->ty_Flags = stype->ty_Flags & ~TF_ISINTERNAL;
1224                 type->ty_Bytes = stype->ty_Bytes;
1225                 type->ty_AlignMask = stype->ty_AlignMask;
1226                 type->ty_Visibility = stype->ty_Visibility;
1227         }
1228         if (stype->ty_AssExp || stype->ty_SQFlags != type->ty_SQFlags) {
1229                 type = TypeToQualType(type, NULL,
1230                                       stype->ty_SQFlags,
1231                                       SetDupExp(sg, stype->ty_AssExp));
1232         }
1233
1234         return(type);
1235 }
1236
1237 struct TypeRegNode;
1238 typedef RUNE_HEAD(typereglist, TypeRegNode) typereglist_t;
1239
1240 typedef struct TypeRegNode {
1241         RUNE_ENTRY(TypeRegNode) tr_Node;
1242         string_t        tr_Id;
1243         Type            *tr_Type;
1244 } TypeRegNode;
1245
1246 typereglist_t TypeRegList = RUNE_HEAD_INITIALIZER(TypeRegList);
1247
1248 void
1249 InternalRegisterType(const char *str, Type *type)
1250 {
1251         static int Special = SPECIALF_REGISTERED|SPECIALF_INTERNAL|1;
1252         TypeRegNode *tr;
1253
1254         dassert(Special & SPECIALF_MASK);
1255         tr = zalloc(sizeof(TypeRegNode));
1256         tr->tr_Id = StrTableAlloc(str, strlen(str), Special++);
1257         tr->tr_Type = type;
1258         RUNE_INSERT_TAIL(&TypeRegList, tr, tr_Node);
1259 }
1260
1261 Type *
1262 InternalRegisteredTypeLookup(string_t id)
1263 {
1264         TypeRegNode *tr;
1265
1266         RUNE_FOREACH(tr, &TypeRegList, tr_Node) {
1267                 if (tr->tr_Id == id)
1268                         return(tr->tr_Type);
1269         }
1270         return(NULL);
1271 }