1 /**
2  * Compiler implementation of the
3  * $(LINK2 https://www.dlang.org, D programming language).
4  *
5  * Copyright:   Copyright (C) 1985-1998 by Symantec
6  *              Copyright (C) 2000-2023 by The D Language Foundation, All Rights Reserved
7  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
8  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
9  * Source:      https://github.com/dlang/dmd/blob/master/src/dmd/backend/dtype.d
10  */
11 
12 module dmd.backend.dtype;
13 
14 import core.stdc.stdio;
15 import core.stdc.stdlib;
16 import core.stdc.string;
17 
18 import dmd.backend.cdef;
19 import dmd.backend.cc;
20 import dmd.backend.dlist;
21 import dmd.backend.el;
22 import dmd.backend.global;
23 import dmd.backend.mem;
24 import dmd.backend.oper;
25 import dmd.backend.ty;
26 import dmd.backend.type;
27 
28 
29 nothrow:
30 @safe:
31 
32 @trusted
33 struct_t* struct_calloc() { return cast(struct_t*) mem_calloc(struct_t.sizeof); }
34 
35 private __gshared
36 {
37     type *type_list;          // free list of types
38     param_t *param_list;      // free list of params
39 
40     int type_num,type_max;   /* gather statistics on # of types      */
41 }
42 
43 __gshared
44 {
45     type*[TYMAX] tstypes;
46     type*[TYMAX] tsptr2types;
47 
48     type* tstrace,tsclib,tsjlib,tsdlib,
49             tslogical;
50     type* tspvoid,tspcvoid;
51     type* tsptrdiff, tssize;
52 }
53 
54 /***********************
55  * Compute size of type in bytes.
56  * Params:
57  *      t = type
58  * Returns:
59  *      size
60  */
61 @trusted @nogc
62 targ_size_t type_size(const type *t)
63 {   targ_size_t s;
64     tym_t tyb;
65 
66     type_debug(t);
67     tyb = tybasic(t.Tty);
68 
69     debug if (tyb >= TYMAX)
70         /*type_print(t),*/
71         printf("tyb = x%x\n", tyb);
72 
73     assert(tyb < TYMAX);
74     s = _tysize[tyb];
75     if (s == cast(targ_size_t) -1)
76     {
77         switch (tyb)
78         {
79             // in case program plays games with function pointers
80             case TYffunc:
81             case TYfpfunc:
82             case TYfsfunc:
83             case TYf16func:
84             case TYhfunc:
85             case TYnfunc:       /* in case program plays games with function pointers */
86             case TYnpfunc:
87             case TYnsfunc:
88             case TYifunc:
89             case TYjfunc:
90                 s = 1;
91                 break;
92             case TYarray:
93             {
94                 if (t.Tflags & TFsizeunknown)
95                 {
96                 }
97                 if (t.Tflags & TFvla)
98                 {
99                     s = _tysize[pointertype];
100                     break;
101                 }
102                 s = type_size(t.Tnext);
103                 uint u = cast(uint)t.Tdim * cast(uint) s;
104                 if (t.Tdim && ((u / t.Tdim) != s || cast(int)u < 0))
105                     assert(0);          // overflow should have been detected in front end
106                 s = u;
107                 break;
108             }
109             case TYstruct:
110             {
111                 auto ts = t.Ttag.Stype;     // find main instance
112                                             // (for const struct X)
113                 assert(ts.Ttag);
114                 s = ts.Ttag.Sstruct.Sstructsize;
115                 break;
116             }
117             case TYvoid:
118                 s = 1;
119                 break;
120 
121             case TYref:
122                 s = tysize(TYnptr);
123                 break;
124 
125             default:
126                 debug printf("%s\n", tym_str(t.Tty));
127                 assert(0);
128         }
129     }
130     return s;
131 }
132 
133 /********************************
134  * Return the size of a type for alignment purposes.
135  */
136 
137 @trusted
138 uint type_alignsize(type *t)
139 {   targ_size_t sz;
140 
141 L1:
142     type_debug(t);
143 
144     sz = tyalignsize(t.Tty);
145     if (sz == cast(targ_size_t)-1)
146     {
147         switch (tybasic(t.Tty))
148         {
149             case TYarray:
150                 if (t.Tflags & TFsizeunknown)
151                     goto err1;
152                 t = t.Tnext;
153                 goto L1;
154             case TYstruct:
155                 t = t.Ttag.Stype;         // find main instance
156                                             // (for const struct X)
157                 if (t.Tflags & TFsizeunknown)
158                     goto err1;
159                 sz = t.Ttag.Sstruct.Salignsize;
160                 if (sz > t.Ttag.Sstruct.Sstructalign + 1)
161                     sz = t.Ttag.Sstruct.Sstructalign + 1;
162                 break;
163 
164             case TYldouble:
165                 assert(0);
166 
167             case TYcdouble:
168                 sz = 8;         // not 16
169                 break;
170 
171             default:
172             err1:                   // let type_size() handle error messages
173                 sz = type_size(t);
174                 break;
175         }
176     }
177 
178     //printf("type_alignsize() = %d\n", sz);
179     return cast(uint)sz;
180 }
181 
182 /***********************************
183  * Compute special zero sized struct.
184  * Params:
185  *      t = type of parameter
186  *      tyf = function type
187  * Returns:
188  *      true if it is
189  */
190 @trusted
191 bool type_zeroSize(type *t, tym_t tyf)
192 {
193     if (tyf != TYjfunc && config.exe & (EX_FREEBSD | EX_OPENBSD | EX_OSX))
194     {
195         /* Use clang convention for 0 size structs
196          */
197         if (t && tybasic(t.Tty) == TYstruct)
198         {
199             type *ts = t.Ttag.Stype;     // find main instance
200                                            // (for const struct X)
201             if (ts.Tflags & TFsizeunknown)
202             {
203             }
204             if (ts.Ttag.Sstruct.Sflags & STR0size)
205 //{ printf("0size\n"); type_print(t); *(char*)0=0;
206                 return true;
207 //}
208         }
209     }
210     return false;
211 }
212 
213 /*********************************
214  * Compute the size of a single parameter.
215  * Params:
216  *      t = type of parameter
217  *      tyf = function type
218  * Returns:
219  *      size in bytes
220  */
221 uint type_parameterSize(type *t, tym_t tyf)
222 {
223     if (type_zeroSize(t, tyf))
224         return 0;
225     return cast(uint)type_size(t);
226 }
227 
228 /*****************************
229  * Compute the total size of parameters for function call.
230  * Used for stdcall name mangling.
231  * Note that hidden parameters do not contribute to size.
232  * Params:
233  *   t = function type
234  * Returns:
235  *   total stack usage in bytes
236  */
237 
238 @trusted
239 uint type_paramsize(type *t)
240 {
241     targ_size_t sz = 0;
242     if (tyfunc(t.Tty))
243     {
244         for (param_t *p = t.Tparamtypes; p; p = p.Pnext)
245         {
246             const size_t n = type_parameterSize(p.Ptype, tybasic(t.Tty));
247             sz += _align(REGSIZE,n);       // align to REGSIZE boundary
248         }
249     }
250     return cast(uint)sz;
251 }
252 
253 /*****************************
254  * Create a type & initialize it.
255  * Input:
256  *      ty = TYxxxx
257  * Returns:
258  *      pointer to newly created type.
259  */
260 
261 @trusted @nogc
262 type *type_alloc(tym_t ty)
263 {   type *t;
264 
265     assert(tybasic(ty) != TYtemplate);
266     if (type_list)
267     {   t = type_list;
268         type_list = t.Tnext;
269     }
270     else
271         t = cast(type *) mem_fmalloc(type.sizeof);
272     *t = type();
273     t.Tty = ty;
274 version (SRCPOS_4TYPES)
275 {
276     if (PARSER && config.fulltypes)
277         t.Tsrcpos = getlinnum();
278 }
279 debug
280 {
281     t.id = type.IDtype;
282     type_num++;
283     if (type_num > type_max)
284         type_max = type_num;
285 }
286     //printf("type_alloc() = %p %s\n", t, tym_str(t.Tty));
287     //if (t == (type*)0xB6B744) *(char*)0=0;
288     return t;
289 }
290 
291 /*****************************
292  * Fake a type & initialize it.
293  * Input:
294  *      ty = TYxxxx
295  * Returns:
296  *      pointer to newly created type.
297  */
298 @nogc
299 type *type_fake(tym_t ty)
300 {   type *t;
301 
302     assert(ty != TYstruct);
303 
304     t = type_alloc(ty);
305     if (typtr(ty) || tyfunc(ty))
306     {   t.Tnext = type_alloc(TYvoid);  /* fake with pointer to void    */
307         t.Tnext.Tcount = 1;
308     }
309     return t;
310 }
311 
312 /*****************************
313  * Allocate a type of ty with a Tnext of tn.
314  */
315 
316 type *type_allocn(tym_t ty,type *tn)
317 {   type *t;
318 
319     //printf("type_allocn(ty = x%x, tn = %p)\n", ty, tn);
320     assert(tn);
321     type_debug(tn);
322     t = type_alloc(ty);
323     t.Tnext = tn;
324     tn.Tcount++;
325     //printf("\tt = %p\n", t);
326     return t;
327 }
328 
329 /********************************
330  * Allocate a pointer type.
331  * Returns:
332  *      Tcount already incremented
333  */
334 
335 type *type_pointer(type *tnext)
336 {
337     type *t = type_allocn(TYnptr, tnext);
338     t.Tcount++;
339     return t;
340 }
341 
342 /********************************
343  * Allocate a dynamic array type.
344  * Returns:
345  *      Tcount already incremented
346  */
347 @trusted
348 type *type_dyn_array(type *tnext)
349 {
350     type *t = type_allocn(TYdarray, tnext);
351     t.Tcount++;
352     return t;
353 }
354 
355 /********************************
356  * Allocate a static array type.
357  * Returns:
358  *      Tcount already incremented
359  */
360 
361 extern (C) type *type_static_array(targ_size_t dim, type *tnext)
362 {
363     type *t = type_allocn(TYarray, tnext);
364     t.Tdim = dim;
365     t.Tcount++;
366     return t;
367 }
368 
369 /********************************
370  * Allocate an associative array type,
371  * which are key=value pairs
372  * Returns:
373  *      Tcount already incremented
374  */
375 
376 @trusted
377 type *type_assoc_array(type *tkey, type *tvalue)
378 {
379     type *t = type_allocn(TYaarray, tvalue);
380     t.Tkey = tkey;
381     tkey.Tcount++;
382     t.Tcount++;
383     return t;
384 }
385 
386 /********************************
387  * Allocate a delegate type.
388  * Returns:
389  *      Tcount already incremented
390  */
391 
392 @trusted
393 type *type_delegate(type *tnext)
394 {
395     type *t = type_allocn(TYdelegate, tnext);
396     t.Tcount++;
397     return t;
398 }
399 
400 /***********************************
401  * Allocation a function type.
402  * Params:
403  *      tyf      = function type
404  *      ptypes   = types of the function parameters
405  *      variadic = if ... function
406  *      tret     = return type
407  * Returns:
408  *      Tcount already incremented
409  */
410 @trusted
411 extern (C)
412 type *type_function(tym_t tyf, type*[] ptypes, bool variadic, type *tret)
413 {
414     param_t *paramtypes = null;
415     foreach (p; ptypes)
416     {
417         param_append_type(&paramtypes, p);
418     }
419     type *t = type_allocn(tyf, tret);
420     t.Tflags |= TFprototype;
421     if (!variadic)
422         t.Tflags |= TFfixed;
423     t.Tparamtypes = paramtypes;
424     t.Tcount++;
425     return t;
426 }
427 
428 /***************************************
429  * Create an enum type.
430  * Input:
431  *      name    name of enum
432  *      tbase   "base" type of enum
433  * Returns:
434  *      Tcount already incremented
435  */
436 @trusted
437 type *type_enum(const(char)* name, type *tbase)
438 {
439     Symbol *s = symbol_calloc(name[0 .. strlen(name)]);
440     s.Sclass = SC.enum_;
441     s.Senum = cast(enum_t *) mem_calloc(enum_t.sizeof);
442     s.Senum.SEflags |= SENforward;        // forward reference
443 
444     type *t = type_allocn(TYenum, tbase);
445     t.Ttag = cast(Classsym *)s;            // enum tag name
446     t.Tcount++;
447     s.Stype = t;
448     t.Tcount++;
449     return t;
450 }
451 
452 /**************************************
453  * Create a struct/union/class type.
454  * Params:
455  *      name = name of struct (this function makes its own copy of the string)
456  *      is0size = if struct has no fields (even if Sstructsize is 1)
457  * Returns:
458  *      Tcount already incremented
459  */
460 @trusted
461 type *type_struct_class(const(char)* name, uint alignsize, uint structsize,
462         type *arg1type, type *arg2type, bool isUnion, bool isClass, bool isPOD, bool is0size)
463 {
464     static if (0)
465     {
466         printf("type_struct_class(%s, %p, %p)\n", name, arg1type, arg2type);
467         if (arg1type)
468         {
469             printf("arg1type:\n");
470             type_print(arg1type);
471         }
472         if (arg2type)
473         {
474             printf("arg2type:\n");
475             type_print(arg2type);
476         }
477     }
478     Symbol *s = symbol_calloc(name[0 .. strlen(name)]);
479     s.Sclass = SC.struct_;
480     s.Sstruct = struct_calloc();
481     s.Sstruct.Salignsize = alignsize;
482     s.Sstruct.Sstructalign = cast(ubyte)alignsize;
483     s.Sstruct.Sstructsize = structsize;
484     s.Sstruct.Sarg1type = arg1type;
485     s.Sstruct.Sarg2type = arg2type;
486 
487     if (!isPOD)
488         s.Sstruct.Sflags |= STRnotpod;
489     if (isUnion)
490         s.Sstruct.Sflags |= STRunion;
491     if (isClass)
492     {   s.Sstruct.Sflags |= STRclass;
493         assert(!isUnion && isPOD);
494     }
495     if (is0size)
496         s.Sstruct.Sflags |= STR0size;
497 
498     type *t = type_alloc(TYstruct);
499     t.Ttag = cast(Classsym *)s;            // structure tag name
500     t.Tcount++;
501     s.Stype = t;
502     t.Tcount++;
503     return t;
504 }
505 
506 /*****************************
507  * Free up data type.
508  */
509 
510 @trusted
511 void type_free(type *t)
512 {   type *tn;
513     tym_t ty;
514 
515     while (t)
516     {
517         //printf("type_free(%p, Tcount = %d)\n", t, t.Tcount);
518         type_debug(t);
519         assert(cast(int)t.Tcount != -1);
520         if (--t.Tcount)                /* if usage count doesn't go to 0 */
521             break;
522         ty = tybasic(t.Tty);
523         if (tyfunc(ty))
524         {   param_free(&t.Tparamtypes);
525             list_free(&t.Texcspec, cast(list_free_fp)&type_free);
526             goto L1;
527         }
528         if (t.Tflags & TFvla && t.Tel)
529         {
530             el_free(t.Tel);
531             goto L1;
532         }
533         if (t.Tkey && typtr(ty))
534             type_free(t.Tkey);
535       L1:
536 
537 debug
538 {
539         type_num--;
540         //printf("Free'ing type %p %s\n", t, tym_str(t.Tty));
541         t.id = 0;                      /* no longer a valid type       */
542 }
543 
544         tn = t.Tnext;
545         t.Tnext = type_list;
546         type_list = t;                  /* link into free list          */
547         t = tn;
548     }
549 }
550 
551 version (STATS)
552 {
553 /* count number of free types available on type list */
554 void type_count_free()
555     {
556     type *t;
557     int count;
558 
559     for(t=type_list;t;t=t.Tnext)
560         count++;
561     printf("types on free list %d with max of %d\n",count,type_max);
562     }
563 }
564 
565 /**********************************
566  * Initialize type package.
567  */
568 
569 private type * type_allocbasic(tym_t ty)
570 {   type *t;
571 
572     t = type_alloc(ty);
573     t.Tmangle = mTYman_c;
574     t.Tcount = 1;              /* so it is not inadvertently free'd    */
575     return t;
576 }
577 
578 @trusted
579 void type_init()
580 {
581     tstypes[TYbool]    = type_allocbasic(TYbool);
582     tstypes[TYwchar_t] = type_allocbasic(TYwchar_t);
583     tstypes[TYdchar]   = type_allocbasic(TYdchar);
584     tstypes[TYvoid]    = type_allocbasic(TYvoid);
585     tstypes[TYnullptr] = type_allocbasic(TYnullptr);
586     tstypes[TYchar16]  = type_allocbasic(TYchar16);
587     tstypes[TYuchar]   = type_allocbasic(TYuchar);
588     tstypes[TYschar]   = type_allocbasic(TYschar);
589     tstypes[TYchar]    = type_allocbasic(TYchar);
590     tstypes[TYshort]   = type_allocbasic(TYshort);
591     tstypes[TYushort]  = type_allocbasic(TYushort);
592     tstypes[TYint]     = type_allocbasic(TYint);
593     tstypes[TYuint]    = type_allocbasic(TYuint);
594     tstypes[TYlong]    = type_allocbasic(TYlong);
595     tstypes[TYulong]   = type_allocbasic(TYulong);
596     tstypes[TYllong]   = type_allocbasic(TYllong);
597     tstypes[TYullong]  = type_allocbasic(TYullong);
598     tstypes[TYfloat]   = type_allocbasic(TYfloat);
599     tstypes[TYdouble]  = type_allocbasic(TYdouble);
600     tstypes[TYdouble_alias]  = type_allocbasic(TYdouble_alias);
601     tstypes[TYldouble] = type_allocbasic(TYldouble);
602     tstypes[TYifloat]  = type_allocbasic(TYifloat);
603     tstypes[TYidouble] = type_allocbasic(TYidouble);
604     tstypes[TYildouble] = type_allocbasic(TYildouble);
605     tstypes[TYcfloat]   = type_allocbasic(TYcfloat);
606     tstypes[TYcdouble]  = type_allocbasic(TYcdouble);
607     tstypes[TYcldouble] = type_allocbasic(TYcldouble);
608 
609     if (I64)
610     {
611         TYptrdiff = TYllong;
612         TYsize = TYullong;
613         tsptrdiff = tstypes[TYllong];
614         tssize = tstypes[TYullong];
615     }
616     else
617     {
618         TYptrdiff = TYint;
619         TYsize = TYuint;
620         tsptrdiff = tstypes[TYint];
621         tssize = tstypes[TYuint];
622     }
623 
624     // Type of trace function
625     tstrace = type_fake(I16 ? TYffunc : TYnfunc);
626     tstrace.Tmangle = mTYman_c;
627     tstrace.Tcount++;
628 
629     chartype = (config.flags3 & CFG3ju) ? tstypes[TYuchar] : tstypes[TYchar];
630 
631     // Type of far library function
632     tsclib = type_fake(LARGECODE ? TYfpfunc : TYnpfunc);
633     tsclib.Tmangle = mTYman_c;
634     tsclib.Tcount++;
635 
636     tspvoid = type_allocn(pointertype,tstypes[TYvoid]);
637     tspvoid.Tmangle = mTYman_c;
638     tspvoid.Tcount++;
639 
640     // Type of far library function
641     tsjlib =    type_fake(TYjfunc);
642     tsjlib.Tmangle = mTYman_c;
643     tsjlib.Tcount++;
644 
645     tsdlib = tsjlib;
646 
647     // Type of logical expression
648     tslogical = (config.flags4 & CFG4bool) ? tstypes[TYbool] : tstypes[TYint];
649 
650     for (int i = 0; i < TYMAX; i++)
651     {
652         if (tstypes[i])
653         {   tsptr2types[i] = type_allocn(pointertype,tstypes[i]);
654             tsptr2types[i].Tcount++;
655         }
656     }
657 }
658 
659 /**********************************
660  * Free type_list.
661  */
662 
663 void type_term()
664 {
665 static if (TERMCODE)
666 {
667     type *tn;
668     param_t *pn;
669     int i;
670 
671     for (i = 0; i < tstypes.length; i++)
672     {   type *t = tsptr2types[i];
673 
674         if (t)
675         {   assert(!(t.Tty & (mTYconst | mTYvolatile | mTYimmutable | mTYshared)));
676             assert(!(t.Tflags));
677             assert(!(t.Tmangle));
678             type_free(t);
679         }
680         type_free(tstypes[i]);
681     }
682 
683     type_free(tsclib);
684     type_free(tspvoid);
685     type_free(tspcvoid);
686     type_free(tsjlib);
687     type_free(tstrace);
688 
689     while (type_list)
690     {   tn = type_list.Tnext;
691         mem_ffree(type_list);
692         type_list = tn;
693     }
694 
695     while (param_list)
696     {   pn = param_list.Pnext;
697         mem_ffree(param_list);
698         param_list = pn;
699     }
700 
701 debug
702 {
703     printf("Max # of types = %d\n",type_max);
704     if (type_num != 0)
705         printf("type_num = %d\n",type_num);
706 /*    assert(type_num == 0);*/
707 }
708 
709 }
710 }
711 
712 /*******************************
713  * Type type information.
714  */
715 
716 /**************************
717  * Make copy of a type.
718  */
719 
720 @trusted
721 type *type_copy(type *t)
722 {   type *tn;
723     param_t *p;
724 
725     type_debug(t);
726     tn = type_alloc(t.Tty);
727 
728     *tn = *t;
729     switch (tybasic(tn.Tty))
730     {
731             case TYarray:
732                 if (tn.Tflags & TFvla)
733                     tn.Tel = el_copytree(tn.Tel);
734                 break;
735 
736             default:
737                 if (tyfunc(tn.Tty))
738                 {
739                     tn.Tparamtypes = null;
740                     for (p = t.Tparamtypes; p; p = p.Pnext)
741                     {   param_t *pn;
742 
743                         pn = param_append_type(&tn.Tparamtypes,p.Ptype);
744                         if (p.Pident)
745                         {
746                             pn.Pident = cast(char *)mem_strdup(p.Pident);
747                         }
748                         assert(!p.Pelem);
749                     }
750                 }
751                 else
752                 {
753                 if (tn.Tkey && typtr(tn.Tty))
754                     tn.Tkey.Tcount++;
755                 }
756                 break;
757     }
758     if (tn.Tnext)
759     {   type_debug(tn.Tnext);
760         tn.Tnext.Tcount++;
761     }
762     tn.Tcount = 0;
763     return tn;
764 }
765 
766 /****************************
767  * Modify the tym_t field of a type.
768  */
769 
770 type *type_setty(type **pt,uint newty)
771 {   type *t;
772 
773     t = *pt;
774     type_debug(t);
775     if (cast(tym_t)newty != t.Tty)
776     {   if (t.Tcount > 1)              /* if other people pointing at t */
777         {   type *tn;
778 
779             tn = type_copy(t);
780             tn.Tcount++;
781             type_free(t);
782             t = tn;
783             *pt = t;
784         }
785         t.Tty = newty;
786     }
787     return t;
788 }
789 
790 /******************************
791  * Set type field of some object to t.
792  */
793 
794 type *type_settype(type **pt, type *t)
795 {
796     if (t)
797     {   type_debug(t);
798         t.Tcount++;
799     }
800     type_free(*pt);
801     return *pt = t;
802 }
803 
804 /****************************
805  * Modify the Tmangle field of a type.
806  */
807 
808 type *type_setmangle(type **pt,mangle_t mangle)
809 {   type *t;
810 
811     t = *pt;
812     type_debug(t);
813     if (mangle != type_mangle(t))
814     {
815         if (t.Tcount > 1)              // if other people pointing at t
816         {   type *tn;
817 
818             tn = type_copy(t);
819             tn.Tcount++;
820             type_free(t);
821             t = tn;
822             *pt = t;
823         }
824         t.Tmangle = mangle;
825     }
826     return t;
827 }
828 
829 /******************************
830  * Set/clear const and volatile bits in *pt according to the settings
831  * in cv.
832  */
833 
834 type *type_setcv(type **pt,tym_t cv)
835 {   uint ty;
836 
837     type_debug(*pt);
838     ty = (*pt).Tty & ~(mTYconst | mTYvolatile | mTYimmutable | mTYshared);
839     return type_setty(pt,ty | (cv & (mTYconst | mTYvolatile | mTYimmutable | mTYshared)));
840 }
841 
842 /*****************************
843  * Set dimension of array.
844  */
845 
846 type *type_setdim(type **pt,targ_size_t dim)
847 {   type *t = *pt;
848 
849     type_debug(t);
850     if (t.Tcount > 1)                  /* if other people pointing at t */
851     {   type *tn;
852 
853         tn = type_copy(t);
854         tn.Tcount++;
855         type_free(t);
856         t = tn;
857     }
858     t.Tflags &= ~TFsizeunknown; /* we have determined its size */
859     t.Tdim = dim;              /* index of array               */
860     return *pt = t;
861 }
862 
863 
864 /*****************************
865  * Create a 'dependent' version of type t.
866  */
867 
868 type *type_setdependent(type *t)
869 {
870     type_debug(t);
871     if (t.Tcount > 0 &&                        /* if other people pointing at t */
872         !(t.Tflags & TFdependent))
873     {
874         t = type_copy(t);
875     }
876     t.Tflags |= TFdependent;
877     return t;
878 }
879 
880 /************************************
881  * Determine if type t is a dependent type.
882  */
883 
884 @trusted
885 int type_isdependent(type *t)
886 {
887     Symbol *stempl;
888     type *tstart;
889 
890     //printf("type_isdependent(%p)\n", t);
891     //type_print(t);
892     for (tstart = t; t; t = t.Tnext)
893     {
894         type_debug(t);
895         if (t.Tflags & TFdependent)
896             goto Lisdependent;
897         if (tyfunc(t.Tty)
898                 || tybasic(t.Tty) == TYtemplate
899                 )
900         {
901             for (param_t *p = t.Tparamtypes; p; p = p.Pnext)
902             {
903                 if (p.Ptype && type_isdependent(p.Ptype))
904                     goto Lisdependent;
905                 if (p.Pelem && el_isdependent(p.Pelem))
906                     goto Lisdependent;
907             }
908         }
909         else if (type_struct(t) &&
910                  (stempl = t.Ttag.Sstruct.Stempsym) != null)
911         {
912             for (param_t *p = t.Ttag.Sstruct.Sarglist; p; p = p.Pnext)
913             {
914                 if (p.Ptype && type_isdependent(p.Ptype))
915                     goto Lisdependent;
916                 if (p.Pelem && el_isdependent(p.Pelem))
917                     goto Lisdependent;
918             }
919         }
920     }
921     //printf("\tis not dependent\n");
922     return 0;
923 
924 Lisdependent:
925     //printf("\tis dependent\n");
926     // Dependence on a dependent type makes this type dependent as well
927     tstart.Tflags |= TFdependent;
928     return 1;
929 }
930 
931 
932 /*******************************
933  * Recursively check if type u is embedded in type t.
934  * Returns:
935  *      != 0 if embedded
936  */
937 
938 @trusted
939 int type_embed(type *t,type *u)
940 {   param_t *p;
941 
942     for (; t; t = t.Tnext)
943     {
944         type_debug(t);
945         if (t == u)
946             return 1;
947         if (tyfunc(t.Tty))
948         {
949             for (p = t.Tparamtypes; p; p = p.Pnext)
950                 if (type_embed(p.Ptype,u))
951                     return 1;
952         }
953     }
954     return 0;
955 }
956 
957 
958 /***********************************
959  * Determine if type is a VLA.
960  */
961 
962 int type_isvla(type *t)
963 {
964     while (t)
965     {
966         if (tybasic(t.Tty) != TYarray)
967             break;
968         if (t.Tflags & TFvla)
969             return 1;
970         t = t.Tnext;
971     }
972     return 0;
973 }
974 
975 
976 /**********************************
977  * Pretty-print a type.
978  */
979 
980 @trusted
981 void type_print(const type *t)
982 {
983   type_debug(t);
984   printf("Tty=%s", tym_str(t.Tty));
985   printf(" Tmangle=%d",t.Tmangle);
986   printf(" Tflags=x%x",t.Tflags);
987   printf(" Tcount=%d",t.Tcount);
988   if (!(t.Tflags & TFsizeunknown) &&
989         tybasic(t.Tty) != TYvoid &&
990         tybasic(t.Tty) != TYident &&
991         tybasic(t.Tty) != TYtemplate &&
992         tybasic(t.Tty) != TYmfunc &&
993         tybasic(t.Tty) != TYarray)
994       printf(" Tsize=%lld", cast(long)type_size(t));
995   printf(" Tnext=%p",t.Tnext);
996   switch (tybasic(t.Tty))
997   {     case TYstruct:
998         case TYmemptr:
999             printf(" Ttag=%p,'%s'",t.Ttag,t.Ttag.Sident.ptr);
1000             //printf(" Sfldlst=%p",t.Ttag.Sstruct.Sfldlst);
1001             break;
1002 
1003         case TYarray:
1004             printf(" Tdim=%lld", cast(long)t.Tdim);
1005             break;
1006 
1007         case TYident:
1008             printf(" Tident='%s'",t.Tident);
1009             break;
1010         case TYtemplate:
1011             printf(" Tsym='%s'",(cast(typetemp_t *)t).Tsym.Sident.ptr);
1012             {
1013                 int i;
1014 
1015                 i = 1;
1016                 for (const(param_t)* p = t.Tparamtypes; p; p = p.Pnext)
1017                 {   printf("\nTP%d (%p): ",i++,p);
1018                     fflush(stdout);
1019 
1020 printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p.Pident,p.Ptype,p.Pelem,p.Pnext);
1021                     param_debug(p);
1022                     if (p.Pident)
1023                         printf("'%s' ", p.Pident);
1024                     if (p.Ptype)
1025                         type_print(p.Ptype);
1026                     if (p.Pelem)
1027                         elem_print(p.Pelem);
1028                 }
1029             }
1030             break;
1031 
1032         default:
1033             if (tyfunc(t.Tty))
1034             {
1035                 int i;
1036 
1037                 i = 1;
1038                 for (const(param_t)* p = t.Tparamtypes; p; p = p.Pnext)
1039                 {   printf("\nP%d (%p): ",i++,p);
1040                     fflush(stdout);
1041 
1042 printf("Pident=%p,Ptype=%p,Pelem=%p,Pnext=%p ",p.Pident,p.Ptype,p.Pelem,p.Pnext);
1043                     param_debug(p);
1044                     if (p.Pident)
1045                         printf("'%s' ", p.Pident);
1046                     type_print(p.Ptype);
1047                 }
1048             }
1049             break;
1050   }
1051   printf("\n");
1052   if (t.Tnext) type_print(t.Tnext);
1053 }
1054 
1055 /*******************************
1056  * Pretty-print a param_t
1057  */
1058 
1059 @trusted
1060 void param_t_print(const scope param_t* p)
1061 {
1062     printf("Pident=%p,Ptype=%p,Pelem=%p,Psym=%p,Pnext=%p\n",p.Pident,p.Ptype,p.Pelem,p.Psym,p.Pnext);
1063     if (p.Pident)
1064         printf("\tPident = '%s'\n", p.Pident);
1065     if (p.Ptype)
1066     {   printf("\tPtype =\n");
1067         type_print(p.Ptype);
1068     }
1069     if (p.Pelem)
1070     {   printf("\tPelem =\n");
1071         elem_print(p.Pelem);
1072     }
1073     if (p.Pdeftype)
1074     {   printf("\tPdeftype =\n");
1075         type_print(p.Pdeftype);
1076     }
1077     if (p.Psym)
1078     {   printf("\tPsym = '%s'\n", p.Psym.Sident.ptr);
1079     }
1080     if (p.Pptpl)
1081     {   printf("\tPptpl = %p\n", p.Pptpl);
1082     }
1083 }
1084 
1085 void param_t_print_list(scope param_t* p)
1086 {
1087     for (; p; p = p.Pnext)
1088         p.print();
1089 }
1090 
1091 
1092 /****************************
1093  * Allocate a param_t.
1094  */
1095 
1096 @trusted
1097 param_t *param_calloc()
1098 {
1099     static param_t pzero;
1100     param_t *p;
1101 
1102     if (param_list)
1103     {
1104         p = param_list;
1105         param_list = p.Pnext;
1106     }
1107     else
1108     {
1109         p = cast(param_t *) mem_fmalloc(param_t.sizeof);
1110     }
1111     *p = pzero;
1112 
1113     debug p.id = param_t.IDparam;
1114 
1115     return p;
1116 }
1117 
1118 /***************************
1119  * Allocate a param_t of type t, and append it to parameter list.
1120  */
1121 
1122 param_t *param_append_type(param_t **pp,type *t)
1123 {   param_t *p;
1124 
1125     p = param_calloc();
1126     while (*pp)
1127     {   param_debug(*pp);
1128         pp = &((*pp).Pnext);   /* find end of list     */
1129     }
1130     *pp = p;                    /* append p to list     */
1131     type_debug(t);
1132     p.Ptype = t;
1133     t.Tcount++;
1134     return p;
1135 }
1136 
1137 /************************
1138  * Version of param_free() suitable for list_free().
1139  */
1140 
1141 @trusted
1142 void param_free_l(param_t *p)
1143 {
1144     param_free(&p);
1145 }
1146 
1147 /***********************
1148  * Free parameter list.
1149  * Output:
1150  *      paramlst = null
1151  */
1152 
1153 @trusted
1154 void param_free(param_t **pparamlst)
1155 {   param_t* p,pn;
1156 
1157     //debug_assert(PARSER);
1158     for (p = *pparamlst; p; p = pn)
1159     {   param_debug(p);
1160         pn = p.Pnext;
1161         type_free(p.Ptype);
1162         mem_free(p.Pident);
1163         el_free(p.Pelem);
1164         type_free(p.Pdeftype);
1165         if (p.Pptpl)
1166             param_free(&p.Pptpl);
1167 
1168         debug p.id = 0;
1169 
1170         p.Pnext = param_list;
1171         param_list = p;
1172     }
1173     *pparamlst = null;
1174 }
1175 
1176 /***********************************
1177  * Compute number of parameters
1178  */
1179 
1180 uint param_t_length(scope param_t* p)
1181 {
1182     uint nparams = 0;
1183 
1184     for (; p; p = p.Pnext)
1185         nparams++;
1186     return nparams;
1187 }
1188 
1189 /*************************************
1190  * Create template-argument-list blank from
1191  * template-parameter-list
1192  * Input:
1193  *      ptali   initial template-argument-list
1194  */
1195 
1196 @trusted
1197 param_t* param_t_createTal(scope param_t* p, param_t *ptali)
1198 {
1199     param_t *ptal = null;
1200     param_t **pp = &ptal;
1201 
1202     for (; p; p = p.Pnext)
1203     {
1204         *pp = param_calloc();
1205         if (p.Pident)
1206         {
1207             // Should find a way to just point rather than dup
1208             (*pp).Pident = cast(char *)mem_strdup(p.Pident);
1209         }
1210         if (ptali)
1211         {
1212             if (ptali.Ptype)
1213             {   (*pp).Ptype = ptali.Ptype;
1214                 (*pp).Ptype.Tcount++;
1215             }
1216             if (ptali.Pelem)
1217             {
1218                 elem *e = el_copytree(ptali.Pelem);
1219                 (*pp).Pelem = e;
1220             }
1221             (*pp).Psym = ptali.Psym;
1222             (*pp).Pflags = ptali.Pflags;
1223             assert(!ptali.Pptpl);
1224             ptali = ptali.Pnext;
1225         }
1226         pp = &(*pp).Pnext;
1227     }
1228     return ptal;
1229 }
1230 
1231 /**********************************
1232  * Look for Pident matching id
1233  */
1234 
1235 @trusted
1236 param_t* param_t_search(return scope param_t* p, const(char)* id)
1237 {
1238     for (; p; p = p.Pnext)
1239     {
1240         if (p.Pident && strcmp(p.Pident, id) == 0)
1241             break;
1242     }
1243     return p;
1244 }
1245 
1246 /**********************************
1247  * Look for Pident matching id
1248  */
1249 
1250 @trusted
1251 int param_t_searchn(param_t* p, char *id)
1252 {
1253     int n = 0;
1254 
1255     for (; p; p = p.Pnext)
1256     {
1257         if (p.Pident && strcmp(p.Pident, id) == 0)
1258             return n;
1259         n++;
1260     }
1261     return -1;
1262 }
1263 
1264 /*************************************
1265  * Search for member, create symbol as needed.
1266  * Used for symbol tables for VLA's such as:
1267  *      void func(int n, int a[n]);
1268  */
1269 
1270 @trusted
1271 Symbol *param_search(const(char)* name, param_t **pp)
1272 {   Symbol *s = null;
1273     param_t *p;
1274 
1275     p = (*pp).search(cast(char *)name);
1276     if (p)
1277     {
1278         s = p.Psym;
1279         if (!s)
1280         {
1281             s = symbol_calloc(p.Pident[0 .. strlen(p.Pident)]);
1282             s.Sclass = SC.parameter;
1283             s.Stype = p.Ptype;
1284             s.Stype.Tcount++;
1285             p.Psym = s;
1286         }
1287     }
1288     return s;
1289 }
1290 
1291 // Return TRUE if type lists match.
1292 private int paramlstmatch(param_t *p1,param_t *p2)
1293 {
1294         return p1 == p2 ||
1295             p1 && p2 && typematch(p1.Ptype,p2.Ptype,0) &&
1296             paramlstmatch(p1.Pnext,p2.Pnext)
1297             ;
1298 }
1299 
1300 /*************************************************
1301  * A cheap version of exp2.typematch() and exp2.paramlstmatch(),
1302  * so that we can get cpp_mangle() to work for MARS.
1303  * It's less complex because it doesn't do templates and
1304  * can rely on strict typechecking.
1305  * Returns:
1306  *      !=0 if types match.
1307  */
1308 
1309 @trusted
1310 int typematch(type *t1,type *t2,int relax)
1311 { tym_t t1ty, t2ty;
1312   tym_t tym;
1313 
1314   tym = ~(mTYimport | mTYnaked);
1315 
1316   return t1 == t2 ||
1317             t1 && t2 &&
1318 
1319             (
1320                 /* ignore name mangling */
1321                 (t1ty = (t1.Tty & tym)) == (t2ty = (t2.Tty & tym))
1322             )
1323                  &&
1324 
1325             (tybasic(t1ty) != TYarray || t1.Tdim == t2.Tdim ||
1326              t1.Tflags & TFsizeunknown || t2.Tflags & TFsizeunknown)
1327                  &&
1328 
1329             (tybasic(t1ty) != TYstruct
1330                 && tybasic(t1ty) != TYenum
1331                 && tybasic(t1ty) != TYmemptr
1332              || t1.Ttag == t2.Ttag)
1333                  &&
1334 
1335             typematch(t1.Tnext,t2.Tnext, 0)
1336                  &&
1337 
1338             (!tyfunc(t1ty) ||
1339              ((t1.Tflags & TFfixed) == (t2.Tflags & TFfixed) &&
1340                  paramlstmatch(t1.Tparamtypes,t2.Tparamtypes) ))
1341          ;
1342 }