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