1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4  * written by Walter Bright
5  * http://www.digitalmars.com
6  * Distributed under the Boost Software License, Version 1.0.
7  * http://www.boost.org/LICENSE_1_0.txt
8  * https://github.com/D-Programming-Language/dmd/blob/master/src/mtype.c
9  */
10 
11 #include "root/dsystem.h"
12 #include "root/checkedint.h"
13 #include "root/rmem.h"
14 
15 #include "mars.h"
16 #include "mangle.h"
17 #include "dsymbol.h"
18 #include "mtype.h"
19 #include "scope.h"
20 #include "init.h"
21 #include "expression.h"
22 #include "statement.h"
23 #include "attrib.h"
24 #include "declaration.h"
25 #include "template.h"
26 #include "id.h"
27 #include "enum.h"
28 #include "module.h"
29 #include "import.h"
30 #include "aggregate.h"
31 #include "hdrgen.h"
32 #include "target.h"
33 
34 bool symbolIsVisible(Scope *sc, Dsymbol *s);
35 typedef int (*ForeachDg)(void *ctx, size_t paramidx, Parameter *param);
36 int Parameter_foreach(Parameters *parameters, ForeachDg dg, void *ctx, size_t *pn = NULL);
37 FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL);
38 Expression *extractSideEffect(Scope *sc, const char *name, Expression **e0, Expression *e, bool alwaysCopy = false);
39 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads);
40 Expression *semantic(Expression *e, Scope *sc);
41 Expression *semanticY(DotIdExp *exp, Scope *sc, int flag);
42 Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag);
43 Expression *typeToExpression(Type *t);
44 Expression *typeToExpressionHelper(TypeQualified *t, Expression *e, size_t i = 0);
45 Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret);
46 
47 int Tsize_t = Tuns32;
48 int Tptrdiff_t = Tint32;
49 
50 /***************************** Type *****************************/
51 
52 ClassDeclaration *Type::dtypeinfo;
53 ClassDeclaration *Type::typeinfoclass;
54 ClassDeclaration *Type::typeinfointerface;
55 ClassDeclaration *Type::typeinfostruct;
56 ClassDeclaration *Type::typeinfopointer;
57 ClassDeclaration *Type::typeinfoarray;
58 ClassDeclaration *Type::typeinfostaticarray;
59 ClassDeclaration *Type::typeinfoassociativearray;
60 ClassDeclaration *Type::typeinfovector;
61 ClassDeclaration *Type::typeinfoenum;
62 ClassDeclaration *Type::typeinfofunction;
63 ClassDeclaration *Type::typeinfodelegate;
64 ClassDeclaration *Type::typeinfotypelist;
65 ClassDeclaration *Type::typeinfoconst;
66 ClassDeclaration *Type::typeinfoinvariant;
67 ClassDeclaration *Type::typeinfoshared;
68 ClassDeclaration *Type::typeinfowild;
69 
70 TemplateDeclaration *Type::rtinfo;
71 
72 Type *Type::tvoid;
73 Type *Type::tint8;
74 Type *Type::tuns8;
75 Type *Type::tint16;
76 Type *Type::tuns16;
77 Type *Type::tint32;
78 Type *Type::tuns32;
79 Type *Type::tint64;
80 Type *Type::tuns64;
81 Type *Type::tint128;
82 Type *Type::tuns128;
83 Type *Type::tfloat32;
84 Type *Type::tfloat64;
85 Type *Type::tfloat80;
86 
87 Type *Type::timaginary32;
88 Type *Type::timaginary64;
89 Type *Type::timaginary80;
90 
91 Type *Type::tcomplex32;
92 Type *Type::tcomplex64;
93 Type *Type::tcomplex80;
94 
95 Type *Type::tbool;
96 Type *Type::tchar;
97 Type *Type::twchar;
98 Type *Type::tdchar;
99 
100 Type *Type::tshiftcnt;
101 Type *Type::terror;
102 Type *Type::tnull;
103 
104 Type *Type::tsize_t;
105 Type *Type::tptrdiff_t;
106 Type *Type::thash_t;
107 
108 Type *Type::tvoidptr;
109 Type *Type::tstring;
110 Type *Type::twstring;
111 Type *Type::tdstring;
112 Type *Type::tvalist;
113 Type *Type::basic[TMAX];
114 unsigned char Type::sizeTy[TMAX];
115 StringTable Type::stringtable;
116 
117 void initTypeMangle();
118 
Type(TY ty)119 Type::Type(TY ty)
120 {
121     this->ty = ty;
122     this->mod = 0;
123     this->deco = NULL;
124     this->cto = NULL;
125     this->ito = NULL;
126     this->sto = NULL;
127     this->scto = NULL;
128     this->wto = NULL;
129     this->wcto = NULL;
130     this->swto = NULL;
131     this->swcto = NULL;
132     this->pto = NULL;
133     this->rto = NULL;
134     this->arrayof = NULL;
135     this->vtinfo = NULL;
136     this->ctype = NULL;
137 }
138 
kind()139 const char *Type::kind()
140 {
141     assert(false); // should be overridden
142     return NULL;
143 }
144 
copy()145 Type *Type::copy()
146 {
147     void *pt = mem.xmalloc(sizeTy[ty]);
148     Type *t = (Type *)memcpy(pt, (void *)this, sizeTy[ty]);
149     return t;
150 }
151 
syntaxCopy()152 Type *Type::syntaxCopy()
153 {
154     print();
155     fprintf(stderr, "ty = %d\n", ty);
156     assert(0);
157     return this;
158 }
159 
equals(RootObject * o)160 bool Type::equals(RootObject *o)
161 {
162     Type *t = (Type *)o;
163     //printf("Type::equals(%s, %s)\n", toChars(), t->toChars());
164     // deco strings are unique
165     // and semantic() has been run
166     if (this == o || ((t && deco == t->deco) && deco != NULL))
167     {
168         //printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
169         return true;
170     }
171     //if (deco && t && t->deco) printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
172     return false;
173 }
174 
equivalent(Type * t)175 bool Type::equivalent(Type *t)
176 {
177     return immutableOf()->equals(t->immutableOf());
178 }
179 
_init()180 void Type::_init()
181 {
182     stringtable._init(14000);
183 
184     for (size_t i = 0; i < TMAX; i++)
185         sizeTy[i] = sizeof(TypeBasic);
186     sizeTy[Tsarray] = sizeof(TypeSArray);
187     sizeTy[Tarray] = sizeof(TypeDArray);
188     sizeTy[Taarray] = sizeof(TypeAArray);
189     sizeTy[Tpointer] = sizeof(TypePointer);
190     sizeTy[Treference] = sizeof(TypeReference);
191     sizeTy[Tfunction] = sizeof(TypeFunction);
192     sizeTy[Tdelegate] = sizeof(TypeDelegate);
193     sizeTy[Tident] = sizeof(TypeIdentifier);
194     sizeTy[Tinstance] = sizeof(TypeInstance);
195     sizeTy[Ttypeof] = sizeof(TypeTypeof);
196     sizeTy[Tenum] = sizeof(TypeEnum);
197     sizeTy[Tstruct] = sizeof(TypeStruct);
198     sizeTy[Tclass] = sizeof(TypeClass);
199     sizeTy[Ttuple] = sizeof(TypeTuple);
200     sizeTy[Tslice] = sizeof(TypeSlice);
201     sizeTy[Treturn] = sizeof(TypeReturn);
202     sizeTy[Terror] = sizeof(TypeError);
203     sizeTy[Tnull] = sizeof(TypeNull);
204     sizeTy[Tvector] = sizeof(TypeVector);
205     sizeTy[Ttraits] = sizeof(TypeTraits);
206 
207     initTypeMangle();
208 
209     // Set basic types
210     static TY basetab[] =
211         { Tvoid, Tint8, Tuns8, Tint16, Tuns16, Tint32, Tuns32, Tint64, Tuns64,
212           Tint128, Tuns128,
213           Tfloat32, Tfloat64, Tfloat80,
214           Timaginary32, Timaginary64, Timaginary80,
215           Tcomplex32, Tcomplex64, Tcomplex80,
216           Tbool,
217           Tchar, Twchar, Tdchar, Terror };
218 
219     for (size_t i = 0; basetab[i] != Terror; i++)
220     {
221         Type *t = new TypeBasic(basetab[i]);
222         t = t->merge();
223         basic[basetab[i]] = t;
224     }
225     basic[Terror] = new TypeError();
226 
227     tvoid = basic[Tvoid];
228     tint8 = basic[Tint8];
229     tuns8 = basic[Tuns8];
230     tint16 = basic[Tint16];
231     tuns16 = basic[Tuns16];
232     tint32 = basic[Tint32];
233     tuns32 = basic[Tuns32];
234     tint64 = basic[Tint64];
235     tuns64 = basic[Tuns64];
236     tint128 = basic[Tint128];
237     tuns128 = basic[Tuns128];
238     tfloat32 = basic[Tfloat32];
239     tfloat64 = basic[Tfloat64];
240     tfloat80 = basic[Tfloat80];
241 
242     timaginary32 = basic[Timaginary32];
243     timaginary64 = basic[Timaginary64];
244     timaginary80 = basic[Timaginary80];
245 
246     tcomplex32 = basic[Tcomplex32];
247     tcomplex64 = basic[Tcomplex64];
248     tcomplex80 = basic[Tcomplex80];
249 
250     tbool = basic[Tbool];
251     tchar = basic[Tchar];
252     twchar = basic[Twchar];
253     tdchar = basic[Tdchar];
254 
255     tshiftcnt = tint32;
256     terror = basic[Terror];
257     tnull = basic[Tnull];
258     tnull = new TypeNull();
259     tnull->deco = tnull->merge()->deco;
260 
261     tvoidptr = tvoid->pointerTo();
262     tstring = tchar->immutableOf()->arrayOf();
263     twstring = twchar->immutableOf()->arrayOf();
264     tdstring = tdchar->immutableOf()->arrayOf();
265     tvalist = Target::va_listType();
266 
267     if (global.params.isLP64)
268     {
269         Tsize_t = Tuns64;
270         Tptrdiff_t = Tint64;
271     }
272     else
273     {
274         Tsize_t = Tuns32;
275         Tptrdiff_t = Tint32;
276     }
277 
278     tsize_t = basic[Tsize_t];
279     tptrdiff_t = basic[Tptrdiff_t];
280     thash_t = tsize_t;
281 }
282 
size()283 d_uns64 Type::size()
284 {
285     return size(Loc());
286 }
287 
size(Loc loc)288 d_uns64 Type::size(Loc loc)
289 {
290     error(loc, "no size for type %s", toChars());
291     return SIZE_INVALID;
292 }
293 
alignsize()294 unsigned Type::alignsize()
295 {
296     return (unsigned)size(Loc());
297 }
298 
semantic(Loc loc,Scope *)299 Type *Type::semantic(Loc loc, Scope *)
300 {
301     if (ty == Tint128 || ty == Tuns128)
302     {
303         error(loc, "cent and ucent types not implemented");
304         return terror;
305     }
306 
307     return merge();
308 }
309 
trySemantic(Loc loc,Scope * sc)310 Type *Type::trySemantic(Loc loc, Scope *sc)
311 {
312     //printf("+trySemantic(%s) %d\n", toChars(), global.errors);
313     unsigned errors = global.startGagging();
314     Type *t = semantic(loc, sc);
315     if (global.endGagging(errors) || t->ty == Terror)        // if any errors happened
316     {
317         t = NULL;
318     }
319     //printf("-trySemantic(%s) %d\n", toChars(), global.errors);
320     return t;
321 }
322 
323 /********************************
324  * Return a copy of this type with all attributes null-initialized.
325  * Useful for creating a type with different modifiers.
326  */
327 
nullAttributes()328 Type *Type::nullAttributes()
329 {
330     unsigned sz = sizeTy[ty];
331     void *pt = mem.xmalloc(sz);
332     Type *t = (Type *)memcpy(pt, (void *)this, sz);
333     t->deco = NULL;
334     t->arrayof = NULL;
335     t->pto = NULL;
336     t->rto = NULL;
337     t->cto = NULL;
338     t->ito = NULL;
339     t->sto = NULL;
340     t->scto = NULL;
341     t->wto = NULL;
342     t->wcto = NULL;
343     t->swto = NULL;
344     t->swcto = NULL;
345     t->vtinfo = NULL;
346     t->ctype = NULL;
347     if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref;
348     if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref;
349     return t;
350 }
351 
352 /********************************
353  * Convert to 'const'.
354  */
355 
constOf()356 Type *Type::constOf()
357 {
358     //printf("Type::constOf() %p %s\n", this, toChars());
359     if (mod == MODconst)
360         return this;
361     if (cto)
362     {
363         assert(cto->mod == MODconst);
364         return cto;
365     }
366     Type *t = makeConst();
367     t = t->merge();
368     t->fixTo(this);
369     //printf("-Type::constOf() %p %s\n", t, t->toChars());
370     return t;
371 }
372 
373 /********************************
374  * Convert to 'immutable'.
375  */
376 
immutableOf()377 Type *Type::immutableOf()
378 {
379     //printf("Type::immutableOf() %p %s\n", this, toChars());
380     if (isImmutable())
381         return this;
382     if (ito)
383     {
384         assert(ito->isImmutable());
385         return ito;
386     }
387     Type *t = makeImmutable();
388     t = t->merge();
389     t->fixTo(this);
390     //printf("\t%p\n", t);
391     return t;
392 }
393 
394 /********************************
395  * Make type mutable.
396  */
397 
mutableOf()398 Type *Type::mutableOf()
399 {
400     //printf("Type::mutableOf() %p, %s\n", this, toChars());
401     Type *t = this;
402     if (isImmutable())
403     {
404         t = ito;                // immutable => naked
405         assert(!t || (t->isMutable() && !t->isShared()));
406     }
407     else if (isConst())
408     {
409         if (isShared())
410         {
411             if (isWild())
412                 t = swcto;      // shared wild const -> shared
413             else
414                 t = sto;        // shared const => shared
415         }
416         else
417         {
418             if (isWild())
419                 t = wcto;       // wild const -> naked
420             else
421                 t = cto;        // const => naked
422         }
423         assert(!t || t->isMutable());
424     }
425     else if (isWild())
426     {
427         if (isShared())
428             t = sto;            // shared wild => shared
429         else
430             t = wto;            // wild => naked
431         assert(!t || t->isMutable());
432     }
433     if (!t)
434     {
435         t = makeMutable();
436         t = t->merge();
437         t->fixTo(this);
438     }
439     else
440         t = t->merge();
441     assert(t->isMutable());
442     return t;
443 }
444 
sharedOf()445 Type *Type::sharedOf()
446 {
447     //printf("Type::sharedOf() %p, %s\n", this, toChars());
448     if (mod == MODshared)
449         return this;
450     if (sto)
451     {
452         assert(sto->mod == MODshared);
453         return sto;
454     }
455     Type *t = makeShared();
456     t = t->merge();
457     t->fixTo(this);
458     //printf("\t%p\n", t);
459     return t;
460 }
461 
sharedConstOf()462 Type *Type::sharedConstOf()
463 {
464     //printf("Type::sharedConstOf() %p, %s\n", this, toChars());
465     if (mod == (MODshared | MODconst))
466         return this;
467     if (scto)
468     {
469         assert(scto->mod == (MODshared | MODconst));
470         return scto;
471     }
472     Type *t = makeSharedConst();
473     t = t->merge();
474     t->fixTo(this);
475     //printf("\t%p\n", t);
476     return t;
477 }
478 
479 
480 /********************************
481  * Make type unshared.
482  *      0            => 0
483  *      const        => const
484  *      immutable    => immutable
485  *      shared       => 0
486  *      shared const => const
487  *      wild         => wild
488  *      wild const   => wild const
489  *      shared wild  => wild
490  *      shared wild const => wild const
491  */
492 
unSharedOf()493 Type *Type::unSharedOf()
494 {
495     //printf("Type::unSharedOf() %p, %s\n", this, toChars());
496     Type *t = this;
497 
498     if (isShared())
499     {
500         if (isWild())
501         {
502             if (isConst())
503                 t = wcto;   // shared wild const => wild const
504             else
505                 t = wto;    // shared wild => wild
506         }
507         else
508         {
509             if (isConst())
510                 t = cto;    // shared const => const
511             else
512                 t = sto;    // shared => naked
513         }
514         assert(!t || !t->isShared());
515     }
516 
517     if (!t)
518     {
519         t = this->nullAttributes();
520         t->mod = mod & ~MODshared;
521         t->ctype = ctype;
522         t = t->merge();
523 
524         t->fixTo(this);
525     }
526     else
527         t = t->merge();
528     assert(!t->isShared());
529     return t;
530 }
531 
532 /********************************
533  * Convert to 'wild'.
534  */
535 
wildOf()536 Type *Type::wildOf()
537 {
538     //printf("Type::wildOf() %p %s\n", this, toChars());
539     if (mod == MODwild)
540         return this;
541     if (wto)
542     {
543         assert(wto->mod == MODwild);
544         return wto;
545     }
546     Type *t = makeWild();
547     t = t->merge();
548     t->fixTo(this);
549     //printf("\t%p %s\n", t, t->toChars());
550     return t;
551 }
552 
wildConstOf()553 Type *Type::wildConstOf()
554 {
555     //printf("Type::wildConstOf() %p %s\n", this, toChars());
556     if (mod == MODwildconst)
557         return this;
558     if (wcto)
559     {
560         assert(wcto->mod == MODwildconst);
561         return wcto;
562     }
563     Type *t = makeWildConst();
564     t = t->merge();
565     t->fixTo(this);
566     //printf("\t%p %s\n", t, t->toChars());
567     return t;
568 }
569 
sharedWildOf()570 Type *Type::sharedWildOf()
571 {
572     //printf("Type::sharedWildOf() %p, %s\n", this, toChars());
573     if (mod == (MODshared | MODwild))
574         return this;
575     if (swto)
576     {
577         assert(swto->mod == (MODshared | MODwild));
578         return swto;
579     }
580     Type *t = makeSharedWild();
581     t = t->merge();
582     t->fixTo(this);
583     //printf("\t%p %s\n", t, t->toChars());
584     return t;
585 }
586 
sharedWildConstOf()587 Type *Type::sharedWildConstOf()
588 {
589     //printf("Type::sharedWildConstOf() %p, %s\n", this, toChars());
590     if (mod == (MODshared | MODwildconst))
591         return this;
592     if (swcto)
593     {
594         assert(swcto->mod == (MODshared | MODwildconst));
595         return swcto;
596     }
597     Type *t = makeSharedWildConst();
598     t = t->merge();
599     t->fixTo(this);
600     //printf("\t%p %s\n", t, t->toChars());
601     return t;
602 }
603 
604 /**********************************
605  * For our new type 'this', which is type-constructed from t,
606  * fill in the cto, ito, sto, scto, wto shortcuts.
607  */
608 
fixTo(Type * t)609 void Type::fixTo(Type *t)
610 {
611     // If fixing this: immutable(T*) by t: immutable(T)*,
612     // cache t to this->xto won't break transitivity.
613     Type *mto = NULL;
614     Type *tn = nextOf();
615     if (!tn || (ty != Tsarray && tn->mod == t->nextOf()->mod))
616     {
617         switch (t->mod)
618         {
619             case 0:                           mto = t;  break;
620             case MODconst:                    cto = t;  break;
621             case MODwild:                     wto = t;  break;
622             case MODwildconst:               wcto = t;  break;
623             case MODshared:                   sto = t;  break;
624             case MODshared | MODconst:       scto = t;  break;
625             case MODshared | MODwild:        swto = t;  break;
626             case MODshared | MODwildconst:  swcto = t;  break;
627             case MODimmutable:                ito = t;  break;
628         }
629     }
630 
631     assert(mod != t->mod);
632 #define X(m, n) (((m) << 4) | (n))
633     switch (mod)
634     {
635         case 0:
636             break;
637 
638         case MODconst:
639             cto = mto;
640             t->cto = this;
641             break;
642 
643         case MODwild:
644             wto = mto;
645             t->wto = this;
646             break;
647 
648         case MODwildconst:
649             wcto = mto;
650             t->wcto = this;
651             break;
652 
653         case MODshared:
654             sto = mto;
655             t->sto = this;
656             break;
657 
658         case MODshared | MODconst:
659             scto = mto;
660             t->scto = this;
661             break;
662 
663         case MODshared | MODwild:
664             swto = mto;
665             t->swto = this;
666             break;
667 
668         case MODshared | MODwildconst:
669             swcto = mto;
670             t->swcto = this;
671             break;
672 
673         case MODimmutable:
674             t->ito = this;
675             if (t->  cto) t->  cto->ito = this;
676             if (t->  sto) t->  sto->ito = this;
677             if (t-> scto) t-> scto->ito = this;
678             if (t->  wto) t->  wto->ito = this;
679             if (t-> wcto) t-> wcto->ito = this;
680             if (t-> swto) t-> swto->ito = this;
681             if (t->swcto) t->swcto->ito = this;
682             break;
683 
684         default:
685             assert(0);
686     }
687 #undef X
688 
689     check();
690     t->check();
691     //printf("fixTo: %s, %s\n", toChars(), t->toChars());
692 }
693 
694 /***************************
695  * Look for bugs in constructing types.
696  */
697 
check()698 void Type::check()
699 {
700     switch (mod)
701     {
702         case 0:
703             if (cto) assert(cto->mod == MODconst);
704             if (ito) assert(ito->mod == MODimmutable);
705             if (sto) assert(sto->mod == MODshared);
706             if (scto) assert(scto->mod == (MODshared | MODconst));
707             if (wto) assert(wto->mod == MODwild);
708             if (wcto) assert(wcto->mod == MODwildconst);
709             if (swto) assert(swto->mod == (MODshared | MODwild));
710             if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
711             break;
712 
713         case MODconst:
714             if (cto) assert(cto->mod == 0);
715             if (ito) assert(ito->mod == MODimmutable);
716             if (sto) assert(sto->mod == MODshared);
717             if (scto) assert(scto->mod == (MODshared | MODconst));
718             if (wto) assert(wto->mod == MODwild);
719             if (wcto) assert(wcto->mod == MODwildconst);
720             if (swto) assert(swto->mod == (MODshared | MODwild));
721             if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
722             break;
723 
724         case MODwild:
725             if (cto) assert(cto->mod == MODconst);
726             if (ito) assert(ito->mod == MODimmutable);
727             if (sto) assert(sto->mod == MODshared);
728             if (scto) assert(scto->mod == (MODshared | MODconst));
729             if (wto) assert(wto->mod == 0);
730             if (wcto) assert(wcto->mod == MODwildconst);
731             if (swto) assert(swto->mod == (MODshared | MODwild));
732             if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
733             break;
734 
735         case MODwildconst:
736             assert(!  cto ||   cto->mod == MODconst);
737             assert(!  ito ||   ito->mod == MODimmutable);
738             assert(!  sto ||   sto->mod == MODshared);
739             assert(! scto ||  scto->mod == (MODshared | MODconst));
740             assert(!  wto ||   wto->mod == MODwild);
741             assert(! wcto ||  wcto->mod == 0);
742             assert(! swto ||  swto->mod == (MODshared | MODwild));
743             assert(!swcto || swcto->mod == (MODshared | MODwildconst));
744             break;
745 
746         case MODshared:
747             if (cto) assert(cto->mod == MODconst);
748             if (ito) assert(ito->mod == MODimmutable);
749             if (sto) assert(sto->mod == 0);
750             if (scto) assert(scto->mod == (MODshared | MODconst));
751             if (wto) assert(wto->mod == MODwild);
752             if (wcto) assert(wcto->mod == MODwildconst);
753             if (swto) assert(swto->mod == (MODshared | MODwild));
754             if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
755             break;
756 
757         case MODshared | MODconst:
758             if (cto) assert(cto->mod == MODconst);
759             if (ito) assert(ito->mod == MODimmutable);
760             if (sto) assert(sto->mod == MODshared);
761             if (scto) assert(scto->mod == 0);
762             if (wto) assert(wto->mod == MODwild);
763             if (wcto) assert(wcto->mod == MODwildconst);
764             if (swto) assert(swto->mod == (MODshared | MODwild));
765             if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
766             break;
767 
768         case MODshared | MODwild:
769             if (cto) assert(cto->mod == MODconst);
770             if (ito) assert(ito->mod == MODimmutable);
771             if (sto) assert(sto->mod == MODshared);
772             if (scto) assert(scto->mod == (MODshared | MODconst));
773             if (wto) assert(wto->mod == MODwild);
774             if (wcto) assert(wcto->mod == MODwildconst);
775             if (swto) assert(swto->mod == 0);
776             if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
777             break;
778 
779         case MODshared | MODwildconst:
780             assert(!  cto ||   cto->mod == MODconst);
781             assert(!  ito ||   ito->mod == MODimmutable);
782             assert(!  sto ||   sto->mod == MODshared);
783             assert(! scto ||  scto->mod == (MODshared | MODconst));
784             assert(!  wto ||   wto->mod == MODwild);
785             assert(! wcto ||  wcto->mod == MODwildconst);
786             assert(! swto ||  swto->mod == (MODshared | MODwild));
787             assert(!swcto || swcto->mod == 0);
788             break;
789 
790         case MODimmutable:
791             if (cto) assert(cto->mod == MODconst);
792             if (ito) assert(ito->mod == 0);
793             if (sto) assert(sto->mod == MODshared);
794             if (scto) assert(scto->mod == (MODshared | MODconst));
795             if (wto) assert(wto->mod == MODwild);
796             if (wcto) assert(wcto->mod == MODwildconst);
797             if (swto) assert(swto->mod == (MODshared | MODwild));
798             if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
799             break;
800 
801         default:
802             assert(0);
803     }
804 
805     Type *tn = nextOf();
806     if (tn && ty != Tfunction && tn->ty != Tfunction && ty != Tenum)
807     {
808         // Verify transitivity
809         switch (mod)
810         {
811             case 0:
812             case MODconst:
813             case MODwild:
814             case MODwildconst:
815             case MODshared:
816             case MODshared | MODconst:
817             case MODshared | MODwild:
818             case MODshared | MODwildconst:
819             case MODimmutable:
820                 assert(tn->mod == MODimmutable || (tn->mod & mod) == mod);
821                 break;
822 
823             default:
824                 assert(0);
825         }
826         tn->check();
827     }
828 }
829 
makeConst()830 Type *Type::makeConst()
831 {
832     //printf("Type::makeConst() %p, %s\n", this, toChars());
833     if (cto) return cto;
834     Type *t = this->nullAttributes();
835     t->mod = MODconst;
836     //printf("-Type::makeConst() %p, %s\n", t, toChars());
837     return t;
838 }
839 
makeImmutable()840 Type *Type::makeImmutable()
841 {
842     if (ito) return ito;
843     Type *t = this->nullAttributes();
844     t->mod = MODimmutable;
845     return t;
846 }
847 
makeShared()848 Type *Type::makeShared()
849 {
850     if (sto) return sto;
851     Type *t = this->nullAttributes();
852     t->mod = MODshared;
853     return t;
854 }
855 
makeSharedConst()856 Type *Type::makeSharedConst()
857 {
858     if (scto) return scto;
859     Type *t = this->nullAttributes();
860     t->mod = MODshared | MODconst;
861     return t;
862 }
863 
makeWild()864 Type *Type::makeWild()
865 {
866     if (wto) return wto;
867     Type *t = this->nullAttributes();
868     t->mod = MODwild;
869     return t;
870 }
871 
makeWildConst()872 Type *Type::makeWildConst()
873 {
874     if (wcto) return wcto;
875     Type *t = this->nullAttributes();
876     t->mod = MODwildconst;
877     return t;
878 }
879 
makeSharedWild()880 Type *Type::makeSharedWild()
881 {
882     if (swto) return swto;
883     Type *t = this->nullAttributes();
884     t->mod = MODshared | MODwild;
885     return t;
886 }
887 
makeSharedWildConst()888 Type *Type::makeSharedWildConst()
889 {
890     if (swcto) return swcto;
891     Type *t = this->nullAttributes();
892     t->mod = MODshared | MODwildconst;
893     return t;
894 }
895 
makeMutable()896 Type *Type::makeMutable()
897 {
898     Type *t = this->nullAttributes();
899     t->mod = mod & MODshared;
900     return t;
901 }
902 
903 /*************************************
904  * Apply STCxxxx bits to existing type.
905  * Use *before* semantic analysis is run.
906  */
907 
addSTC(StorageClass stc)908 Type *Type::addSTC(StorageClass stc)
909 {
910     Type *t = this;
911     if (t->isImmutable())
912         ;
913     else if (stc & STCimmutable)
914     {
915         t = t->makeImmutable();
916     }
917     else
918     {
919         if ((stc & STCshared) && !t->isShared())
920         {
921             if (t->isWild())
922             {
923                 if (t->isConst())
924                     t = t->makeSharedWildConst();
925                 else
926                     t = t->makeSharedWild();
927             }
928             else
929             {
930                 if (t->isConst())
931                     t = t->makeSharedConst();
932                 else
933                     t = t->makeShared();
934             }
935         }
936         if ((stc & STCconst) && !t->isConst())
937         {
938             if (t->isShared())
939             {
940                 if (t->isWild())
941                     t = t->makeSharedWildConst();
942                 else
943                     t = t->makeSharedConst();
944             }
945             else
946             {
947                 if (t->isWild())
948                     t = t->makeWildConst();
949                 else
950                     t = t->makeConst();
951             }
952         }
953         if ((stc & STCwild) && !t->isWild())
954         {
955             if (t->isShared())
956             {
957                 if (t->isConst())
958                     t = t->makeSharedWildConst();
959                 else
960                     t = t->makeSharedWild();
961             }
962             else
963             {
964                 if (t->isConst())
965                     t = t->makeWildConst();
966                 else
967                     t = t->makeWild();
968             }
969         }
970     }
971     return t;
972 }
973 
974 /************************************
975  * Convert MODxxxx to STCxxx
976  */
977 
ModToStc(unsigned mod)978 StorageClass ModToStc(unsigned mod)
979 {
980     StorageClass stc = 0;
981     if (mod & MODimmutable) stc |= STCimmutable;
982     if (mod & MODconst)     stc |= STCconst;
983     if (mod & MODwild)      stc |= STCwild;
984     if (mod & MODshared)    stc |= STCshared;
985     return stc;
986 }
987 
988 /************************************
989  * Apply MODxxxx bits to existing type.
990  */
991 
castMod(MOD mod)992 Type *Type::castMod(MOD mod)
993 {   Type *t;
994 
995     switch (mod)
996     {
997         case 0:
998             t = unSharedOf()->mutableOf();
999             break;
1000 
1001         case MODconst:
1002             t = unSharedOf()->constOf();
1003             break;
1004 
1005         case MODwild:
1006             t = unSharedOf()->wildOf();
1007             break;
1008 
1009         case MODwildconst:
1010             t = unSharedOf()->wildConstOf();
1011             break;
1012 
1013         case MODshared:
1014             t = mutableOf()->sharedOf();
1015             break;
1016 
1017         case MODshared | MODconst:
1018             t = sharedConstOf();
1019             break;
1020 
1021         case MODshared | MODwild:
1022             t = sharedWildOf();
1023             break;
1024 
1025         case MODshared | MODwildconst:
1026             t = sharedWildConstOf();
1027             break;
1028 
1029         case MODimmutable:
1030             t = immutableOf();
1031             break;
1032 
1033         default:
1034             assert(0);
1035     }
1036     return t;
1037 }
1038 
1039 /************************************
1040  * Add MODxxxx bits to existing type.
1041  * We're adding, not replacing, so adding const to
1042  * a shared type => "shared const"
1043  */
1044 
addMod(MOD mod)1045 Type *Type::addMod(MOD mod)
1046 {
1047     /* Add anything to immutable, and it remains immutable
1048      */
1049     Type *t = this;
1050     if (!t->isImmutable())
1051     {
1052         //printf("addMod(%x) %s\n", mod, toChars());
1053         switch (mod)
1054         {
1055             case 0:
1056                 break;
1057 
1058             case MODconst:
1059                 if (isShared())
1060                 {
1061                     if (isWild())
1062                         t = sharedWildConstOf();
1063                     else
1064                         t = sharedConstOf();
1065                 }
1066                 else
1067                 {
1068                     if (isWild())
1069                         t = wildConstOf();
1070                     else
1071                         t = constOf();
1072                 }
1073                 break;
1074 
1075             case MODwild:
1076                 if (isShared())
1077                 {
1078                     if (isConst())
1079                         t = sharedWildConstOf();
1080                     else
1081                         t = sharedWildOf();
1082                 }
1083                 else
1084                 {
1085                     if (isConst())
1086                         t = wildConstOf();
1087                     else
1088                         t = wildOf();
1089                 }
1090                 break;
1091 
1092             case MODwildconst:
1093                 if (isShared())
1094                     t = sharedWildConstOf();
1095                 else
1096                     t = wildConstOf();
1097                 break;
1098 
1099             case MODshared:
1100                 if (isWild())
1101                 {
1102                     if (isConst())
1103                         t = sharedWildConstOf();
1104                     else
1105                         t = sharedWildOf();
1106                 }
1107                 else
1108                 {
1109                     if (isConst())
1110                         t = sharedConstOf();
1111                     else
1112                         t = sharedOf();
1113                 }
1114                 break;
1115 
1116             case MODshared | MODconst:
1117                 if (isWild())
1118                     t = sharedWildConstOf();
1119                 else
1120                     t = sharedConstOf();
1121                 break;
1122 
1123             case MODshared | MODwild:
1124                 if (isConst())
1125                     t = sharedWildConstOf();
1126                 else
1127                     t = sharedWildOf();
1128                 break;
1129 
1130             case MODshared | MODwildconst:
1131                 t = sharedWildConstOf();
1132                 break;
1133 
1134             case MODimmutable:
1135                 t = immutableOf();
1136                 break;
1137 
1138             default:
1139                 assert(0);
1140         }
1141     }
1142     return t;
1143 }
1144 
1145 /************************************
1146  * Add storage class modifiers to type.
1147  */
1148 
addStorageClass(StorageClass stc)1149 Type *Type::addStorageClass(StorageClass stc)
1150 {
1151     /* Just translate to MOD bits and let addMod() do the work
1152      */
1153     MOD mod = 0;
1154 
1155     if (stc & STCimmutable)
1156         mod = MODimmutable;
1157     else
1158     {
1159         if (stc & (STCconst | STCin))
1160             mod |= MODconst;
1161         if (stc & STCwild)
1162             mod |= MODwild;
1163         if (stc & STCshared)
1164             mod |= MODshared;
1165     }
1166     return addMod(mod);
1167 }
1168 
pointerTo()1169 Type *Type::pointerTo()
1170 {
1171     if (ty == Terror)
1172         return this;
1173     if (!pto)
1174     {
1175         Type *t = new TypePointer(this);
1176         if (ty == Tfunction)
1177         {
1178             t->deco = t->merge()->deco;
1179             pto = t;
1180         }
1181         else
1182             pto = t->merge();
1183     }
1184     return pto;
1185 }
1186 
referenceTo()1187 Type *Type::referenceTo()
1188 {
1189     if (ty == Terror)
1190         return this;
1191     if (!rto)
1192     {
1193         Type *t = new TypeReference(this);
1194         rto = t->merge();
1195     }
1196     return rto;
1197 }
1198 
arrayOf()1199 Type *Type::arrayOf()
1200 {
1201     if (ty == Terror)
1202         return this;
1203     if (!arrayof)
1204     {
1205         Type *t = new TypeDArray(this);
1206         arrayof = t->merge();
1207     }
1208     return arrayof;
1209 }
1210 
1211 // Make corresponding static array type without semantic
sarrayOf(dinteger_t dim)1212 Type *Type::sarrayOf(dinteger_t dim)
1213 {
1214     assert(deco);
1215     Type *t = new TypeSArray(this, new IntegerExp(Loc(), dim, Type::tsize_t));
1216 
1217     // according to TypeSArray::semantic()
1218     t = t->addMod(mod);
1219     t = t->merge();
1220 
1221     return t;
1222 }
1223 
aliasthisOf()1224 Type *Type::aliasthisOf()
1225 {
1226     AggregateDeclaration *ad = isAggregate(this);
1227     if (ad && ad->aliasthis)
1228     {
1229         Dsymbol *s = ad->aliasthis;
1230         if (s->isAliasDeclaration())
1231             s = s->toAlias();
1232         Declaration *d = s->isDeclaration();
1233         if (d && !d->isTupleDeclaration())
1234         {
1235             assert(d->type);
1236             Type *t = d->type;
1237             if (d->isVarDeclaration() && d->needThis())
1238             {
1239                 t = t->addMod(this->mod);
1240             }
1241             else if (d->isFuncDeclaration())
1242             {
1243                 FuncDeclaration *fd = resolveFuncCall(Loc(), NULL, d, NULL, this, NULL, 1);
1244                 if (fd && fd->errors)
1245                     return Type::terror;
1246                 if (fd && !fd->type->nextOf() && !fd->functionSemantic())
1247                     fd = NULL;
1248                 if (fd)
1249                 {
1250                     t = fd->type->nextOf();
1251                     if (!t) // issue 14185
1252                         return Type::terror;
1253                     t = t->substWildTo(mod == 0 ? MODmutable : (MODFlags)mod);
1254                 }
1255                 else
1256                     return Type::terror;
1257             }
1258             return t;
1259         }
1260         EnumDeclaration *ed = s->isEnumDeclaration();
1261         if (ed)
1262         {
1263             Type *t = ed->type;
1264             return t;
1265         }
1266         TemplateDeclaration *td = s->isTemplateDeclaration();
1267         if (td)
1268         {
1269             assert(td->_scope);
1270             FuncDeclaration *fd = resolveFuncCall(Loc(), NULL, td, NULL, this, NULL, 1);
1271             if (fd && fd->errors)
1272                 return Type::terror;
1273             if (fd && fd->functionSemantic())
1274             {
1275                 Type *t = fd->type->nextOf();
1276                 t = t->substWildTo(mod == 0 ? MODmutable : (MODFlags)mod);
1277                 return t;
1278             }
1279             else
1280                 return Type::terror;
1281         }
1282         //printf("%s\n", s->kind());
1283     }
1284     return NULL;
1285 }
1286 
checkAliasThisRec()1287 bool Type::checkAliasThisRec()
1288 {
1289     Type *tb = toBasetype();
1290     AliasThisRec* pflag;
1291     if (tb->ty == Tstruct)
1292         pflag = &((TypeStruct *)tb)->att;
1293     else if (tb->ty == Tclass)
1294         pflag = &((TypeClass *)tb)->att;
1295     else
1296         return false;
1297 
1298     AliasThisRec flag = (AliasThisRec)(*pflag & RECtypeMask);
1299     if (flag == RECfwdref)
1300     {
1301         Type *att = aliasthisOf();
1302         flag = att && att->implicitConvTo(this) ? RECyes : RECno;
1303     }
1304     *pflag = (AliasThisRec)(flag | (*pflag & ~RECtypeMask));
1305     return flag == RECyes;
1306 }
1307 
toDsymbol(Scope *)1308 Dsymbol *Type::toDsymbol(Scope *)
1309 {
1310     return NULL;
1311 }
1312 
1313 /*******************************
1314  * If this is a shell around another type,
1315  * get that other type.
1316  */
1317 
toBasetype()1318 Type *Type::toBasetype()
1319 {
1320     return this;
1321 }
1322 
1323 /***************************
1324  * Return !=0 if modfrom can be implicitly converted to modto
1325  */
MODimplicitConv(MOD modfrom,MOD modto)1326 bool MODimplicitConv(MOD modfrom, MOD modto)
1327 {
1328     if (modfrom == modto)
1329         return true;
1330 
1331     //printf("MODimplicitConv(from = %x, to = %x)\n", modfrom, modto);
1332     #define X(m, n) (((m) << 4) | (n))
1333     switch (X(modfrom & ~MODshared, modto & ~MODshared))
1334     {
1335         case X(0,            MODconst):
1336         case X(MODwild,      MODconst):
1337         case X(MODwild,      MODwildconst):
1338         case X(MODwildconst, MODconst):
1339             return (modfrom & MODshared) == (modto & MODshared);
1340 
1341         case X(MODimmutable, MODconst):
1342         case X(MODimmutable, MODwildconst):
1343             return true;
1344 
1345         default:
1346             return false;
1347     }
1348     #undef X
1349 }
1350 
1351 /***************************
1352  * Return MATCHexact or MATCHconst if a method of type '() modfrom' can call a method of type '() modto'.
1353  */
MODmethodConv(MOD modfrom,MOD modto)1354 MATCH MODmethodConv(MOD modfrom, MOD modto)
1355 {
1356     if (modfrom == modto)
1357         return MATCHexact;
1358     if (MODimplicitConv(modfrom, modto))
1359         return MATCHconst;
1360 
1361     #define X(m, n) (((m) << 4) | (n))
1362     switch (X(modfrom, modto))
1363     {
1364         case X(0,            MODwild):
1365         case X(MODimmutable, MODwild):
1366         case X(MODconst,     MODwild):
1367         case X(MODwildconst, MODwild):
1368         case X(MODshared,              MODshared|MODwild):
1369         case X(MODshared|MODimmutable, MODshared|MODwild):
1370         case X(MODshared|MODconst,     MODshared|MODwild):
1371         case X(MODshared|MODwildconst, MODshared|MODwild):
1372             return MATCHconst;
1373 
1374         default:
1375             return MATCHnomatch;
1376     }
1377     #undef X
1378 }
1379 
1380 /***************************
1381  * Merge mod bits to form common mod.
1382  */
MODmerge(MOD mod1,MOD mod2)1383 MOD MODmerge(MOD mod1, MOD mod2)
1384 {
1385     if (mod1 == mod2)
1386         return mod1;
1387 
1388     //printf("MODmerge(1 = %x, 2 = %x)\n", mod1, mod2);
1389     MOD result = 0;
1390     if ((mod1 | mod2) & MODshared)
1391     {
1392         // If either type is shared, the result will be shared
1393         result |= MODshared;
1394         mod1 &= ~MODshared;
1395         mod2 &= ~MODshared;
1396     }
1397     if (mod1 == 0 || mod1 == MODmutable || mod1 == MODconst ||
1398         mod2 == 0 || mod2 == MODmutable || mod2 == MODconst)
1399     {
1400         // If either type is mutable or const, the result will be const.
1401         result |= MODconst;
1402     }
1403     else
1404     {
1405         // MODimmutable vs MODwild
1406         // MODimmutable vs MODwildconst
1407         //      MODwild vs MODwildconst
1408         assert(mod1 & MODwild || mod2 & MODwild);
1409         result |= MODwildconst;
1410     }
1411     return result;
1412 }
1413 
1414 /*********************************
1415  * Store modifier name into buf.
1416  */
MODtoBuffer(OutBuffer * buf,MOD mod)1417 void MODtoBuffer(OutBuffer *buf, MOD mod)
1418 {
1419     switch (mod)
1420     {
1421         case 0:
1422             break;
1423 
1424         case MODimmutable:
1425             buf->writestring(Token::tochars[TOKimmutable]);
1426             break;
1427 
1428         case MODshared:
1429             buf->writestring(Token::tochars[TOKshared]);
1430             break;
1431 
1432         case MODshared | MODconst:
1433             buf->writestring(Token::tochars[TOKshared]);
1434             buf->writeByte(' ');
1435             /* fall through */
1436         case MODconst:
1437             buf->writestring(Token::tochars[TOKconst]);
1438             break;
1439 
1440         case MODshared | MODwild:
1441             buf->writestring(Token::tochars[TOKshared]);
1442             buf->writeByte(' ');
1443             /* fall through */
1444         case MODwild:
1445             buf->writestring(Token::tochars[TOKwild]);
1446             break;
1447 
1448         case MODshared | MODwildconst:
1449             buf->writestring(Token::tochars[TOKshared]);
1450             buf->writeByte(' ');
1451             /* fall through */
1452         case MODwildconst:
1453             buf->writestring(Token::tochars[TOKwild]);
1454             buf->writeByte(' ');
1455             buf->writestring(Token::tochars[TOKconst]);
1456             break;
1457 
1458         default:
1459             assert(0);
1460     }
1461 }
1462 
1463 
1464 /*********************************
1465  * Return modifier name.
1466  */
MODtoChars(MOD mod)1467 char *MODtoChars(MOD mod)
1468 {
1469     OutBuffer buf;
1470     buf.reserve(16);
1471     MODtoBuffer(&buf, mod);
1472     return buf.extractString();
1473 }
1474 
1475 /********************************
1476  * For pretty-printing a type.
1477  */
1478 
toChars()1479 const char *Type::toChars()
1480 {
1481     OutBuffer buf;
1482     buf.reserve(16);
1483     HdrGenState hgs;
1484     hgs.fullQual = (ty == Tclass && !mod);
1485 
1486     ::toCBuffer(this, &buf, NULL, &hgs);
1487     return buf.extractString();
1488 }
1489 
toPrettyChars(bool QualifyTypes)1490 char *Type::toPrettyChars(bool QualifyTypes)
1491 {
1492     OutBuffer buf;
1493     buf.reserve(16);
1494     HdrGenState hgs;
1495     hgs.fullQual = QualifyTypes;
1496 
1497     ::toCBuffer(this, &buf, NULL, &hgs);
1498     return buf.extractString();
1499 }
1500 
1501 /*********************************
1502  * Store this type's modifier name into buf.
1503  */
modToBuffer(OutBuffer * buf)1504 void Type::modToBuffer(OutBuffer *buf)
1505 {
1506     if (mod)
1507     {
1508         buf->writeByte(' ');
1509         MODtoBuffer(buf, mod);
1510     }
1511 }
1512 
1513 /*********************************
1514  * Return this type's modifier name.
1515  */
modToChars()1516 char *Type::modToChars()
1517 {
1518     OutBuffer buf;
1519     buf.reserve(16);
1520     modToBuffer(&buf);
1521     return buf.extractString();
1522 }
1523 
1524 /** For each active modifier (MODconst, MODimmutable, etc) call fp with a
1525 void* for the work param and a string representation of the attribute. */
modifiersApply(void * param,int (* fp)(void *,const char *))1526 int Type::modifiersApply(void *param, int (*fp)(void *, const char *))
1527 {
1528     static unsigned char modsArr[] = { MODconst, MODimmutable, MODwild, MODshared };
1529 
1530     for (size_t idx = 0; idx < 4; ++idx)
1531     {
1532         if (mod & modsArr[idx])
1533         {
1534             if (int res = fp(param, MODtoChars(modsArr[idx])))
1535                 return res;
1536         }
1537     }
1538     return 0;
1539 }
1540 
1541 /************************************
1542  * Strip all parameter's idenfiers and their default arguments for merging types.
1543  * If some of parameter types or return type are function pointer, delegate, or
1544  * the types which contains either, then strip also from them.
1545  */
1546 
stripDefaultArgs(Type * t)1547 Type *stripDefaultArgs(Type *t)
1548 {
1549   struct N
1550   {
1551     static Parameters *stripParams(Parameters *parameters)
1552     {
1553         Parameters *params = parameters;
1554         if (params && params->dim > 0)
1555         {
1556             for (size_t i = 0; i < params->dim; i++)
1557             {
1558                 Parameter *p = (*params)[i];
1559                 Type *ta = stripDefaultArgs(p->type);
1560                 if (ta != p->type || p->defaultArg || p->ident)
1561                 {
1562                     if (params == parameters)
1563                     {
1564                         params = new Parameters();
1565                         params->setDim(parameters->dim);
1566                         for (size_t j = 0; j < params->dim; j++)
1567                             (*params)[j] = (*parameters)[j];
1568                     }
1569                     (*params)[i] = new Parameter(p->storageClass, ta, NULL, NULL);
1570                 }
1571             }
1572         }
1573         return params;
1574     }
1575   };
1576 
1577     if (t == NULL)
1578         return t;
1579 
1580     if (t->ty == Tfunction)
1581     {
1582         TypeFunction *tf = (TypeFunction *)t;
1583         Type *tret = stripDefaultArgs(tf->next);
1584         Parameters *params = N::stripParams(tf->parameters);
1585         if (tret == tf->next && params == tf->parameters)
1586             goto Lnot;
1587         tf = (TypeFunction *)tf->copy();
1588         tf->parameters = params;
1589         tf->next = tret;
1590         //printf("strip %s\n   <- %s\n", tf->toChars(), t->toChars());
1591         t = tf;
1592     }
1593     else if (t->ty == Ttuple)
1594     {
1595         TypeTuple *tt = (TypeTuple *)t;
1596         Parameters *args = N::stripParams(tt->arguments);
1597         if (args == tt->arguments)
1598             goto Lnot;
1599         t = t->copy();
1600         ((TypeTuple *)t)->arguments = args;
1601     }
1602     else if (t->ty == Tenum)
1603     {
1604         // TypeEnum::nextOf() may be != NULL, but it's not necessary here.
1605         goto Lnot;
1606     }
1607     else
1608     {
1609         Type *tn = t->nextOf();
1610         Type *n = stripDefaultArgs(tn);
1611         if (n == tn)
1612             goto Lnot;
1613         t = t->copy();
1614         ((TypeNext *)t)->next = n;
1615     }
1616     //printf("strip %s\n", t->toChars());
1617 Lnot:
1618     return t;
1619 }
1620 
1621 /************************************
1622  */
1623 
merge()1624 Type *Type::merge()
1625 {
1626     if (ty == Terror) return this;
1627     if (ty == Ttypeof) return this;
1628     if (ty == Tident) return this;
1629     if (ty == Tinstance) return this;
1630     if (ty == Taarray && !((TypeAArray *)this)->index->merge()->deco)
1631         return this;
1632     if (ty != Tenum && nextOf() && !nextOf()->deco)
1633         return this;
1634 
1635     //printf("merge(%s)\n", toChars());
1636     Type *t = this;
1637     assert(t);
1638     if (!deco)
1639     {
1640         OutBuffer buf;
1641         buf.reserve(32);
1642 
1643         mangleToBuffer(this, &buf);
1644 
1645         StringValue *sv = stringtable.update((char *)buf.data, buf.offset);
1646         if (sv->ptrvalue)
1647         {
1648             t = (Type *) sv->ptrvalue;
1649             assert(t->deco);
1650             //printf("old value, deco = '%s' %p\n", t->deco, t->deco);
1651         }
1652         else
1653         {
1654             sv->ptrvalue = (char *)(t = stripDefaultArgs(t));
1655             deco = t->deco = const_cast<char *>(sv->toDchars());
1656             //printf("new value, deco = '%s' %p\n", t->deco, t->deco);
1657         }
1658     }
1659     return t;
1660 }
1661 
1662 /*************************************
1663  * This version does a merge even if the deco is already computed.
1664  * Necessary for types that have a deco, but are not merged.
1665  */
merge2()1666 Type *Type::merge2()
1667 {
1668     //printf("merge2(%s)\n", toChars());
1669     Type *t = this;
1670     assert(t);
1671     if (!t->deco)
1672         return t->merge();
1673 
1674     StringValue *sv = stringtable.lookup((char *)t->deco, strlen(t->deco));
1675     if (sv && sv->ptrvalue)
1676     {   t = (Type *) sv->ptrvalue;
1677         assert(t->deco);
1678     }
1679     else
1680         assert(0);
1681     return t;
1682 }
1683 
isintegral()1684 bool Type::isintegral()
1685 {
1686     return false;
1687 }
1688 
isfloating()1689 bool Type::isfloating()
1690 {
1691     return false;
1692 }
1693 
isreal()1694 bool Type::isreal()
1695 {
1696     return false;
1697 }
1698 
isimaginary()1699 bool Type::isimaginary()
1700 {
1701     return false;
1702 }
1703 
iscomplex()1704 bool Type::iscomplex()
1705 {
1706     return false;
1707 }
1708 
isscalar()1709 bool Type::isscalar()
1710 {
1711     return false;
1712 }
1713 
isunsigned()1714 bool Type::isunsigned()
1715 {
1716     return false;
1717 }
1718 
isClassHandle()1719 ClassDeclaration *Type::isClassHandle()
1720 {
1721     return NULL;
1722 }
1723 
isscope()1724 bool Type::isscope()
1725 {
1726     return false;
1727 }
1728 
isString()1729 bool Type::isString()
1730 {
1731     return false;
1732 }
1733 
1734 /**************************
1735  * When T is mutable,
1736  * Given:
1737  *      T a, b;
1738  * Can we bitwise assign:
1739  *      a = b;
1740  * ?
1741  */
isAssignable()1742 bool Type::isAssignable()
1743 {
1744     return true;
1745 }
1746 
1747 /**************************
1748  * Returns true if T can be converted to boolean value.
1749  */
isBoolean()1750 bool Type::isBoolean()
1751 {
1752     return isscalar();
1753 }
1754 
1755 /********************************
1756  * true if when type goes out of scope, it needs a destructor applied.
1757  * Only applies to value types, not ref types.
1758  */
needsDestruction()1759 bool Type::needsDestruction()
1760 {
1761     return false;
1762 }
1763 
1764 /*********************************
1765  *
1766  */
1767 
needsNested()1768 bool Type::needsNested()
1769 {
1770     return false;
1771 }
1772 
1773 /*********************************
1774  * Check type to see if it is based on a deprecated symbol.
1775  */
1776 
checkDeprecated(Loc loc,Scope * sc)1777 void Type::checkDeprecated(Loc loc, Scope *sc)
1778 {
1779     Dsymbol *s = toDsymbol(sc);
1780 
1781     if (s)
1782         s->checkDeprecated(loc, sc);
1783 }
1784 
1785 
defaultInit(Loc)1786 Expression *Type::defaultInit(Loc)
1787 {
1788     return NULL;
1789 }
1790 
1791 /***************************************
1792  * Use when we prefer the default initializer to be a literal,
1793  * rather than a global immutable variable.
1794  */
defaultInitLiteral(Loc loc)1795 Expression *Type::defaultInitLiteral(Loc loc)
1796 {
1797     return defaultInit(loc);
1798 }
1799 
isZeroInit(Loc)1800 bool Type::isZeroInit(Loc)
1801 {
1802     return false;           // assume not
1803 }
1804 
isBaseOf(Type *,int *)1805 bool Type::isBaseOf(Type *, int *)
1806 {
1807     return 0;           // assume not
1808 }
1809 
1810 /********************************
1811  * Determine if 'this' can be implicitly converted
1812  * to type 'to'.
1813  * Returns:
1814  *      MATCHnomatch, MATCHconvert, MATCHconst, MATCHexact
1815  */
1816 
implicitConvTo(Type * to)1817 MATCH Type::implicitConvTo(Type *to)
1818 {
1819     //printf("Type::implicitConvTo(this=%p, to=%p)\n", this, to);
1820     //printf("from: %s\n", toChars());
1821     //printf("to  : %s\n", to->toChars());
1822     if (this->equals(to))
1823         return MATCHexact;
1824     return MATCHnomatch;
1825 }
1826 
1827 /*******************************
1828  * Determine if converting 'this' to 'to' is an identity operation,
1829  * a conversion to const operation, or the types aren't the same.
1830  * Returns:
1831  *      MATCHexact      'this' == 'to'
1832  *      MATCHconst      'to' is const
1833  *      MATCHnomatch    conversion to mutable or invariant
1834  */
1835 
constConv(Type * to)1836 MATCH Type::constConv(Type *to)
1837 {
1838     //printf("Type::constConv(this = %s, to = %s)\n", toChars(), to->toChars());
1839     if (equals(to))
1840         return MATCHexact;
1841     if (ty == to->ty && MODimplicitConv(mod, to->mod))
1842         return MATCHconst;
1843     return MATCHnomatch;
1844 }
1845 
1846 /***************************************
1847  * Return MOD bits matching this type to wild parameter type (tprm).
1848  */
1849 
deduceWild(Type * t,bool)1850 unsigned char Type::deduceWild(Type *t, bool)
1851 {
1852     //printf("Type::deduceWild this = '%s', tprm = '%s'\n", toChars(), tprm->toChars());
1853 
1854     if (t->isWild())
1855     {
1856         if (isImmutable())
1857             return MODimmutable;
1858         else if (isWildConst())
1859         {
1860             if (t->isWildConst())
1861                 return MODwild;
1862             else
1863                 return MODwildconst;
1864         }
1865         else if (isWild())
1866             return MODwild;
1867         else if (isConst())
1868             return MODconst;
1869         else if (isMutable())
1870             return MODmutable;
1871         else
1872             assert(0);
1873     }
1874     return 0;
1875 }
1876 
unqualify(unsigned m)1877 Type *Type::unqualify(unsigned m)
1878 {
1879     Type *t = mutableOf()->unSharedOf();
1880 
1881     Type *tn = ty == Tenum ? NULL : nextOf();
1882     if (tn && tn->ty != Tfunction)
1883     {
1884         Type *utn = tn->unqualify(m);
1885         if (utn != tn)
1886         {
1887             if (ty == Tpointer)
1888                 t = utn->pointerTo();
1889             else if (ty == Tarray)
1890                 t = utn->arrayOf();
1891             else if (ty == Tsarray)
1892                 t = new TypeSArray(utn, ((TypeSArray *)this)->dim);
1893             else if (ty == Taarray)
1894             {
1895                 t = new TypeAArray(utn, ((TypeAArray *)this)->index);
1896                 ((TypeAArray *)t)->sc = ((TypeAArray *)this)->sc;   // duplicate scope
1897             }
1898             else
1899                 assert(0);
1900 
1901             t = t->merge();
1902         }
1903     }
1904     t = t->addMod(mod & ~m);
1905     return t;
1906 }
1907 
substWildTo(unsigned mod)1908 Type *Type::substWildTo(unsigned mod)
1909 {
1910     //printf("+Type::substWildTo this = %s, mod = x%x\n", toChars(), mod);
1911     Type *t;
1912 
1913     if (Type *tn = nextOf())
1914     {
1915         // substitution has no effect on function pointer type.
1916         if (ty == Tpointer && tn->ty == Tfunction)
1917         {
1918             t = this;
1919             goto L1;
1920         }
1921 
1922         t = tn->substWildTo(mod);
1923         if (t == tn)
1924             t = this;
1925         else
1926         {
1927             if (ty == Tpointer)
1928                 t = t->pointerTo();
1929             else if (ty == Tarray)
1930                 t = t->arrayOf();
1931             else if (ty == Tsarray)
1932                 t = new TypeSArray(t, ((TypeSArray *)this)->dim->syntaxCopy());
1933             else if (ty == Taarray)
1934             {
1935                 t = new TypeAArray(t, ((TypeAArray *)this)->index->syntaxCopy());
1936                 ((TypeAArray *)t)->sc = ((TypeAArray *)this)->sc;   // duplicate scope
1937             }
1938             else if (ty == Tdelegate)
1939             {
1940                 t = new TypeDelegate(t);
1941             }
1942             else
1943                 assert(0);
1944 
1945             t = t->merge();
1946         }
1947     }
1948     else
1949         t = this;
1950 
1951 L1:
1952     if (isWild())
1953     {
1954         if (mod == MODimmutable)
1955         {
1956             t = t->immutableOf();
1957         }
1958         else if (mod == MODwildconst)
1959         {
1960             t = t->wildConstOf();
1961         }
1962         else if (mod == MODwild)
1963         {
1964             if (isWildConst())
1965                 t = t->wildConstOf();
1966             else
1967                 t = t->wildOf();
1968         }
1969         else if (mod == MODconst)
1970         {
1971             t = t->constOf();
1972         }
1973         else
1974         {
1975             if (isWildConst())
1976                 t = t->constOf();
1977             else
1978                 t = t->mutableOf();
1979         }
1980     }
1981     if (isConst())
1982         t = t->addMod(MODconst);
1983     if (isShared())
1984         t = t->addMod(MODshared);
1985 
1986     //printf("-Type::substWildTo t = %s\n", t->toChars());
1987     return t;
1988 }
1989 
substWildTo(unsigned)1990 Type *TypeFunction::substWildTo(unsigned)
1991 {
1992     if (!iswild && !(mod & MODwild))
1993         return this;
1994 
1995     // Substitude inout qualifier of function type to mutable or immutable
1996     // would break type system. Instead substitude inout to the most weak
1997     // qualifer - const.
1998     unsigned m = MODconst;
1999 
2000     assert(next);
2001     Type *tret = next->substWildTo(m);
2002     Parameters *params = parameters;
2003     if (mod & MODwild)
2004         params = parameters->copy();
2005     for (size_t i = 0; i < params->dim; i++)
2006     {
2007         Parameter *p = (*params)[i];
2008         Type *t = p->type->substWildTo(m);
2009         if (t == p->type)
2010             continue;
2011         if (params == parameters)
2012             params = parameters->copy();
2013         (*params)[i] = new Parameter(p->storageClass, t, NULL, NULL);
2014     }
2015     if (next == tret && params == parameters)
2016         return this;
2017 
2018     // Similar to TypeFunction::syntaxCopy;
2019     TypeFunction *t = new TypeFunction(params, tret, varargs, linkage);
2020     t->mod = ((mod & MODwild) ? (mod & ~MODwild) | MODconst : mod);
2021     t->isnothrow = isnothrow;
2022     t->isnogc = isnogc;
2023     t->purity = purity;
2024     t->isproperty = isproperty;
2025     t->isref = isref;
2026     t->isreturn = isreturn;
2027     t->isscope = isscope;
2028     t->isscopeinferred = isscopeinferred;
2029     t->iswild = 0;
2030     t->trust = trust;
2031     t->fargs = fargs;
2032     return t->merge();
2033 }
2034 
2035 /**************************
2036  * Return type with the top level of it being mutable.
2037  */
toHeadMutable()2038 Type *Type::toHeadMutable()
2039 {
2040     if (!mod)
2041         return this;
2042     return mutableOf();
2043 }
2044 
2045 /***************************************
2046  * Calculate built-in properties which just the type is necessary.
2047  *
2048  * If flag & 1, don't report "not a property" error and just return NULL.
2049  */
getProperty(Loc loc,Identifier * ident,int flag)2050 Expression *Type::getProperty(Loc loc, Identifier *ident, int flag)
2051 {
2052     Expression *e;
2053 
2054     if (ident == Id::__sizeof)
2055     {
2056         d_uns64 sz = size(loc);
2057         if (sz == SIZE_INVALID)
2058             return new ErrorExp();
2059         e = new IntegerExp(loc, sz, Type::tsize_t);
2060     }
2061     else if (ident == Id::__xalignof)
2062     {
2063         unsigned explicitAlignment = alignment();
2064         unsigned naturalAlignment = alignsize();
2065         unsigned actualAlignment = (explicitAlignment == STRUCTALIGN_DEFAULT ? naturalAlignment : explicitAlignment);
2066         e = new IntegerExp(loc, actualAlignment, Type::tsize_t);
2067     }
2068     else if (ident == Id::_init)
2069     {
2070         Type *tb = toBasetype();
2071         e = defaultInitLiteral(loc);
2072         if (tb->ty == Tstruct && tb->needsNested())
2073         {
2074             StructLiteralExp *se = (StructLiteralExp *)e;
2075             se->useStaticInit = true;
2076         }
2077     }
2078     else if (ident == Id::_mangleof)
2079     {
2080         if (!deco)
2081         {
2082             error(loc, "forward reference of type %s.mangleof", toChars());
2083             e = new ErrorExp();
2084         }
2085         else
2086         {
2087             e = new StringExp(loc, (char *)deco, strlen(deco));
2088             Scope sc;
2089             e = ::semantic(e, &sc);
2090         }
2091     }
2092     else if (ident == Id::stringof)
2093     {
2094         const char *s = toChars();
2095         e = new StringExp(loc, const_cast<char *>(s), strlen(s));
2096         Scope sc;
2097         e = ::semantic(e, &sc);
2098     }
2099     else if (flag && this != Type::terror)
2100     {
2101         return NULL;
2102     }
2103     else
2104     {
2105         Dsymbol *s = NULL;
2106         if (ty == Tstruct || ty == Tclass || ty == Tenum)
2107             s = toDsymbol(NULL);
2108         if (s)
2109             s = s->search_correct(ident);
2110         if (this != Type::terror)
2111         {
2112             if (s)
2113                 error(loc, "no property '%s' for type '%s', did you mean '%s'?", ident->toChars(), toChars(), s->toChars());
2114             else
2115                 error(loc, "no property '%s' for type '%s'", ident->toChars(), toChars());
2116         }
2117         e = new ErrorExp();
2118     }
2119     return e;
2120 }
2121 
2122 /***************************************
2123  * Access the members of the object e. This type is same as e->type.
2124  *
2125  * If flag & 1, don't report "not a property" error and just return NULL.
2126  */
dotExp(Scope * sc,Expression * e,Identifier * ident,int flag)2127 Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
2128 {
2129     VarDeclaration *v = NULL;
2130 
2131     Expression *ex = e;
2132     while (ex->op == TOKcomma)
2133         ex = ((CommaExp *)ex)->e2;
2134     if (ex->op == TOKdotvar)
2135     {
2136         DotVarExp *dv = (DotVarExp *)ex;
2137         v = dv->var->isVarDeclaration();
2138     }
2139     else if (ex->op == TOKvar)
2140     {
2141         VarExp *ve = (VarExp *)ex;
2142         v = ve->var->isVarDeclaration();
2143     }
2144     if (v)
2145     {
2146         if (ident == Id::offsetof)
2147         {
2148             if (v->isField())
2149             {
2150                 AggregateDeclaration *ad = v->toParent()->isAggregateDeclaration();
2151                 ad->size(e->loc);
2152                 if (ad->sizeok != SIZEOKdone)
2153                     return new ErrorExp();
2154                 e = new IntegerExp(e->loc, v->offset, Type::tsize_t);
2155                 return e;
2156             }
2157         }
2158         else if (ident == Id::_init)
2159         {
2160             Type *tb = toBasetype();
2161             e = defaultInitLiteral(e->loc);
2162             if (tb->ty == Tstruct && tb->needsNested())
2163             {
2164                 StructLiteralExp *se = (StructLiteralExp *)e;
2165                 se->useStaticInit = true;
2166             }
2167             goto Lreturn;
2168         }
2169     }
2170     if (ident == Id::stringof)
2171     {
2172         /* Bugzilla 3796: this should demangle e->type->deco rather than
2173          * pretty-printing the type.
2174          */
2175         const char *s = e->toChars();
2176         e = new StringExp(e->loc, const_cast<char *>(s), strlen(s));
2177     }
2178     else
2179         e = getProperty(e->loc, ident, flag & 1);
2180 
2181 Lreturn:
2182     if (e)
2183         e = ::semantic(e, sc);
2184     return e;
2185 }
2186 
2187 /************************************
2188  * Return alignment to use for this type.
2189  */
2190 
alignment()2191 structalign_t Type::alignment()
2192 {
2193     return STRUCTALIGN_DEFAULT;
2194 }
2195 
2196 /***************************************
2197  * Figures out what to do with an undefined member reference
2198  * for classes and structs.
2199  *
2200  * If flag & 1, don't report "not a property" error and just return NULL.
2201  */
noMember(Scope * sc,Expression * e,Identifier * ident,int flag)2202 Expression *Type::noMember(Scope *sc, Expression *e, Identifier *ident, int flag)
2203 {
2204     //printf("Type::noMember(e: %s ident: %s flag: %d)\n", e->toChars(), ident->toChars(), flag);
2205 
2206     static int nest;      // https://issues.dlang.org/show_bug.cgi?id=17380
2207 
2208     if (++nest > global.recursionLimit)
2209     {
2210       ::error(e->loc, "cannot resolve identifier `%s`", ident->toChars());
2211       --nest;
2212       return (flag & 1) ? NULL : new ErrorExp();
2213     }
2214 
2215     assert(ty == Tstruct || ty == Tclass);
2216     AggregateDeclaration *sym = toDsymbol(sc)->isAggregateDeclaration();
2217     assert(sym);
2218 
2219     if (ident != Id::__sizeof &&
2220         ident != Id::__xalignof &&
2221         ident != Id::_init &&
2222         ident != Id::_mangleof &&
2223         ident != Id::stringof &&
2224         ident != Id::offsetof &&
2225         // Bugzilla 15045: Don't forward special built-in member functions.
2226         ident != Id::ctor &&
2227         ident != Id::dtor &&
2228         ident != Id::__xdtor &&
2229         ident != Id::postblit &&
2230         ident != Id::__xpostblit)
2231     {
2232         /* Look for overloaded opDot() to see if we should forward request
2233          * to it.
2234          */
2235         if (Dsymbol *fd = search_function(sym, Id::opDot))
2236         {
2237             /* Rewrite e.ident as:
2238              *  e.opDot().ident
2239              */
2240             e = build_overload(e->loc, sc, e, NULL, fd);
2241             e = new DotIdExp(e->loc, e, ident);
2242             e = ::semantic(e, sc);
2243             --nest;
2244             return e;
2245         }
2246 
2247         /* Look for overloaded opDispatch to see if we should forward request
2248          * to it.
2249          */
2250         if (Dsymbol *fd = search_function(sym, Id::opDispatch))
2251         {
2252             /* Rewrite e.ident as:
2253              *  e.opDispatch!("ident")
2254              */
2255             TemplateDeclaration *td = fd->isTemplateDeclaration();
2256             if (!td)
2257             {
2258                 fd->error("must be a template opDispatch(string s), not a %s", fd->kind());
2259                 --nest;
2260                 return new ErrorExp();
2261             }
2262             StringExp *se = new StringExp(e->loc, const_cast<char *>(ident->toChars()));
2263             Objects *tiargs = new Objects();
2264             tiargs->push(se);
2265             DotTemplateInstanceExp *dti = new DotTemplateInstanceExp(e->loc, e, Id::opDispatch, tiargs);
2266             dti->ti->tempdecl = td;
2267 
2268             /* opDispatch, which doesn't need IFTI,  may occur instantiate error.
2269              * It should be gagged if flag & 1.
2270              * e.g.
2271              *  template opDispatch(name) if (isValid!name) { ... }
2272              */
2273             unsigned errors = flag & 1 ? global.startGagging() : 0;
2274             e = semanticY(dti, sc, 0);
2275             if (flag & 1 && global.endGagging(errors))
2276                 e = NULL;
2277             --nest;
2278             return e;
2279         }
2280 
2281         /* See if we should forward to the alias this.
2282          */
2283         if (sym->aliasthis)
2284         {   /* Rewrite e.ident as:
2285              *  e.aliasthis.ident
2286              */
2287             e = resolveAliasThis(sc, e);
2288             DotIdExp *die = new DotIdExp(e->loc, e, ident);
2289             e = semanticY(die, sc, flag & 1);
2290             --nest;
2291             return e;
2292         }
2293     }
2294 
2295     e = Type::dotExp(sc, e, ident, flag);
2296     --nest;
2297     return e;
2298 }
2299 
error(Loc loc,const char * format,...)2300 void Type::error(Loc loc, const char *format, ...)
2301 {
2302     va_list ap;
2303     va_start(ap, format);
2304     ::verror(loc, format, ap);
2305     va_end( ap );
2306 }
2307 
warning(Loc loc,const char * format,...)2308 void Type::warning(Loc loc, const char *format, ...)
2309 {
2310     va_list ap;
2311     va_start(ap, format);
2312     ::vwarning(loc, format, ap);
2313     va_end( ap );
2314 }
2315 
getTypeInfoIdent()2316 Identifier *Type::getTypeInfoIdent()
2317 {
2318     // _init_10TypeInfo_%s
2319     OutBuffer buf;
2320     buf.reserve(32);
2321     mangleToBuffer(this, &buf);
2322 
2323     size_t len = buf.offset;
2324     buf.writeByte(0);
2325 
2326     // Allocate buffer on stack, fail over to using malloc()
2327     char namebuf[128];
2328     size_t namelen = 19 + sizeof(len) * 3 + len + 1;
2329     char *name = namelen <= sizeof(namebuf) ? namebuf : (char *)mem.xmalloc(namelen);
2330 
2331     int length = sprintf(name, "_D%lluTypeInfo_%s6__initZ", (unsigned long long) 9 + len, buf.data);
2332     //printf("%p, deco = %s, name = %s\n", this, deco, name);
2333     assert(0 < length && (size_t)length < namelen);     // don't overflow the buffer
2334 
2335     Identifier *id = Identifier::idPool(name, length);
2336 
2337     if (name != namebuf)
2338         free(name);
2339     return id;
2340 }
2341 
isTypeBasic()2342 TypeBasic *Type::isTypeBasic()
2343 {
2344     return NULL;
2345 }
2346 
toTypeFunction()2347 TypeFunction *Type::toTypeFunction()
2348 {
2349     if (ty != Tfunction)
2350         assert(0);
2351     return (TypeFunction *)this;
2352 }
2353 
2354 /***************************************
2355  * Resolve 'this' type to either type, symbol, or expression.
2356  * If errors happened, resolved to Type.terror.
2357  */
resolve(Loc loc,Scope * sc,Expression ** pe,Type ** pt,Dsymbol ** ps,bool)2358 void Type::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool)
2359 {
2360     //printf("Type::resolve() %s, %d\n", toChars(), ty);
2361     Type *t = semantic(loc, sc);
2362     *pt = t;
2363     *pe = NULL;
2364     *ps = NULL;
2365 }
2366 
2367 /***************************************
2368  * Normalize `e` as the result of Type::resolve() process.
2369  */
resolveExp(Expression * e,Type ** pt,Expression ** pe,Dsymbol ** ps)2370 void Type::resolveExp(Expression *e, Type **pt, Expression **pe, Dsymbol **ps)
2371 {
2372     *pt = NULL;
2373     *pe = NULL;
2374     *ps = NULL;
2375 
2376     Dsymbol *s;
2377     switch (e->op)
2378     {
2379         case TOKerror:
2380             *pt = Type::terror;
2381             return;
2382 
2383         case TOKtype:
2384             *pt = e->type;
2385             return;
2386 
2387         case TOKvar:
2388             s = ((VarExp *)e)->var;
2389             if (s->isVarDeclaration())
2390                 goto Ldefault;
2391             //if (s->isOverDeclaration())
2392             //    todo;
2393             break;
2394 
2395         case TOKtemplate:
2396             // TemplateDeclaration
2397             s = ((TemplateExp *)e)->td;
2398             break;
2399 
2400         case TOKimport:
2401             s = ((ScopeExp *)e)->sds;
2402             // TemplateDeclaration, TemplateInstance, Import, Package, Module
2403             break;
2404 
2405         case TOKfunction:
2406             s = getDsymbol(e);
2407             break;
2408 
2409         //case TOKthis:
2410         //case TOKsuper:
2411 
2412         //case TOKtuple:
2413 
2414         //case TOKoverloadset:
2415 
2416         //case TOKdotvar:
2417         //case TOKdottd:
2418         //case TOKdotti:
2419         //case TOKdottype:
2420         //case TOKdot:
2421 
2422         default:
2423     Ldefault:
2424             *pe = e;
2425             return;
2426     }
2427 
2428     *ps = s;
2429 }
2430 
2431 /***************************************
2432  * Return !=0 if the type or any of its subtypes is wild.
2433  */
2434 
hasWild()2435 int Type::hasWild() const
2436 {
2437     return mod & MODwild;
2438 }
2439 
2440 /***************************************
2441  * Return !=0 if type has pointers that need to
2442  * be scanned by the GC during a collection cycle.
2443  */
hasPointers()2444 bool Type::hasPointers()
2445 {
2446     //printf("Type::hasPointers() %s, %d\n", toChars(), ty);
2447     return false;
2448 }
2449 
2450 /*************************************
2451  * Detect if type has pointer fields that are initialized to void.
2452  * Local stack variables with such void fields can remain uninitialized,
2453  * leading to pointer bugs.
2454  * Returns:
2455  *  true if so
2456  */
hasVoidInitPointers()2457 bool Type::hasVoidInitPointers()
2458 {
2459     return false;
2460 }
2461 
2462 /*************************************
2463  * If this is a type of something, return that something.
2464  */
2465 
nextOf()2466 Type *Type::nextOf()
2467 {
2468     return NULL;
2469 }
2470 
2471 /*************************************
2472  * If this is a type of static array, return its base element type.
2473  */
2474 
baseElemOf()2475 Type *Type::baseElemOf()
2476 {
2477     Type *t = toBasetype();
2478     while (t->ty == Tsarray)
2479         t = ((TypeSArray *)t)->next->toBasetype();
2480     return t;
2481 }
2482 
2483 /*************************************
2484  * Bugzilla 14488: Check if the inner most base type is complex or imaginary.
2485  * Should only give alerts when set to emit transitional messages.
2486  */
2487 
checkComplexTransition(Loc loc)2488 void Type::checkComplexTransition(Loc loc)
2489 {
2490     Type *t = baseElemOf();
2491     while (t->ty == Tpointer || t->ty == Tarray)
2492         t = t->nextOf()->baseElemOf();
2493 
2494     if (t->isimaginary() || t->iscomplex())
2495     {
2496         Type *rt;
2497         switch (t->ty)
2498         {
2499             case Tcomplex32:
2500             case Timaginary32:
2501                 rt = Type::tfloat32; break;
2502             case Tcomplex64:
2503             case Timaginary64:
2504                 rt = Type::tfloat64; break;
2505             case Tcomplex80:
2506             case Timaginary80:
2507                 rt = Type::tfloat80; break;
2508             default:
2509                 assert(0);
2510         }
2511         if (t->iscomplex())
2512         {
2513             message(loc, "use of complex type `%s` is scheduled for deprecation, "
2514                     "use `std.complex.Complex!(%s)` instead", toChars(), rt->toChars());
2515         }
2516         else
2517         {
2518             message(loc, "use of imaginary type `%s` is scheduled for deprecation, "
2519                     "use `%s` instead\n", toChars(), rt->toChars());
2520         }
2521     }
2522 }
2523 
2524 /*******************************************
2525  * Compute number of elements for a (possibly multidimensional) static array,
2526  * or 1 for other types.
2527  * Params:
2528  *  loc = for error message
2529  * Returns:
2530  *  number of elements, uint.max on overflow
2531  */
numberOfElems(const Loc & loc)2532 unsigned Type::numberOfElems(const Loc &loc)
2533 {
2534   //printf("Type::numberOfElems()\n");
2535   uinteger_t n = 1;
2536   Type *tb = this;
2537   while ((tb = tb->toBasetype())->ty == Tsarray)
2538     {
2539       bool overflow = false;
2540       n = mulu(n, ((TypeSArray *)tb)->dim->toUInteger(), overflow);
2541       if (overflow || n >= UINT32_MAX)
2542       {
2543           error(loc, "static array `%s` size overflowed to %llu", toChars(), (unsigned long long)n);
2544           return UINT32_MAX;
2545       }
2546       tb = ((TypeSArray *)tb)->next;
2547     }
2548   return (unsigned)n;
2549 }
2550 
2551 /****************************************
2552  * Return the mask that an integral type will
2553  * fit into.
2554  */
sizemask()2555 uinteger_t Type::sizemask()
2556 {   uinteger_t m;
2557 
2558     switch (toBasetype()->ty)
2559     {
2560         case Tbool:     m = 1;                          break;
2561         case Tchar:
2562         case Tint8:
2563         case Tuns8:     m = 0xFF;                       break;
2564         case Twchar:
2565         case Tint16:
2566         case Tuns16:    m = 0xFFFFUL;                   break;
2567         case Tdchar:
2568         case Tint32:
2569         case Tuns32:    m = 0xFFFFFFFFUL;               break;
2570         case Tint64:
2571         case Tuns64:    m = 0xFFFFFFFFFFFFFFFFULL;      break;
2572         default:
2573                 assert(0);
2574     }
2575     return m;
2576 }
2577 
2578 /* ============================= TypeError =========================== */
2579 
TypeError()2580 TypeError::TypeError()
2581         : Type(Terror)
2582 {
2583 }
2584 
syntaxCopy()2585 Type *TypeError::syntaxCopy()
2586 {
2587     // No semantic analysis done, no need to copy
2588     return this;
2589 }
2590 
size(Loc)2591 d_uns64 TypeError::size(Loc) { return SIZE_INVALID; }
getProperty(Loc,Identifier *,int)2592 Expression *TypeError::getProperty(Loc, Identifier *, int) { return new ErrorExp(); }
dotExp(Scope *,Expression *,Identifier *,int)2593 Expression *TypeError::dotExp(Scope *, Expression *, Identifier *, int) { return new ErrorExp(); }
defaultInit(Loc)2594 Expression *TypeError::defaultInit(Loc) { return new ErrorExp(); }
defaultInitLiteral(Loc)2595 Expression *TypeError::defaultInitLiteral(Loc) { return new ErrorExp(); }
2596 
2597 /* ============================= TypeNext =========================== */
2598 
TypeNext(TY ty,Type * next)2599 TypeNext::TypeNext(TY ty, Type *next)
2600         : Type(ty)
2601 {
2602     this->next = next;
2603 }
2604 
checkDeprecated(Loc loc,Scope * sc)2605 void TypeNext::checkDeprecated(Loc loc, Scope *sc)
2606 {
2607     Type::checkDeprecated(loc, sc);
2608     if (next)   // next can be NULL if TypeFunction and auto return type
2609         next->checkDeprecated(loc, sc);
2610 }
2611 
hasWild()2612 int TypeNext::hasWild() const
2613 {
2614     if (ty == Tfunction)
2615         return 0;
2616     if (ty == Tdelegate)
2617         return Type::hasWild();
2618     return mod & MODwild || (next && next->hasWild());
2619 }
2620 
2621 
2622 /*******************************
2623  * For TypeFunction, nextOf() can return NULL if the function return
2624  * type is meant to be inferred, and semantic() hasn't yet ben run
2625  * on the function. After semantic(), it must no longer be NULL.
2626  */
2627 
nextOf()2628 Type *TypeNext::nextOf()
2629 {
2630     return next;
2631 }
2632 
makeConst()2633 Type *TypeNext::makeConst()
2634 {
2635     //printf("TypeNext::makeConst() %p, %s\n", this, toChars());
2636     if (cto)
2637     {
2638         assert(cto->mod == MODconst);
2639         return cto;
2640     }
2641     TypeNext *t = (TypeNext *)Type::makeConst();
2642     if (ty != Tfunction && next->ty != Tfunction &&
2643         !next->isImmutable())
2644     {
2645         if (next->isShared())
2646         {
2647             if (next->isWild())
2648                 t->next = next->sharedWildConstOf();
2649             else
2650                 t->next = next->sharedConstOf();
2651         }
2652         else
2653         {
2654             if (next->isWild())
2655                 t->next = next->wildConstOf();
2656             else
2657                 t->next = next->constOf();
2658         }
2659     }
2660     //printf("TypeNext::makeConst() returns %p, %s\n", t, t->toChars());
2661     return t;
2662 }
2663 
makeImmutable()2664 Type *TypeNext::makeImmutable()
2665 {
2666     //printf("TypeNext::makeImmutable() %s\n", toChars());
2667     if (ito)
2668     {
2669         assert(ito->isImmutable());
2670         return ito;
2671     }
2672     TypeNext *t = (TypeNext *)Type::makeImmutable();
2673     if (ty != Tfunction && next->ty != Tfunction &&
2674         !next->isImmutable())
2675     {
2676         t->next = next->immutableOf();
2677     }
2678     return t;
2679 }
2680 
makeShared()2681 Type *TypeNext::makeShared()
2682 {
2683     //printf("TypeNext::makeShared() %s\n", toChars());
2684     if (sto)
2685     {
2686         assert(sto->mod == MODshared);
2687         return sto;
2688     }
2689     TypeNext *t = (TypeNext *)Type::makeShared();
2690     if (ty != Tfunction && next->ty != Tfunction &&
2691         !next->isImmutable())
2692     {
2693         if (next->isWild())
2694         {
2695             if (next->isConst())
2696                 t->next = next->sharedWildConstOf();
2697             else
2698                 t->next = next->sharedWildOf();
2699         }
2700         else
2701         {
2702             if (next->isConst())
2703                 t->next = next->sharedConstOf();
2704             else
2705                 t->next = next->sharedOf();
2706         }
2707     }
2708     //printf("TypeNext::makeShared() returns %p, %s\n", t, t->toChars());
2709     return t;
2710 }
2711 
makeSharedConst()2712 Type *TypeNext::makeSharedConst()
2713 {
2714     //printf("TypeNext::makeSharedConst() %s\n", toChars());
2715     if (scto)
2716     {
2717         assert(scto->mod == (MODshared | MODconst));
2718         return scto;
2719     }
2720     TypeNext *t = (TypeNext *)Type::makeSharedConst();
2721     if (ty != Tfunction && next->ty != Tfunction &&
2722         !next->isImmutable())
2723     {
2724         if (next->isWild())
2725             t->next = next->sharedWildConstOf();
2726         else
2727             t->next = next->sharedConstOf();
2728     }
2729     //printf("TypeNext::makeSharedConst() returns %p, %s\n", t, t->toChars());
2730     return t;
2731 }
2732 
makeWild()2733 Type *TypeNext::makeWild()
2734 {
2735     //printf("TypeNext::makeWild() %s\n", toChars());
2736     if (wto)
2737     {
2738         assert(wto->mod == MODwild);
2739         return wto;
2740     }
2741     TypeNext *t = (TypeNext *)Type::makeWild();
2742     if (ty != Tfunction && next->ty != Tfunction &&
2743         !next->isImmutable())
2744     {
2745         if (next->isShared())
2746         {
2747             if (next->isConst())
2748                 t->next = next->sharedWildConstOf();
2749             else
2750                 t->next = next->sharedWildOf();
2751         }
2752         else
2753         {
2754             if (next->isConst())
2755                 t->next = next->wildConstOf();
2756             else
2757                 t->next = next->wildOf();
2758         }
2759     }
2760     //printf("TypeNext::makeWild() returns %p, %s\n", t, t->toChars());
2761     return t;
2762 }
2763 
makeWildConst()2764 Type *TypeNext::makeWildConst()
2765 {
2766     //printf("TypeNext::makeWildConst() %s\n", toChars());
2767     if (wcto)
2768     {
2769         assert(wcto->mod == MODwildconst);
2770         return wcto;
2771     }
2772     TypeNext *t = (TypeNext *)Type::makeWildConst();
2773     if (ty != Tfunction && next->ty != Tfunction &&
2774         !next->isImmutable())
2775     {
2776         if (next->isShared())
2777             t->next = next->sharedWildConstOf();
2778         else
2779             t->next = next->wildConstOf();
2780     }
2781     //printf("TypeNext::makeWildConst() returns %p, %s\n", t, t->toChars());
2782     return t;
2783 }
2784 
makeSharedWild()2785 Type *TypeNext::makeSharedWild()
2786 {
2787     //printf("TypeNext::makeSharedWild() %s\n", toChars());
2788     if (swto)
2789     {
2790         assert(swto->isSharedWild());
2791         return swto;
2792     }
2793     TypeNext *t = (TypeNext *)Type::makeSharedWild();
2794     if (ty != Tfunction && next->ty != Tfunction &&
2795         !next->isImmutable())
2796     {
2797         if (next->isConst())
2798             t->next = next->sharedWildConstOf();
2799         else
2800             t->next = next->sharedWildOf();
2801     }
2802     //printf("TypeNext::makeSharedWild() returns %p, %s\n", t, t->toChars());
2803     return t;
2804 }
2805 
makeSharedWildConst()2806 Type *TypeNext::makeSharedWildConst()
2807 {
2808     //printf("TypeNext::makeSharedWildConst() %s\n", toChars());
2809     if (swcto)
2810     {
2811         assert(swcto->mod == (MODshared | MODwildconst));
2812         return swcto;
2813     }
2814     TypeNext *t = (TypeNext *)Type::makeSharedWildConst();
2815     if (ty != Tfunction && next->ty != Tfunction &&
2816         !next->isImmutable())
2817     {
2818         t->next = next->sharedWildConstOf();
2819     }
2820     //printf("TypeNext::makeSharedWildConst() returns %p, %s\n", t, t->toChars());
2821     return t;
2822 }
2823 
makeMutable()2824 Type *TypeNext::makeMutable()
2825 {
2826     //printf("TypeNext::makeMutable() %p, %s\n", this, toChars());
2827     TypeNext *t = (TypeNext *)Type::makeMutable();
2828     if (ty == Tsarray)
2829     {
2830         t->next = next->mutableOf();
2831     }
2832     //printf("TypeNext::makeMutable() returns %p, %s\n", t, t->toChars());
2833     return t;
2834 }
2835 
constConv(Type * to)2836 MATCH TypeNext::constConv(Type *to)
2837 {
2838     //printf("TypeNext::constConv from = %s, to = %s\n", toChars(), to->toChars());
2839     if (equals(to))
2840         return MATCHexact;
2841 
2842     if (!(ty == to->ty && MODimplicitConv(mod, to->mod)))
2843         return MATCHnomatch;
2844 
2845     Type *tn = to->nextOf();
2846     if (!(tn && next->ty == tn->ty))
2847         return MATCHnomatch;
2848 
2849     MATCH m;
2850     if (to->isConst())  // whole tail const conversion
2851     {   // Recursive shared level check
2852         m = next->constConv(tn);
2853         if (m == MATCHexact)
2854             m = MATCHconst;
2855     }
2856     else
2857     {   //printf("\tnext => %s, to->next => %s\n", next->toChars(), tn->toChars());
2858         m = next->equals(tn) ? MATCHconst : MATCHnomatch;
2859     }
2860     return m;
2861 }
2862 
deduceWild(Type * t,bool isRef)2863 unsigned char TypeNext::deduceWild(Type *t, bool isRef)
2864 {
2865     if (ty == Tfunction)
2866         return 0;
2867 
2868     unsigned char wm;
2869 
2870     Type *tn = t->nextOf();
2871     if (!isRef && (ty == Tarray || ty == Tpointer) && tn)
2872     {
2873         wm = next->deduceWild(tn, true);
2874         if (!wm)
2875             wm = Type::deduceWild(t, true);
2876     }
2877     else
2878     {
2879         wm = Type::deduceWild(t, isRef);
2880         if (!wm && tn)
2881             wm = next->deduceWild(tn, true);
2882     }
2883 
2884     return wm;
2885 }
2886 
2887 
transitive()2888 void TypeNext::transitive()
2889 {
2890     /* Invoke transitivity of type attributes
2891      */
2892     next = next->addMod(mod);
2893 }
2894 
2895 /* ============================= TypeBasic =========================== */
2896 
2897 #define TFLAGSintegral  1
2898 #define TFLAGSfloating  2
2899 #define TFLAGSunsigned  4
2900 #define TFLAGSreal      8
2901 #define TFLAGSimaginary 0x10
2902 #define TFLAGScomplex   0x20
2903 
TypeBasic(TY ty)2904 TypeBasic::TypeBasic(TY ty)
2905         : Type(ty)
2906 {   const char *d;
2907     unsigned flags;
2908 
2909     flags = 0;
2910     switch (ty)
2911     {
2912         case Tvoid:     d = Token::toChars(TOKvoid);
2913                         break;
2914 
2915         case Tint8:     d = Token::toChars(TOKint8);
2916                         flags |= TFLAGSintegral;
2917                         break;
2918 
2919         case Tuns8:     d = Token::toChars(TOKuns8);
2920                         flags |= TFLAGSintegral | TFLAGSunsigned;
2921                         break;
2922 
2923         case Tint16:    d = Token::toChars(TOKint16);
2924                         flags |= TFLAGSintegral;
2925                         break;
2926 
2927         case Tuns16:    d = Token::toChars(TOKuns16);
2928                         flags |= TFLAGSintegral | TFLAGSunsigned;
2929                         break;
2930 
2931         case Tint32:    d = Token::toChars(TOKint32);
2932                         flags |= TFLAGSintegral;
2933                         break;
2934 
2935         case Tuns32:    d = Token::toChars(TOKuns32);
2936                         flags |= TFLAGSintegral | TFLAGSunsigned;
2937                         break;
2938 
2939         case Tfloat32:  d = Token::toChars(TOKfloat32);
2940                         flags |= TFLAGSfloating | TFLAGSreal;
2941                         break;
2942 
2943         case Tint64:    d = Token::toChars(TOKint64);
2944                         flags |= TFLAGSintegral;
2945                         break;
2946 
2947         case Tuns64:    d = Token::toChars(TOKuns64);
2948                         flags |= TFLAGSintegral | TFLAGSunsigned;
2949                         break;
2950 
2951         case Tint128:   d = Token::toChars(TOKint128);
2952                         flags |= TFLAGSintegral;
2953                         break;
2954 
2955         case Tuns128:   d = Token::toChars(TOKuns128);
2956                         flags |= TFLAGSintegral | TFLAGSunsigned;
2957                         break;
2958 
2959         case Tfloat64:  d = Token::toChars(TOKfloat64);
2960                         flags |= TFLAGSfloating | TFLAGSreal;
2961                         break;
2962 
2963         case Tfloat80:  d = Token::toChars(TOKfloat80);
2964                         flags |= TFLAGSfloating | TFLAGSreal;
2965                         break;
2966 
2967         case Timaginary32: d = Token::toChars(TOKimaginary32);
2968                         flags |= TFLAGSfloating | TFLAGSimaginary;
2969                         break;
2970 
2971         case Timaginary64: d = Token::toChars(TOKimaginary64);
2972                         flags |= TFLAGSfloating | TFLAGSimaginary;
2973                         break;
2974 
2975         case Timaginary80: d = Token::toChars(TOKimaginary80);
2976                         flags |= TFLAGSfloating | TFLAGSimaginary;
2977                         break;
2978 
2979         case Tcomplex32: d = Token::toChars(TOKcomplex32);
2980                         flags |= TFLAGSfloating | TFLAGScomplex;
2981                         break;
2982 
2983         case Tcomplex64: d = Token::toChars(TOKcomplex64);
2984                         flags |= TFLAGSfloating | TFLAGScomplex;
2985                         break;
2986 
2987         case Tcomplex80: d = Token::toChars(TOKcomplex80);
2988                         flags |= TFLAGSfloating | TFLAGScomplex;
2989                         break;
2990 
2991         case Tbool:     d = "bool";
2992                         flags |= TFLAGSintegral | TFLAGSunsigned;
2993                         break;
2994 
2995         case Tchar:     d = Token::toChars(TOKchar);
2996                         flags |= TFLAGSintegral | TFLAGSunsigned;
2997                         break;
2998 
2999         case Twchar:    d = Token::toChars(TOKwchar);
3000                         flags |= TFLAGSintegral | TFLAGSunsigned;
3001                         break;
3002 
3003         case Tdchar:    d = Token::toChars(TOKdchar);
3004                         flags |= TFLAGSintegral | TFLAGSunsigned;
3005                         break;
3006 
3007         default:        assert(0);
3008     }
3009     this->dstring = d;
3010     this->flags = flags;
3011     merge();
3012 }
3013 
kind()3014 const char *TypeBasic::kind()
3015 {
3016     return dstring;
3017 }
3018 
syntaxCopy()3019 Type *TypeBasic::syntaxCopy()
3020 {
3021     // No semantic analysis done on basic types, no need to copy
3022     return this;
3023 }
3024 
size(Loc)3025 d_uns64 TypeBasic::size(Loc)
3026 {   unsigned size;
3027 
3028     //printf("TypeBasic::size()\n");
3029     switch (ty)
3030     {
3031         case Tint8:
3032         case Tuns8:     size = 1;       break;
3033         case Tint16:
3034         case Tuns16:    size = 2;       break;
3035         case Tint32:
3036         case Tuns32:
3037         case Tfloat32:
3038         case Timaginary32:
3039                         size = 4;       break;
3040         case Tint64:
3041         case Tuns64:
3042         case Tfloat64:
3043         case Timaginary64:
3044                         size = 8;       break;
3045         case Tfloat80:
3046         case Timaginary80:
3047                         size = Target::realsize; break;
3048         case Tcomplex32:
3049                         size = 8;               break;
3050         case Tcomplex64:
3051         case Tint128:
3052         case Tuns128:
3053                         size = 16;              break;
3054         case Tcomplex80:
3055                         size = Target::realsize * 2; break;
3056 
3057         case Tvoid:
3058             //size = Type::size();      // error message
3059             size = 1;
3060             break;
3061 
3062         case Tbool:     size = 1;               break;
3063         case Tchar:     size = 1;               break;
3064         case Twchar:    size = 2;               break;
3065         case Tdchar:    size = 4;               break;
3066 
3067         default:
3068             assert(0);
3069             break;
3070     }
3071     //printf("TypeBasic::size() = %d\n", size);
3072     return size;
3073 }
3074 
alignsize()3075 unsigned TypeBasic::alignsize()
3076 {
3077     return Target::alignsize(this);
3078 }
3079 
3080 
getProperty(Loc loc,Identifier * ident,int flag)3081 Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
3082 {
3083     Expression *e;
3084     dinteger_t ivalue;
3085     real_t fvalue;
3086 
3087     //printf("TypeBasic::getProperty('%s')\n", ident->toChars());
3088     if (ident == Id::max)
3089     {
3090         switch (ty)
3091         {
3092         case Tint8:
3093             ivalue = 0x7F;
3094             goto Livalue;
3095         case Tuns8:
3096             ivalue = 0xFF;
3097             goto Livalue;
3098         case Tint16:
3099             ivalue = 0x7FFFUL;
3100             goto Livalue;
3101         case Tuns16:
3102             ivalue = 0xFFFFUL;
3103             goto Livalue;
3104         case Tint32:
3105             ivalue = 0x7FFFFFFFUL;
3106             goto Livalue;
3107         case Tuns32:
3108             ivalue = 0xFFFFFFFFUL;
3109             goto Livalue;
3110         case Tint64:
3111             ivalue = 0x7FFFFFFFFFFFFFFFLL;
3112             goto Livalue;
3113         case Tuns64:
3114             ivalue = 0xFFFFFFFFFFFFFFFFULL;
3115             goto Livalue;
3116         case Tbool:
3117             ivalue = 1;
3118             goto Livalue;
3119         case Tchar:
3120             ivalue = 0xFF;
3121             goto Livalue;
3122         case Twchar:
3123             ivalue = 0xFFFFUL;
3124             goto Livalue;
3125         case Tdchar:
3126             ivalue = 0x10FFFFUL;
3127             goto Livalue;
3128         case Tcomplex32:
3129         case Timaginary32:
3130         case Tfloat32:
3131             fvalue = Target::FloatProperties::max;
3132             goto Lfvalue;
3133         case Tcomplex64:
3134         case Timaginary64:
3135         case Tfloat64:
3136             fvalue = Target::DoubleProperties::max;
3137             goto Lfvalue;
3138         case Tcomplex80:
3139         case Timaginary80:
3140         case Tfloat80:
3141             fvalue = Target::RealProperties::max;
3142             goto Lfvalue;
3143         }
3144     }
3145     else if (ident == Id::min)
3146     {
3147         switch (ty)
3148         {
3149         case Tint8:
3150             ivalue = -128;
3151             goto Livalue;
3152         case Tuns8:
3153             ivalue = 0;
3154             goto Livalue;
3155         case Tint16:
3156             ivalue = -32768;
3157             goto Livalue;
3158         case Tuns16:
3159             ivalue = 0;
3160             goto Livalue;
3161         case Tint32:
3162             ivalue = -2147483647L - 1;
3163             goto Livalue;
3164         case Tuns32:
3165             ivalue = 0;
3166             goto Livalue;
3167         case Tint64:
3168             ivalue = (-9223372036854775807LL-1LL);
3169             goto Livalue;
3170         case Tuns64:
3171             ivalue = 0;
3172             goto Livalue;
3173         case Tbool:
3174             ivalue = 0;
3175             goto Livalue;
3176         case Tchar:
3177             ivalue = 0;
3178             goto Livalue;
3179         case Twchar:
3180             ivalue = 0;
3181             goto Livalue;
3182         case Tdchar:
3183             ivalue = 0;
3184             goto Livalue;
3185 
3186         case Tcomplex32:
3187         case Timaginary32:
3188         case Tfloat32:
3189         case Tcomplex64:
3190         case Timaginary64:
3191         case Tfloat64:
3192         case Tcomplex80:
3193         case Timaginary80:
3194         case Tfloat80:
3195             error(loc, "use .min_normal property instead of .min");
3196             return new ErrorExp();
3197         }
3198     }
3199     else if (ident == Id::min_normal)
3200     {
3201         switch (ty)
3202         {
3203         case Tcomplex32:
3204         case Timaginary32:
3205         case Tfloat32:
3206             fvalue = Target::FloatProperties::min_normal;
3207             goto Lfvalue;
3208         case Tcomplex64:
3209         case Timaginary64:
3210         case Tfloat64:
3211             fvalue = Target::DoubleProperties::min_normal;
3212             goto Lfvalue;
3213         case Tcomplex80:
3214         case Timaginary80:
3215         case Tfloat80:
3216             fvalue = Target::RealProperties::min_normal;
3217             goto Lfvalue;
3218         }
3219     }
3220     else if (ident == Id::nan)
3221     {
3222         switch (ty)
3223         {
3224         case Tcomplex32:
3225         case Tcomplex64:
3226         case Tcomplex80:
3227         case Timaginary32:
3228         case Timaginary64:
3229         case Timaginary80:
3230         case Tfloat32:
3231         case Tfloat64:
3232         case Tfloat80:
3233             fvalue = Target::RealProperties::nan;
3234             goto Lfvalue;
3235         }
3236     }
3237     else if (ident == Id::infinity)
3238     {
3239         switch (ty)
3240         {
3241         case Tcomplex32:
3242         case Tcomplex64:
3243         case Tcomplex80:
3244         case Timaginary32:
3245         case Timaginary64:
3246         case Timaginary80:
3247         case Tfloat32:
3248         case Tfloat64:
3249         case Tfloat80:
3250             fvalue = Target::RealProperties::infinity;
3251             goto Lfvalue;
3252         }
3253     }
3254     else if (ident == Id::dig)
3255     {
3256         switch (ty)
3257         {
3258         case Tcomplex32:
3259         case Timaginary32:
3260         case Tfloat32:
3261             ivalue = Target::FloatProperties::dig;
3262             goto Lint;
3263         case Tcomplex64:
3264         case Timaginary64:
3265         case Tfloat64:
3266             ivalue = Target::DoubleProperties::dig;
3267             goto Lint;
3268         case Tcomplex80:
3269         case Timaginary80:
3270         case Tfloat80:
3271             ivalue = Target::RealProperties::dig;
3272             goto Lint;
3273         }
3274     }
3275     else if (ident == Id::epsilon)
3276     {
3277         switch (ty)
3278         {
3279         case Tcomplex32:
3280         case Timaginary32:
3281         case Tfloat32:
3282             fvalue = Target::FloatProperties::epsilon;
3283             goto Lfvalue;
3284         case Tcomplex64:
3285         case Timaginary64:
3286         case Tfloat64:
3287             fvalue = Target::DoubleProperties::epsilon;
3288             goto Lfvalue;
3289         case Tcomplex80:
3290         case Timaginary80:
3291         case Tfloat80:
3292             fvalue = Target::RealProperties::epsilon;
3293             goto Lfvalue;
3294         }
3295     }
3296     else if (ident == Id::mant_dig)
3297     {
3298         switch (ty)
3299         {
3300         case Tcomplex32:
3301         case Timaginary32:
3302         case Tfloat32:
3303             ivalue = Target::FloatProperties::mant_dig;
3304             goto Lint;
3305         case Tcomplex64:
3306         case Timaginary64:
3307         case Tfloat64:
3308             ivalue = Target::DoubleProperties::mant_dig;
3309             goto Lint;
3310         case Tcomplex80:
3311         case Timaginary80:
3312         case Tfloat80:
3313             ivalue = Target::RealProperties::mant_dig;
3314             goto Lint;
3315         }
3316     }
3317     else if (ident == Id::max_10_exp)
3318     {
3319         switch (ty)
3320         {
3321         case Tcomplex32:
3322         case Timaginary32:
3323         case Tfloat32:
3324             ivalue = Target::FloatProperties::max_10_exp;
3325             goto Lint;
3326         case Tcomplex64:
3327         case Timaginary64:
3328         case Tfloat64:
3329             ivalue = Target::DoubleProperties::max_10_exp;
3330             goto Lint;
3331         case Tcomplex80:
3332         case Timaginary80:
3333         case Tfloat80:
3334             ivalue = Target::RealProperties::max_10_exp;
3335             goto Lint;
3336         }
3337     }
3338     else if (ident == Id::max_exp)
3339     {
3340         switch (ty)
3341         {
3342         case Tcomplex32:
3343         case Timaginary32:
3344         case Tfloat32:
3345             ivalue = Target::FloatProperties::max_exp;
3346             goto Lint;
3347         case Tcomplex64:
3348         case Timaginary64:
3349         case Tfloat64:
3350             ivalue = Target::DoubleProperties::max_exp;
3351             goto Lint;
3352         case Tcomplex80:
3353         case Timaginary80:
3354         case Tfloat80:
3355             ivalue = Target::RealProperties::max_exp;
3356             goto Lint;
3357         }
3358     }
3359     else if (ident == Id::min_10_exp)
3360     {
3361         switch (ty)
3362         {
3363         case Tcomplex32:
3364         case Timaginary32:
3365         case Tfloat32:
3366             ivalue = Target::FloatProperties::min_10_exp;
3367             goto Lint;
3368         case Tcomplex64:
3369         case Timaginary64:
3370         case Tfloat64:
3371             ivalue = Target::DoubleProperties::min_10_exp;
3372             goto Lint;
3373         case Tcomplex80:
3374         case Timaginary80:
3375         case Tfloat80:
3376             ivalue = Target::RealProperties::min_10_exp;
3377             goto Lint;
3378         }
3379     }
3380     else if (ident == Id::min_exp)
3381     {
3382         switch (ty)
3383         {
3384         case Tcomplex32:
3385         case Timaginary32:
3386         case Tfloat32:
3387             ivalue = Target::FloatProperties::min_exp;
3388             goto Lint;
3389         case Tcomplex64:
3390         case Timaginary64:
3391         case Tfloat64:
3392             ivalue = Target::DoubleProperties::min_exp;
3393             goto Lint;
3394         case Tcomplex80:
3395         case Timaginary80:
3396         case Tfloat80:
3397             ivalue = Target::RealProperties::min_exp;
3398             goto Lint;
3399         }
3400     }
3401 
3402     return Type::getProperty(loc, ident, flag);
3403 
3404 Livalue:
3405     e = new IntegerExp(loc, ivalue, this);
3406     return e;
3407 
3408 Lfvalue:
3409     if (isreal() || isimaginary())
3410         e = new RealExp(loc, fvalue, this);
3411     else
3412     {
3413         complex_t cvalue = complex_t(fvalue, fvalue);
3414         //for (int i = 0; i < 20; i++)
3415         //    printf("%02x ", ((unsigned char *)&cvalue)[i]);
3416         //printf("\n");
3417         e = new ComplexExp(loc, cvalue, this);
3418     }
3419     return e;
3420 
3421 Lint:
3422     e = new IntegerExp(loc, ivalue, Type::tint32);
3423     return e;
3424 }
3425 
dotExp(Scope * sc,Expression * e,Identifier * ident,int flag)3426 Expression *TypeBasic::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
3427 {
3428     Type *t;
3429 
3430     if (ident == Id::re)
3431     {
3432         switch (ty)
3433         {
3434             case Tcomplex32:    t = tfloat32;           goto L1;
3435             case Tcomplex64:    t = tfloat64;           goto L1;
3436             case Tcomplex80:    t = tfloat80;           goto L1;
3437             L1:
3438                 e = e->castTo(sc, t);
3439                 break;
3440 
3441             case Tfloat32:
3442             case Tfloat64:
3443             case Tfloat80:
3444                 break;
3445 
3446             case Timaginary32:  t = tfloat32;           goto L2;
3447             case Timaginary64:  t = tfloat64;           goto L2;
3448             case Timaginary80:  t = tfloat80;           goto L2;
3449             L2:
3450                 e = new RealExp(e->loc, CTFloat::zero, t);
3451                 break;
3452 
3453             default:
3454                 e = Type::getProperty(e->loc, ident, flag);
3455                 break;
3456         }
3457     }
3458     else if (ident == Id::im)
3459     {   Type *t2;
3460 
3461         switch (ty)
3462         {
3463             case Tcomplex32:    t = timaginary32;       t2 = tfloat32;  goto L3;
3464             case Tcomplex64:    t = timaginary64;       t2 = tfloat64;  goto L3;
3465             case Tcomplex80:    t = timaginary80;       t2 = tfloat80;  goto L3;
3466             L3:
3467                 e = e->castTo(sc, t);
3468                 e->type = t2;
3469                 break;
3470 
3471             case Timaginary32:  t = tfloat32;   goto L4;
3472             case Timaginary64:  t = tfloat64;   goto L4;
3473             case Timaginary80:  t = tfloat80;   goto L4;
3474             L4:
3475                 e = e->copy();
3476                 e->type = t;
3477                 break;
3478 
3479             case Tfloat32:
3480             case Tfloat64:
3481             case Tfloat80:
3482                 e = new RealExp(e->loc, CTFloat::zero, this);
3483                 break;
3484 
3485             default:
3486                 e = Type::getProperty(e->loc, ident, flag);
3487                 break;
3488         }
3489     }
3490     else
3491     {
3492         return Type::dotExp(sc, e, ident, flag);
3493     }
3494     if (!(flag & 1) || e)
3495         e = ::semantic(e, sc);
3496     return e;
3497 }
3498 
defaultInit(Loc loc)3499 Expression *TypeBasic::defaultInit(Loc loc)
3500 {
3501     dinteger_t value = 0;
3502 
3503     switch (ty)
3504     {
3505         case Tchar:
3506             value = 0xFF;
3507             break;
3508 
3509         case Twchar:
3510         case Tdchar:
3511             value = 0xFFFF;
3512             break;
3513 
3514         case Timaginary32:
3515         case Timaginary64:
3516         case Timaginary80:
3517         case Tfloat32:
3518         case Tfloat64:
3519         case Tfloat80:
3520             return new RealExp(loc, Target::RealProperties::snan, this);
3521 
3522         case Tcomplex32:
3523         case Tcomplex64:
3524         case Tcomplex80:
3525         {   // Can't use fvalue + I*fvalue (the im part becomes a quiet NaN).
3526             complex_t cvalue = complex_t(Target::RealProperties::snan, Target::RealProperties::snan);
3527             return new ComplexExp(loc, cvalue, this);
3528         }
3529 
3530         case Tvoid:
3531             error(loc, "void does not have a default initializer");
3532             return new ErrorExp();
3533     }
3534     return new IntegerExp(loc, value, this);
3535 }
3536 
isZeroInit(Loc)3537 bool TypeBasic::isZeroInit(Loc)
3538 {
3539     switch (ty)
3540     {
3541         case Tchar:
3542         case Twchar:
3543         case Tdchar:
3544         case Timaginary32:
3545         case Timaginary64:
3546         case Timaginary80:
3547         case Tfloat32:
3548         case Tfloat64:
3549         case Tfloat80:
3550         case Tcomplex32:
3551         case Tcomplex64:
3552         case Tcomplex80:
3553             return false;       // no
3554         default:
3555             return true;        // yes
3556     }
3557 }
3558 
isintegral()3559 bool TypeBasic::isintegral()
3560 {
3561     //printf("TypeBasic::isintegral('%s') x%x\n", toChars(), flags);
3562     return (flags & TFLAGSintegral) != 0;
3563 }
3564 
isfloating()3565 bool TypeBasic::isfloating()
3566 {
3567     return (flags & TFLAGSfloating) != 0;
3568 }
3569 
isreal()3570 bool TypeBasic::isreal()
3571 {
3572     return (flags & TFLAGSreal) != 0;
3573 }
3574 
isimaginary()3575 bool TypeBasic::isimaginary()
3576 {
3577     return (flags & TFLAGSimaginary) != 0;
3578 }
3579 
iscomplex()3580 bool TypeBasic::iscomplex()
3581 {
3582     return (flags & TFLAGScomplex) != 0;
3583 }
3584 
isunsigned()3585 bool TypeBasic::isunsigned()
3586 {
3587     return (flags & TFLAGSunsigned) != 0;
3588 }
3589 
isscalar()3590 bool TypeBasic::isscalar()
3591 {
3592     return (flags & (TFLAGSintegral | TFLAGSfloating)) != 0;
3593 }
3594 
implicitConvTo(Type * to)3595 MATCH TypeBasic::implicitConvTo(Type *to)
3596 {
3597     //printf("TypeBasic::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
3598     if (this == to)
3599         return MATCHexact;
3600 
3601     if (ty == to->ty)
3602     {
3603         if (mod == to->mod)
3604             return MATCHexact;
3605         else if (MODimplicitConv(mod, to->mod))
3606             return MATCHconst;
3607         else if (!((mod ^ to->mod) & MODshared))    // for wild matching
3608             return MATCHconst;
3609         else
3610             return MATCHconvert;
3611     }
3612 
3613     if (ty == Tvoid || to->ty == Tvoid)
3614         return MATCHnomatch;
3615     if (to->ty == Tbool)
3616         return MATCHnomatch;
3617 
3618     TypeBasic *tob;
3619     if (to->ty == Tvector && to->deco)
3620     {
3621         TypeVector *tv = (TypeVector *)to;
3622         tob = tv->elementType();
3623     }
3624     else if (to->ty == Tenum)
3625     {
3626         EnumDeclaration *ed = ((TypeEnum *)to)->sym;
3627         if (ed->isSpecial())
3628         {
3629             /* Special enums that allow implicit conversions to them.  */
3630             tob = to->toBasetype()->isTypeBasic();
3631             if (tob)
3632                 return implicitConvTo(tob);
3633         }
3634         else
3635             return MATCHnomatch;
3636     }
3637     else
3638         tob = to->isTypeBasic();
3639     if (!tob)
3640         return MATCHnomatch;
3641 
3642     if (flags & TFLAGSintegral)
3643     {
3644         // Disallow implicit conversion of integers to imaginary or complex
3645         if (tob->flags & (TFLAGSimaginary | TFLAGScomplex))
3646             return MATCHnomatch;
3647 
3648         // If converting from integral to integral
3649         if (tob->flags & TFLAGSintegral)
3650         {   d_uns64 sz = size(Loc());
3651             d_uns64 tosz = tob->size(Loc());
3652 
3653             /* Can't convert to smaller size
3654              */
3655             if (sz > tosz)
3656                 return MATCHnomatch;
3657 
3658             /* Can't change sign if same size
3659              */
3660             /*if (sz == tosz && (flags ^ tob->flags) & TFLAGSunsigned)
3661                 return MATCHnomatch;*/
3662         }
3663     }
3664     else if (flags & TFLAGSfloating)
3665     {
3666         // Disallow implicit conversion of floating point to integer
3667         if (tob->flags & TFLAGSintegral)
3668             return MATCHnomatch;
3669 
3670         assert(tob->flags & TFLAGSfloating || to->ty == Tvector);
3671 
3672         // Disallow implicit conversion from complex to non-complex
3673         if (flags & TFLAGScomplex && !(tob->flags & TFLAGScomplex))
3674             return MATCHnomatch;
3675 
3676         // Disallow implicit conversion of real or imaginary to complex
3677         if (flags & (TFLAGSreal | TFLAGSimaginary) &&
3678             tob->flags & TFLAGScomplex)
3679             return MATCHnomatch;
3680 
3681         // Disallow implicit conversion to-from real and imaginary
3682         if ((flags & (TFLAGSreal | TFLAGSimaginary)) !=
3683             (tob->flags & (TFLAGSreal | TFLAGSimaginary)))
3684             return MATCHnomatch;
3685     }
3686     return MATCHconvert;
3687 }
3688 
isTypeBasic()3689 TypeBasic *TypeBasic::isTypeBasic()
3690 {
3691     return (TypeBasic *)this;
3692 }
3693 
3694 /* ============================= TypeVector =========================== */
3695 
3696 /* The basetype must be one of:
3697  *   byte[16],ubyte[16],short[8],ushort[8],int[4],uint[4],long[2],ulong[2],float[4],double[2]
3698  * For AVX:
3699  *   byte[32],ubyte[32],short[16],ushort[16],int[8],uint[8],long[4],ulong[4],float[8],double[4]
3700  */
TypeVector(Type * basetype)3701 TypeVector::TypeVector(Type *basetype)
3702         : Type(Tvector)
3703 {
3704     this->basetype = basetype;
3705 }
3706 
create(Loc,Type * basetype)3707 TypeVector *TypeVector::create(Loc, Type *basetype)
3708 {
3709     return new TypeVector(basetype);
3710 }
3711 
kind()3712 const char *TypeVector::kind()
3713 {
3714     return "vector";
3715 }
3716 
syntaxCopy()3717 Type *TypeVector::syntaxCopy()
3718 {
3719     return new TypeVector(basetype->syntaxCopy());
3720 }
3721 
semantic(Loc loc,Scope * sc)3722 Type *TypeVector::semantic(Loc loc, Scope *sc)
3723 {
3724     unsigned int errors = global.errors;
3725     basetype = basetype->semantic(loc, sc);
3726     if (errors != global.errors)
3727         return terror;
3728     basetype = basetype->toBasetype()->mutableOf();
3729     if (basetype->ty != Tsarray)
3730     {
3731         error(loc, "T in __vector(T) must be a static array, not %s", basetype->toChars());
3732         return terror;
3733     }
3734     TypeSArray *t = (TypeSArray *)basetype;
3735     int sz = (int)t->size(loc);
3736     switch (Target::isVectorTypeSupported(sz, t->nextOf()))
3737     {
3738     case 0: // valid
3739         break;
3740     case 1: // no support at all
3741         error(loc, "SIMD vector types not supported on this platform");
3742         return terror;
3743     case 2: // invalid size
3744         error(loc, "%d byte vector type %s is not supported on this platform", sz, toChars());
3745         return terror;
3746     case 3: // invalid base type
3747         error(loc, "vector type %s is not supported on this platform", toChars());
3748         return terror;
3749     default:
3750         assert(0);
3751     }
3752     return merge();
3753 }
3754 
elementType()3755 TypeBasic *TypeVector::elementType()
3756 {
3757     assert(basetype->ty == Tsarray);
3758     TypeSArray *t = (TypeSArray *)basetype;
3759     TypeBasic *tb = t->nextOf()->isTypeBasic();
3760     assert(tb);
3761     return tb;
3762 }
3763 
isBoolean()3764 bool TypeVector::isBoolean()
3765 {
3766     return false;
3767 }
3768 
size(Loc)3769 d_uns64 TypeVector::size(Loc)
3770 {
3771     return basetype->size();
3772 }
3773 
alignsize()3774 unsigned TypeVector::alignsize()
3775 {
3776     return (unsigned)basetype->size();
3777 }
3778 
getProperty(Loc loc,Identifier * ident,int flag)3779 Expression *TypeVector::getProperty(Loc loc, Identifier *ident, int flag)
3780 {
3781     return Type::getProperty(loc, ident, flag);
3782 }
3783 
dotExp(Scope * sc,Expression * e,Identifier * ident,int flag)3784 Expression *TypeVector::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
3785 {
3786     if (ident == Id::ptr && e->op == TOKcall)
3787     {
3788         /* The trouble with TOKcall is the return ABI for float[4] is different from
3789          * __vector(float[4]), and a type paint won't do.
3790          */
3791         e = new AddrExp(e->loc, e);
3792         e = ::semantic(e, sc);
3793         e = e->castTo(sc, basetype->nextOf()->pointerTo());
3794         return e;
3795     }
3796     if (ident == Id::array)
3797     {
3798         //e = e->castTo(sc, basetype);
3799         // Keep lvalue-ness
3800         e = new VectorArrayExp(e->loc, e);
3801         e = ::semantic(e, sc);
3802         return e;
3803     }
3804     if (ident == Id::_init || ident == Id::offsetof || ident == Id::stringof || ident == Id::__xalignof)
3805     {
3806         // init should return a new VectorExp (Bugzilla 12776)
3807         // offsetof does not work on a cast expression, so use e directly
3808         // stringof should not add a cast to the output
3809         return Type::dotExp(sc, e, ident, flag);
3810     }
3811     return basetype->dotExp(sc, e->castTo(sc, basetype), ident, flag);
3812 }
3813 
defaultInit(Loc loc)3814 Expression *TypeVector::defaultInit(Loc loc)
3815 {
3816     //printf("TypeVector::defaultInit()\n");
3817     assert(basetype->ty == Tsarray);
3818     Expression *e = basetype->defaultInit(loc);
3819     VectorExp *ve = new VectorExp(loc, e, this);
3820     ve->type = this;
3821     ve->dim = (int)(basetype->size(loc) / elementType()->size(loc));
3822     return ve;
3823 }
3824 
defaultInitLiteral(Loc loc)3825 Expression *TypeVector::defaultInitLiteral(Loc loc)
3826 {
3827     //printf("TypeVector::defaultInitLiteral()\n");
3828     assert(basetype->ty == Tsarray);
3829     Expression *e = basetype->defaultInitLiteral(loc);
3830     VectorExp *ve = new VectorExp(loc, e, this);
3831     ve->type = this;
3832     ve->dim = (int)(basetype->size(loc) / elementType()->size(loc));
3833     return ve;
3834 }
3835 
isZeroInit(Loc loc)3836 bool TypeVector::isZeroInit(Loc loc)
3837 {
3838     return basetype->isZeroInit(loc);
3839 }
3840 
isintegral()3841 bool TypeVector::isintegral()
3842 {
3843     //printf("TypeVector::isintegral('%s') x%x\n", toChars(), flags);
3844     return basetype->nextOf()->isintegral();
3845 }
3846 
isfloating()3847 bool TypeVector::isfloating()
3848 {
3849     return basetype->nextOf()->isfloating();
3850 }
3851 
isunsigned()3852 bool TypeVector::isunsigned()
3853 {
3854     return basetype->nextOf()->isunsigned();
3855 }
3856 
isscalar()3857 bool TypeVector::isscalar()
3858 {
3859     return basetype->nextOf()->isscalar();
3860 }
3861 
implicitConvTo(Type * to)3862 MATCH TypeVector::implicitConvTo(Type *to)
3863 {
3864     //printf("TypeVector::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
3865     if (this == to)
3866         return MATCHexact;
3867 #ifdef IN_GCC
3868     if (to->ty == Tvector)
3869     {
3870         TypeVector *tv = (TypeVector *)to;
3871         assert(basetype->ty == Tsarray && tv->basetype->ty == Tsarray);
3872 
3873         // Can't convert to a vector which has different size.
3874         if (basetype->size() != tv->basetype->size())
3875             return MATCHnomatch;
3876 
3877         // Allow conversion to void[]
3878         if (tv->basetype->nextOf()->ty == Tvoid)
3879             return MATCHconvert;
3880 
3881         // Otherwise implicitly convertible only if basetypes are.
3882         return basetype->implicitConvTo(tv->basetype);
3883     }
3884 #else
3885     if (ty == to->ty)
3886         return MATCHconvert;
3887 #endif
3888     return MATCHnomatch;
3889 }
3890 
3891 /***************************** TypeArray *****************************/
3892 
TypeArray(TY ty,Type * next)3893 TypeArray::TypeArray(TY ty, Type *next)
3894     : TypeNext(ty, next)
3895 {
3896 }
3897 
dotExp(Scope * sc,Expression * e,Identifier * ident,int flag)3898 Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
3899 {
3900     e = Type::dotExp(sc, e, ident, flag);
3901 
3902     if (!(flag & 1) || e)
3903         e = ::semantic(e, sc);
3904     return e;
3905 }
3906 
3907 
3908 /***************************** TypeSArray *****************************/
3909 
TypeSArray(Type * t,Expression * dim)3910 TypeSArray::TypeSArray(Type *t, Expression *dim)
3911     : TypeArray(Tsarray, t)
3912 {
3913     //printf("TypeSArray(%s)\n", dim->toChars());
3914     this->dim = dim;
3915 }
3916 
kind()3917 const char *TypeSArray::kind()
3918 {
3919     return "sarray";
3920 }
3921 
syntaxCopy()3922 Type *TypeSArray::syntaxCopy()
3923 {
3924     Type *t = next->syntaxCopy();
3925     Expression *e = dim->syntaxCopy();
3926     t = new TypeSArray(t, e);
3927     t->mod = mod;
3928     return t;
3929 }
3930 
size(Loc loc)3931 d_uns64 TypeSArray::size(Loc loc)
3932 {
3933     //printf("TypeSArray::size()\n");
3934     uinteger_t n = numberOfElems(loc);
3935     uinteger_t elemsize = baseElemOf()->size();
3936     bool overflow = false;
3937     uinteger_t sz = mulu(n, elemsize, overflow);
3938     if (overflow || sz >= UINT32_MAX)
3939     {
3940         if (elemsize != SIZE_INVALID && n != UINT32_MAX)
3941             error(loc, "static array `%s` size overflowed to %lld", toChars(), (long long)sz);
3942         return SIZE_INVALID;
3943     }
3944     return sz;
3945 }
3946 
alignsize()3947 unsigned TypeSArray::alignsize()
3948 {
3949     return next->alignsize();
3950 }
3951 
3952 /**************************
3953  * This evaluates exp while setting length to be the number
3954  * of elements in the tuple t.
3955  */
semanticLength(Scope * sc,Type * t,Expression * exp)3956 Expression *semanticLength(Scope *sc, Type *t, Expression *exp)
3957 {
3958     if (t->ty == Ttuple)
3959     {
3960         ScopeDsymbol *sym = new ArrayScopeSymbol(sc, (TypeTuple *)t);
3961         sym->parent = sc->scopesym;
3962         sc = sc->push(sym);
3963 
3964         sc = sc->startCTFE();
3965         exp = ::semantic(exp, sc);
3966         sc = sc->endCTFE();
3967 
3968         sc->pop();
3969     }
3970     else
3971     {
3972         sc = sc->startCTFE();
3973         exp = ::semantic(exp, sc);
3974         sc = sc->endCTFE();
3975     }
3976 
3977     return exp;
3978 }
3979 
semanticLength(Scope * sc,TupleDeclaration * s,Expression * exp)3980 Expression *semanticLength(Scope *sc, TupleDeclaration *s, Expression *exp)
3981 {
3982     ScopeDsymbol *sym = new ArrayScopeSymbol(sc, s);
3983     sym->parent = sc->scopesym;
3984     sc = sc->push(sym);
3985 
3986     sc = sc->startCTFE();
3987     exp = ::semantic(exp, sc);
3988     sc = sc->endCTFE();
3989 
3990     sc->pop();
3991     return exp;
3992 }
3993 
resolve(Loc loc,Scope * sc,Expression ** pe,Type ** pt,Dsymbol ** ps,bool intypeid)3994 void TypeSArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
3995 {
3996     //printf("TypeSArray::resolve() %s\n", toChars());
3997     next->resolve(loc, sc, pe, pt, ps, intypeid);
3998     //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
3999     if (*pe)
4000     {
4001         // It's really an index expression
4002         if (Dsymbol *s = getDsymbol(*pe))
4003             *pe = new DsymbolExp(loc, s);
4004         *pe = new ArrayExp(loc, *pe, dim);
4005     }
4006     else if (*ps)
4007     {
4008         Dsymbol *s = *ps;
4009         TupleDeclaration *td = s->isTupleDeclaration();
4010         if (td)
4011         {
4012             ScopeDsymbol *sym = new ArrayScopeSymbol(sc, td);
4013             sym->parent = sc->scopesym;
4014             sc = sc->push(sym);
4015             sc = sc->startCTFE();
4016             dim = ::semantic(dim, sc);
4017             sc = sc->endCTFE();
4018             sc = sc->pop();
4019 
4020             dim = dim->ctfeInterpret();
4021             uinteger_t d = dim->toUInteger();
4022 
4023             if (d >= td->objects->dim)
4024             {
4025                 error(loc, "tuple index %llu exceeds length %u", d, td->objects->dim);
4026                 *ps = NULL;
4027                 *pt = Type::terror;
4028                 return;
4029             }
4030             RootObject *o = (*td->objects)[(size_t)d];
4031             if (o->dyncast() == DYNCAST_DSYMBOL)
4032             {
4033                 *ps = (Dsymbol *)o;
4034                 return;
4035             }
4036             if (o->dyncast() == DYNCAST_EXPRESSION)
4037             {
4038                 Expression *e = (Expression *)o;
4039                 if (e->op == TOKdsymbol)
4040                 {
4041                     *ps = ((DsymbolExp *)e)->s;
4042                     *pe = NULL;
4043                 }
4044                 else
4045                 {
4046                     *ps = NULL;
4047                     *pe = e;
4048                 }
4049                 return;
4050             }
4051             if (o->dyncast() == DYNCAST_TYPE)
4052             {
4053                 *ps = NULL;
4054                 *pt = ((Type *)o)->addMod(this->mod);
4055                 return;
4056             }
4057 
4058             /* Create a new TupleDeclaration which
4059              * is a slice [d..d+1] out of the old one.
4060              * Do it this way because TemplateInstance::semanticTiargs()
4061              * can handle unresolved Objects this way.
4062              */
4063             Objects *objects = new Objects;
4064             objects->setDim(1);
4065             (*objects)[0] = o;
4066 
4067             TupleDeclaration *tds = new TupleDeclaration(loc, td->ident, objects);
4068             *ps = tds;
4069         }
4070         else
4071             goto Ldefault;
4072     }
4073     else
4074     {
4075         if ((*pt)->ty != Terror)
4076             next = *pt;     // prevent re-running semantic() on 'next'
4077      Ldefault:
4078         Type::resolve(loc, sc, pe, pt, ps, intypeid);
4079     }
4080 }
4081 
semantic(Loc loc,Scope * sc)4082 Type *TypeSArray::semantic(Loc loc, Scope *sc)
4083 {
4084     //printf("TypeSArray::semantic() %s\n", toChars());
4085 
4086     Type *t;
4087     Expression *e;
4088     Dsymbol *s;
4089     next->resolve(loc, sc, &e, &t, &s);
4090     if (dim && s && s->isTupleDeclaration())
4091     {   TupleDeclaration *sd = s->isTupleDeclaration();
4092 
4093         dim = semanticLength(sc, sd, dim);
4094         dim = dim->ctfeInterpret();
4095         uinteger_t d = dim->toUInteger();
4096 
4097         if (d >= sd->objects->dim)
4098         {   error(loc, "tuple index %llu exceeds %u", d, sd->objects->dim);
4099             return Type::terror;
4100         }
4101         RootObject *o = (*sd->objects)[(size_t)d];
4102         if (o->dyncast() != DYNCAST_TYPE)
4103         {   error(loc, "%s is not a type", toChars());
4104             return Type::terror;
4105         }
4106         t = ((Type *)o)->addMod(this->mod);
4107         return t;
4108     }
4109 
4110     Type *tn = next->semantic(loc, sc);
4111     if (tn->ty == Terror)
4112         return terror;
4113 
4114     Type *tbn = tn->toBasetype();
4115 
4116     if (dim)
4117     {
4118         unsigned int errors = global.errors;
4119         dim = semanticLength(sc, tbn, dim);
4120         if (errors != global.errors)
4121             goto Lerror;
4122 
4123         dim = dim->optimize(WANTvalue);
4124         dim = dim->ctfeInterpret();
4125         if (dim->op == TOKerror)
4126             goto Lerror;
4127         errors = global.errors;
4128         dinteger_t d1 = dim->toInteger();
4129         if (errors != global.errors)
4130             goto Lerror;
4131 
4132         dim = dim->implicitCastTo(sc, tsize_t);
4133         dim = dim->optimize(WANTvalue);
4134         if (dim->op == TOKerror)
4135             goto Lerror;
4136         errors = global.errors;
4137         dinteger_t d2 = dim->toInteger();
4138         if (errors != global.errors)
4139             goto Lerror;
4140 
4141         if (dim->op == TOKerror)
4142             goto Lerror;
4143 
4144         if (d1 != d2)
4145         {
4146         Loverflow:
4147             error(loc, "%s size %llu * %llu exceeds 0x%llx size limit for static array",
4148                 toChars(), (unsigned long long)tbn->size(loc), (unsigned long long)d1, Target::maxStaticDataSize);
4149             goto Lerror;
4150         }
4151 
4152         Type *tbx = tbn->baseElemOf();
4153         if ((tbx->ty == Tstruct && !((TypeStruct *)tbx)->sym->members) ||
4154             (tbx->ty == Tenum && !((TypeEnum *)tbx)->sym->members))
4155         {
4156             /* To avoid meaningless error message, skip the total size limit check
4157              * when the bottom of element type is opaque.
4158              */
4159         }
4160         else if (tbn->isTypeBasic() ||
4161                  tbn->ty == Tpointer ||
4162                  tbn->ty == Tarray ||
4163                  tbn->ty == Tsarray ||
4164                  tbn->ty == Taarray ||
4165                  (tbn->ty == Tstruct && (((TypeStruct *)tbn)->sym->sizeok == SIZEOKdone)) ||
4166                  tbn->ty == Tclass)
4167         {
4168             /* Only do this for types that don't need to have semantic()
4169              * run on them for the size, since they may be forward referenced.
4170              */
4171             bool overflow = false;
4172             if (mulu(tbn->size(loc), d2, overflow) >= Target::maxStaticDataSize || overflow)
4173                 goto Loverflow;
4174         }
4175     }
4176     switch (tbn->ty)
4177     {
4178         case Ttuple:
4179         {   // Index the tuple to get the type
4180             assert(dim);
4181             TypeTuple *tt = (TypeTuple *)tbn;
4182             uinteger_t d = dim->toUInteger();
4183 
4184             if (d >= tt->arguments->dim)
4185             {   error(loc, "tuple index %llu exceeds %u", d, tt->arguments->dim);
4186                 goto Lerror;
4187             }
4188             Type *telem = (*tt->arguments)[(size_t)d]->type;
4189             return telem->addMod(this->mod);
4190         }
4191         case Tfunction:
4192         case Tnone:
4193             error(loc, "can't have array of %s", tbn->toChars());
4194             goto Lerror;
4195         default:
4196             break;
4197     }
4198     if (tbn->isscope())
4199     {   error(loc, "cannot have array of scope %s", tbn->toChars());
4200         goto Lerror;
4201     }
4202 
4203     /* Ensure things like const(immutable(T)[3]) become immutable(T[3])
4204      * and const(T)[3] become const(T[3])
4205      */
4206     next = tn;
4207     transitive();
4208     t = addMod(tn->mod);
4209 
4210     return t->merge();
4211 
4212 Lerror:
4213     return Type::terror;
4214 }
4215 
dotExp(Scope * sc,Expression * e,Identifier * ident,int flag)4216 Expression *TypeSArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
4217 {
4218     if (ident == Id::length)
4219     {
4220         Loc oldLoc = e->loc;
4221         e = dim->copy();
4222         e->loc = oldLoc;
4223     }
4224     else if (ident == Id::ptr)
4225     {
4226         if (e->op == TOKtype)
4227         {
4228             e->error("%s is not an expression", e->toChars());
4229             return new ErrorExp();
4230         }
4231         else if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
4232         {
4233             e->deprecation("%s.ptr cannot be used in @safe code, use &%s[0] instead", e->toChars(), e->toChars());
4234             // return new ErrorExp();
4235         }
4236         e = e->castTo(sc, e->type->nextOf()->pointerTo());
4237     }
4238     else
4239     {
4240         e = TypeArray::dotExp(sc, e, ident, flag);
4241     }
4242     if (!(flag & 1) || e)
4243         e = ::semantic(e, sc);
4244     return e;
4245 }
4246 
alignment()4247 structalign_t TypeSArray::alignment()
4248 {
4249     return next->alignment();
4250 }
4251 
isString()4252 bool TypeSArray::isString()
4253 {
4254     TY nty = next->toBasetype()->ty;
4255     return nty == Tchar || nty == Twchar || nty == Tdchar;
4256 }
4257 
constConv(Type * to)4258 MATCH TypeSArray::constConv(Type *to)
4259 {
4260     if (to->ty == Tsarray)
4261     {
4262         TypeSArray *tsa = (TypeSArray *)to;
4263         if (!dim->equals(tsa->dim))
4264             return MATCHnomatch;
4265     }
4266     return TypeNext::constConv(to);
4267 }
4268 
implicitConvTo(Type * to)4269 MATCH TypeSArray::implicitConvTo(Type *to)
4270 {
4271     //printf("TypeSArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4272 
4273     if (to->ty == Tarray)
4274     {
4275         TypeDArray *ta = (TypeDArray *)to;
4276 
4277         if (!MODimplicitConv(next->mod, ta->next->mod))
4278             return MATCHnomatch;
4279 
4280         /* Allow conversion to void[]
4281          */
4282         if (ta->next->ty == Tvoid)
4283         {
4284             return MATCHconvert;
4285         }
4286 
4287         MATCH m = next->constConv(ta->next);
4288         if (m > MATCHnomatch)
4289         {
4290             return MATCHconvert;
4291         }
4292         return MATCHnomatch;
4293     }
4294 
4295     if (to->ty == Tsarray)
4296     {
4297         if (this == to)
4298             return MATCHexact;
4299 
4300         TypeSArray *tsa = (TypeSArray *)to;
4301 
4302         if (dim->equals(tsa->dim))
4303         {
4304             /* Since static arrays are value types, allow
4305              * conversions from const elements to non-const
4306              * ones, just like we allow conversion from const int
4307              * to int.
4308              */
4309             MATCH m = next->implicitConvTo(tsa->next);
4310             if (m >= MATCHconst)
4311             {
4312                 if (mod != to->mod)
4313                     m = MATCHconst;
4314                 return m;
4315             }
4316         }
4317     }
4318     return MATCHnomatch;
4319 }
4320 
defaultInit(Loc loc)4321 Expression *TypeSArray::defaultInit(Loc loc)
4322 {
4323     if (next->ty == Tvoid)
4324         return tuns8->defaultInit(loc);
4325     else
4326         return next->defaultInit(loc);
4327 }
4328 
isZeroInit(Loc loc)4329 bool TypeSArray::isZeroInit(Loc loc)
4330 {
4331     return next->isZeroInit(loc);
4332 }
4333 
needsDestruction()4334 bool TypeSArray::needsDestruction()
4335 {
4336     return next->needsDestruction();
4337 }
4338 
4339 /*********************************
4340  *
4341  */
4342 
needsNested()4343 bool TypeSArray::needsNested()
4344 {
4345     return next->needsNested();
4346 }
4347 
defaultInitLiteral(Loc loc)4348 Expression *TypeSArray::defaultInitLiteral(Loc loc)
4349 {
4350     size_t d = (size_t)dim->toInteger();
4351     Expression *elementinit;
4352     if (next->ty == Tvoid)
4353         elementinit = tuns8->defaultInitLiteral(loc);
4354     else
4355         elementinit = next->defaultInitLiteral(loc);
4356     Expressions *elements = new Expressions();
4357     elements->setDim(d);
4358     for (size_t i = 0; i < d; i++)
4359         (*elements)[i] = NULL;
4360     ArrayLiteralExp *ae = new ArrayLiteralExp(Loc(), this, elementinit, elements);
4361     return ae;
4362 }
4363 
hasPointers()4364 bool TypeSArray::hasPointers()
4365 {
4366     /* Don't want to do this, because:
4367      *    struct S { T* array[0]; }
4368      * may be a variable length struct.
4369      */
4370     //if (dim->toInteger() == 0)
4371     //    return false;
4372 
4373     if (next->ty == Tvoid)
4374     {
4375         // Arrays of void contain arbitrary data, which may include pointers
4376         return true;
4377     }
4378     else
4379         return next->hasPointers();
4380 }
4381 
4382 /***************************** TypeDArray *****************************/
4383 
TypeDArray(Type * t)4384 TypeDArray::TypeDArray(Type *t)
4385     : TypeArray(Tarray, t)
4386 {
4387     //printf("TypeDArray(t = %p)\n", t);
4388 }
4389 
kind()4390 const char *TypeDArray::kind()
4391 {
4392     return "darray";
4393 }
4394 
syntaxCopy()4395 Type *TypeDArray::syntaxCopy()
4396 {
4397     Type *t = next->syntaxCopy();
4398     if (t == next)
4399         t = this;
4400     else
4401     {
4402         t = new TypeDArray(t);
4403         t->mod = mod;
4404     }
4405     return t;
4406 }
4407 
size(Loc)4408 d_uns64 TypeDArray::size(Loc)
4409 {
4410     //printf("TypeDArray::size()\n");
4411     return Target::ptrsize * 2;
4412 }
4413 
alignsize()4414 unsigned TypeDArray::alignsize()
4415 {
4416     // A DArray consists of two ptr-sized values, so align it on pointer size
4417     // boundary
4418     return Target::ptrsize;
4419 }
4420 
semantic(Loc loc,Scope * sc)4421 Type *TypeDArray::semantic(Loc loc, Scope *sc)
4422 {
4423     Type *tn = next->semantic(loc,sc);
4424     Type *tbn = tn->toBasetype();
4425     switch (tbn->ty)
4426     {
4427         case Ttuple:
4428             return tbn;
4429         case Tfunction:
4430         case Tnone:
4431             error(loc, "can't have array of %s", tbn->toChars());
4432             return Type::terror;
4433         case Terror:
4434             return Type::terror;
4435         default:
4436             break;
4437     }
4438     if (tn->isscope())
4439     {   error(loc, "cannot have array of scope %s", tn->toChars());
4440         return Type::terror;
4441     }
4442     next = tn;
4443     transitive();
4444     return merge();
4445 }
4446 
resolve(Loc loc,Scope * sc,Expression ** pe,Type ** pt,Dsymbol ** ps,bool intypeid)4447 void TypeDArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
4448 {
4449     //printf("TypeDArray::resolve() %s\n", toChars());
4450     next->resolve(loc, sc, pe, pt, ps, intypeid);
4451     //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
4452     if (*pe)
4453     {
4454         // It's really a slice expression
4455         if (Dsymbol *s = getDsymbol(*pe))
4456             *pe = new DsymbolExp(loc, s);
4457         *pe = new ArrayExp(loc, *pe);
4458     }
4459     else if (*ps)
4460     {
4461         TupleDeclaration *td = (*ps)->isTupleDeclaration();
4462         if (td)
4463             ;   // keep *ps
4464         else
4465             goto Ldefault;
4466     }
4467     else
4468     {
4469         if ((*pt)->ty != Terror)
4470             next = *pt;     // prevent re-running semantic() on 'next'
4471      Ldefault:
4472         Type::resolve(loc, sc, pe, pt, ps, intypeid);
4473     }
4474 }
4475 
dotExp(Scope * sc,Expression * e,Identifier * ident,int flag)4476 Expression *TypeDArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
4477 {
4478     if (e->op == TOKtype &&
4479         (ident == Id::length || ident == Id::ptr))
4480     {
4481         e->error("%s is not an expression", e->toChars());
4482         return new ErrorExp();
4483     }
4484     if (ident == Id::length)
4485     {
4486         if (e->op == TOKstring)
4487         {
4488             StringExp *se = (StringExp *)e;
4489             return new IntegerExp(se->loc, se->len, Type::tsize_t);
4490         }
4491         if (e->op == TOKnull)
4492             return new IntegerExp(e->loc, 0, Type::tsize_t);
4493         if (checkNonAssignmentArrayOp(e))
4494             return new ErrorExp();
4495         e = new ArrayLengthExp(e->loc, e);
4496         e->type = Type::tsize_t;
4497         return e;
4498     }
4499     else if (ident == Id::ptr)
4500     {
4501         if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
4502         {
4503             e->deprecation("%s.ptr cannot be used in @safe code, use &%s[0] instead", e->toChars(), e->toChars());
4504             // return new ErrorExp();
4505         }
4506         e = e->castTo(sc, next->pointerTo());
4507         return e;
4508     }
4509     else
4510     {
4511         e = TypeArray::dotExp(sc, e, ident, flag);
4512     }
4513     return e;
4514 }
4515 
isString()4516 bool TypeDArray::isString()
4517 {
4518     TY nty = next->toBasetype()->ty;
4519     return nty == Tchar || nty == Twchar || nty == Tdchar;
4520 }
4521 
implicitConvTo(Type * to)4522 MATCH TypeDArray::implicitConvTo(Type *to)
4523 {
4524     //printf("TypeDArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4525     if (equals(to))
4526         return MATCHexact;
4527 
4528     if (to->ty == Tarray)
4529     {
4530         TypeDArray *ta = (TypeDArray *)to;
4531 
4532         if (!MODimplicitConv(next->mod, ta->next->mod))
4533             return MATCHnomatch;        // not const-compatible
4534 
4535         /* Allow conversion to void[]
4536          */
4537         if (next->ty != Tvoid && ta->next->ty == Tvoid)
4538         {
4539             return MATCHconvert;
4540         }
4541 
4542         MATCH m = next->constConv(ta->next);
4543         if (m > MATCHnomatch)
4544         {
4545             if (m == MATCHexact && mod != to->mod)
4546                 m = MATCHconst;
4547             return m;
4548         }
4549     }
4550     return Type::implicitConvTo(to);
4551 }
4552 
defaultInit(Loc loc)4553 Expression *TypeDArray::defaultInit(Loc loc)
4554 {
4555     return new NullExp(loc, this);
4556 }
4557 
isZeroInit(Loc)4558 bool TypeDArray::isZeroInit(Loc)
4559 {
4560     return true;
4561 }
4562 
isBoolean()4563 bool TypeDArray::isBoolean()
4564 {
4565     return true;
4566 }
4567 
hasPointers()4568 bool TypeDArray::hasPointers()
4569 {
4570     return true;
4571 }
4572 
4573 
4574 /***************************** TypeAArray *****************************/
4575 
TypeAArray(Type * t,Type * index)4576 TypeAArray::TypeAArray(Type *t, Type *index)
4577     : TypeArray(Taarray, t)
4578 {
4579     this->index = index;
4580     this->loc = Loc();
4581     this->sc = NULL;
4582 }
4583 
create(Type * t,Type * index)4584 TypeAArray *TypeAArray::create(Type *t, Type *index)
4585 {
4586     return new TypeAArray(t, index);
4587 }
4588 
kind()4589 const char *TypeAArray::kind()
4590 {
4591     return "aarray";
4592 }
4593 
syntaxCopy()4594 Type *TypeAArray::syntaxCopy()
4595 {
4596     Type *t = next->syntaxCopy();
4597     Type *ti = index->syntaxCopy();
4598     if (t == next && ti == index)
4599         t = this;
4600     else
4601     {
4602         t = new TypeAArray(t, ti);
4603         t->mod = mod;
4604     }
4605     return t;
4606 }
4607 
size(Loc)4608 d_uns64 TypeAArray::size(Loc)
4609 {
4610     return Target::ptrsize;
4611 }
4612 
semantic(Loc loc,Scope * sc)4613 Type *TypeAArray::semantic(Loc loc, Scope *sc)
4614 {
4615     //printf("TypeAArray::semantic() %s index->ty = %d\n", toChars(), index->ty);
4616     if (deco)
4617         return this;
4618 
4619     this->loc = loc;
4620     this->sc = sc;
4621     if (sc)
4622         sc->setNoFree();
4623 
4624     // Deal with the case where we thought the index was a type, but
4625     // in reality it was an expression.
4626     if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray ||
4627         index->ty == Ttypeof || index->ty == Treturn)
4628     {
4629         Expression *e;
4630         Type *t;
4631         Dsymbol *s;
4632 
4633         index->resolve(loc, sc, &e, &t, &s);
4634         if (e)
4635         {
4636             // It was an expression -
4637             // Rewrite as a static array
4638             TypeSArray *tsa = new TypeSArray(next, e);
4639             return tsa->semantic(loc, sc);
4640         }
4641         else if (t)
4642             index = t->semantic(loc, sc);
4643         else
4644         {
4645             index->error(loc, "index is not a type or an expression");
4646             return Type::terror;
4647         }
4648     }
4649     else
4650         index = index->semantic(loc,sc);
4651     index = index->merge2();
4652 
4653     if (index->nextOf() && !index->nextOf()->isImmutable())
4654     {
4655         index = index->constOf()->mutableOf();
4656     }
4657 
4658     switch (index->toBasetype()->ty)
4659     {
4660         case Tfunction:
4661         case Tvoid:
4662         case Tnone:
4663         case Ttuple:
4664             error(loc, "can't have associative array key of %s", index->toBasetype()->toChars());
4665             /* fall through */
4666         case Terror:
4667             return Type::terror;
4668         default:
4669             break;
4670     }
4671     Type *tbase = index->baseElemOf();
4672     while (tbase->ty == Tarray)
4673         tbase = tbase->nextOf()->baseElemOf();
4674     if (tbase->ty == Tstruct)
4675     {
4676         /* AA's need typeid(index).equals() and getHash(). Issue error if not correctly set up.
4677          */
4678         StructDeclaration *sd = ((TypeStruct *)tbase)->sym;
4679         if (sd->semanticRun < PASSsemanticdone)
4680             sd->semantic(NULL);
4681 
4682         // duplicate a part of StructDeclaration::semanticTypeInfoMembers
4683         //printf("AA = %s, key: xeq = %p, xerreq = %p xhash = %p\n", toChars(), sd->xeq, sd->xerreq, sd->xhash);
4684         if (sd->xeq &&
4685             sd->xeq->_scope &&
4686             sd->xeq->semanticRun < PASSsemantic3done)
4687         {
4688             unsigned errors = global.startGagging();
4689             sd->xeq->semantic3(sd->xeq->_scope);
4690             if (global.endGagging(errors))
4691                 sd->xeq = sd->xerreq;
4692         }
4693 
4694         const char *s = (index->toBasetype()->ty != Tstruct) ? "bottom of " : "";
4695         if (!sd->xeq)
4696         {
4697             // If sd->xhash != NULL:
4698             //   sd or its fields have user-defined toHash.
4699             //   AA assumes that its result is consistent with bitwise equality.
4700             // else:
4701             //   bitwise equality & hashing
4702         }
4703         else if (sd->xeq == sd->xerreq)
4704         {
4705             if (search_function(sd, Id::eq))
4706             {
4707                 error(loc, "%sAA key type %s does not have 'bool opEquals(ref const %s) const'",
4708                         s, sd->toChars(), sd->toChars());
4709             }
4710             else
4711             {
4712                 error(loc, "%sAA key type %s does not support const equality",
4713                         s, sd->toChars());
4714             }
4715             return Type::terror;
4716         }
4717         else if (!sd->xhash)
4718         {
4719             if (search_function(sd, Id::eq))
4720             {
4721                 error(loc, "%sAA key type %s should have 'size_t toHash() const nothrow @safe' if opEquals defined",
4722                         s, sd->toChars());
4723             }
4724             else
4725             {
4726                 error(loc, "%sAA key type %s supports const equality but doesn't support const hashing",
4727                         s, sd->toChars());
4728             }
4729             return Type::terror;
4730         }
4731         else
4732         {
4733             // defined equality & hashing
4734             assert(sd->xeq && sd->xhash);
4735 
4736             /* xeq and xhash may be implicitly defined by compiler. For example:
4737              *   struct S { int[] arr; }
4738              * With 'arr' field equality and hashing, compiler will implicitly
4739              * generate functions for xopEquals and xtoHash in TypeInfo_Struct.
4740              */
4741         }
4742     }
4743     else if (tbase->ty == Tclass && !((TypeClass *)tbase)->sym->isInterfaceDeclaration())
4744     {
4745         ClassDeclaration *cd = ((TypeClass *)tbase)->sym;
4746         if (cd->semanticRun < PASSsemanticdone)
4747             cd->semantic(NULL);
4748 
4749         if (!ClassDeclaration::object)
4750         {
4751             error(Loc(), "missing or corrupt object.d");
4752             fatal();
4753         }
4754 
4755         static FuncDeclaration *feq   = NULL;
4756         static FuncDeclaration *fcmp  = NULL;
4757         static FuncDeclaration *fhash = NULL;
4758         if (!feq)   feq   = search_function(ClassDeclaration::object, Id::eq)->isFuncDeclaration();
4759         if (!fcmp)  fcmp  = search_function(ClassDeclaration::object, Id::cmp)->isFuncDeclaration();
4760         if (!fhash) fhash = search_function(ClassDeclaration::object, Id::tohash)->isFuncDeclaration();
4761         assert(fcmp && feq && fhash);
4762 
4763         if (feq->vtblIndex < (int)cd->vtbl.dim && cd->vtbl[feq ->vtblIndex] == feq)
4764         {
4765             if (fcmp->vtblIndex < (int)cd->vtbl.dim && cd->vtbl[fcmp->vtblIndex] != fcmp)
4766             {
4767                 const char *s = (index->toBasetype()->ty != Tclass) ? "bottom of " : "";
4768                 error(loc, "%sAA key type %s now requires equality rather than comparison",
4769                     s, cd->toChars());
4770                 errorSupplemental(loc, "Please override Object.opEquals and toHash.");
4771             }
4772         }
4773     }
4774     next = next->semantic(loc,sc)->merge2();
4775     transitive();
4776 
4777     switch (next->toBasetype()->ty)
4778     {
4779         case Tfunction:
4780         case Tvoid:
4781         case Tnone:
4782         case Ttuple:
4783             error(loc, "can't have associative array of %s", next->toChars());
4784             /* fall through */
4785         case Terror:
4786             return Type::terror;
4787     }
4788     if (next->isscope())
4789     {   error(loc, "cannot have array of scope %s", next->toChars());
4790         return Type::terror;
4791     }
4792     return merge();
4793 }
4794 
resolve(Loc loc,Scope * sc,Expression ** pe,Type ** pt,Dsymbol ** ps,bool intypeid)4795 void TypeAArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
4796 {
4797     //printf("TypeAArray::resolve() %s\n", toChars());
4798 
4799     // Deal with the case where we thought the index was a type, but
4800     // in reality it was an expression.
4801     if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray)
4802     {
4803         Expression *e;
4804         Type *t;
4805         Dsymbol *s;
4806 
4807         index->resolve(loc, sc, &e, &t, &s, intypeid);
4808         if (e)
4809         {
4810             // It was an expression -
4811             // Rewrite as a static array
4812             TypeSArray *tsa = new TypeSArray(next, e);
4813             tsa->mod = this->mod;   // just copy mod field so tsa's semantic is not yet done
4814             return tsa->resolve(loc, sc, pe, pt, ps, intypeid);
4815         }
4816         else if (t)
4817             index = t;
4818         else
4819             index->error(loc, "index is not a type or an expression");
4820     }
4821     Type::resolve(loc, sc, pe, pt, ps, intypeid);
4822 }
4823 
4824 
dotExp(Scope * sc,Expression * e,Identifier * ident,int flag)4825 Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
4826 {
4827     if (ident == Id::length)
4828     {
4829         static FuncDeclaration *fd_aaLen = NULL;
4830         if (fd_aaLen == NULL)
4831         {
4832             Parameters *fparams = new Parameters();
4833             fparams->push(new Parameter(STCin, this, NULL, NULL));
4834             fd_aaLen = FuncDeclaration::genCfunc(fparams, Type::tsize_t, Id::aaLen);
4835             TypeFunction *tf = fd_aaLen->type->toTypeFunction();
4836             tf->purity = PUREconst;
4837             tf->isnothrow = true;
4838             tf->isnogc = false;
4839         }
4840         Expression *ev = new VarExp(e->loc, fd_aaLen, false);
4841         e = new CallExp(e->loc, ev, e);
4842         e->type = fd_aaLen->type->toTypeFunction()->next;
4843     }
4844     else
4845         e = Type::dotExp(sc, e, ident, flag);
4846     return e;
4847 }
4848 
defaultInit(Loc loc)4849 Expression *TypeAArray::defaultInit(Loc loc)
4850 {
4851     return new NullExp(loc, this);
4852 }
4853 
isZeroInit(Loc)4854 bool TypeAArray::isZeroInit(Loc)
4855 {
4856     return true;
4857 }
4858 
isBoolean()4859 bool TypeAArray::isBoolean()
4860 {
4861     return true;
4862 }
4863 
hasPointers()4864 bool TypeAArray::hasPointers()
4865 {
4866     return true;
4867 }
4868 
implicitConvTo(Type * to)4869 MATCH TypeAArray::implicitConvTo(Type *to)
4870 {
4871     //printf("TypeAArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4872     if (equals(to))
4873         return MATCHexact;
4874 
4875     if (to->ty == Taarray)
4876     {   TypeAArray *ta = (TypeAArray *)to;
4877 
4878         if (!MODimplicitConv(next->mod, ta->next->mod))
4879             return MATCHnomatch;        // not const-compatible
4880 
4881         if (!MODimplicitConv(index->mod, ta->index->mod))
4882             return MATCHnomatch;        // not const-compatible
4883 
4884         MATCH m = next->constConv(ta->next);
4885         MATCH mi = index->constConv(ta->index);
4886         if (m > MATCHnomatch && mi > MATCHnomatch)
4887         {
4888             return MODimplicitConv(mod, to->mod) ? MATCHconst : MATCHnomatch;
4889         }
4890     }
4891     return Type::implicitConvTo(to);
4892 }
4893 
constConv(Type * to)4894 MATCH TypeAArray::constConv(Type *to)
4895 {
4896     if (to->ty == Taarray)
4897     {
4898         TypeAArray *taa = (TypeAArray *)to;
4899         MATCH mindex = index->constConv(taa->index);
4900         MATCH mkey = next->constConv(taa->next);
4901         // Pick the worst match
4902         return mkey < mindex ? mkey : mindex;
4903     }
4904     return Type::constConv(to);
4905 }
4906 
4907 /***************************** TypePointer *****************************/
4908 
TypePointer(Type * t)4909 TypePointer::TypePointer(Type *t)
4910     : TypeNext(Tpointer, t)
4911 {
4912 }
4913 
create(Type * t)4914 TypePointer *TypePointer::create(Type *t)
4915 {
4916     return new TypePointer(t);
4917 }
4918 
kind()4919 const char *TypePointer::kind()
4920 {
4921     return "pointer";
4922 }
4923 
syntaxCopy()4924 Type *TypePointer::syntaxCopy()
4925 {
4926     Type *t = next->syntaxCopy();
4927     if (t == next)
4928         t = this;
4929     else
4930     {
4931         t = new TypePointer(t);
4932         t->mod = mod;
4933     }
4934     return t;
4935 }
4936 
semantic(Loc loc,Scope * sc)4937 Type *TypePointer::semantic(Loc loc, Scope *sc)
4938 {
4939     //printf("TypePointer::semantic() %s\n", toChars());
4940     if (deco)
4941         return this;
4942     Type *n = next->semantic(loc, sc);
4943     switch (n->toBasetype()->ty)
4944     {
4945         case Ttuple:
4946             error(loc, "can't have pointer to %s", n->toChars());
4947             /* fall through */
4948         case Terror:
4949             return Type::terror;
4950         default:
4951             break;
4952     }
4953     if (n != next)
4954     {
4955         deco = NULL;
4956     }
4957     next = n;
4958     if (next->ty != Tfunction)
4959     {   transitive();
4960         return merge();
4961     }
4962     deco = merge()->deco;
4963     /* Don't return merge(), because arg identifiers and default args
4964      * can be different
4965      * even though the types match
4966      */
4967     return this;
4968 }
4969 
4970 
size(Loc)4971 d_uns64 TypePointer::size(Loc)
4972 {
4973     return Target::ptrsize;
4974 }
4975 
implicitConvTo(Type * to)4976 MATCH TypePointer::implicitConvTo(Type *to)
4977 {
4978     //printf("TypePointer::implicitConvTo(to = %s) %s\n", to->toChars(), toChars());
4979 
4980     if (equals(to))
4981         return MATCHexact;
4982     if (next->ty == Tfunction)
4983     {
4984         if (to->ty == Tpointer)
4985         {
4986             TypePointer *tp = (TypePointer *)to;
4987             if (tp->next->ty == Tfunction)
4988             {
4989                 if (next->equals(tp->next))
4990                     return MATCHconst;
4991 
4992                 if (next->covariant(tp->next) == 1)
4993                 {
4994                     Type *tret = this->next->nextOf();
4995                     Type *toret = tp->next->nextOf();
4996                     if (tret->ty == Tclass && toret->ty == Tclass)
4997                     {
4998                         /* Bugzilla 10219: Check covariant interface return with offset tweaking.
4999                          * interface I {}
5000                          * class C : Object, I {}
5001                          * I function() dg = function C() {}    // should be error
5002                          */
5003                         int offset = 0;
5004                         if (toret->isBaseOf(tret, &offset) && offset != 0)
5005                             return MATCHnomatch;
5006                     }
5007                     return MATCHconvert;
5008                 }
5009             }
5010             else if (tp->next->ty == Tvoid)
5011             {
5012                 // Allow conversions to void*
5013                 return MATCHconvert;
5014             }
5015         }
5016         return MATCHnomatch;
5017     }
5018     else if (to->ty == Tpointer)
5019     {
5020         TypePointer *tp = (TypePointer *)to;
5021         assert(tp->next);
5022 
5023         if (!MODimplicitConv(next->mod, tp->next->mod))
5024             return MATCHnomatch;        // not const-compatible
5025 
5026         /* Alloc conversion to void*
5027          */
5028         if (next->ty != Tvoid && tp->next->ty == Tvoid)
5029         {
5030             return MATCHconvert;
5031         }
5032 
5033         MATCH m = next->constConv(tp->next);
5034         if (m > MATCHnomatch)
5035         {
5036             if (m == MATCHexact && mod != to->mod)
5037                 m = MATCHconst;
5038             return m;
5039         }
5040     }
5041     return MATCHnomatch;
5042 }
5043 
constConv(Type * to)5044 MATCH TypePointer::constConv(Type *to)
5045 {
5046     if (next->ty == Tfunction)
5047     {
5048         if (to->nextOf() && next->equals(((TypeNext *)to)->next))
5049             return Type::constConv(to);
5050         else
5051             return MATCHnomatch;
5052     }
5053     return TypeNext::constConv(to);
5054 }
5055 
isscalar()5056 bool TypePointer::isscalar()
5057 {
5058     return true;
5059 }
5060 
defaultInit(Loc loc)5061 Expression *TypePointer::defaultInit(Loc loc)
5062 {
5063     return new NullExp(loc, this);
5064 }
5065 
isZeroInit(Loc)5066 bool TypePointer::isZeroInit(Loc)
5067 {
5068     return true;
5069 }
5070 
hasPointers()5071 bool TypePointer::hasPointers()
5072 {
5073     return true;
5074 }
5075 
5076 
5077 /***************************** TypeReference *****************************/
5078 
TypeReference(Type * t)5079 TypeReference::TypeReference(Type *t)
5080     : TypeNext(Treference, t)
5081 {
5082     // BUG: what about references to static arrays?
5083 }
5084 
kind()5085 const char *TypeReference::kind()
5086 {
5087     return "reference";
5088 }
5089 
syntaxCopy()5090 Type *TypeReference::syntaxCopy()
5091 {
5092     Type *t = next->syntaxCopy();
5093     if (t == next)
5094         t = this;
5095     else
5096     {
5097         t = new TypeReference(t);
5098         t->mod = mod;
5099     }
5100     return t;
5101 }
5102 
semantic(Loc loc,Scope * sc)5103 Type *TypeReference::semantic(Loc loc, Scope *sc)
5104 {
5105     //printf("TypeReference::semantic()\n");
5106     Type *n = next->semantic(loc, sc);
5107     if (n != next)
5108         deco = NULL;
5109     next = n;
5110     transitive();
5111     return merge();
5112 }
5113 
5114 
size(Loc)5115 d_uns64 TypeReference::size(Loc)
5116 {
5117     return Target::ptrsize;
5118 }
5119 
dotExp(Scope * sc,Expression * e,Identifier * ident,int flag)5120 Expression *TypeReference::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
5121 {
5122     // References just forward things along
5123     return next->dotExp(sc, e, ident, flag);
5124 }
5125 
defaultInit(Loc loc)5126 Expression *TypeReference::defaultInit(Loc loc)
5127 {
5128     return new NullExp(loc, this);
5129 }
5130 
isZeroInit(Loc)5131 bool TypeReference::isZeroInit(Loc)
5132 {
5133     return true;
5134 }
5135 
5136 
5137 /***************************** TypeFunction *****************************/
5138 
TypeFunction(Parameters * parameters,Type * treturn,int varargs,LINK linkage,StorageClass stc)5139 TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc)
5140     : TypeNext(Tfunction, treturn)
5141 {
5142 //if (!treturn) *(char*)0=0;
5143 //    assert(treturn);
5144     assert(0 <= varargs && varargs <= 2);
5145     this->parameters = parameters;
5146     this->varargs = varargs;
5147     this->linkage = linkage;
5148     this->inuse = 0;
5149     this->isnothrow = false;
5150     this->isnogc = false;
5151     this->purity = PUREimpure;
5152     this->isproperty = false;
5153     this->isref = false;
5154     this->isreturn = false;
5155     this->isscope = false;
5156     this->isscopeinferred = false;
5157     this->iswild = 0;
5158     this->fargs = NULL;
5159 
5160     if (stc & STCpure)
5161         this->purity = PUREfwdref;
5162     if (stc & STCnothrow)
5163         this->isnothrow = true;
5164     if (stc & STCnogc)
5165         this->isnogc = true;
5166     if (stc & STCproperty)
5167         this->isproperty = true;
5168 
5169     if (stc & STCref)
5170         this->isref = true;
5171     if (stc & STCreturn)
5172         this->isreturn = true;
5173     if (stc & STCscope)
5174         this->isscope = true;
5175     if (stc & STCscopeinferred)
5176         this->isscopeinferred = true;
5177 
5178     this->trust = TRUSTdefault;
5179     if (stc & STCsafe)
5180         this->trust = TRUSTsafe;
5181     if (stc & STCsystem)
5182         this->trust = TRUSTsystem;
5183     if (stc & STCtrusted)
5184         this->trust = TRUSTtrusted;
5185 }
5186 
create(Parameters * parameters,Type * treturn,int varargs,LINK linkage,StorageClass stc)5187 TypeFunction *TypeFunction::create(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc)
5188 {
5189     return new TypeFunction(parameters, treturn, varargs, linkage, stc);
5190 }
5191 
kind()5192 const char *TypeFunction::kind()
5193 {
5194     return "function";
5195 }
5196 
syntaxCopy()5197 Type *TypeFunction::syntaxCopy()
5198 {
5199     Type *treturn = next ? next->syntaxCopy() : NULL;
5200     Parameters *params = Parameter::arraySyntaxCopy(parameters);
5201     TypeFunction *t = new TypeFunction(params, treturn, varargs, linkage);
5202     t->mod = mod;
5203     t->isnothrow = isnothrow;
5204     t->isnogc = isnogc;
5205     t->purity = purity;
5206     t->isproperty = isproperty;
5207     t->isref = isref;
5208     t->isreturn = isreturn;
5209     t->isscope = isscope;
5210     t->isscopeinferred = isscopeinferred;
5211     t->iswild = iswild;
5212     t->trust = trust;
5213     t->fargs = fargs;
5214     return t;
5215 }
5216 
5217 /*******************************
5218  * Covariant means that 'this' can substitute for 't',
5219  * i.e. a pure function is a match for an impure type.
5220  * Params:
5221  *      t = type 'this' is covariant with
5222  *      pstc = if not null, store STCxxxx which would make it covariant
5223  *      fix17349 = enable fix https://issues.dlang.org/show_bug.cgi?id=17349
5224  * Returns:
5225  *      0       types are distinct
5226  *      1       this is covariant with t
5227  *      2       arguments match as far as overloading goes,
5228  *              but types are not covariant
5229  *      3       cannot determine covariance because of forward references
5230  *      *pstc   STCxxxx which would make it covariant
5231  */
5232 
covariant(Type * t,StorageClass * pstc,bool fix17349)5233 int Type::covariant(Type *t, StorageClass *pstc, bool fix17349)
5234 {
5235     if (pstc)
5236         *pstc = 0;
5237     StorageClass stc = 0;
5238 
5239     bool notcovariant = false;
5240 
5241     TypeFunction *t1;
5242     TypeFunction *t2;
5243 
5244     if (equals(t))
5245         return 1;                       // covariant
5246 
5247     if (ty != Tfunction || t->ty != Tfunction)
5248         goto Ldistinct;
5249 
5250     t1 = (TypeFunction *)this;
5251     t2 = (TypeFunction *)t;
5252 
5253     if (t1->varargs != t2->varargs)
5254         goto Ldistinct;
5255 
5256     if (t1->parameters && t2->parameters)
5257     {
5258         size_t dim = Parameter::dim(t1->parameters);
5259         if (dim != Parameter::dim(t2->parameters))
5260             goto Ldistinct;
5261 
5262         for (size_t i = 0; i < dim; i++)
5263         {
5264             Parameter *fparam1 = Parameter::getNth(t1->parameters, i);
5265             Parameter *fparam2 = Parameter::getNth(t2->parameters, i);
5266 
5267             if (!fparam1->type->equals(fparam2->type))
5268             {
5269                 if (!fix17349)
5270                     goto Ldistinct;
5271                 Type *tp1 = fparam1->type;
5272                 Type *tp2 = fparam2->type;
5273                 if (tp1->ty == tp2->ty)
5274                 {
5275                     if (tp1->ty == Tclass)
5276                     {
5277                         if (((TypeClass *)tp1)->sym == ((TypeClass *)tp2)->sym && MODimplicitConv(tp2->mod, tp1->mod))
5278                             goto Lcov;
5279                     }
5280                     else if (tp1->ty == Tstruct)
5281                     {
5282                         if (((TypeStruct *)tp1)->sym == ((TypeStruct *)tp2)->sym && MODimplicitConv(tp2->mod, tp1->mod))
5283                             goto Lcov;
5284                     }
5285                     else if (tp1->ty == Tpointer)
5286                     {
5287                         if (tp2->implicitConvTo(tp1))
5288                             goto Lcov;
5289                     }
5290                     else if (tp1->ty == Tarray)
5291                     {
5292                         if (tp2->implicitConvTo(tp1))
5293                             goto Lcov;
5294                     }
5295                     else if (tp1->ty == Tdelegate)
5296                     {
5297                         if (tp1->implicitConvTo(tp2))
5298                             goto Lcov;
5299                     }
5300                 }
5301                 goto Ldistinct;
5302             }
5303         Lcov:
5304             notcovariant |= !fparam1->isCovariant(t1->isref, fparam2);
5305         }
5306     }
5307     else if (t1->parameters != t2->parameters)
5308     {
5309         size_t dim1 = !t1->parameters ? 0 : t1->parameters->dim;
5310         size_t dim2 = !t2->parameters ? 0 : t2->parameters->dim;
5311         if (dim1 || dim2)
5312             goto Ldistinct;
5313     }
5314 
5315     // The argument lists match
5316     if (notcovariant)
5317         goto Lnotcovariant;
5318     if (t1->linkage != t2->linkage)
5319         goto Lnotcovariant;
5320 
5321   {
5322     // Return types
5323     Type *t1n = t1->next;
5324     Type *t2n = t2->next;
5325 
5326     if (!t1n || !t2n)           // happens with return type inference
5327         goto Lnotcovariant;
5328 
5329     if (t1n->equals(t2n))
5330         goto Lcovariant;
5331     if (t1n->ty == Tclass && t2n->ty == Tclass)
5332     {
5333         /* If same class type, but t2n is const, then it's
5334          * covariant. Do this test first because it can work on
5335          * forward references.
5336          */
5337         if (((TypeClass *)t1n)->sym == ((TypeClass *)t2n)->sym &&
5338             MODimplicitConv(t1n->mod, t2n->mod))
5339             goto Lcovariant;
5340 
5341         // If t1n is forward referenced:
5342         ClassDeclaration *cd = ((TypeClass *)t1n)->sym;
5343         if (cd->semanticRun < PASSsemanticdone && !cd->isBaseInfoComplete())
5344             cd->semantic(NULL);
5345         if (!cd->isBaseInfoComplete())
5346         {
5347             return 3;   // forward references
5348         }
5349     }
5350     if (t1n->ty == Tstruct && t2n->ty == Tstruct)
5351     {
5352         if (((TypeStruct *)t1n)->sym == ((TypeStruct *)t2n)->sym &&
5353             MODimplicitConv(t1n->mod, t2n->mod))
5354             goto Lcovariant;
5355     }
5356     else if (t1n->ty == t2n->ty && t1n->implicitConvTo(t2n))
5357         goto Lcovariant;
5358     else if (t1n->ty == Tnull)
5359     {
5360         // NULL is covariant with any pointer type, but not with any
5361         // dynamic arrays, associative arrays or delegates.
5362         // https://issues.dlang.org/show_bug.cgi?id=8589
5363         // https://issues.dlang.org/show_bug.cgi?id=19618
5364         Type *t2bn = t2n->toBasetype();
5365         if (t2bn->ty == Tnull || t2bn->ty == Tpointer || t2bn->ty == Tclass)
5366             goto Lcovariant;
5367     }
5368   }
5369     goto Lnotcovariant;
5370 
5371 Lcovariant:
5372     if (t1->isref != t2->isref)
5373         goto Lnotcovariant;
5374 
5375     if (!t1->isref && (t1->isscope || t2->isscope))
5376     {
5377         StorageClass stc1 = t1->isscope ? STCscope : 0;
5378         StorageClass stc2 = t2->isscope ? STCscope : 0;
5379         if (t1->isreturn)
5380         {
5381             stc1 |= STCreturn;
5382             if (!t1->isscope)
5383                 stc1 |= STCref;
5384         }
5385         if (t2->isreturn)
5386         {
5387             stc2 |= STCreturn;
5388             if (!t2->isscope)
5389                 stc2 |= STCref;
5390         }
5391         if (!Parameter::isCovariantScope(t1->isref, stc1, stc2))
5392             goto Lnotcovariant;
5393     }
5394 
5395     // We can subtract 'return ref' from 'this', but cannot add it
5396     else if (t1->isreturn && !t2->isreturn)
5397         goto Lnotcovariant;
5398 
5399     /* Can convert mutable to const
5400      */
5401     if (!MODimplicitConv(t2->mod, t1->mod))
5402     {
5403         goto Ldistinct;
5404     }
5405 
5406     /* Can convert pure to impure, nothrow to throw, and nogc to gc
5407      */
5408     if (!t1->purity && t2->purity)
5409         stc |= STCpure;
5410 
5411     if (!t1->isnothrow && t2->isnothrow)
5412         stc |= STCnothrow;
5413 
5414     if (!t1->isnogc && t2->isnogc)
5415         stc |= STCnogc;
5416 
5417     /* Can convert safe/trusted to system
5418      */
5419     if (t1->trust <= TRUSTsystem && t2->trust >= TRUSTtrusted)
5420     {
5421         // Should we infer trusted or safe? Go with safe.
5422         stc |= STCsafe;
5423     }
5424 
5425     if (stc)
5426     {   if (pstc)
5427             *pstc = stc;
5428         goto Lnotcovariant;
5429     }
5430 
5431     //printf("\tcovaraint: 1\n");
5432     return 1;
5433 
5434 Ldistinct:
5435     //printf("\tcovaraint: 0\n");
5436     return 0;
5437 
5438 Lnotcovariant:
5439     //printf("\tcovaraint: 2\n");
5440     return 2;
5441 }
5442 
semantic(Loc loc,Scope * sc)5443 Type *TypeFunction::semantic(Loc loc, Scope *sc)
5444 {
5445     if (deco)                   // if semantic() already run
5446     {
5447         //printf("already done\n");
5448         return this;
5449     }
5450     //printf("TypeFunction::semantic() this = %p\n", this);
5451     //printf("TypeFunction::semantic() %s, sc->stc = %llx, fargs = %p\n", toChars(), sc->stc, fargs);
5452 
5453     bool errors = false;
5454 
5455     if (inuse > global.recursionLimit)
5456     {
5457         inuse = 0;
5458         ::error(loc, "recursive type");
5459         return Type::terror;
5460     }
5461 
5462     /* Copy in order to not mess up original.
5463      * This can produce redundant copies if inferring return type,
5464      * as semantic() will get called again on this.
5465      */
5466     TypeFunction *tf = copy()->toTypeFunction();
5467     if (parameters)
5468     {
5469         tf->parameters = parameters->copy();
5470         for (size_t i = 0; i < parameters->dim; i++)
5471         {
5472             void *pp = mem.xmalloc(sizeof(Parameter));
5473             Parameter *p = (Parameter *)memcpy(pp, (void *)(*parameters)[i], sizeof(Parameter));
5474             (*tf->parameters)[i] = p;
5475         }
5476     }
5477 
5478     if (sc->stc & STCpure)
5479         tf->purity = PUREfwdref;
5480     if (sc->stc & STCnothrow)
5481         tf->isnothrow = true;
5482     if (sc->stc & STCnogc)
5483         tf->isnogc = true;
5484     if (sc->stc & STCref)
5485         tf->isref = true;
5486     if (sc->stc & STCreturn)
5487         tf->isreturn = true;
5488     if (sc->stc & STCscope)
5489         tf->isscope = true;
5490     if (sc->stc & STCscopeinferred)
5491         tf->isscopeinferred = true;
5492 
5493 //    if ((sc->stc & (STCreturn | STCref)) == STCreturn)
5494 //        tf->isscope = true;                                 // return by itself means 'return scope'
5495 
5496     if (tf->trust == TRUSTdefault)
5497     {
5498         if (sc->stc & STCsafe)
5499             tf->trust = TRUSTsafe;
5500         if (sc->stc & STCsystem)
5501             tf->trust = TRUSTsystem;
5502         if (sc->stc & STCtrusted)
5503             tf->trust = TRUSTtrusted;
5504     }
5505 
5506     if (sc->stc & STCproperty)
5507         tf->isproperty = true;
5508 
5509     tf->linkage = sc->linkage;
5510     bool wildreturn = false;
5511     if (tf->next)
5512     {
5513         sc = sc->push();
5514         sc->stc &= ~(STC_TYPECTOR | STC_FUNCATTR);
5515         tf->next = tf->next->semantic(loc, sc);
5516         sc = sc->pop();
5517         errors |= tf->checkRetType(loc);
5518         if (tf->next->isscope() && !(sc->flags & SCOPEctor))
5519         {
5520             error(loc, "functions cannot return scope %s", tf->next->toChars());
5521             errors = true;
5522         }
5523         if (tf->next->hasWild())
5524             wildreturn = true;
5525 
5526         if (tf->isreturn && !tf->isref && !tf->next->hasPointers())
5527         {
5528             error(loc, "function type '%s' has 'return' but does not return any indirections", tf->toChars());
5529         }
5530     }
5531 
5532     unsigned char wildparams = 0;
5533     if (tf->parameters)
5534     {
5535         /* Create a scope for evaluating the default arguments for the parameters
5536          */
5537         Scope *argsc = sc->push();
5538         argsc->stc = 0;                 // don't inherit storage class
5539         argsc->protection = Prot(PROTpublic);
5540         argsc->func = NULL;
5541 
5542         size_t dim = Parameter::dim(tf->parameters);
5543         for (size_t i = 0; i < dim; i++)
5544         {
5545             Parameter *fparam = Parameter::getNth(tf->parameters, i);
5546             inuse++;
5547             fparam->type = fparam->type->semantic(loc, argsc);
5548             inuse--;
5549 
5550             if (fparam->type->ty == Terror)
5551             {
5552                 errors = true;
5553                 continue;
5554             }
5555 
5556             fparam->type = fparam->type->addStorageClass(fparam->storageClass);
5557 
5558             if (fparam->storageClass & (STCauto | STCalias | STCstatic))
5559             {
5560                 if (!fparam->type)
5561                     continue;
5562             }
5563 
5564             Type *t = fparam->type->toBasetype();
5565 
5566             if (t->ty == Tfunction)
5567             {
5568                 error(loc, "cannot have parameter of function type %s", fparam->type->toChars());
5569                 errors = true;
5570             }
5571             else if (!(fparam->storageClass & (STCref | STCout)) &&
5572                      (t->ty == Tstruct || t->ty == Tsarray || t->ty == Tenum))
5573             {
5574                 Type *tb2 = t->baseElemOf();
5575                 if ((tb2->ty == Tstruct && !((TypeStruct *)tb2)->sym->members) ||
5576                     (tb2->ty == Tenum && !((TypeEnum *)tb2)->sym->memtype))
5577                 {
5578                     error(loc, "cannot have parameter of opaque type %s by value", fparam->type->toChars());
5579                     errors = true;
5580                 }
5581             }
5582             else if (!(fparam->storageClass & STClazy) && t->ty == Tvoid)
5583             {
5584                 error(loc, "cannot have parameter of type %s", fparam->type->toChars());
5585                 errors = true;
5586             }
5587 
5588             if ((fparam->storageClass & (STCref | STCwild)) == (STCref | STCwild))
5589             {
5590                 // 'ref inout' implies 'return'
5591                 fparam->storageClass |= STCreturn;
5592             }
5593 
5594             if (fparam->storageClass & STCreturn)
5595             {
5596                 if (fparam->storageClass & (STCref | STCout))
5597                 {
5598                     // Disabled for the moment awaiting improvement to allow return by ref
5599                     // to be transformed into return by scope.
5600                     if (0 && !tf->isref)
5601                     {
5602                         StorageClass stc = fparam->storageClass & (STCref | STCout);
5603                         error(loc, "parameter %s is 'return %s' but function does not return by ref",
5604                             fparam->ident ? fparam->ident->toChars() : "",
5605                             stcToChars(stc));
5606                         errors = true;
5607                     }
5608                 }
5609                 else
5610                 {
5611                     fparam->storageClass |= STCscope;        // 'return' implies 'scope'
5612                     if (tf->isref)
5613                     {
5614                     }
5615                     else if (!tf->isref && tf->next && !tf->next->hasPointers())
5616                     {
5617                         error(loc, "parameter %s is 'return' but function does not return any indirections",
5618                             fparam->ident ? fparam->ident->toChars() : "");
5619                         errors = true;
5620                     }
5621                 }
5622             }
5623 
5624             if (fparam->storageClass & (STCref | STClazy))
5625             {
5626             }
5627             else if (fparam->storageClass & STCout)
5628             {
5629                 if (unsigned char m = fparam->type->mod & (MODimmutable | MODconst | MODwild))
5630                 {
5631                     error(loc, "cannot have %s out parameter of type %s", MODtoChars(m), t->toChars());
5632                     errors = true;
5633                 }
5634                 else
5635                 {
5636                     Type *tv = t;
5637                     while (tv->ty == Tsarray)
5638                         tv = tv->nextOf()->toBasetype();
5639                     if (tv->ty == Tstruct && ((TypeStruct *)tv)->sym->noDefaultCtor)
5640                     {
5641                         error(loc, "cannot have out parameter of type %s because the default construction is disabled",
5642                             fparam->type->toChars());
5643                         errors = true;
5644                     }
5645                 }
5646             }
5647 
5648             if (fparam->storageClass & STCscope && !fparam->type->hasPointers() && fparam->type->ty != Ttuple)
5649             {
5650                 fparam->storageClass &= ~STCscope;
5651                 if (!(fparam->storageClass & STCref))
5652                     fparam->storageClass &= ~STCreturn;
5653             }
5654 
5655             if (t->hasWild())
5656             {
5657                 wildparams |= 1;
5658                 //if (tf->next && !wildreturn)
5659                 //    error(loc, "inout on parameter means inout must be on return type as well (if from D1 code, replace with 'ref')");
5660             }
5661 
5662             if (fparam->defaultArg)
5663             {
5664                 Expression *e = fparam->defaultArg;
5665                 if (fparam->storageClass & (STCref | STCout))
5666                 {
5667                     e = ::semantic(e, argsc);
5668                     e = resolveProperties(argsc, e);
5669                 }
5670                 else
5671                 {
5672                     e = inferType(e, fparam->type);
5673                     Initializer *iz = new ExpInitializer(e->loc, e);
5674                     iz = ::semantic(iz, argsc, fparam->type, INITnointerpret);
5675                     e = initializerToExpression(iz);
5676                 }
5677                 if (e->op == TOKfunction)               // see Bugzilla 4820
5678                 {
5679                     FuncExp *fe = (FuncExp *)e;
5680                     // Replace function literal with a function symbol,
5681                     // since default arg expression must be copied when used
5682                     // and copying the literal itself is wrong.
5683                     e = new VarExp(e->loc, fe->fd, false);
5684                     e = new AddrExp(e->loc, e);
5685                     e = ::semantic(e, argsc);
5686                 }
5687                 e = e->implicitCastTo(argsc, fparam->type);
5688 
5689                 // default arg must be an lvalue
5690                 if (fparam->storageClass & (STCout | STCref))
5691                     e = e->toLvalue(argsc, e);
5692 
5693                 fparam->defaultArg = e;
5694                 if (e->op == TOKerror)
5695                     errors = true;
5696             }
5697 
5698             /* If fparam after semantic() turns out to be a tuple, the number of parameters may
5699              * change.
5700              */
5701             if (t->ty == Ttuple)
5702             {
5703                 /* TypeFunction::parameter also is used as the storage of
5704                  * Parameter objects for FuncDeclaration. So we should copy
5705                  * the elements of TypeTuple::arguments to avoid unintended
5706                  * sharing of Parameter object among other functions.
5707                  */
5708                 TypeTuple *tt = (TypeTuple *)t;
5709                 if (tt->arguments && tt->arguments->dim)
5710                 {
5711                     /* Propagate additional storage class from tuple parameters to their
5712                      * element-parameters.
5713                      * Make a copy, as original may be referenced elsewhere.
5714                      */
5715                     size_t tdim = tt->arguments->dim;
5716                     Parameters *newparams = new Parameters();
5717                     newparams->setDim(tdim);
5718                     for (size_t j = 0; j < tdim; j++)
5719                     {
5720                         Parameter *narg = (*tt->arguments)[j];
5721 
5722                         // Bugzilla 12744: If the storage classes of narg
5723                         // conflict with the ones in fparam, it's ignored.
5724                         StorageClass stc  = fparam->storageClass | narg->storageClass;
5725                         StorageClass stc1 = fparam->storageClass & (STCref | STCout | STClazy);
5726                         StorageClass stc2 =   narg->storageClass & (STCref | STCout | STClazy);
5727                         if (stc1 && stc2 && stc1 != stc2)
5728                         {
5729                             OutBuffer buf1;  stcToBuffer(&buf1, stc1 | ((stc1 & STCref) ? (fparam->storageClass & STCauto) : 0));
5730                             OutBuffer buf2;  stcToBuffer(&buf2, stc2);
5731 
5732                             error(loc, "incompatible parameter storage classes '%s' and '%s'",
5733                                       buf1.peekString(), buf2.peekString());
5734                             errors = true;
5735                             stc = stc1 | (stc & ~(STCref | STCout | STClazy));
5736                         }
5737 
5738                         (*newparams)[j] = new Parameter(
5739                                 stc, narg->type, narg->ident, narg->defaultArg);
5740                     }
5741                     fparam->type = new TypeTuple(newparams);
5742                 }
5743                 fparam->storageClass = 0;
5744 
5745                 /* Reset number of parameters, and back up one to do this fparam again,
5746                  * now that it is a tuple
5747                  */
5748                 dim = Parameter::dim(tf->parameters);
5749                 i--;
5750                 continue;
5751             }
5752 
5753             /* Resolve "auto ref" storage class to be either ref or value,
5754              * based on the argument matching the parameter
5755              */
5756             if (fparam->storageClass & STCauto)
5757             {
5758                 if (fargs && i < fargs->dim && (fparam->storageClass & STCref))
5759                 {
5760                     Expression *farg = (*fargs)[i];
5761                     if (farg->isLvalue())
5762                         ;                               // ref parameter
5763                     else
5764                         fparam->storageClass &= ~STCref;        // value parameter
5765                     fparam->storageClass &= ~STCauto;    // Bugzilla 14656
5766                     fparam->storageClass |= STCautoref;
5767                 }
5768                 else
5769                 {
5770                     error(loc, "'auto' can only be used as part of 'auto ref' for template function parameters");
5771                     errors = true;
5772                 }
5773             }
5774 
5775             // Remove redundant storage classes for type, they are already applied
5776             fparam->storageClass &= ~(STC_TYPECTOR | STCin);
5777         }
5778         argsc->pop();
5779     }
5780     if (tf->isWild())
5781         wildparams |= 2;
5782 
5783     if (wildreturn && !wildparams)
5784     {
5785         error(loc, "inout on return means inout must be on a parameter as well for %s", toChars());
5786         errors = true;
5787     }
5788     tf->iswild = wildparams;
5789 
5790     if (tf->isproperty && (tf->varargs || Parameter::dim(tf->parameters) > 2))
5791     {
5792         error(loc, "properties can only have zero, one, or two parameter");
5793         errors = true;
5794     }
5795 
5796     if (tf->varargs == 1 && tf->linkage != LINKd && Parameter::dim(tf->parameters) == 0)
5797     {
5798         error(loc, "variadic functions with non-D linkage must have at least one parameter");
5799         errors = true;
5800     }
5801 
5802     if (errors)
5803         return terror;
5804 
5805     if (tf->next)
5806         tf->deco = tf->merge()->deco;
5807 
5808     /* Don't return merge(), because arg identifiers and default args
5809      * can be different
5810      * even though the types match
5811      */
5812     return tf;
5813 }
5814 
checkRetType(Loc loc)5815 bool TypeFunction::checkRetType(Loc loc)
5816 {
5817     Type *tb = next->toBasetype();
5818     if (tb->ty == Tfunction)
5819     {
5820         error(loc, "functions cannot return a function");
5821         next = Type::terror;
5822     }
5823     if (tb->ty == Ttuple)
5824     {
5825         error(loc, "functions cannot return a tuple");
5826         next = Type::terror;
5827     }
5828     if (!isref && (tb->ty == Tstruct || tb->ty == Tsarray))
5829     {
5830         Type *tb2 = tb->baseElemOf();
5831         if (tb2->ty == Tstruct && !((TypeStruct *)tb2)->sym->members)
5832         {
5833             error(loc, "functions cannot return opaque type %s by value", tb->toChars());
5834             next = Type::terror;
5835         }
5836     }
5837     if (tb->ty == Terror)
5838         return true;
5839 
5840     return false;
5841 }
5842 
5843 /* Determine purity level based on mutability of t
5844  * and whether it is a 'ref' type or not.
5845  */
purityOfType(bool isref,Type * t)5846 static PURE purityOfType(bool isref, Type *t)
5847 {
5848     if (isref)
5849     {
5850         if (t->mod & MODimmutable)
5851             return PUREstrong;
5852         if (t->mod & (MODconst | MODwild))
5853             return PUREconst;
5854         return PUREweak;
5855     }
5856 
5857     t = t->baseElemOf();
5858 
5859     if (!t->hasPointers() || t->mod & MODimmutable)
5860         return PUREstrong;
5861 
5862     /* Accept immutable(T)[] and immutable(T)* as being strongly pure
5863      */
5864     if (t->ty == Tarray || t->ty == Tpointer)
5865     {
5866         Type *tn = t->nextOf()->toBasetype();
5867         if (tn->mod & MODimmutable)
5868             return PUREstrong;
5869         if (tn->mod & (MODconst | MODwild))
5870             return PUREconst;
5871     }
5872 
5873     /* The rest of this is too strict; fix later.
5874      * For example, the only pointer members of a struct may be immutable,
5875      * which would maintain strong purity.
5876      * (Just like for dynamic arrays and pointers above.)
5877      */
5878     if (t->mod & (MODconst | MODwild))
5879         return PUREconst;
5880 
5881     /* Should catch delegates and function pointers, and fold in their purity
5882      */
5883     return PUREweak;
5884 }
5885 
5886 /********************************************
5887  * Set 'purity' field of 'this'.
5888  * Do this lazily, as the parameter types might be forward referenced.
5889  */
purityLevel()5890 void TypeFunction::purityLevel()
5891 {
5892     TypeFunction *tf = this;
5893     if (tf->purity != PUREfwdref)
5894         return;
5895 
5896     purity = PUREstrong; // assume strong until something weakens it
5897 
5898     /* Evaluate what kind of purity based on the modifiers for the parameters
5899      */
5900     const size_t dim = Parameter::dim(tf->parameters);
5901     for (size_t i = 0; i < dim; i++)
5902     {
5903         Parameter *fparam = Parameter::getNth(tf->parameters, i);
5904         Type *t = fparam->type;
5905         if (!t)
5906             continue;
5907 
5908         if (fparam->storageClass & (STClazy | STCout))
5909         {
5910             purity = PUREweak;
5911             break;
5912         }
5913         switch (purityOfType((fparam->storageClass & STCref) != 0, t))
5914         {
5915             case PUREweak:
5916                 purity = PUREweak;
5917                 break;
5918 
5919             case PUREconst:
5920                 purity = PUREconst;
5921                 continue;
5922 
5923             case PUREstrong:
5924                 continue;
5925 
5926             default:
5927                 assert(0);
5928         }
5929         break;              // since PUREweak, no need to check further
5930     }
5931 
5932     if (purity > PUREweak && tf->nextOf())
5933     {
5934         /* Adjust purity based on mutability of return type.
5935          * https://issues.dlang.org/show_bug.cgi?id=15862
5936          */
5937         const PURE purity2 = purityOfType(tf->isref, tf->nextOf());
5938         if (purity2 < purity)
5939             purity = purity2;
5940     }
5941     tf->purity = purity;
5942 }
5943 
5944 /********************************
5945  * 'args' are being matched to function 'this'
5946  * Determine match level.
5947  * Input:
5948  *      flag    1       performing a partial ordering match
5949  * Returns:
5950  *      MATCHxxxx
5951  */
5952 
callMatch(Type * tthis,Expressions * args,int flag)5953 MATCH TypeFunction::callMatch(Type *tthis, Expressions *args, int flag)
5954 {
5955     //printf("TypeFunction::callMatch() %s\n", toChars());
5956     MATCH match = MATCHexact;           // assume exact match
5957     unsigned char wildmatch = 0;
5958 
5959     if (tthis)
5960     {
5961         Type *t = tthis;
5962         if (t->toBasetype()->ty == Tpointer)
5963             t = t->toBasetype()->nextOf();      // change struct* to struct
5964         if (t->mod != mod)
5965         {
5966             if (MODimplicitConv(t->mod, mod))
5967                 match = MATCHconst;
5968             else if ((mod & MODwild) && MODimplicitConv(t->mod, (mod & ~MODwild) | MODconst))
5969             {
5970                 match = MATCHconst;
5971             }
5972             else
5973                 return MATCHnomatch;
5974         }
5975         if (isWild())
5976         {
5977             if (t->isWild())
5978                 wildmatch |= MODwild;
5979             else if (t->isConst())
5980                 wildmatch |= MODconst;
5981             else if (t->isImmutable())
5982                 wildmatch |= MODimmutable;
5983             else
5984                 wildmatch |= MODmutable;
5985         }
5986     }
5987 
5988     size_t nparams = Parameter::dim(parameters);
5989     size_t nargs = args ? args->dim : 0;
5990     if (nparams == nargs)
5991         ;
5992     else if (nargs > nparams)
5993     {
5994         if (varargs == 0)
5995             goto Nomatch;               // too many args; no match
5996         match = MATCHconvert;           // match ... with a "conversion" match level
5997     }
5998 
5999     for (size_t u = 0; u < nargs; u++)
6000     {
6001         if (u >= nparams)
6002             break;
6003         Parameter *p = Parameter::getNth(parameters, u);
6004         Expression *arg = (*args)[u];
6005         assert(arg);
6006         Type *tprm = p->type;
6007         Type *targ = arg->type;
6008 
6009         if (!(p->storageClass & STClazy && tprm->ty == Tvoid && targ->ty != Tvoid))
6010         {
6011             bool isRef = (p->storageClass & (STCref | STCout)) != 0;
6012             wildmatch |= targ->deduceWild(tprm, isRef);
6013         }
6014     }
6015     if (wildmatch)
6016     {
6017         /* Calculate wild matching modifier
6018          */
6019         if (wildmatch & MODconst || wildmatch & (wildmatch - 1))
6020             wildmatch = MODconst;
6021         else if (wildmatch & MODimmutable)
6022             wildmatch = MODimmutable;
6023         else if (wildmatch & MODwild)
6024             wildmatch = MODwild;
6025         else
6026         {
6027             assert(wildmatch & MODmutable);
6028             wildmatch = MODmutable;
6029         }
6030     }
6031 
6032     for (size_t u = 0; u < nparams; u++)
6033     {
6034         MATCH m;
6035 
6036         Parameter *p = Parameter::getNth(parameters, u);
6037         assert(p);
6038         if (u >= nargs)
6039         {
6040             if (p->defaultArg)
6041                 continue;
6042             goto L1;        // try typesafe variadics
6043         }
6044         {
6045             Expression *arg = (*args)[u];
6046             assert(arg);
6047             //printf("arg: %s, type: %s\n", arg->toChars(), arg->type->toChars());
6048 
6049             Type *targ = arg->type;
6050             Type *tprm = wildmatch ? p->type->substWildTo(wildmatch) : p->type;
6051 
6052             if (p->storageClass & STClazy && tprm->ty == Tvoid && targ->ty != Tvoid)
6053                 m = MATCHconvert;
6054             else
6055             {
6056                 //printf("%s of type %s implicitConvTo %s\n", arg->toChars(), targ->toChars(), tprm->toChars());
6057                 if (flag)
6058                 {
6059                     // for partial ordering, value is an irrelevant mockup, just look at the type
6060                     m = targ->implicitConvTo(tprm);
6061                 }
6062                 else
6063                     m = arg->implicitConvTo(tprm);
6064                 //printf("match %d\n", m);
6065             }
6066 
6067             // Non-lvalues do not match ref or out parameters
6068             if (p->storageClass & (STCref | STCout))
6069             {
6070                 // Bugzilla 13783: Don't use toBasetype() to handle enum types.
6071                 Type *ta = targ;
6072                 Type *tp = tprm;
6073                 //printf("fparam[%d] ta = %s, tp = %s\n", u, ta->toChars(), tp->toChars());
6074 
6075                 if (m && !arg->isLvalue())
6076                 {
6077                     if (p->storageClass & STCout)
6078                         goto Nomatch;
6079 
6080                     if (arg->op == TOKstring && tp->ty == Tsarray)
6081                     {
6082                         if (ta->ty != Tsarray)
6083                         {
6084                             Type *tn = tp->nextOf()->castMod(ta->nextOf()->mod);
6085                             dinteger_t dim = ((StringExp *)arg)->len;
6086                             ta = tn->sarrayOf(dim);
6087                         }
6088                     }
6089                     else if (arg->op == TOKslice && tp->ty == Tsarray)
6090                     {
6091                         // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
6092                         if (ta->ty != Tsarray)
6093                         {
6094                             Type *tn = ta->nextOf();
6095                             dinteger_t dim = ((TypeSArray *)tp)->dim->toUInteger();
6096                             ta = tn->sarrayOf(dim);
6097                         }
6098                     }
6099                     else
6100                         goto Nomatch;
6101                 }
6102 
6103                 /* Find most derived alias this type being matched.
6104                  * Bugzilla 15674: Allow on both ref and out parameters.
6105                  */
6106                 while (1)
6107                 {
6108                     Type *tat = ta->toBasetype()->aliasthisOf();
6109                     if (!tat || !tat->implicitConvTo(tprm))
6110                         break;
6111                     ta = tat;
6112                 }
6113 
6114                 /* A ref variable should work like a head-const reference.
6115                  * e.g. disallows:
6116                  *  ref T      <- an lvalue of const(T) argument
6117                  *  ref T[dim] <- an lvalue of const(T[dim]) argument
6118                  */
6119                 if (!ta->constConv(tp))
6120                     goto Nomatch;
6121             }
6122         }
6123 
6124         /* prefer matching the element type rather than the array
6125          * type when more arguments are present with T[]...
6126          */
6127         if (varargs == 2 && u + 1 == nparams && nargs > nparams)
6128             goto L1;
6129 
6130         //printf("\tm = %d\n", m);
6131         if (m == MATCHnomatch)                  // if no match
6132         {
6133           L1:
6134             if (varargs == 2 && u + 1 == nparams)       // if last varargs param
6135             {
6136                 Type *tb = p->type->toBasetype();
6137                 TypeSArray *tsa;
6138                 dinteger_t sz;
6139 
6140                 switch (tb->ty)
6141                 {
6142                 case Tsarray:
6143                     tsa = (TypeSArray *)tb;
6144                     sz = tsa->dim->toInteger();
6145                     if (sz != nargs - u)
6146                         goto Nomatch;
6147                     /* fall through */
6148                 case Tarray:
6149                     {
6150                         TypeArray *ta = (TypeArray *)tb;
6151                         for (; u < nargs; u++)
6152                         {
6153                             Expression *arg = (*args)[u];
6154                             assert(arg);
6155 
6156                             /* If lazy array of delegates,
6157                              * convert arg(s) to delegate(s)
6158                              */
6159                             Type *tret = p->isLazyArray();
6160                             if (tret)
6161                             {
6162                                 if (ta->next->equals(arg->type))
6163                                     m = MATCHexact;
6164                                 else if (tret->toBasetype()->ty == Tvoid)
6165                                     m = MATCHconvert;
6166                                 else
6167                                 {
6168                                     m = arg->implicitConvTo(tret);
6169                                     if (m == MATCHnomatch)
6170                                         m = arg->implicitConvTo(ta->next);
6171                                 }
6172                             }
6173                             else
6174                                 m = arg->implicitConvTo(ta->next);
6175 
6176                             if (m == MATCHnomatch)
6177                                 goto Nomatch;
6178                             if (m < match)
6179                                 match = m;
6180                         }
6181                         goto Ldone;
6182                     }
6183                 case Tclass:
6184                     // Should see if there's a constructor match?
6185                     // Or just leave it ambiguous?
6186                     goto Ldone;
6187 
6188                 default:
6189                     goto Nomatch;
6190                 }
6191             }
6192             goto Nomatch;
6193         }
6194         if (m < match)
6195             match = m;                  // pick worst match
6196     }
6197 
6198 Ldone:
6199     //printf("match = %d\n", match);
6200     return match;
6201 
6202 Nomatch:
6203     //printf("no match\n");
6204     return MATCHnomatch;
6205 }
6206 
6207 /********************************************
6208  * Return true if there are lazy parameters.
6209  */
hasLazyParameters()6210 bool TypeFunction::hasLazyParameters()
6211 {
6212     size_t dim = Parameter::dim(parameters);
6213     for (size_t i = 0; i < dim; i++)
6214     {
6215         Parameter *fparam = Parameter::getNth(parameters, i);
6216         if (fparam->storageClass & STClazy)
6217             return true;
6218     }
6219     return false;
6220 }
6221 
6222 /***************************
6223  * Examine function signature for parameter p and see if
6224  * the value of p can 'escape' the scope of the function.
6225  * This is useful to minimize the needed annotations for the parameters.
6226  * Params:
6227  *  p = parameter to this function
6228  * Returns:
6229  *  true if escapes via assignment to global or through a parameter
6230  */
6231 
parameterEscapes(Parameter * p)6232 bool TypeFunction::parameterEscapes(Parameter *p)
6233 {
6234     /* Scope parameters do not escape.
6235      * Allow 'lazy' to imply 'scope' -
6236      * lazy parameters can be passed along
6237      * as lazy parameters to the next function, but that isn't
6238      * escaping.
6239      */
6240     if (parameterStorageClass(p) & (STCscope | STClazy))
6241         return false;
6242     return true;
6243 }
6244 
6245 /************************************
6246  * Take the specified storage class for p,
6247  * and use the function signature to infer whether
6248  * STCscope and STCreturn should be OR'd in.
6249  * (This will not affect the name mangling.)
6250  * Params:
6251  *  p = one of the parameters to 'this'
6252  * Returns:
6253  *  storage class with STCscope or STCreturn OR'd in
6254  */
parameterStorageClass(Parameter * p)6255 StorageClass TypeFunction::parameterStorageClass(Parameter *p)
6256 {
6257     StorageClass stc = p->storageClass;
6258     if (!global.params.vsafe)
6259         return stc;
6260 
6261     if (stc & (STCscope | STCreturn | STClazy) || purity == PUREimpure)
6262         return stc;
6263 
6264     /* If haven't inferred the return type yet, can't infer storage classes
6265      */
6266     if (!nextOf())
6267         return stc;
6268 
6269     purityLevel();
6270 
6271     // See if p can escape via any of the other parameters
6272     if (purity == PUREweak)
6273     {
6274         const size_t dim = Parameter::dim(parameters);
6275         for (size_t i = 0; i < dim; i++)
6276         {
6277             Parameter *fparam = Parameter::getNth(parameters, i);
6278             Type *t = fparam->type;
6279             if (!t)
6280                 continue;
6281             t = t->baseElemOf();
6282             if (t->isMutable() && t->hasPointers())
6283             {
6284                 if (fparam->storageClass & (STCref | STCout))
6285                 {
6286                 }
6287                 else if (t->ty == Tarray || t->ty == Tpointer)
6288                 {
6289                     Type *tn = t->nextOf()->toBasetype();
6290                     if (!(tn->isMutable() && tn->hasPointers()))
6291                         continue;
6292                 }
6293                 return stc;
6294             }
6295         }
6296     }
6297 
6298     stc |= STCscope;
6299 
6300     /* Inferring STCreturn here has false positives
6301      * for pure functions, producing spurious error messages
6302      * about escaping references.
6303      * Give up on it for now.
6304      */
6305     return stc;
6306 }
6307 
defaultInit(Loc loc)6308 Expression *TypeFunction::defaultInit(Loc loc)
6309 {
6310     error(loc, "function does not have a default initializer");
6311     return new ErrorExp();
6312 }
6313 
addStorageClass(StorageClass stc)6314 Type *TypeFunction::addStorageClass(StorageClass stc)
6315 {
6316     //printf("addStorageClass(%llx) %d\n", stc, (stc & STCscope) != 0);
6317     TypeFunction *t = Type::addStorageClass(stc)->toTypeFunction();
6318     if ((stc & STCpure && !t->purity) ||
6319         (stc & STCnothrow && !t->isnothrow) ||
6320         (stc & STCnogc && !t->isnogc) ||
6321         (stc & STCscope && !t->isscope) ||
6322         (stc & STCsafe && t->trust < TRUSTtrusted))
6323     {
6324         // Klunky to change these
6325         TypeFunction *tf = new TypeFunction(t->parameters, t->next, t->varargs, t->linkage, 0);
6326         tf->mod = t->mod;
6327         tf->fargs = fargs;
6328         tf->purity = t->purity;
6329         tf->isnothrow = t->isnothrow;
6330         tf->isnogc = t->isnogc;
6331         tf->isproperty = t->isproperty;
6332         tf->isref = t->isref;
6333         tf->isreturn = t->isreturn;
6334         tf->isscope = t->isscope;
6335         tf->isscopeinferred = t->isscopeinferred;
6336         tf->trust = t->trust;
6337         tf->iswild = t->iswild;
6338 
6339         if (stc & STCpure)
6340             tf->purity = PUREfwdref;
6341         if (stc & STCnothrow)
6342             tf->isnothrow = true;
6343         if (stc & STCnogc)
6344             tf->isnogc = true;
6345         if (stc & STCsafe)
6346             tf->trust = TRUSTsafe;
6347         if (stc & STCscope)
6348         {
6349             tf->isscope = true;
6350             if (stc & STCscopeinferred)
6351                 tf->isscopeinferred = true;
6352         }
6353 
6354         tf->deco = tf->merge()->deco;
6355         t = tf;
6356     }
6357     return t;
6358 }
6359 
6360 /** For each active attribute (ref/const/nogc/etc) call fp with a void* for the
6361 work param and a string representation of the attribute. */
attributesApply(void * param,int (* fp)(void *,const char *),TRUSTformat trustFormat)6362 int TypeFunction::attributesApply(void *param, int (*fp)(void *, const char *), TRUSTformat trustFormat)
6363 {
6364     int res = 0;
6365 
6366     if (purity) res = fp(param, "pure");
6367     if (res) return res;
6368 
6369     if (isnothrow) res = fp(param, "nothrow");
6370     if (res) return res;
6371 
6372     if (isnogc) res = fp(param, "@nogc");
6373     if (res) return res;
6374 
6375     if (isproperty) res = fp(param, "@property");
6376     if (res) return res;
6377 
6378     if (isref) res = fp(param, "ref");
6379     if (res) return res;
6380 
6381     if (isreturn) res = fp(param, "return");
6382     if (res) return res;
6383 
6384     if (isscope && !isscopeinferred) res = fp(param, "scope");
6385     if (res) return res;
6386 
6387     TRUST trustAttrib = trust;
6388 
6389     if (trustAttrib == TRUSTdefault)
6390     {
6391         // Print out "@system" when trust equals TRUSTdefault (if desired).
6392         if (trustFormat == TRUSTformatSystem)
6393             trustAttrib = TRUSTsystem;
6394         else
6395             return res;  // avoid calling with an empty string
6396     }
6397 
6398     return fp(param, trustToChars(trustAttrib));
6399 }
6400 
6401 /***************************** TypeDelegate *****************************/
6402 
TypeDelegate(Type * t)6403 TypeDelegate::TypeDelegate(Type *t)
6404     : TypeNext(Tfunction, t)
6405 {
6406     ty = Tdelegate;
6407 }
6408 
create(Type * t)6409 TypeDelegate *TypeDelegate::create(Type *t)
6410 {
6411     return new TypeDelegate(t);
6412 }
6413 
kind()6414 const char *TypeDelegate::kind()
6415 {
6416     return "delegate";
6417 }
6418 
syntaxCopy()6419 Type *TypeDelegate::syntaxCopy()
6420 {
6421     Type *t = next->syntaxCopy();
6422     if (t == next)
6423         t = this;
6424     else
6425     {
6426         t = new TypeDelegate(t);
6427         t->mod = mod;
6428     }
6429     return t;
6430 }
6431 
semantic(Loc loc,Scope * sc)6432 Type *TypeDelegate::semantic(Loc loc, Scope *sc)
6433 {
6434     //printf("TypeDelegate::semantic() %s\n", toChars());
6435     if (deco)                   // if semantic() already run
6436     {
6437         //printf("already done\n");
6438         return this;
6439     }
6440     next = next->semantic(loc,sc);
6441     if (next->ty != Tfunction)
6442         return terror;
6443 
6444     /* In order to deal with Bugzilla 4028, perhaps default arguments should
6445      * be removed from next before the merge.
6446      */
6447 
6448     /* Don't return merge(), because arg identifiers and default args
6449      * can be different
6450      * even though the types match
6451      */
6452     deco = merge()->deco;
6453     return this;
6454 }
6455 
addStorageClass(StorageClass stc)6456 Type *TypeDelegate::addStorageClass(StorageClass stc)
6457 {
6458     TypeDelegate *t = (TypeDelegate*)Type::addStorageClass(stc);
6459     if (!global.params.vsafe)
6460         return t;
6461 
6462     /* The rest is meant to add 'scope' to a delegate declaration if it is of the form:
6463      *  alias dg_t = void* delegate();
6464      *  scope dg_t dg = ...;
6465      */
6466     if (stc & STCscope)
6467     {
6468         Type *n = t->next->addStorageClass(STCscope | STCscopeinferred);
6469         if (n != t->next)
6470         {
6471             t->next = n;
6472             t->deco = t->merge()->deco; // mangling supposed to not be changed due to STCscopeinferrred
6473         }
6474     }
6475     return t;
6476 }
6477 
size(Loc)6478 d_uns64 TypeDelegate::size(Loc)
6479 {
6480     return Target::ptrsize * 2;
6481 }
6482 
alignsize()6483 unsigned TypeDelegate::alignsize()
6484 {
6485     return Target::ptrsize;
6486 }
6487 
implicitConvTo(Type * to)6488 MATCH TypeDelegate::implicitConvTo(Type *to)
6489 {
6490     //printf("TypeDelegate::implicitConvTo(this=%p, to=%p)\n", this, to);
6491     //printf("from: %s\n", toChars());
6492     //printf("to  : %s\n", to->toChars());
6493     if (this == to)
6494         return MATCHexact;
6495 #if 1 // not allowing covariant conversions because it interferes with overriding
6496     if (to->ty == Tdelegate && this->nextOf()->covariant(to->nextOf()) == 1)
6497     {
6498         Type *tret = this->next->nextOf();
6499         Type *toret = ((TypeDelegate *)to)->next->nextOf();
6500         if (tret->ty == Tclass && toret->ty == Tclass)
6501         {
6502             /* Bugzilla 10219: Check covariant interface return with offset tweaking.
6503              * interface I {}
6504              * class C : Object, I {}
6505              * I delegate() dg = delegate C() {}    // should be error
6506              */
6507             int offset = 0;
6508             if (toret->isBaseOf(tret, &offset) && offset != 0)
6509                 return MATCHnomatch;
6510         }
6511         return MATCHconvert;
6512     }
6513 #endif
6514     return MATCHnomatch;
6515 }
6516 
defaultInit(Loc loc)6517 Expression *TypeDelegate::defaultInit(Loc loc)
6518 {
6519     return new NullExp(loc, this);
6520 }
6521 
isZeroInit(Loc)6522 bool TypeDelegate::isZeroInit(Loc)
6523 {
6524     return true;
6525 }
6526 
isBoolean()6527 bool TypeDelegate::isBoolean()
6528 {
6529     return true;
6530 }
6531 
dotExp(Scope * sc,Expression * e,Identifier * ident,int flag)6532 Expression *TypeDelegate::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
6533 {
6534     if (ident == Id::ptr)
6535     {
6536         e = new DelegatePtrExp(e->loc, e);
6537         e = ::semantic(e, sc);
6538     }
6539     else if (ident == Id::funcptr)
6540     {
6541         if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
6542         {
6543             e->error("%s.funcptr cannot be used in @safe code", e->toChars());
6544             return new ErrorExp();
6545         }
6546         e = new DelegateFuncptrExp(e->loc, e);
6547         e = ::semantic(e, sc);
6548     }
6549     else
6550     {
6551         e = Type::dotExp(sc, e, ident, flag);
6552     }
6553     return e;
6554 }
6555 
hasPointers()6556 bool TypeDelegate::hasPointers()
6557 {
6558     return true;
6559 }
6560 
6561 /***************************** TypeTraits ********************************/
6562 
TypeTraits(const Loc & loc,TraitsExp * exp)6563 TypeTraits::TypeTraits(const Loc &loc, TraitsExp *exp)
6564      : Type(Ttraits)
6565 {
6566     this->loc = loc;
6567     this->exp = exp;
6568     this->sym = NULL;
6569 }
6570 
syntaxCopy()6571 Type *TypeTraits::syntaxCopy()
6572 {
6573     TraitsExp *te = (TraitsExp *) exp->syntaxCopy();
6574     TypeTraits *tt = new TypeTraits(loc, te);
6575     tt->mod = mod;
6576     return tt;
6577 }
6578 
semantic(Loc,Scope * sc)6579 Type *TypeTraits::semantic(Loc, Scope *sc)
6580 {
6581     if (ty == Terror)
6582         return this;
6583 
6584     const int inAlias = (sc->flags & SCOPEalias) != 0;
6585     if (exp->ident != Id::allMembers &&
6586         exp->ident != Id::derivedMembers &&
6587         exp->ident != Id::getMember &&
6588         exp->ident != Id::parent &&
6589         exp->ident != Id::getOverloads &&
6590         exp->ident != Id::getVirtualFunctions &&
6591         exp->ident != Id::getVirtualMethods &&
6592         exp->ident != Id::getAttributes &&
6593         exp->ident != Id::getUnitTests &&
6594         exp->ident != Id::getAliasThis)
6595     {
6596         static const char *ctxt[2] = {"as type", "in alias"};
6597         ::error(loc, "trait `%s` is either invalid or not supported %s",
6598                 exp->ident->toChars(), ctxt[inAlias]);
6599         ty = Terror;
6600         return this;
6601     }
6602 
6603     Type *result = NULL;
6604 
6605     if (Expression *e = semanticTraits(exp, sc))
6606     {
6607         switch (e->op)
6608         {
6609         case TOKdotvar:
6610             sym = ((DotVarExp *)e)->var;
6611             break;
6612         case TOKvar:
6613             sym = ((VarExp *)e)->var;
6614             break;
6615         case TOKfunction:
6616         {
6617             FuncExp *fe = (FuncExp *)e;
6618             if (fe->td)
6619                 sym = fe->td;
6620             else
6621                 sym = fe->fd;
6622             break;
6623         }
6624         case TOKdottd:
6625             sym = ((DotTemplateExp*)e)->td;
6626             break;
6627         case TOKdsymbol:
6628             sym = ((DsymbolExp *)e)->s;
6629             break;
6630         case TOKtemplate:
6631             sym = ((TemplateExp *)e)->td;
6632             break;
6633         case TOKscope:
6634             sym = ((ScopeExp *)e)->sds;
6635             break;
6636         case TOKtuple:
6637         {
6638             TupleExp *te = e->toTupleExp();
6639             Objects *elems = new Objects;
6640             elems->setDim(te->exps->dim);
6641             for (size_t i = 0; i < elems->dim; i++)
6642             {
6643                 Expression *src = (*te->exps)[i];
6644                 switch (src->op)
6645                 {
6646                 case TOKtype:
6647                     (*elems)[i] = ((TypeExp *)src)->type;
6648                     break;
6649                 case TOKdottype:
6650                     (*elems)[i] = ((DotTypeExp *)src)->type;
6651                     break;
6652                 case TOKoverloadset:
6653                     (*elems)[i] = ((OverExp *)src)->type;
6654                     break;
6655                 default:
6656                     if (Dsymbol *sym = isDsymbol(src))
6657                         (*elems)[i] = sym;
6658                     else
6659                         (*elems)[i] = src;
6660                 }
6661             }
6662             TupleDeclaration *td = new TupleDeclaration(e->loc,
6663                 Identifier::generateId("__aliastup"), elems);
6664             sym = td;
6665             break;
6666         }
6667         case TOKdottype:
6668             result = isType(((DotTypeExp *)e)->sym);
6669             break;
6670         case TOKtype:
6671             result = ((TypeExp *)e)->type;
6672             break;
6673         case TOKoverloadset:
6674             result = ((OverExp *)e)->type;
6675             break;
6676         default:
6677             break;
6678         }
6679     }
6680 
6681     if (result)
6682         result = result->addMod(mod);
6683     if (!inAlias && !result)
6684     {
6685         if (!global.errors)
6686             ::error(loc, "`%s` does not give a valid type", toChars());
6687         return Type::terror;
6688     }
6689 
6690     return result;
6691 }
6692 
resolve(Loc loc,Scope * sc,Expression ** pe,Type ** pt,Dsymbol ** ps,bool)6693 void TypeTraits::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool)
6694 {
6695     *pt = NULL;
6696     *pe = NULL;
6697     *ps = NULL;
6698 
6699     if (Type *t = semantic(loc, sc))
6700         *pt = t;
6701     else if (sym)
6702         *ps = sym;
6703     else
6704         *pt = Type::terror;
6705 }
6706 
size(Loc)6707 d_uns64 TypeTraits::size(Loc)
6708 {
6709     return SIZE_INVALID;
6710 }
6711 
6712 /***************************** TypeQualified *****************************/
6713 
TypeQualified(TY ty,Loc loc)6714 TypeQualified::TypeQualified(TY ty, Loc loc)
6715     : Type(ty)
6716 {
6717     this->loc = loc;
6718 }
6719 
syntaxCopyHelper(TypeQualified * t)6720 void TypeQualified::syntaxCopyHelper(TypeQualified *t)
6721 {
6722     //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars());
6723     idents.setDim(t->idents.dim);
6724     for (size_t i = 0; i < idents.dim; i++)
6725     {
6726         RootObject *id = t->idents[i];
6727         if (id->dyncast() == DYNCAST_DSYMBOL)
6728         {
6729             TemplateInstance *ti = (TemplateInstance *)id;
6730 
6731             ti = (TemplateInstance *)ti->syntaxCopy(NULL);
6732             id = ti;
6733         }
6734         else if (id->dyncast() == DYNCAST_EXPRESSION)
6735         {
6736             Expression *e = (Expression *)id;
6737             e = e->syntaxCopy();
6738             id = e;
6739         }
6740         else if (id->dyncast() == DYNCAST_TYPE)
6741         {
6742             Type *tx = (Type *)id;
6743             tx = tx->syntaxCopy();
6744             id = tx;
6745         }
6746         idents[i] = id;
6747     }
6748 }
6749 
addIdent(Identifier * ident)6750 void TypeQualified::addIdent(Identifier *ident)
6751 {
6752     idents.push(ident);
6753 }
6754 
addInst(TemplateInstance * inst)6755 void TypeQualified::addInst(TemplateInstance *inst)
6756 {
6757     idents.push(inst);
6758 }
6759 
addIndex(RootObject * e)6760 void TypeQualified::addIndex(RootObject *e)
6761 {
6762     idents.push(e);
6763 }
6764 
size(Loc)6765 d_uns64 TypeQualified::size(Loc)
6766 {
6767     error(this->loc, "size of type %s is not known", toChars());
6768     return SIZE_INVALID;
6769 }
6770 
6771 /*************************************
6772  * Resolve a tuple index.
6773  */
resolveTupleIndex(Loc loc,Scope * sc,Dsymbol * s,Expression ** pe,Type ** pt,Dsymbol ** ps,RootObject * oindex)6774 void TypeQualified::resolveTupleIndex(Loc loc, Scope *sc, Dsymbol *s,
6775         Expression **pe, Type **pt, Dsymbol **ps, RootObject *oindex)
6776 {
6777     *pt = NULL;
6778     *ps = NULL;
6779     *pe = NULL;
6780 
6781     TupleDeclaration *td = s->isTupleDeclaration();
6782 
6783     Expression *eindex = isExpression(oindex);
6784     Type *tindex = isType(oindex);
6785     Dsymbol *sindex = isDsymbol(oindex);
6786 
6787     if (!td)
6788     {
6789         // It's really an index expression
6790         if (tindex)
6791             eindex = new TypeExp(loc, tindex);
6792         else if (sindex)
6793             eindex = ::resolve(loc, sc, sindex, false);
6794         Expression *e = new IndexExp(loc, ::resolve(loc, sc, s, false), eindex);
6795         e = ::semantic(e, sc);
6796         resolveExp(e, pt, pe, ps);
6797         return;
6798     }
6799 
6800     // Convert oindex to Expression, then try to resolve to constant.
6801     if (tindex)
6802         tindex->resolve(loc, sc, &eindex, &tindex, &sindex);
6803     if (sindex)
6804         eindex = ::resolve(loc, sc, sindex, false);
6805     if (!eindex)
6806     {
6807         ::error(loc, "index is %s not an expression", oindex->toChars());
6808         *pt = Type::terror;
6809         return;
6810     }
6811     sc = sc->startCTFE();
6812     eindex = ::semantic(eindex, sc);
6813     sc = sc->endCTFE();
6814 
6815     eindex = eindex->ctfeInterpret();
6816     if (eindex->op == TOKerror)
6817     {
6818         *pt = Type::terror;
6819         return;
6820     }
6821 
6822     const uinteger_t d = eindex->toUInteger();
6823     if (d >= td->objects->dim)
6824     {
6825         ::error(loc, "tuple index %llu exceeds length %u", (ulonglong)d, (unsigned)td->objects->dim);
6826         *pt = Type::terror;
6827         return;
6828     }
6829 
6830     RootObject *o = (*td->objects)[(size_t)d];
6831     *pt = isType(o);
6832     *ps = isDsymbol(o);
6833     *pe = isExpression(o);
6834 
6835     if (*pt)
6836         *pt = (*pt)->semantic(loc, sc);
6837     if (*pe)
6838         resolveExp(*pe, pt, pe, ps);
6839 }
6840 
6841 /*************************************
6842  * Takes an array of Identifiers and figures out if
6843  * it represents a Type or an Expression.
6844  * Output:
6845  *      if expression, *pe is set
6846  *      if type, *pt is set
6847  */
resolveHelper(Loc loc,Scope * sc,Dsymbol * s,Dsymbol *,Expression ** pe,Type ** pt,Dsymbol ** ps,bool intypeid)6848 void TypeQualified::resolveHelper(Loc loc, Scope *sc,
6849         Dsymbol *s, Dsymbol *,
6850         Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
6851 {
6852     *pe = NULL;
6853     *pt = NULL;
6854     *ps = NULL;
6855     if (s)
6856     {
6857         //printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
6858         Declaration *d = s->isDeclaration();
6859         if (d && (d->storage_class & STCtemplateparameter))
6860             s = s->toAlias();
6861         else
6862             s->checkDeprecated(loc, sc);            // check for deprecated aliases
6863 
6864         s = s->toAlias();
6865         //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
6866         for (size_t i = 0; i < idents.dim; i++)
6867         {
6868             RootObject *id = idents[i];
6869 
6870             if (id->dyncast() == DYNCAST_EXPRESSION ||
6871                 id->dyncast() == DYNCAST_TYPE)
6872             {
6873                 Type *tx;
6874                 Expression *ex;
6875                 Dsymbol *sx;
6876                 resolveTupleIndex(loc, sc, s, &ex, &tx, &sx, id);
6877                 if (sx)
6878                 {
6879                     s = sx->toAlias();
6880                     continue;
6881                 }
6882                 if (tx)
6883                     ex = new TypeExp(loc, tx);
6884                 assert(ex);
6885 
6886                 ex = typeToExpressionHelper(this, ex, i + 1);
6887                 ex = ::semantic(ex, sc);
6888                 resolveExp(ex, pt, pe, ps);
6889                 return;
6890             }
6891 
6892             Type *t = s->getType();     // type symbol, type alias, or type tuple?
6893             unsigned errorsave = global.errors;
6894             Dsymbol *sm = s->searchX(loc, sc, id);
6895             if (sm && !(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, sm))
6896             {
6897                 ::deprecation(loc, "%s is not visible from module %s", sm->toPrettyChars(), sc->_module->toChars());
6898                 // sm = NULL;
6899             }
6900             if (global.errors != errorsave)
6901             {
6902                 *pt = Type::terror;
6903                 return;
6904             }
6905             //printf("\t3: s = %p %s %s, sm = %p\n", s, s->kind(), s->toChars(), sm);
6906             if (intypeid && !t && sm && sm->needThis())
6907                 goto L3;
6908             if (VarDeclaration *v = s->isVarDeclaration())
6909             {
6910                 // https://issues.dlang.org/show_bug.cgi?id=19913
6911                 // v->type would be null if it is a forward referenced member.
6912                 if (v->type == NULL)
6913                     v->semantic(sc);
6914                 if (v->storage_class & (STCconst | STCimmutable | STCmanifest) ||
6915                     v->type->isConst() || v->type->isImmutable())
6916                 {
6917                     // Bugzilla 13087: this.field is not constant always
6918                     if (!v->isThisDeclaration())
6919                         goto L3;
6920                 }
6921             }
6922             if (!sm)
6923             {
6924                 if (!t)
6925                 {
6926                     if (s->isDeclaration())         // var, func, or tuple declaration?
6927                     {
6928                         t = s->isDeclaration()->type;
6929                         if (!t && s->isTupleDeclaration())  // expression tuple?
6930                             goto L3;
6931                     }
6932                     else if (s->isTemplateInstance() ||
6933                              s->isImport() || s->isPackage() || s->isModule())
6934                     {
6935                         goto L3;
6936                     }
6937                 }
6938                 if (t)
6939                 {
6940                     sm = t->toDsymbol(sc);
6941                     if (sm && id->dyncast() == DYNCAST_IDENTIFIER)
6942                     {
6943                         sm = sm->search(loc, (Identifier *)id);
6944                         if (sm)
6945                             goto L2;
6946                     }
6947                 L3:
6948                     Expression *e;
6949                     VarDeclaration *v = s->isVarDeclaration();
6950                     FuncDeclaration *f = s->isFuncDeclaration();
6951                     if (intypeid || (!v && !f))
6952                         e = ::resolve(loc, sc, s, true);
6953                     else
6954                         e = new VarExp(loc, s->isDeclaration(), true);
6955 
6956                     e = typeToExpressionHelper(this, e, i);
6957                     e = ::semantic(e, sc);
6958                     resolveExp(e, pt, pe, ps);
6959                     return;
6960                 }
6961                 else
6962                 {
6963                     if (id->dyncast() == DYNCAST_DSYMBOL)
6964                     {
6965                         // searchX already handles errors for template instances
6966                         assert(global.errors);
6967                     }
6968                     else
6969                     {
6970                         assert(id->dyncast() == DYNCAST_IDENTIFIER);
6971                         sm = s->search_correct((Identifier *)id);
6972                         if (sm)
6973                             error(loc, "identifier '%s' of '%s' is not defined, did you mean %s '%s'?",
6974                                   id->toChars(), toChars(), sm->kind(), sm->toChars());
6975                         else
6976                             error(loc, "identifier '%s' of '%s' is not defined", id->toChars(), toChars());
6977                     }
6978                     *pe = new ErrorExp();
6979                 }
6980                 return;
6981             }
6982         L2:
6983             s = sm->toAlias();
6984         }
6985 
6986         if (EnumMember *em = s->isEnumMember())
6987         {
6988             // It's not a type, it's an expression
6989             *pe = em->getVarExp(loc, sc);
6990             return;
6991         }
6992         if (VarDeclaration *v = s->isVarDeclaration())
6993         {
6994             /* This is mostly same with DsymbolExp::semantic(), but we cannot use it
6995              * because some variables used in type context need to prevent lowering
6996              * to a literal or contextful expression. For example:
6997              *
6998              *  enum a = 1; alias b = a;
6999              *  template X(alias e){ alias v = e; }  alias x = X!(1);
7000              *  struct S { int v; alias w = v; }
7001              *      // TypeIdentifier 'a', 'e', and 'v' should be TOKvar,
7002              *      // because getDsymbol() need to work in AliasDeclaration::semantic().
7003              */
7004             if (!v->type ||
7005                 (!v->type->deco && v->inuse))
7006             {
7007                 if (v->inuse)   // Bugzilla 9494
7008                     error(loc, "circular reference to %s '%s'", v->kind(), v->toPrettyChars());
7009                 else
7010                     error(loc, "forward reference to %s '%s'", v->kind(), v->toPrettyChars());
7011                 *pt = Type::terror;
7012                 return;
7013             }
7014             if (v->type->ty == Terror)
7015                 *pt = Type::terror;
7016             else
7017                 *pe = new VarExp(loc, v);
7018             return;
7019         }
7020         if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
7021         {
7022             //printf("'%s' is a function literal\n", fld->toChars());
7023             *pe = new FuncExp(loc, fld);
7024             *pe = ::semantic(*pe, sc);
7025             return;
7026         }
7027 L1:
7028         Type *t = s->getType();
7029         if (!t)
7030         {
7031             // If the symbol is an import, try looking inside the import
7032             if (Import *si = s->isImport())
7033             {
7034                 s = si->search(loc, s->ident);
7035                 if (s && s != si)
7036                     goto L1;
7037                 s = si;
7038             }
7039             *ps = s;
7040             return;
7041         }
7042         if (t->ty == Tinstance && t != this && !t->deco)
7043         {
7044             if (!((TypeInstance *)t)->tempinst->errors)
7045                 error(loc, "forward reference to '%s'", t->toChars());
7046             *pt = Type::terror;
7047             return;
7048         }
7049 
7050         if (t->ty == Ttuple)
7051             *pt = t;
7052         else
7053             *pt = t->merge();
7054     }
7055     if (!s)
7056     {
7057         /* Look for what user might have intended
7058          */
7059         const char *p = mutableOf()->unSharedOf()->toChars();
7060         Identifier *id = Identifier::idPool(p, strlen(p));
7061         if (const char *n = importHint(p))
7062             error(loc, "`%s` is not defined, perhaps `import %s;` ?", p, n);
7063         else if (Dsymbol *s2 = sc->search_correct(id))
7064             error(loc, "undefined identifier `%s`, did you mean %s `%s`?", p, s2->kind(), s2->toChars());
7065         else if (const char *q = Scope::search_correct_C(id))
7066             error(loc, "undefined identifier `%s`, did you mean `%s`?", p, q);
7067         else
7068             error(loc, "undefined identifier `%s`", p);
7069 
7070         *pt = Type::terror;
7071     }
7072 }
7073 
7074 /***************************** TypeIdentifier *****************************/
7075 
TypeIdentifier(Loc loc,Identifier * ident)7076 TypeIdentifier::TypeIdentifier(Loc loc, Identifier *ident)
7077     : TypeQualified(Tident, loc)
7078 {
7079     this->ident = ident;
7080 }
7081 
kind()7082 const char *TypeIdentifier::kind()
7083 {
7084     return "identifier";
7085 }
7086 
syntaxCopy()7087 Type *TypeIdentifier::syntaxCopy()
7088 {
7089     TypeIdentifier *t = new TypeIdentifier(loc, ident);
7090     t->syntaxCopyHelper(this);
7091     t->mod = mod;
7092     return t;
7093 }
7094 
7095 /*************************************
7096  * Takes an array of Identifiers and figures out if
7097  * it represents a Type or an Expression.
7098  * Output:
7099  *      if expression, *pe is set
7100  *      if type, *pt is set
7101  */
7102 
resolve(Loc loc,Scope * sc,Expression ** pe,Type ** pt,Dsymbol ** ps,bool intypeid)7103 void TypeIdentifier::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
7104 {
7105     //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars());
7106 
7107     if ((ident->equals(Id::_super) || ident->equals(Id::This)) && !hasThis(sc))
7108     {
7109         AggregateDeclaration *ad = sc->getStructClassScope();
7110         if (ad)
7111         {
7112             ClassDeclaration *cd = ad->isClassDeclaration();
7113             if (cd)
7114             {
7115                 if (ident->equals(Id::This))
7116                     ident = cd->ident;
7117                 else if (cd->baseClass && ident->equals(Id::_super))
7118                     ident = cd->baseClass->ident;
7119             }
7120             else
7121             {
7122                 StructDeclaration *sd = ad->isStructDeclaration();
7123                 if (sd && ident->equals(Id::This))
7124                     ident = sd->ident;
7125             }
7126         }
7127     }
7128     if (ident == Id::ctfe)
7129     {
7130         error(loc, "variable __ctfe cannot be read at compile time");
7131         *pe = NULL;
7132         *ps = NULL;
7133         *pt = Type::terror;
7134         return;
7135     }
7136 
7137     Dsymbol *scopesym;
7138     Dsymbol *s = sc->search(loc, ident, &scopesym);
7139     resolveHelper(loc, sc, s, scopesym, pe, pt, ps, intypeid);
7140     if (*pt)
7141         (*pt) = (*pt)->addMod(mod);
7142 }
7143 
7144 /*****************************************
7145  * See if type resolves to a symbol, if so,
7146  * return that symbol.
7147  */
7148 
toDsymbol(Scope * sc)7149 Dsymbol *TypeIdentifier::toDsymbol(Scope *sc)
7150 {
7151     //printf("TypeIdentifier::toDsymbol('%s')\n", toChars());
7152     if (!sc)
7153         return NULL;
7154 
7155     Type *t;
7156     Expression *e;
7157     Dsymbol *s;
7158 
7159     resolve(loc, sc, &e, &t, &s);
7160     if (t && t->ty != Tident)
7161         s = t->toDsymbol(sc);
7162     if (e)
7163         s = getDsymbol(e);
7164 
7165     return s;
7166 }
7167 
semantic(Loc loc,Scope * sc)7168 Type *TypeIdentifier::semantic(Loc loc, Scope *sc)
7169 {
7170     Type *t;
7171     Expression *e;
7172     Dsymbol *s;
7173 
7174     //printf("TypeIdentifier::semantic(%s)\n", toChars());
7175     resolve(loc, sc, &e, &t, &s);
7176     if (t)
7177     {
7178         //printf("\tit's a type %d, %s, %s\n", t->ty, t->toChars(), t->deco);
7179         t = t->addMod(mod);
7180     }
7181     else
7182     {
7183         if (s)
7184         {
7185             s->error(loc, "is used as a type");
7186             //halt();
7187         }
7188         else
7189             error(loc, "%s is used as a type", toChars());
7190         t = terror;
7191     }
7192     //t->print();
7193     return t;
7194 }
7195 
7196 /***************************** TypeInstance *****************************/
7197 
TypeInstance(Loc loc,TemplateInstance * tempinst)7198 TypeInstance::TypeInstance(Loc loc, TemplateInstance *tempinst)
7199     : TypeQualified(Tinstance, loc)
7200 {
7201     this->tempinst = tempinst;
7202 }
7203 
kind()7204 const char *TypeInstance::kind()
7205 {
7206     return "instance";
7207 }
7208 
syntaxCopy()7209 Type *TypeInstance::syntaxCopy()
7210 {
7211     //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim);
7212     TypeInstance *t = new TypeInstance(loc, (TemplateInstance *)tempinst->syntaxCopy(NULL));
7213     t->syntaxCopyHelper(this);
7214     t->mod = mod;
7215     return t;
7216 }
7217 
resolve(Loc loc,Scope * sc,Expression ** pe,Type ** pt,Dsymbol ** ps,bool intypeid)7218 void TypeInstance::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
7219 {
7220     // Note close similarity to TypeIdentifier::resolve()
7221     *pe = NULL;
7222     *pt = NULL;
7223     *ps = NULL;
7224     //printf("TypeInstance::resolve(sc = %p, tempinst = '%s')\n", sc, tempinst->toChars());
7225     tempinst->semantic(sc);
7226     if (!global.gag && tempinst->errors)
7227     {
7228         *pt = terror;
7229         return;
7230     }
7231 
7232     resolveHelper(loc, sc, tempinst, NULL, pe, pt, ps, intypeid);
7233     if (*pt)
7234         *pt = (*pt)->addMod(mod);
7235     //if (*pt) printf("pt = '%s'\n", (*pt)->toChars());
7236 }
7237 
semantic(Loc loc,Scope * sc)7238 Type *TypeInstance::semantic(Loc loc, Scope *sc)
7239 {
7240     Type *t;
7241     Expression *e;
7242     Dsymbol *s;
7243 
7244     //printf("TypeInstance::semantic(%p, %s)\n", this, toChars());
7245     {
7246         unsigned errors = global.errors;
7247         resolve(loc, sc, &e, &t, &s);
7248         // if we had an error evaluating the symbol, suppress further errors
7249         if (!t && errors != global.errors)
7250             return terror;
7251     }
7252 
7253     if (!t)
7254     {
7255         if (!e && s && s->errors)
7256         {
7257             // if there was an error evaluating the symbol, it might actually
7258             // be a type. Avoid misleading error messages.
7259             error(loc, "%s had previous errors", toChars());
7260         }
7261         else
7262             error(loc, "%s is used as a type", toChars());
7263         t = terror;
7264     }
7265     return t;
7266 }
7267 
toDsymbol(Scope * sc)7268 Dsymbol *TypeInstance::toDsymbol(Scope *sc)
7269 {
7270     Type *t;
7271     Expression *e;
7272     Dsymbol *s;
7273 
7274     //printf("TypeInstance::semantic(%s)\n", toChars());
7275     resolve(loc, sc, &e, &t, &s);
7276     if (t && t->ty != Tinstance)
7277         s = t->toDsymbol(sc);
7278 
7279     return s;
7280 }
7281 
7282 
7283 /***************************** TypeTypeof *****************************/
7284 
TypeTypeof(Loc loc,Expression * exp)7285 TypeTypeof::TypeTypeof(Loc loc, Expression *exp)
7286         : TypeQualified(Ttypeof, loc)
7287 {
7288     this->exp = exp;
7289     inuse = 0;
7290 }
7291 
kind()7292 const char *TypeTypeof::kind()
7293 {
7294     return "typeof";
7295 }
7296 
syntaxCopy()7297 Type *TypeTypeof::syntaxCopy()
7298 {
7299     //printf("TypeTypeof::syntaxCopy() %s\n", toChars());
7300     TypeTypeof *t = new TypeTypeof(loc, exp->syntaxCopy());
7301     t->syntaxCopyHelper(this);
7302     t->mod = mod;
7303     return t;
7304 }
7305 
toDsymbol(Scope * sc)7306 Dsymbol *TypeTypeof::toDsymbol(Scope *sc)
7307 {
7308     //printf("TypeTypeof::toDsymbol('%s')\n", toChars());
7309     Expression *e;
7310     Type *t;
7311     Dsymbol *s;
7312     resolve(loc, sc, &e, &t, &s);
7313 
7314     return s;
7315 }
7316 
resolve(Loc loc,Scope * sc,Expression ** pe,Type ** pt,Dsymbol ** ps,bool intypeid)7317 void TypeTypeof::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
7318 {
7319     *pe = NULL;
7320     *pt = NULL;
7321     *ps = NULL;
7322 
7323     //printf("TypeTypeof::resolve(sc = %p, idents = '%s')\n", sc, toChars());
7324     //static int nest; if (++nest == 50) *(char*)0=0;
7325     if (sc == NULL)
7326     {
7327         *pt = Type::terror;
7328         error(loc, "Invalid scope.");
7329         return;
7330     }
7331     if (inuse)
7332     {
7333         inuse = 2;
7334         error(loc, "circular typeof definition");
7335     Lerr:
7336         *pt = Type::terror;
7337         inuse--;
7338         return;
7339     }
7340     inuse++;
7341 
7342     Type *t;
7343     {
7344         /* Currently we cannot evalute 'exp' in speculative context, because
7345          * the type implementation may leak to the final execution. Consider:
7346          *
7347          * struct S(T) {
7348          *   string toString() const { return "x"; }
7349          * }
7350          * void main() {
7351          *   alias X = typeof(S!int());
7352          *   assert(typeid(X).xtoString(null) == "x");
7353          * }
7354          */
7355         Scope *sc2 = sc->push();
7356         sc2->intypeof = 1;
7357         Expression *exp2 = ::semantic(exp, sc2);
7358         exp2 = resolvePropertiesOnly(sc2, exp2);
7359         sc2->pop();
7360 
7361         if (exp2->op == TOKerror)
7362         {
7363             if (!global.gag)
7364                 exp = exp2;
7365             goto Lerr;
7366         }
7367         exp = exp2;
7368 
7369         if (exp->op == TOKtype ||
7370             exp->op == TOKscope)
7371         {
7372             if (exp->checkType())
7373                 goto Lerr;
7374 
7375             /* Today, 'typeof(func)' returns void if func is a
7376              * function template (TemplateExp), or
7377              * template lambda (FuncExp).
7378              * It's actually used in Phobos as an idiom, to branch code for
7379              * template functions.
7380              */
7381         }
7382         if (FuncDeclaration *f = exp->op == TOKvar    ? ((   VarExp *)exp)->var->isFuncDeclaration()
7383                                : exp->op == TOKdotvar ? ((DotVarExp *)exp)->var->isFuncDeclaration() : NULL)
7384         {
7385             if (f->checkForwardRef(loc))
7386                 goto Lerr;
7387         }
7388         if (FuncDeclaration *f = isFuncAddress(exp))
7389         {
7390             if (f->checkForwardRef(loc))
7391                 goto Lerr;
7392         }
7393 
7394         t = exp->type;
7395         if (!t)
7396         {
7397             error(loc, "expression (%s) has no type", exp->toChars());
7398             goto Lerr;
7399         }
7400         if (t->ty == Ttypeof)
7401         {
7402             error(loc, "forward reference to %s", toChars());
7403             goto Lerr;
7404         }
7405     }
7406     if (idents.dim == 0)
7407         *pt = t;
7408     else
7409     {
7410         if (Dsymbol *s = t->toDsymbol(sc))
7411             resolveHelper(loc, sc, s, NULL, pe, pt, ps, intypeid);
7412         else
7413         {
7414             Expression *e = typeToExpressionHelper(this, new TypeExp(loc, t));
7415             e = ::semantic(e, sc);
7416             resolveExp(e, pt, pe, ps);
7417         }
7418     }
7419     if (*pt)
7420         (*pt) = (*pt)->addMod(mod);
7421     inuse--;
7422     return;
7423 }
7424 
semantic(Loc loc,Scope * sc)7425 Type *TypeTypeof::semantic(Loc loc, Scope *sc)
7426 {
7427     //printf("TypeTypeof::semantic() %s\n", toChars());
7428 
7429     Expression *e;
7430     Type *t;
7431     Dsymbol *s;
7432     resolve(loc, sc, &e, &t, &s);
7433     if (s && (t = s->getType()) != NULL)
7434         t = t->addMod(mod);
7435     if (!t)
7436     {
7437         error(loc, "%s is used as a type", toChars());
7438         t = Type::terror;
7439     }
7440     return t;
7441 }
7442 
size(Loc loc)7443 d_uns64 TypeTypeof::size(Loc loc)
7444 {
7445     if (exp->type)
7446         return exp->type->size(loc);
7447     else
7448         return TypeQualified::size(loc);
7449 }
7450 
7451 
7452 
7453 /***************************** TypeReturn *****************************/
7454 
TypeReturn(Loc loc)7455 TypeReturn::TypeReturn(Loc loc)
7456         : TypeQualified(Treturn, loc)
7457 {
7458 }
7459 
kind()7460 const char *TypeReturn::kind()
7461 {
7462     return "return";
7463 }
7464 
syntaxCopy()7465 Type *TypeReturn::syntaxCopy()
7466 {
7467     TypeReturn *t = new TypeReturn(loc);
7468     t->syntaxCopyHelper(this);
7469     t->mod = mod;
7470     return t;
7471 }
7472 
toDsymbol(Scope * sc)7473 Dsymbol *TypeReturn::toDsymbol(Scope *sc)
7474 {
7475     Expression *e;
7476     Type *t;
7477     Dsymbol *s;
7478     resolve(loc, sc, &e, &t, &s);
7479 
7480     return s;
7481 }
7482 
resolve(Loc loc,Scope * sc,Expression ** pe,Type ** pt,Dsymbol ** ps,bool intypeid)7483 void TypeReturn::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
7484 {
7485     *pe = NULL;
7486     *pt = NULL;
7487     *ps = NULL;
7488 
7489     //printf("TypeReturn::resolve(sc = %p, idents = '%s')\n", sc, toChars());
7490     Type *t;
7491     {
7492         FuncDeclaration *func = sc->func;
7493         if (!func)
7494         {
7495             error(loc, "typeof(return) must be inside function");
7496             goto Lerr;
7497         }
7498         if (func->fes)
7499             func = func->fes->func;
7500 
7501         t = func->type->nextOf();
7502         if (!t)
7503         {
7504             error(loc, "cannot use typeof(return) inside function %s with inferred return type", sc->func->toChars());
7505             goto Lerr;
7506         }
7507     }
7508     if (idents.dim == 0)
7509         *pt = t;
7510     else
7511     {
7512         if (Dsymbol *s = t->toDsymbol(sc))
7513             resolveHelper(loc, sc, s, NULL, pe, pt, ps, intypeid);
7514         else
7515         {
7516             Expression *e = typeToExpressionHelper(this, new TypeExp(loc, t));
7517             e = ::semantic(e, sc);
7518             resolveExp(e, pt, pe, ps);
7519         }
7520     }
7521     if (*pt)
7522         (*pt) = (*pt)->addMod(mod);
7523     return;
7524 
7525 Lerr:
7526     *pt = Type::terror;
7527     return;
7528 }
7529 
semantic(Loc loc,Scope * sc)7530 Type *TypeReturn::semantic(Loc loc, Scope *sc)
7531 {
7532     //printf("TypeReturn::semantic() %s\n", toChars());
7533 
7534     Expression *e;
7535     Type *t;
7536     Dsymbol *s;
7537     resolve(loc, sc, &e, &t, &s);
7538     if (s && (t = s->getType()) != NULL)
7539         t = t->addMod(mod);
7540     if (!t)
7541     {
7542         error(loc, "%s is used as a type", toChars());
7543         t = Type::terror;
7544     }
7545     return t;
7546 }
7547 
7548 /***************************** TypeEnum *****************************/
7549 
TypeEnum(EnumDeclaration * sym)7550 TypeEnum::TypeEnum(EnumDeclaration *sym)
7551         : Type(Tenum)
7552 {
7553     this->sym = sym;
7554 }
7555 
kind()7556 const char *TypeEnum::kind()
7557 {
7558     return "enum";
7559 }
7560 
syntaxCopy()7561 Type *TypeEnum::syntaxCopy()
7562 {
7563     return this;
7564 }
7565 
semantic(Loc,Scope *)7566 Type *TypeEnum::semantic(Loc, Scope *)
7567 {
7568     //printf("TypeEnum::semantic() %s\n", toChars());
7569     if (deco)
7570         return this;
7571     return merge();
7572 }
7573 
size(Loc loc)7574 d_uns64 TypeEnum::size(Loc loc)
7575 {
7576     return sym->getMemtype(loc)->size(loc);
7577 }
7578 
alignsize()7579 unsigned TypeEnum::alignsize()
7580 {
7581     Type *t = sym->getMemtype(Loc());
7582     if (t->ty == Terror)
7583         return 4;
7584     return t->alignsize();
7585 }
7586 
toDsymbol(Scope *)7587 Dsymbol *TypeEnum::toDsymbol(Scope *)
7588 {
7589     return sym;
7590 }
7591 
toBasetype()7592 Type *TypeEnum::toBasetype()
7593 {
7594     if (!sym->members && !sym->memtype)
7595         return this;
7596     Type *tb = sym->getMemtype(Loc())->toBasetype();
7597     return tb->castMod(mod);         // retain modifier bits from 'this'
7598 }
7599 
dotExp(Scope * sc,Expression * e,Identifier * ident,int flag)7600 Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
7601 {
7602     // Bugzilla 14010
7603     if (ident == Id::_mangleof)
7604         return getProperty(e->loc, ident, flag & 1);
7605 
7606     if (sym->semanticRun < PASSsemanticdone)
7607         sym->semantic(NULL);
7608     if (!sym->members)
7609     {
7610         if (sym->isSpecial())
7611         {
7612             /* Special enums forward to the base type
7613              */
7614             e = sym->memtype->dotExp(sc, e, ident, flag);
7615         }
7616         else if (!(flag & 1))
7617         {
7618             sym->error("is forward referenced when looking for '%s'", ident->toChars());
7619             e = new ErrorExp();
7620         }
7621         else
7622             e = NULL;
7623         return e;
7624     }
7625 
7626     Dsymbol *s = sym->search(e->loc, ident);
7627     if (!s)
7628     {
7629         if (ident == Id::max ||
7630             ident == Id::min ||
7631             ident == Id::_init)
7632         {
7633             return getProperty(e->loc, ident, flag & 1);
7634         }
7635         Expression *res = sym->getMemtype(Loc())->dotExp(sc, e, ident, 1);
7636         if (!(flag & 1) && !res)
7637         {
7638             if (Dsymbol *ns = sym->search_correct(ident))
7639                 e->error("no property '%s' for type '%s'. Did you mean '%s.%s' ?",
7640                     ident->toChars(), toChars(), toChars(), ns->toChars());
7641             else
7642                 e->error("no property '%s' for type '%s'",
7643                     ident->toChars(), toChars());
7644 
7645             return new ErrorExp();
7646         }
7647         return res;
7648     }
7649     EnumMember *m = s->isEnumMember();
7650     return m->getVarExp(e->loc, sc);
7651 }
7652 
getProperty(Loc loc,Identifier * ident,int flag)7653 Expression *TypeEnum::getProperty(Loc loc, Identifier *ident, int flag)
7654 {
7655     Expression *e;
7656     if (ident == Id::max || ident == Id::min)
7657     {
7658         return sym->getMaxMinValue(loc, ident);
7659     }
7660     else if (ident == Id::_init)
7661     {
7662         e = defaultInitLiteral(loc);
7663     }
7664     else if (ident == Id::stringof)
7665     {
7666         const char *s = toChars();
7667         e = new StringExp(loc, const_cast<char *>(s), strlen(s));
7668         Scope sc;
7669         e = ::semantic(e, &sc);
7670     }
7671     else if (ident == Id::_mangleof)
7672     {
7673         e = Type::getProperty(loc, ident, flag);
7674     }
7675     else
7676     {
7677         e = toBasetype()->getProperty(loc, ident, flag);
7678     }
7679     return e;
7680 }
7681 
isintegral()7682 bool TypeEnum::isintegral()
7683 {
7684     return sym->getMemtype(Loc())->isintegral();
7685 }
7686 
isfloating()7687 bool TypeEnum::isfloating()
7688 {
7689     return sym->getMemtype(Loc())->isfloating();
7690 }
7691 
isreal()7692 bool TypeEnum::isreal()
7693 {
7694     return sym->getMemtype(Loc())->isreal();
7695 }
7696 
isimaginary()7697 bool TypeEnum::isimaginary()
7698 {
7699     return sym->getMemtype(Loc())->isimaginary();
7700 }
7701 
iscomplex()7702 bool TypeEnum::iscomplex()
7703 {
7704     return sym->getMemtype(Loc())->iscomplex();
7705 }
7706 
isunsigned()7707 bool TypeEnum::isunsigned()
7708 {
7709     return sym->getMemtype(Loc())->isunsigned();
7710 }
7711 
isscalar()7712 bool TypeEnum::isscalar()
7713 {
7714     return sym->getMemtype(Loc())->isscalar();
7715 }
7716 
isString()7717 bool TypeEnum::isString()
7718 {
7719     return sym->getMemtype(Loc())->isString();
7720 }
7721 
isAssignable()7722 bool TypeEnum::isAssignable()
7723 {
7724     return sym->getMemtype(Loc())->isAssignable();
7725 }
7726 
isBoolean()7727 bool TypeEnum::isBoolean()
7728 {
7729     return sym->getMemtype(Loc())->isBoolean();
7730 }
7731 
needsDestruction()7732 bool TypeEnum::needsDestruction()
7733 {
7734     return sym->getMemtype(Loc())->needsDestruction();
7735 }
7736 
needsNested()7737 bool TypeEnum::needsNested()
7738 {
7739     return sym->getMemtype(Loc())->needsNested();
7740 }
7741 
implicitConvTo(Type * to)7742 MATCH TypeEnum::implicitConvTo(Type *to)
7743 {
7744     MATCH m;
7745 
7746     //printf("TypeEnum::implicitConvTo()\n");
7747     if (ty == to->ty && sym == ((TypeEnum *)to)->sym)
7748         m = (mod == to->mod) ? MATCHexact : MATCHconst;
7749     else if (sym->getMemtype(Loc())->implicitConvTo(to))
7750         m = MATCHconvert;       // match with conversions
7751     else
7752         m = MATCHnomatch;       // no match
7753     return m;
7754 }
7755 
constConv(Type * to)7756 MATCH TypeEnum::constConv(Type *to)
7757 {
7758     if (equals(to))
7759         return MATCHexact;
7760     if (ty == to->ty && sym == ((TypeEnum *)to)->sym &&
7761         MODimplicitConv(mod, to->mod))
7762         return MATCHconst;
7763     return MATCHnomatch;
7764 }
7765 
7766 
defaultInit(Loc loc)7767 Expression *TypeEnum::defaultInit(Loc loc)
7768 {
7769     // Initialize to first member of enum
7770     Expression *e = sym->getDefaultValue(loc);
7771     e = e->copy();
7772     e->loc = loc;
7773     e->type = this;     // to deal with const, immutable, etc., variants
7774     return e;
7775 }
7776 
isZeroInit(Loc loc)7777 bool TypeEnum::isZeroInit(Loc loc)
7778 {
7779     return sym->getDefaultValue(loc)->isBool(false);
7780 }
7781 
hasPointers()7782 bool TypeEnum::hasPointers()
7783 {
7784     return sym->getMemtype(Loc())->hasPointers();
7785 }
7786 
hasVoidInitPointers()7787 bool TypeEnum::hasVoidInitPointers()
7788 {
7789     return sym->getMemtype(Loc())->hasVoidInitPointers();
7790 }
7791 
nextOf()7792 Type *TypeEnum::nextOf()
7793 {
7794     return sym->getMemtype(Loc())->nextOf();
7795 }
7796 
7797 /***************************** TypeStruct *****************************/
7798 
TypeStruct(StructDeclaration * sym)7799 TypeStruct::TypeStruct(StructDeclaration *sym)
7800         : Type(Tstruct)
7801 {
7802     this->sym = sym;
7803     this->att = RECfwdref;
7804     this->cppmangle = CPPMANGLEdefault;
7805 }
7806 
create(StructDeclaration * sym)7807 TypeStruct *TypeStruct::create(StructDeclaration *sym)
7808 {
7809     return new TypeStruct(sym);
7810 }
7811 
kind()7812 const char *TypeStruct::kind()
7813 {
7814     return "struct";
7815 }
7816 
syntaxCopy()7817 Type *TypeStruct::syntaxCopy()
7818 {
7819     return this;
7820 }
7821 
semantic(Loc,Scope * sc)7822 Type *TypeStruct::semantic(Loc, Scope *sc)
7823 {
7824     //printf("TypeStruct::semantic('%s')\n", sym->toChars());
7825     if (deco)
7826     {
7827         if (sc && sc->cppmangle != CPPMANGLEdefault)
7828         {
7829             if (this->cppmangle == CPPMANGLEdefault)
7830                 this->cppmangle = sc->cppmangle;
7831             else
7832                 assert(this->cppmangle == sc->cppmangle);
7833         }
7834         return this;
7835     }
7836 
7837     /* Don't semantic for sym because it should be deferred until
7838      * sizeof needed or its members accessed.
7839      */
7840     // instead, parent should be set correctly
7841     assert(sym->parent);
7842 
7843     if (sym->type->ty == Terror)
7844         return Type::terror;
7845     if (sc)
7846         this->cppmangle = sc->cppmangle;
7847     return merge();
7848 }
7849 
size(Loc loc)7850 d_uns64 TypeStruct::size(Loc loc)
7851 {
7852     return sym->size(loc);
7853 }
7854 
alignsize()7855 unsigned TypeStruct::alignsize()
7856 {
7857     sym->size(Loc());               // give error for forward references
7858     return sym->alignsize;
7859 }
7860 
toDsymbol(Scope *)7861 Dsymbol *TypeStruct::toDsymbol(Scope *)
7862 {
7863     return sym;
7864 }
7865 
searchSymStruct(Scope * sc,Dsymbol * sym,Expression * e,Identifier * ident)7866 static Dsymbol *searchSymStruct(Scope *sc, Dsymbol *sym, Expression *e, Identifier *ident)
7867 {
7868     int flags = sc->flags & SCOPEignoresymbolvisibility ? IgnoreSymbolVisibility : 0;
7869     Dsymbol *sold = NULL;
7870     if (global.params.bug10378 || global.params.check10378)
7871     {
7872         sold = sym->search(e->loc, ident, flags);
7873         if (!global.params.check10378)
7874             return sold;
7875     }
7876 
7877     Dsymbol *s = sym->search(e->loc, ident, flags | SearchLocalsOnly);
7878     if (global.params.check10378)
7879     {
7880         Dsymbol *snew = s;
7881         if (sold != snew)
7882             Scope::deprecation10378(e->loc, sold, snew);
7883         if (global.params.bug10378)
7884             s = sold;
7885     }
7886     return s;
7887 }
7888 
dotExp(Scope * sc,Expression * e,Identifier * ident,int flag)7889 Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
7890 {
7891     Dsymbol *s;
7892 
7893     assert(e->op != TOKdot);
7894 
7895     // Bugzilla 14010
7896     if (ident == Id::_mangleof)
7897         return getProperty(e->loc, ident, flag & 1);
7898 
7899     /* If e.tupleof
7900      */
7901     if (ident == Id::_tupleof)
7902     {
7903         /* Create a TupleExp out of the fields of the struct e:
7904          * (e.field0, e.field1, e.field2, ...)
7905          */
7906         e = ::semantic(e, sc);  // do this before turning on noaccesscheck
7907 
7908         sym->size(e->loc);      // do semantic of type
7909 
7910         Expression *e0 = NULL;
7911         Expression *ev = e->op == TOKtype ? NULL : e;
7912         if (ev)
7913             ev = extractSideEffect(sc, "__tup", &e0, ev);
7914 
7915         Expressions *exps = new Expressions;
7916         exps->reserve(sym->fields.dim);
7917         for (size_t i = 0; i < sym->fields.dim; i++)
7918         {
7919             VarDeclaration *v = sym->fields[i];
7920             Expression *ex;
7921             if (ev)
7922                 ex = new DotVarExp(e->loc, ev, v);
7923             else
7924             {
7925                 ex = new VarExp(e->loc, v);
7926                 ex->type = ex->type->addMod(e->type->mod);
7927             }
7928             exps->push(ex);
7929         }
7930 
7931         e = new TupleExp(e->loc, e0, exps);
7932         Scope *sc2 = sc->push();
7933         sc2->flags = sc->flags | SCOPEnoaccesscheck;
7934         e = ::semantic(e, sc2);
7935         sc2->pop();
7936         return e;
7937     }
7938 
7939     s = searchSymStruct(sc, sym, e, ident);
7940 L1:
7941     if (!s)
7942     {
7943         return noMember(sc, e, ident, flag);
7944     }
7945     if (!(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, s))
7946     {
7947         ::deprecation(e->loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toPrettyChars());
7948         // return noMember(sc, e, ident, flag);
7949     }
7950     if (!s->isFuncDeclaration())        // because of overloading
7951         s->checkDeprecated(e->loc, sc);
7952     s = s->toAlias();
7953 
7954     EnumMember *em = s->isEnumMember();
7955     if (em)
7956     {
7957         return em->getVarExp(e->loc, sc);
7958     }
7959 
7960     if (VarDeclaration *v = s->isVarDeclaration())
7961     {
7962         if (!v->type ||
7963             (!v->type->deco && v->inuse))
7964         {
7965             if (v->inuse) // Bugzilla 9494
7966                 e->error("circular reference to %s '%s'", v->kind(), v->toPrettyChars());
7967             else
7968                 e->error("forward reference to %s '%s'", v->kind(), v->toPrettyChars());
7969             return new ErrorExp();
7970         }
7971         if (v->type->ty == Terror)
7972             return new ErrorExp();
7973 
7974         if ((v->storage_class & STCmanifest) && v->_init)
7975         {
7976             if (v->inuse)
7977             {
7978                 e->error("circular initialization of %s '%s'", v->kind(), v->toPrettyChars());
7979                 return new ErrorExp();
7980             }
7981             checkAccess(e->loc, sc, NULL, v);
7982             Expression *ve = new VarExp(e->loc, v);
7983             ve = ::semantic(ve, sc);
7984             return ve;
7985         }
7986     }
7987 
7988     if (Type *t = s->getType())
7989     {
7990         return ::semantic(new TypeExp(e->loc, t), sc);
7991     }
7992 
7993     TemplateMixin *tm = s->isTemplateMixin();
7994     if (tm)
7995     {
7996         Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, tm));
7997         de->type = e->type;
7998         return de;
7999     }
8000 
8001     TemplateDeclaration *td = s->isTemplateDeclaration();
8002     if (td)
8003     {
8004         if (e->op == TOKtype)
8005             e = new TemplateExp(e->loc, td);
8006         else
8007             e = new DotTemplateExp(e->loc, e, td);
8008         e = ::semantic(e, sc);
8009         return e;
8010     }
8011 
8012     TemplateInstance *ti = s->isTemplateInstance();
8013     if (ti)
8014     {
8015         if (!ti->semanticRun)
8016         {
8017             ti->semantic(sc);
8018             if (!ti->inst || ti->errors)    // if template failed to expand
8019                 return new ErrorExp();
8020         }
8021         s = ti->inst->toAlias();
8022         if (!s->isTemplateInstance())
8023             goto L1;
8024         if (e->op == TOKtype)
8025             e = new ScopeExp(e->loc, ti);
8026         else
8027             e = new DotExp(e->loc, e, new ScopeExp(e->loc, ti));
8028         return ::semantic(e, sc);
8029     }
8030 
8031     if (s->isImport() || s->isModule() || s->isPackage())
8032     {
8033         e = ::resolve(e->loc, sc, s, false);
8034         return e;
8035     }
8036 
8037     OverloadSet *o = s->isOverloadSet();
8038     if (o)
8039     {
8040         OverExp *oe = new OverExp(e->loc, o);
8041         if (e->op == TOKtype)
8042             return oe;
8043         return new DotExp(e->loc, e, oe);
8044     }
8045 
8046     Declaration *d = s->isDeclaration();
8047     if (!d)
8048     {
8049         e->error("%s.%s is not a declaration", e->toChars(), ident->toChars());
8050         return new ErrorExp();
8051     }
8052 
8053     if (e->op == TOKtype)
8054     {
8055         /* It's:
8056          *    Struct.d
8057          */
8058         if (TupleDeclaration *tup = d->isTupleDeclaration())
8059         {
8060             e = new TupleExp(e->loc, tup);
8061             e = ::semantic(e, sc);
8062             return e;
8063         }
8064         if (d->needThis() && sc->intypeof != 1)
8065         {
8066             /* Rewrite as:
8067              *  this.d
8068              */
8069             if (hasThis(sc))
8070             {
8071                 e = new DotVarExp(e->loc, new ThisExp(e->loc), d);
8072                 e = ::semantic(e, sc);
8073                 return e;
8074             }
8075         }
8076         if (d->semanticRun == PASSinit)
8077             d->semantic(NULL);
8078         checkAccess(e->loc, sc, e, d);
8079         VarExp *ve = new VarExp(e->loc, d);
8080         if (d->isVarDeclaration() && d->needThis())
8081             ve->type = d->type->addMod(e->type->mod);
8082         return ve;
8083     }
8084 
8085     bool unreal = e->op == TOKvar && ((VarExp *)e)->var->isField();
8086     if (d->isDataseg() || (unreal && d->isField()))
8087     {
8088         // (e, d)
8089         checkAccess(e->loc, sc, e, d);
8090         Expression *ve = new VarExp(e->loc, d);
8091         e = unreal ? ve : new CommaExp(e->loc, e, ve);
8092         e = ::semantic(e, sc);
8093         return e;
8094     }
8095 
8096     e = new DotVarExp(e->loc, e, d);
8097     e = ::semantic(e, sc);
8098     return e;
8099 }
8100 
alignment()8101 structalign_t TypeStruct::alignment()
8102 {
8103     if (sym->alignment == 0)
8104         sym->size(sym->loc);
8105     return sym->alignment;
8106 }
8107 
defaultInit(Loc)8108 Expression *TypeStruct::defaultInit(Loc)
8109 {
8110     Declaration *d = new SymbolDeclaration(sym->loc, sym);
8111     assert(d);
8112     d->type = this;
8113     d->storage_class |= STCrvalue;      // Bugzilla 14398
8114     return new VarExp(sym->loc, d);
8115 }
8116 
8117 /***************************************
8118  * Use when we prefer the default initializer to be a literal,
8119  * rather than a global immutable variable.
8120  */
defaultInitLiteral(Loc loc)8121 Expression *TypeStruct::defaultInitLiteral(Loc loc)
8122 {
8123     sym->size(loc);
8124     if (sym->sizeok != SIZEOKdone)
8125         return new ErrorExp();
8126     Expressions *structelems = new Expressions();
8127     structelems->setDim(sym->fields.dim - sym->isNested());
8128     unsigned offset = 0;
8129     for (size_t j = 0; j < structelems->dim; j++)
8130     {
8131         VarDeclaration *vd = sym->fields[j];
8132         Expression *e;
8133         if (vd->inuse)
8134         {
8135             error(loc, "circular reference to '%s'", vd->toPrettyChars());
8136             return new ErrorExp();
8137         }
8138         if (vd->offset < offset || vd->type->size() == 0)
8139             e = NULL;
8140         else if (vd->_init)
8141         {
8142             if (vd->_init->isVoidInitializer())
8143                 e = NULL;
8144             else
8145                 e = vd->getConstInitializer(false);
8146         }
8147         else
8148             e = vd->type->defaultInitLiteral(loc);
8149         if (e && e->op == TOKerror)
8150             return e;
8151         if (e)
8152             offset = vd->offset + (unsigned)vd->type->size();
8153         (*structelems)[j] = e;
8154     }
8155     StructLiteralExp *structinit = new StructLiteralExp(loc, (StructDeclaration *)sym, structelems);
8156 
8157     /* Copy from the initializer symbol for larger symbols,
8158      * otherwise the literals expressed as code get excessively large.
8159      */
8160     if (size(loc) > Target::ptrsize * 4U && !needsNested())
8161         structinit->useStaticInit = true;
8162 
8163     structinit->type = this;
8164     return structinit;
8165 }
8166 
8167 
isZeroInit(Loc)8168 bool TypeStruct::isZeroInit(Loc)
8169 {
8170     return sym->zeroInit != 0;
8171 }
8172 
isBoolean()8173 bool TypeStruct::isBoolean()
8174 {
8175     return false;
8176 }
8177 
needsDestruction()8178 bool TypeStruct::needsDestruction()
8179 {
8180     return sym->dtor != NULL;
8181 }
8182 
needsNested()8183 bool TypeStruct::needsNested()
8184 {
8185     if (sym->isNested())
8186         return true;
8187 
8188     for (size_t i = 0; i < sym->fields.dim; i++)
8189     {
8190         VarDeclaration *v = sym->fields[i];
8191         if (!v->isDataseg() && v->type->needsNested())
8192             return true;
8193     }
8194     return false;
8195 }
8196 
isAssignable()8197 bool TypeStruct::isAssignable()
8198 {
8199     bool assignable = true;
8200     unsigned offset = ~0;  // dead-store initialize to prevent spurious warning
8201 
8202     /* If any of the fields are const or immutable,
8203      * then one cannot assign this struct.
8204      */
8205     for (size_t i = 0; i < sym->fields.dim; i++)
8206     {
8207         VarDeclaration *v = sym->fields[i];
8208         //printf("%s [%d] v = (%s) %s, v->offset = %d, v->parent = %s", sym->toChars(), i, v->kind(), v->toChars(), v->offset, v->parent->kind());
8209         if (i == 0)
8210             ;
8211         else if (v->offset == offset)
8212         {
8213             /* If any fields of anonymous union are assignable,
8214              * then regard union as assignable.
8215              * This is to support unsafe things like Rebindable templates.
8216              */
8217             if (assignable)
8218                 continue;
8219         }
8220         else
8221         {
8222             if (!assignable)
8223                 return false;
8224         }
8225         assignable = v->type->isMutable() && v->type->isAssignable();
8226         offset = v->offset;
8227         //printf(" -> assignable = %d\n", assignable);
8228     }
8229 
8230     return assignable;
8231 }
8232 
hasPointers()8233 bool TypeStruct::hasPointers()
8234 {
8235     // Probably should cache this information in sym rather than recompute
8236     StructDeclaration *s = sym;
8237 
8238     sym->size(Loc());               // give error for forward references
8239     for (size_t i = 0; i < s->fields.dim; i++)
8240     {
8241         Declaration *d = s->fields[i];
8242         if (d->storage_class & STCref || d->hasPointers())
8243             return true;
8244     }
8245     return false;
8246 }
8247 
hasVoidInitPointers()8248 bool TypeStruct::hasVoidInitPointers()
8249 {
8250     // Probably should cache this information in sym rather than recompute
8251     StructDeclaration *s = sym;
8252 
8253     sym->size(Loc()); // give error for forward references
8254     for (size_t i = 0; i < s->fields.dim; i++)
8255     {
8256         VarDeclaration *v = s->fields[i];
8257         if (v->_init && v->_init->isVoidInitializer() && v->type->hasPointers())
8258             return true;
8259         if (!v->_init && v->type->hasVoidInitPointers())
8260             return true;
8261     }
8262     return false;
8263 }
8264 
implicitConvTo(Type * to)8265 MATCH TypeStruct::implicitConvTo(Type *to)
8266 {   MATCH m;
8267 
8268     //printf("TypeStruct::implicitConvTo(%s => %s)\n", toChars(), to->toChars());
8269 
8270     if (ty == to->ty && sym == ((TypeStruct *)to)->sym)
8271     {
8272         m = MATCHexact;         // exact match
8273         if (mod != to->mod)
8274         {
8275             m = MATCHconst;
8276             if (MODimplicitConv(mod, to->mod))
8277                 ;
8278             else
8279             {
8280                 /* Check all the fields. If they can all be converted,
8281                  * allow the conversion.
8282                  */
8283                 unsigned offset = ~0;   // dead-store to prevent spurious warning
8284                 for (size_t i = 0; i < sym->fields.dim; i++)
8285                 {
8286                     VarDeclaration *v = sym->fields[i];
8287                     if (i == 0)
8288                         ;
8289                     else if (v->offset == offset)
8290                     {
8291                         if (m > MATCHnomatch)
8292                             continue;
8293                     }
8294                     else
8295                     {
8296                         if (m <= MATCHnomatch)
8297                             return m;
8298                     }
8299 
8300                     // 'from' type
8301                     Type *tvf = v->type->addMod(mod);
8302 
8303                     // 'to' type
8304                     Type *tv = v->type->addMod(to->mod);
8305 
8306                     // field match
8307                     MATCH mf = tvf->implicitConvTo(tv);
8308                     //printf("\t%s => %s, match = %d\n", v->type->toChars(), tv->toChars(), mf);
8309 
8310                     if (mf <= MATCHnomatch)
8311                         return mf;
8312                     if (mf < m)         // if field match is worse
8313                         m = mf;
8314                     offset = v->offset;
8315                 }
8316             }
8317         }
8318     }
8319     else if (sym->aliasthis && !(att & RECtracing))
8320     {
8321         att = (AliasThisRec)(att | RECtracing);
8322         m = aliasthisOf()->implicitConvTo(to);
8323         att = (AliasThisRec)(att & ~RECtracing);
8324     }
8325     else
8326         m = MATCHnomatch;       // no match
8327     return m;
8328 }
8329 
constConv(Type * to)8330 MATCH TypeStruct::constConv(Type *to)
8331 {
8332     if (equals(to))
8333         return MATCHexact;
8334     if (ty == to->ty && sym == ((TypeStruct *)to)->sym &&
8335         MODimplicitConv(mod, to->mod))
8336         return MATCHconst;
8337     return MATCHnomatch;
8338 }
8339 
deduceWild(Type * t,bool isRef)8340 unsigned char TypeStruct::deduceWild(Type *t, bool isRef)
8341 {
8342     if (ty == t->ty && sym == ((TypeStruct *)t)->sym)
8343         return Type::deduceWild(t, isRef);
8344 
8345     unsigned char wm = 0;
8346 
8347     if (t->hasWild() && sym->aliasthis && !(att & RECtracing))
8348     {
8349         att = (AliasThisRec)(att | RECtracing);
8350         wm = aliasthisOf()->deduceWild(t, isRef);
8351         att = (AliasThisRec)(att & ~RECtracing);
8352     }
8353 
8354     return wm;
8355 }
8356 
toHeadMutable()8357 Type *TypeStruct::toHeadMutable()
8358 {
8359     return this;
8360 }
8361 
8362 
8363 /***************************** TypeClass *****************************/
8364 
TypeClass(ClassDeclaration * sym)8365 TypeClass::TypeClass(ClassDeclaration *sym)
8366         : Type(Tclass)
8367 {
8368     this->sym = sym;
8369     this->att = RECfwdref;
8370     this->cppmangle = CPPMANGLEdefault;
8371 }
8372 
kind()8373 const char *TypeClass::kind()
8374 {
8375     return "class";
8376 }
8377 
syntaxCopy()8378 Type *TypeClass::syntaxCopy()
8379 {
8380     return this;
8381 }
8382 
semantic(Loc,Scope * sc)8383 Type *TypeClass::semantic(Loc, Scope *sc)
8384 {
8385     //printf("TypeClass::semantic(%s)\n", sym->toChars());
8386     if (deco)
8387     {
8388         if (sc && sc->cppmangle != CPPMANGLEdefault)
8389         {
8390             if (this->cppmangle == CPPMANGLEdefault)
8391                 this->cppmangle = sc->cppmangle;
8392             else
8393                 assert(this->cppmangle == sc->cppmangle);
8394         }
8395         return this;
8396     }
8397 
8398     /* Don't semantic for sym because it should be deferred until
8399      * sizeof needed or its members accessed.
8400      */
8401     // instead, parent should be set correctly
8402     assert(sym->parent);
8403 
8404     if (sym->type->ty == Terror)
8405         return Type::terror;
8406     if (sc)
8407         this->cppmangle = sc->cppmangle;
8408     return merge();
8409 }
8410 
size(Loc)8411 d_uns64 TypeClass::size(Loc)
8412 {
8413     return Target::ptrsize;
8414 }
8415 
toDsymbol(Scope *)8416 Dsymbol *TypeClass::toDsymbol(Scope *)
8417 {
8418     return sym;
8419 }
8420 
searchSymClass(Scope * sc,Dsymbol * sym,Expression * e,Identifier * ident)8421 static Dsymbol *searchSymClass(Scope *sc, Dsymbol *sym, Expression *e, Identifier *ident)
8422 {
8423     int flags = sc->flags & SCOPEignoresymbolvisibility ? IgnoreSymbolVisibility : 0;
8424     Dsymbol *sold = NULL;
8425     if (global.params.bug10378 || global.params.check10378)
8426     {
8427         sold = sym->search(e->loc, ident, flags | IgnoreSymbolVisibility);
8428         if (!global.params.check10378)
8429             return sold;
8430     }
8431 
8432     Dsymbol *s = sym->search(e->loc, ident, flags | SearchLocalsOnly);
8433     if (!s && !(flags & IgnoreSymbolVisibility))
8434     {
8435         s = sym->search(e->loc, ident, flags | SearchLocalsOnly | IgnoreSymbolVisibility);
8436         if (s && !(flags & IgnoreErrors))
8437             ::deprecation(e->loc, "%s is not visible from class %s", s->toPrettyChars(), sym->toChars());
8438     }
8439     if (global.params.check10378)
8440     {
8441         Dsymbol *snew = s;
8442         if (sold != snew)
8443             Scope::deprecation10378(e->loc, sold, snew);
8444         if (global.params.bug10378)
8445             s = sold;
8446     }
8447     return s;
8448 }
8449 
dotExp(Scope * sc,Expression * e,Identifier * ident,int flag)8450 Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
8451 {
8452     Dsymbol *s;
8453     assert(e->op != TOKdot);
8454 
8455     // Bugzilla 12543
8456     if (ident == Id::__sizeof || ident == Id::__xalignof || ident == Id::_mangleof)
8457     {
8458         return Type::getProperty(e->loc, ident, 0);
8459     }
8460 
8461     /* If e.tupleof
8462      */
8463     if (ident == Id::_tupleof)
8464     {
8465         /* Create a TupleExp
8466          */
8467         e = ::semantic(e, sc);  // do this before turning on noaccesscheck
8468 
8469         sym->size(e->loc); // do semantic of type
8470 
8471         Expression *e0 = NULL;
8472         Expression *ev = e->op == TOKtype ? NULL : e;
8473         if (ev)
8474             ev = extractSideEffect(sc, "__tup", &e0, ev);
8475 
8476         Expressions *exps = new Expressions;
8477         exps->reserve(sym->fields.dim);
8478         for (size_t i = 0; i < sym->fields.dim; i++)
8479         {
8480             VarDeclaration *v = sym->fields[i];
8481             // Don't include hidden 'this' pointer
8482             if (v->isThisDeclaration())
8483                 continue;
8484             Expression *ex;
8485             if (ev)
8486                 ex = new DotVarExp(e->loc, ev, v);
8487             else
8488             {
8489                 ex = new VarExp(e->loc, v);
8490                 ex->type = ex->type->addMod(e->type->mod);
8491             }
8492             exps->push(ex);
8493         }
8494 
8495         e = new TupleExp(e->loc, e0, exps);
8496         Scope *sc2 = sc->push();
8497         sc2->flags = sc->flags | SCOPEnoaccesscheck;
8498         e = ::semantic(e, sc2);
8499         sc2->pop();
8500         return e;
8501     }
8502 
8503     s = searchSymClass(sc, sym, e, ident);
8504 L1:
8505     if (!s)
8506     {
8507         // See if it's 'this' class or a base class
8508         if (sym->ident == ident)
8509         {
8510             if (e->op == TOKtype)
8511                 return Type::getProperty(e->loc, ident, 0);
8512             e = new DotTypeExp(e->loc, e, sym);
8513             e = ::semantic(e, sc);
8514             return e;
8515         }
8516         if (ClassDeclaration *cbase = sym->searchBase(ident))
8517         {
8518             if (e->op == TOKtype)
8519                 return Type::getProperty(e->loc, ident, 0);
8520             if (InterfaceDeclaration *ifbase = cbase->isInterfaceDeclaration())
8521                 e = new CastExp(e->loc, e, ifbase->type);
8522             else
8523                 e = new DotTypeExp(e->loc, e, cbase);
8524             e = ::semantic(e, sc);
8525             return e;
8526         }
8527 
8528         if (ident == Id::classinfo)
8529         {
8530             if (!Type::typeinfoclass)
8531             {
8532                 error(e->loc, "`object.TypeInfo_Class` could not be found, but is implicitly used");
8533                 return new ErrorExp();
8534             }
8535 
8536             Type *t = Type::typeinfoclass->type;
8537             if (e->op == TOKtype || e->op == TOKdottype)
8538             {
8539                 /* For type.classinfo, we know the classinfo
8540                  * at compile time.
8541                  */
8542                 if (!sym->vclassinfo)
8543                     sym->vclassinfo = new TypeInfoClassDeclaration(sym->type);
8544                 e = new VarExp(e->loc, sym->vclassinfo);
8545                 e = e->addressOf();
8546                 e->type = t;    // do this so we don't get redundant dereference
8547             }
8548             else
8549             {
8550                 /* For class objects, the classinfo reference is the first
8551                  * entry in the vtbl[]
8552                  */
8553                 e = new PtrExp(e->loc, e);
8554                 e->type = t->pointerTo();
8555                 if (sym->isInterfaceDeclaration())
8556                 {
8557                     if (sym->isCPPinterface())
8558                     {
8559                         /* C++ interface vtbl[]s are different in that the
8560                          * first entry is always pointer to the first virtual
8561                          * function, not classinfo.
8562                          * We can't get a .classinfo for it.
8563                          */
8564                         error(e->loc, "no .classinfo for C++ interface objects");
8565                     }
8566                     /* For an interface, the first entry in the vtbl[]
8567                      * is actually a pointer to an instance of struct Interface.
8568                      * The first member of Interface is the .classinfo,
8569                      * so add an extra pointer indirection.
8570                      */
8571                     e->type = e->type->pointerTo();
8572                     e = new PtrExp(e->loc, e);
8573                     e->type = t->pointerTo();
8574                 }
8575                 e = new PtrExp(e->loc, e, t);
8576             }
8577             return e;
8578         }
8579 
8580         if (ident == Id::__vptr)
8581         {
8582             /* The pointer to the vtbl[]
8583              * *cast(immutable(void*)**)e
8584              */
8585             e = e->castTo(sc, tvoidptr->immutableOf()->pointerTo()->pointerTo());
8586             e = new PtrExp(e->loc, e);
8587             e = ::semantic(e, sc);
8588             return e;
8589         }
8590 
8591         if (ident == Id::__monitor)
8592         {
8593             /* The handle to the monitor (call it a void*)
8594              * *(cast(void**)e + 1)
8595              */
8596             e = e->castTo(sc, tvoidptr->pointerTo());
8597             e = new AddExp(e->loc, e, new IntegerExp(1));
8598             e = new PtrExp(e->loc, e);
8599             e = ::semantic(e, sc);
8600             return e;
8601         }
8602 
8603         if (ident == Id::outer && sym->vthis)
8604         {
8605             if (sym->vthis->semanticRun == PASSinit)
8606                 sym->vthis->semantic(NULL);
8607 
8608             if (ClassDeclaration *cdp = sym->toParent2()->isClassDeclaration())
8609             {
8610                 DotVarExp *dve = new DotVarExp(e->loc, e, sym->vthis);
8611                 dve->type = cdp->type->addMod(e->type->mod);
8612                 return dve;
8613             }
8614 
8615             /* Bugzilla 15839: Find closest parent class through nested functions.
8616              */
8617             for (Dsymbol *p = sym->toParent2(); p; p = p->toParent2())
8618             {
8619                 FuncDeclaration *fd = p->isFuncDeclaration();
8620                 if (!fd)
8621                     break;
8622                 if (fd->isNested())
8623                     continue;
8624                 AggregateDeclaration *ad = fd->isThis();
8625                 if (!ad)
8626                     break;
8627                 if (ad->isClassDeclaration())
8628                 {
8629                     ThisExp *ve = new ThisExp(e->loc);
8630 
8631                     ve->var = fd->vthis;
8632                     const bool nestedError = fd->vthis->checkNestedReference(sc, e->loc);
8633                     assert(!nestedError);
8634 
8635                     ve->type = fd->vthis->type->addMod(e->type->mod);
8636                     return ve;
8637                 }
8638                 break;
8639             }
8640 
8641             // Continue to show enclosing function's frame (stack or closure).
8642             DotVarExp *dve = new DotVarExp(e->loc, e, sym->vthis);
8643             dve->type = sym->vthis->type->addMod(e->type->mod);
8644             return dve;
8645         }
8646 
8647         return noMember(sc, e, ident, flag & 1);
8648     }
8649     if (!(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, s))
8650     {
8651         ::deprecation(e->loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toPrettyChars());
8652         // return noMember(sc, e, ident, flag);
8653     }
8654     if (!s->isFuncDeclaration())        // because of overloading
8655         s->checkDeprecated(e->loc, sc);
8656     s = s->toAlias();
8657 
8658     EnumMember *em = s->isEnumMember();
8659     if (em)
8660     {
8661         return em->getVarExp(e->loc, sc);
8662     }
8663 
8664     if (VarDeclaration *v = s->isVarDeclaration())
8665     {
8666         if (!v->type ||
8667             (!v->type->deco && v->inuse))
8668         {
8669             if (v->inuse) // Bugzilla 9494
8670                 e->error("circular reference to %s '%s'", v->kind(), v->toPrettyChars());
8671             else
8672                 e->error("forward reference to %s '%s'", v->kind(), v->toPrettyChars());
8673             return new ErrorExp();
8674         }
8675         if (v->type->ty == Terror)
8676             return new ErrorExp();
8677 
8678         if ((v->storage_class & STCmanifest) && v->_init)
8679         {
8680             if (v->inuse)
8681             {
8682                 e->error("circular initialization of %s '%s'", v->kind(), v->toPrettyChars());
8683                 return new ErrorExp();
8684             }
8685             checkAccess(e->loc, sc, NULL, v);
8686             Expression *ve = new VarExp(e->loc, v);
8687             ve = ::semantic(ve, sc);
8688             return ve;
8689         }
8690     }
8691 
8692     if (Type *t = s->getType())
8693     {
8694         return ::semantic(new TypeExp(e->loc, t), sc);
8695     }
8696 
8697     TemplateMixin *tm = s->isTemplateMixin();
8698     if (tm)
8699     {
8700         Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, tm));
8701         de->type = e->type;
8702         return de;
8703     }
8704 
8705     TemplateDeclaration *td = s->isTemplateDeclaration();
8706     if (td)
8707     {
8708         if (e->op == TOKtype)
8709             e = new TemplateExp(e->loc, td);
8710         else
8711             e = new DotTemplateExp(e->loc, e, td);
8712         e = ::semantic(e, sc);
8713         return e;
8714     }
8715 
8716     TemplateInstance *ti = s->isTemplateInstance();
8717     if (ti)
8718     {
8719         if (!ti->semanticRun)
8720         {
8721             ti->semantic(sc);
8722             if (!ti->inst || ti->errors)    // if template failed to expand
8723                 return new ErrorExp();
8724         }
8725         s = ti->inst->toAlias();
8726         if (!s->isTemplateInstance())
8727             goto L1;
8728         if (e->op == TOKtype)
8729             e = new ScopeExp(e->loc, ti);
8730         else
8731             e = new DotExp(e->loc, e, new ScopeExp(e->loc, ti));
8732         return ::semantic(e, sc);
8733     }
8734 
8735     if (s->isImport() || s->isModule() || s->isPackage())
8736     {
8737         e = ::resolve(e->loc, sc, s, false);
8738         return e;
8739     }
8740 
8741     OverloadSet *o = s->isOverloadSet();
8742     if (o)
8743     {
8744         OverExp *oe = new OverExp(e->loc, o);
8745         if (e->op == TOKtype)
8746             return oe;
8747         return new DotExp(e->loc, e, oe);
8748     }
8749 
8750     Declaration *d = s->isDeclaration();
8751     if (!d)
8752     {
8753         e->error("%s.%s is not a declaration", e->toChars(), ident->toChars());
8754         return new ErrorExp();
8755     }
8756 
8757     if (e->op == TOKtype)
8758     {
8759         /* It's:
8760          *    Class.d
8761          */
8762         if (TupleDeclaration *tup = d->isTupleDeclaration())
8763         {
8764             e = new TupleExp(e->loc, tup);
8765             e = ::semantic(e, sc);
8766             return e;
8767         }
8768         if (d->needThis() && sc->intypeof != 1)
8769         {
8770             /* Rewrite as:
8771              *  this.d
8772              */
8773             if (hasThis(sc))
8774             {
8775                 // This is almost same as getRightThis() in expression.c
8776                 Expression *e1 = new ThisExp(e->loc);
8777                 e1 = ::semantic(e1, sc);
8778             L2:
8779                 Type *t = e1->type->toBasetype();
8780                 ClassDeclaration *cd = e->type->isClassHandle();
8781                 ClassDeclaration *tcd = t->isClassHandle();
8782                 if (cd && tcd && (tcd == cd || cd->isBaseOf(tcd, NULL)))
8783                 {
8784                     e = new DotTypeExp(e1->loc, e1, cd);
8785                     e = new DotVarExp(e->loc, e, d);
8786                     e = ::semantic(e, sc);
8787                     return e;
8788                 }
8789                 if (tcd && tcd->isNested())
8790                 {   /* e1 is the 'this' pointer for an inner class: tcd.
8791                      * Rewrite it as the 'this' pointer for the outer class.
8792                      */
8793 
8794                     e1 = new DotVarExp(e->loc, e1, tcd->vthis);
8795                     e1->type = tcd->vthis->type;
8796                     e1->type = e1->type->addMod(t->mod);
8797                     // Do not call checkNestedRef()
8798                     //e1 = ::semantic(e1, sc);
8799 
8800                     // Skip up over nested functions, and get the enclosing
8801                     // class type.
8802                     int n = 0;
8803                     for (s = tcd->toParent();
8804                          s && s->isFuncDeclaration();
8805                          s = s->toParent())
8806                     {   FuncDeclaration *f = s->isFuncDeclaration();
8807                         if (f->vthis)
8808                         {
8809                             //printf("rewriting e1 to %s's this\n", f->toChars());
8810                             n++;
8811                             e1 = new VarExp(e->loc, f->vthis);
8812                         }
8813                         else
8814                         {
8815                             e = new VarExp(e->loc, d);
8816                             return e;
8817                         }
8818                     }
8819                     if (s && s->isClassDeclaration())
8820                     {   e1->type = s->isClassDeclaration()->type;
8821                         e1->type = e1->type->addMod(t->mod);
8822                         if (n > 1)
8823                             e1 = ::semantic(e1, sc);
8824                     }
8825                     else
8826                         e1 = ::semantic(e1, sc);
8827                     goto L2;
8828                 }
8829             }
8830         }
8831         //printf("e = %s, d = %s\n", e->toChars(), d->toChars());
8832         if (d->semanticRun == PASSinit)
8833             d->semantic(NULL);
8834         checkAccess(e->loc, sc, e, d);
8835         VarExp *ve = new VarExp(e->loc, d);
8836         if (d->isVarDeclaration() && d->needThis())
8837             ve->type = d->type->addMod(e->type->mod);
8838         return ve;
8839     }
8840 
8841     bool unreal = e->op == TOKvar && ((VarExp *)e)->var->isField();
8842     if (d->isDataseg() || (unreal && d->isField()))
8843     {
8844         // (e, d)
8845         checkAccess(e->loc, sc, e, d);
8846         Expression *ve = new VarExp(e->loc, d);
8847         e = unreal ? ve : new CommaExp(e->loc, e, ve);
8848         e = ::semantic(e, sc);
8849         return e;
8850     }
8851 
8852     e = new DotVarExp(e->loc, e, d);
8853     e = ::semantic(e, sc);
8854     return e;
8855 }
8856 
isClassHandle()8857 ClassDeclaration *TypeClass::isClassHandle()
8858 {
8859     return sym;
8860 }
8861 
isscope()8862 bool TypeClass::isscope()
8863 {
8864     return sym->isscope;
8865 }
8866 
isBaseOf(Type * t,int * poffset)8867 bool TypeClass::isBaseOf(Type *t, int *poffset)
8868 {
8869     if (t && t->ty == Tclass)
8870     {
8871         ClassDeclaration *cd = ((TypeClass *)t)->sym;
8872         if (sym->isBaseOf(cd, poffset))
8873             return true;
8874     }
8875     return false;
8876 }
8877 
implicitConvTo(Type * to)8878 MATCH TypeClass::implicitConvTo(Type *to)
8879 {
8880     //printf("TypeClass::implicitConvTo(to = '%s') %s\n", to->toChars(), toChars());
8881     MATCH m = constConv(to);
8882     if (m > MATCHnomatch)
8883         return m;
8884 
8885     ClassDeclaration *cdto = to->isClassHandle();
8886     if (cdto)
8887     {
8888         //printf("TypeClass::implicitConvTo(to = '%s') %s, isbase = %d %d\n", to->toChars(), toChars(), cdto->isBaseInfoComplete(), sym->isBaseInfoComplete());
8889         if (cdto->semanticRun < PASSsemanticdone && !cdto->isBaseInfoComplete())
8890             cdto->semantic(NULL);
8891         if (sym->semanticRun < PASSsemanticdone && !sym->isBaseInfoComplete())
8892             sym->semantic(NULL);
8893         if (cdto->isBaseOf(sym, NULL) && MODimplicitConv(mod, to->mod))
8894         {
8895             //printf("'to' is base\n");
8896             return MATCHconvert;
8897         }
8898     }
8899 
8900     m = MATCHnomatch;
8901     if (sym->aliasthis && !(att & RECtracing))
8902     {
8903         att = (AliasThisRec)(att | RECtracing);
8904         m = aliasthisOf()->implicitConvTo(to);
8905         att = (AliasThisRec)(att & ~RECtracing);
8906     }
8907 
8908     return m;
8909 }
8910 
constConv(Type * to)8911 MATCH TypeClass::constConv(Type *to)
8912 {
8913     if (equals(to))
8914         return MATCHexact;
8915     if (ty == to->ty && sym == ((TypeClass *)to)->sym &&
8916         MODimplicitConv(mod, to->mod))
8917         return MATCHconst;
8918 
8919     /* Conversion derived to const(base)
8920      */
8921     int offset = 0;
8922     if (to->isBaseOf(this, &offset) && offset == 0 &&
8923         MODimplicitConv(mod, to->mod))
8924     {
8925         // Disallow:
8926         //  derived to base
8927         //  inout(derived) to inout(base)
8928         if (!to->isMutable() && !to->isWild())
8929             return MATCHconvert;
8930     }
8931 
8932     return MATCHnomatch;
8933 }
8934 
deduceWild(Type * t,bool isRef)8935 unsigned char TypeClass::deduceWild(Type *t, bool isRef)
8936 {
8937     ClassDeclaration *cd = t->isClassHandle();
8938     if (cd && (sym == cd || cd->isBaseOf(sym, NULL)))
8939         return Type::deduceWild(t, isRef);
8940 
8941     unsigned char wm = 0;
8942 
8943     if (t->hasWild() && sym->aliasthis && !(att & RECtracing))
8944     {
8945         att = (AliasThisRec)(att | RECtracing);
8946         wm = aliasthisOf()->deduceWild(t, isRef);
8947         att = (AliasThisRec)(att & ~RECtracing);
8948     }
8949 
8950     return wm;
8951 }
8952 
toHeadMutable()8953 Type *TypeClass::toHeadMutable()
8954 {
8955     return this;
8956 }
8957 
defaultInit(Loc loc)8958 Expression *TypeClass::defaultInit(Loc loc)
8959 {
8960     return new NullExp(loc, this);
8961 }
8962 
isZeroInit(Loc)8963 bool TypeClass::isZeroInit(Loc)
8964 {
8965     return true;
8966 }
8967 
isBoolean()8968 bool TypeClass::isBoolean()
8969 {
8970     return true;
8971 }
8972 
hasPointers()8973 bool TypeClass::hasPointers()
8974 {
8975     return true;
8976 }
8977 
8978 /***************************** TypeTuple *****************************/
8979 
TypeTuple(Parameters * arguments)8980 TypeTuple::TypeTuple(Parameters *arguments)
8981     : Type(Ttuple)
8982 {
8983     //printf("TypeTuple(this = %p)\n", this);
8984     this->arguments = arguments;
8985     //printf("TypeTuple() %p, %s\n", this, toChars());
8986 }
8987 
8988 /****************
8989  * Form TypeTuple from the types of the expressions.
8990  * Assume exps[] is already tuple expanded.
8991  */
8992 
TypeTuple(Expressions * exps)8993 TypeTuple::TypeTuple(Expressions *exps)
8994     : Type(Ttuple)
8995 {
8996     Parameters *arguments = new Parameters;
8997     if (exps)
8998     {
8999         arguments->setDim(exps->dim);
9000         for (size_t i = 0; i < exps->dim; i++)
9001         {   Expression *e = (*exps)[i];
9002             if (e->type->ty == Ttuple)
9003                 e->error("cannot form tuple of tuples");
9004             Parameter *arg = new Parameter(STCundefined, e->type, NULL, NULL);
9005             (*arguments)[i] = arg;
9006         }
9007     }
9008     this->arguments = arguments;
9009     //printf("TypeTuple() %p, %s\n", this, toChars());
9010 }
9011 
create(Parameters * arguments)9012 TypeTuple *TypeTuple::create(Parameters *arguments)
9013 {
9014     return new TypeTuple(arguments);
9015 }
9016 
9017 /*******************************************
9018  * Type tuple with 0, 1 or 2 types in it.
9019  */
TypeTuple()9020 TypeTuple::TypeTuple()
9021     : Type(Ttuple)
9022 {
9023     arguments = new Parameters();
9024 }
9025 
TypeTuple(Type * t1)9026 TypeTuple::TypeTuple(Type *t1)
9027     : Type(Ttuple)
9028 {
9029     arguments = new Parameters();
9030     arguments->push(new Parameter(0, t1, NULL, NULL));
9031 }
9032 
TypeTuple(Type * t1,Type * t2)9033 TypeTuple::TypeTuple(Type *t1, Type *t2)
9034     : Type(Ttuple)
9035 {
9036     arguments = new Parameters();
9037     arguments->push(new Parameter(0, t1, NULL, NULL));
9038     arguments->push(new Parameter(0, t2, NULL, NULL));
9039 }
9040 
kind()9041 const char *TypeTuple::kind()
9042 {
9043     return "tuple";
9044 }
9045 
syntaxCopy()9046 Type *TypeTuple::syntaxCopy()
9047 {
9048     Parameters *args = Parameter::arraySyntaxCopy(arguments);
9049     Type *t = new TypeTuple(args);
9050     t->mod = mod;
9051     return t;
9052 }
9053 
semantic(Loc,Scope *)9054 Type *TypeTuple::semantic(Loc, Scope *)
9055 {
9056     //printf("TypeTuple::semantic(this = %p)\n", this);
9057     //printf("TypeTuple::semantic() %p, %s\n", this, toChars());
9058     if (!deco)
9059         deco = merge()->deco;
9060 
9061     /* Don't return merge(), because a tuple with one type has the
9062      * same deco as that type.
9063      */
9064     return this;
9065 }
9066 
equals(RootObject * o)9067 bool TypeTuple::equals(RootObject *o)
9068 {
9069     Type *t = (Type *)o;
9070     //printf("TypeTuple::equals(%s, %s)\n", toChars(), t->toChars());
9071     if (this == t)
9072         return true;
9073     if (t->ty == Ttuple)
9074     {
9075         TypeTuple *tt = (TypeTuple *)t;
9076         if (arguments->dim == tt->arguments->dim)
9077         {
9078             for (size_t i = 0; i < tt->arguments->dim; i++)
9079             {
9080                 Parameter *arg1 = (*arguments)[i];
9081                 Parameter *arg2 = (*tt->arguments)[i];
9082                 if (!arg1->type->equals(arg2->type))
9083                     return false;
9084             }
9085             return true;
9086         }
9087     }
9088     return false;
9089 }
9090 
getProperty(Loc loc,Identifier * ident,int flag)9091 Expression *TypeTuple::getProperty(Loc loc, Identifier *ident, int flag)
9092 {
9093     Expression *e;
9094 
9095     if (ident == Id::length)
9096     {
9097         e = new IntegerExp(loc, arguments->dim, Type::tsize_t);
9098     }
9099     else if (ident == Id::_init)
9100     {
9101         e = defaultInitLiteral(loc);
9102     }
9103     else if (flag)
9104     {
9105         e = NULL;
9106     }
9107     else
9108     {
9109         error(loc, "no property '%s' for tuple '%s'", ident->toChars(), toChars());
9110         e = new ErrorExp();
9111     }
9112     return e;
9113 }
9114 
defaultInit(Loc loc)9115 Expression *TypeTuple::defaultInit(Loc loc)
9116 {
9117     Expressions *exps = new Expressions();
9118     exps->setDim(arguments->dim);
9119     for (size_t i = 0; i < arguments->dim; i++)
9120     {
9121         Parameter *p = (*arguments)[i];
9122         assert(p->type);
9123         Expression *e = p->type->defaultInitLiteral(loc);
9124         if (e->op == TOKerror)
9125             return e;
9126         (*exps)[i] = e;
9127     }
9128     return new TupleExp(loc, exps);
9129 }
9130 
9131 /***************************** TypeSlice *****************************/
9132 
9133 /* This is so we can slice a TypeTuple */
9134 
TypeSlice(Type * next,Expression * lwr,Expression * upr)9135 TypeSlice::TypeSlice(Type *next, Expression *lwr, Expression *upr)
9136     : TypeNext(Tslice, next)
9137 {
9138     //printf("TypeSlice[%s .. %s]\n", lwr->toChars(), upr->toChars());
9139     this->lwr = lwr;
9140     this->upr = upr;
9141 }
9142 
kind()9143 const char *TypeSlice::kind()
9144 {
9145     return "slice";
9146 }
9147 
syntaxCopy()9148 Type *TypeSlice::syntaxCopy()
9149 {
9150     Type *t = new TypeSlice(next->syntaxCopy(), lwr->syntaxCopy(), upr->syntaxCopy());
9151     t->mod = mod;
9152     return t;
9153 }
9154 
semantic(Loc loc,Scope * sc)9155 Type *TypeSlice::semantic(Loc loc, Scope *sc)
9156 {
9157     //printf("TypeSlice::semantic() %s\n", toChars());
9158     Type *tn = next->semantic(loc, sc);
9159     //printf("next: %s\n", tn->toChars());
9160 
9161     Type *tbn = tn->toBasetype();
9162     if (tbn->ty != Ttuple)
9163     {
9164         error(loc, "can only slice tuple types, not %s", tbn->toChars());
9165         return Type::terror;
9166     }
9167     TypeTuple *tt = (TypeTuple *)tbn;
9168 
9169     lwr = semanticLength(sc, tbn, lwr);
9170     lwr = lwr->ctfeInterpret();
9171     uinteger_t i1 = lwr->toUInteger();
9172 
9173     upr = semanticLength(sc, tbn, upr);
9174     upr = upr->ctfeInterpret();
9175     uinteger_t i2 = upr->toUInteger();
9176 
9177     if (!(i1 <= i2 && i2 <= tt->arguments->dim))
9178     {
9179         error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, tt->arguments->dim);
9180         return Type::terror;
9181     }
9182 
9183     next = tn;
9184     transitive();
9185 
9186     Parameters *args = new Parameters;
9187     args->reserve((size_t)(i2 - i1));
9188     for (size_t i = (size_t)i1; i < (size_t)i2; i++)
9189     {
9190         Parameter *arg = (*tt->arguments)[i];
9191         args->push(arg);
9192     }
9193     Type *t = new TypeTuple(args);
9194     return t->semantic(loc, sc);
9195 }
9196 
resolve(Loc loc,Scope * sc,Expression ** pe,Type ** pt,Dsymbol ** ps,bool intypeid)9197 void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
9198 {
9199     next->resolve(loc, sc, pe, pt, ps, intypeid);
9200     if (*pe)
9201     {
9202         // It's really a slice expression
9203         if (Dsymbol *s = getDsymbol(*pe))
9204             *pe = new DsymbolExp(loc, s);
9205         *pe = new ArrayExp(loc, *pe, new IntervalExp(loc, lwr, upr));
9206     }
9207     else if (*ps)
9208     {
9209         Dsymbol *s = *ps;
9210         TupleDeclaration *td = s->isTupleDeclaration();
9211         if (td)
9212         {
9213             /* It's a slice of a TupleDeclaration
9214              */
9215             ScopeDsymbol *sym = new ArrayScopeSymbol(sc, td);
9216             sym->parent = sc->scopesym;
9217             sc = sc->push(sym);
9218             sc = sc->startCTFE();
9219             lwr = ::semantic(lwr, sc);
9220             upr = ::semantic(upr, sc);
9221             sc = sc->endCTFE();
9222             sc = sc->pop();
9223 
9224             lwr = lwr->ctfeInterpret();
9225             upr = upr->ctfeInterpret();
9226             uinteger_t i1 = lwr->toUInteger();
9227             uinteger_t i2 = upr->toUInteger();
9228 
9229             if (!(i1 <= i2 && i2 <= td->objects->dim))
9230             {
9231                 error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, td->objects->dim);
9232                 *ps = NULL;
9233                 *pt = Type::terror;
9234                 return;
9235             }
9236 
9237             if (i1 == 0 && i2 == td->objects->dim)
9238             {
9239                 *ps = td;
9240                 return;
9241             }
9242 
9243             /* Create a new TupleDeclaration which
9244              * is a slice [i1..i2] out of the old one.
9245              */
9246             Objects *objects = new Objects;
9247             objects->setDim((size_t)(i2 - i1));
9248             for (size_t i = 0; i < objects->dim; i++)
9249             {
9250                 (*objects)[i] = (*td->objects)[(size_t)i1 + i];
9251             }
9252 
9253             TupleDeclaration *tds = new TupleDeclaration(loc, td->ident, objects);
9254             *ps = tds;
9255         }
9256         else
9257             goto Ldefault;
9258     }
9259     else
9260     {
9261         if ((*pt)->ty != Terror)
9262             next = *pt;     // prevent re-running semantic() on 'next'
9263      Ldefault:
9264         Type::resolve(loc, sc, pe, pt, ps, intypeid);
9265     }
9266 }
9267 
9268 /***************************** TypeNull *****************************/
9269 
TypeNull()9270 TypeNull::TypeNull()
9271         : Type(Tnull)
9272 {
9273 }
9274 
kind()9275 const char *TypeNull::kind()
9276 {
9277     return "null";
9278 }
9279 
syntaxCopy()9280 Type *TypeNull::syntaxCopy()
9281 {
9282     // No semantic analysis done, no need to copy
9283     return this;
9284 }
9285 
implicitConvTo(Type * to)9286 MATCH TypeNull::implicitConvTo(Type *to)
9287 {
9288     //printf("TypeNull::implicitConvTo(this=%p, to=%p)\n", this, to);
9289     //printf("from: %s\n", toChars());
9290     //printf("to  : %s\n", to->toChars());
9291     MATCH m = Type::implicitConvTo(to);
9292     if (m != MATCHnomatch)
9293         return m;
9294 
9295     // NULL implicitly converts to any pointer type or dynamic array
9296     //if (type->ty == Tpointer && type->nextOf()->ty == Tvoid)
9297     {
9298         Type *tb = to->toBasetype();
9299         if (tb->ty == Tnull ||
9300             tb->ty == Tpointer || tb->ty == Tarray ||
9301             tb->ty == Taarray  || tb->ty == Tclass ||
9302             tb->ty == Tdelegate)
9303             return MATCHconst;
9304     }
9305 
9306     return MATCHnomatch;
9307 }
9308 
isBoolean()9309 bool TypeNull::isBoolean()
9310 {
9311     return true;
9312 }
9313 
size(Loc loc)9314 d_uns64 TypeNull::size(Loc loc)
9315 {
9316     return tvoidptr->size(loc);
9317 }
9318 
defaultInit(Loc)9319 Expression *TypeNull::defaultInit(Loc)
9320 {
9321     return new NullExp(Loc(), Type::tnull);
9322 }
9323 
9324 /***************************** Parameter *****************************/
9325 
Parameter(StorageClass storageClass,Type * type,Identifier * ident,Expression * defaultArg)9326 Parameter::Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg)
9327 {
9328     this->type = type;
9329     this->ident = ident;
9330     this->storageClass = storageClass;
9331     this->defaultArg = defaultArg;
9332 }
9333 
create(StorageClass storageClass,Type * type,Identifier * ident,Expression * defaultArg)9334 Parameter *Parameter::create(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg)
9335 {
9336     return new Parameter(storageClass, type, ident, defaultArg);
9337 }
9338 
syntaxCopy()9339 Parameter *Parameter::syntaxCopy()
9340 {
9341     return new Parameter(storageClass,
9342         type ? type->syntaxCopy() : NULL,
9343         ident,
9344         defaultArg ? defaultArg->syntaxCopy() : NULL);
9345 }
9346 
arraySyntaxCopy(Parameters * parameters)9347 Parameters *Parameter::arraySyntaxCopy(Parameters *parameters)
9348 {
9349     Parameters *params = NULL;
9350     if (parameters)
9351     {
9352         params = new Parameters();
9353         params->setDim(parameters->dim);
9354         for (size_t i = 0; i < params->dim; i++)
9355             (*params)[i] = (*parameters)[i]->syntaxCopy();
9356     }
9357     return params;
9358 }
9359 
9360 /****************************************************
9361  * Determine if parameter is a lazy array of delegates.
9362  * If so, return the return type of those delegates.
9363  * If not, return NULL.
9364  *
9365  * Returns T if the type is one of the following forms:
9366  *      T delegate()[]
9367  *      T delegate()[dim]
9368  */
9369 
isLazyArray()9370 Type *Parameter::isLazyArray()
9371 {
9372     Type *tb = type->toBasetype();
9373     if (tb->ty == Tsarray || tb->ty == Tarray)
9374     {
9375         Type *tel = ((TypeArray *)tb)->next->toBasetype();
9376         if (tel->ty == Tdelegate)
9377         {
9378             TypeDelegate *td = (TypeDelegate *)tel;
9379             TypeFunction *tf = td->next->toTypeFunction();
9380 
9381             if (!tf->varargs && Parameter::dim(tf->parameters) == 0)
9382             {
9383                 return tf->next;    // return type of delegate
9384             }
9385         }
9386     }
9387     return NULL;
9388 }
9389 
9390 /***************************************
9391  * Determine number of arguments, folding in tuples.
9392  */
9393 
dimDg(void * ctx,size_t,Parameter *)9394 static int dimDg(void *ctx, size_t, Parameter *)
9395 {
9396     ++*(size_t *)ctx;
9397     return 0;
9398 }
9399 
dim(Parameters * parameters)9400 size_t Parameter::dim(Parameters *parameters)
9401 {
9402     size_t n = 0;
9403     Parameter_foreach(parameters, &dimDg, &n);
9404     return n;
9405 }
9406 
9407 /***************************************
9408  * Get nth Parameter, folding in tuples.
9409  * Returns:
9410  *      Parameter*      nth Parameter
9411  *      NULL            not found, *pn gets incremented by the number
9412  *                      of Parameters
9413  */
9414 
9415 struct GetNthParamCtx
9416 {
9417     size_t nth;
9418     Parameter *param;
9419 };
9420 
getNthParamDg(void * ctx,size_t n,Parameter * p)9421 static int getNthParamDg(void *ctx, size_t n, Parameter *p)
9422 {
9423     GetNthParamCtx *c = (GetNthParamCtx *)ctx;
9424     if (n == c->nth)
9425     {
9426         c->param = p;
9427         return 1;
9428     }
9429     return 0;
9430 }
9431 
getNth(Parameters * parameters,size_t nth,size_t *)9432 Parameter *Parameter::getNth(Parameters *parameters, size_t nth, size_t *)
9433 {
9434     GetNthParamCtx ctx = { nth, NULL };
9435     int res = Parameter_foreach(parameters, &getNthParamDg, &ctx);
9436     return res ? ctx.param : NULL;
9437 }
9438 
9439 /***************************************
9440  * Expands tuples in args in depth first order. Calls
9441  * dg(void *ctx, size_t argidx, Parameter *arg) for each Parameter.
9442  * If dg returns !=0, stops and returns that value else returns 0.
9443  * Use this function to avoid the O(N + N^2/2) complexity of
9444  * calculating dim and calling N times getNth.
9445  */
9446 
Parameter_foreach(Parameters * parameters,ForeachDg dg,void * ctx,size_t * pn)9447 int Parameter_foreach(Parameters *parameters, ForeachDg dg, void *ctx, size_t *pn)
9448 {
9449     assert(dg);
9450     if (!parameters)
9451         return 0;
9452 
9453     size_t n = pn ? *pn : 0; // take over index
9454     int result = 0;
9455     for (size_t i = 0; i < parameters->dim; i++)
9456     {
9457         Parameter *p = (*parameters)[i];
9458         Type *t = p->type->toBasetype();
9459 
9460         if (t->ty == Ttuple)
9461         {
9462             TypeTuple *tu = (TypeTuple *)t;
9463             result = Parameter_foreach(tu->arguments, dg, ctx, &n);
9464         }
9465         else
9466             result = dg(ctx, n++, p);
9467 
9468         if (result)
9469             break;
9470     }
9471 
9472     if (pn)
9473         *pn = n; // update index
9474     return result;
9475 }
9476 
9477 
toChars()9478 const char *Parameter::toChars()
9479 {
9480     return ident ? ident->toChars() : "__anonymous_param";
9481 }
9482 
9483 /*********************************
9484  * Compute covariance of parameters `this` and `p`
9485  * as determined by the storage classes of both.
9486  * Params:
9487  *  p = Parameter to compare with
9488  * Returns:
9489  *  true = `this` can be used in place of `p`
9490  *  false = nope
9491  */
isCovariant(bool returnByRef,const Parameter * p)9492 bool Parameter::isCovariant(bool returnByRef, const Parameter *p) const
9493 {
9494     const StorageClass stc = STCref | STCin | STCout | STClazy;
9495     if ((this->storageClass & stc) != (p->storageClass & stc))
9496         return false;
9497 
9498     return isCovariantScope(returnByRef, this->storageClass, p->storageClass);
9499 }
9500 
isCovariantScope(bool returnByRef,StorageClass from,StorageClass to)9501 bool Parameter::isCovariantScope(bool returnByRef, StorageClass from, StorageClass to)
9502 {
9503     if (from == to)
9504         return true;
9505 
9506     struct SR
9507     {
9508         /* Classification of 'scope-return-ref' possibilities
9509         */
9510         enum
9511         {
9512             SRNone,
9513             SRScope,
9514             SRReturnScope,
9515             SRRef,
9516             SRReturnRef,
9517             SRRefScope,
9518             SRReturnRef_Scope,
9519             SRRef_ReturnScope,
9520             SRMAX,
9521         };
9522 
9523         /* Shrinking the representation is necessary because StorageClass is so wide
9524          * Params:
9525          *   returnByRef = true if the function returns by ref
9526          *   stc = storage class of parameter
9527          */
9528         static unsigned buildSR(bool returnByRef, StorageClass stc)
9529         {
9530             unsigned result;
9531             StorageClass stc2 = stc & (STCref | STCscope | STCreturn);
9532             if (stc2 == 0)
9533                 result = SRNone;
9534             else if (stc2 == STCref)
9535                 result = SRRef;
9536             else if (stc2 == STCscope)
9537                 result = SRScope;
9538             else if (stc2 == (STCscope | STCreturn))
9539                 result = SRReturnScope;
9540             else if (stc2 == (STCref | STCreturn))
9541                 result = SRReturnRef;
9542             else if (stc2 == (STCscope | STCref))
9543                 result = SRRefScope;
9544             else if (stc2 == (STCscope | STCref | STCreturn))
9545                 result = returnByRef ? SRReturnRef_Scope : SRRef_ReturnScope;
9546             else
9547                 assert(0);
9548             return result;
9549         }
9550 
9551         static void covariantInit(bool covariant[SRMAX][SRMAX])
9552         {
9553             /* Initialize covariant[][] with this:
9554 
9555                  From\To           n   rs  s
9556                  None              X
9557                  ReturnScope       X   X
9558                  Scope             X   X   X
9559 
9560                  From\To           r   rr  rs  rr-s r-rs
9561                  Ref               X   X
9562                  ReturnRef             X
9563                  RefScope          X   X   X   X    X
9564                  ReturnRef-Scope       X       X
9565                  Ref-ReturnScope   X   X            X
9566             */
9567             for (int i = 0; i < SRMAX; i++)
9568             {
9569                 covariant[i][i] = true;
9570                 covariant[SRRefScope][i] = true;
9571             }
9572             covariant[SRReturnScope][SRNone]        = true;
9573             covariant[SRScope      ][SRNone]        = true;
9574             covariant[SRScope      ][SRReturnScope] = true;
9575 
9576             covariant[SRRef            ][SRReturnRef] = true;
9577             covariant[SRReturnRef_Scope][SRReturnRef] = true;
9578             covariant[SRRef_ReturnScope][SRRef      ] = true;
9579             covariant[SRRef_ReturnScope][SRReturnRef] = true;
9580         }
9581     };
9582 
9583     /* result is true if the 'from' can be used as a 'to'
9584      */
9585 
9586     if ((from ^ to) & STCref)               // differing in 'ref' means no covariance
9587         return false;
9588 
9589     static bool covariant[SR::SRMAX][SR::SRMAX];
9590     static bool init = false;
9591     if (!init)
9592     {
9593         SR::covariantInit(covariant);
9594         init = true;
9595     }
9596 
9597     return covariant[SR::buildSR(returnByRef, from)][SR::buildSR(returnByRef, to)];
9598 }
9599