d: Fix missing call to va_end in getMatchError [PR99917]
[official-gcc.git] / gcc / d / dmd / mtype.c
blob1c73f50c205d222181d75b8e1f0a903a8649c214
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2021 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 */
11 #include "root/dsystem.h"
12 #include "root/checkedint.h"
13 #include "root/rmem.h"
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"
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 *typeToExpression(Type *t);
41 Expression *typeToExpressionHelper(TypeQualified *t, Expression *e, size_t i = 0);
42 RootObject *compileTypeMixin(TypeMixin *tm, Loc loc, Scope *sc);
44 /***************************** Type *****************************/
46 ClassDeclaration *Type::dtypeinfo;
47 ClassDeclaration *Type::typeinfoclass;
48 ClassDeclaration *Type::typeinfointerface;
49 ClassDeclaration *Type::typeinfostruct;
50 ClassDeclaration *Type::typeinfopointer;
51 ClassDeclaration *Type::typeinfoarray;
52 ClassDeclaration *Type::typeinfostaticarray;
53 ClassDeclaration *Type::typeinfoassociativearray;
54 ClassDeclaration *Type::typeinfovector;
55 ClassDeclaration *Type::typeinfoenum;
56 ClassDeclaration *Type::typeinfofunction;
57 ClassDeclaration *Type::typeinfodelegate;
58 ClassDeclaration *Type::typeinfotypelist;
59 ClassDeclaration *Type::typeinfoconst;
60 ClassDeclaration *Type::typeinfoinvariant;
61 ClassDeclaration *Type::typeinfoshared;
62 ClassDeclaration *Type::typeinfowild;
64 TemplateDeclaration *Type::rtinfo;
66 Type *Type::tvoid;
67 Type *Type::tint8;
68 Type *Type::tuns8;
69 Type *Type::tint16;
70 Type *Type::tuns16;
71 Type *Type::tint32;
72 Type *Type::tuns32;
73 Type *Type::tint64;
74 Type *Type::tuns64;
75 Type *Type::tint128;
76 Type *Type::tuns128;
77 Type *Type::tfloat32;
78 Type *Type::tfloat64;
79 Type *Type::tfloat80;
81 Type *Type::timaginary32;
82 Type *Type::timaginary64;
83 Type *Type::timaginary80;
85 Type *Type::tcomplex32;
86 Type *Type::tcomplex64;
87 Type *Type::tcomplex80;
89 Type *Type::tbool;
90 Type *Type::tchar;
91 Type *Type::twchar;
92 Type *Type::tdchar;
94 Type *Type::tshiftcnt;
95 Type *Type::terror;
96 Type *Type::tnull;
97 Type *Type::tnoreturn;
99 Type *Type::tsize_t;
100 Type *Type::tptrdiff_t;
101 Type *Type::thash_t;
103 Type *Type::tvoidptr;
104 Type *Type::tstring;
105 Type *Type::twstring;
106 Type *Type::tdstring;
107 Type *Type::basic[TMAX];
108 unsigned char Type::sizeTy[TMAX];
109 StringTable Type::stringtable;
111 void initTypeMangle();
113 Type::Type(TY ty)
115 this->ty = ty;
116 this->mod = 0;
117 this->deco = NULL;
118 this->cto = NULL;
119 this->ito = NULL;
120 this->sto = NULL;
121 this->scto = NULL;
122 this->wto = NULL;
123 this->wcto = NULL;
124 this->swto = NULL;
125 this->swcto = NULL;
126 this->pto = NULL;
127 this->rto = NULL;
128 this->arrayof = NULL;
129 this->vtinfo = NULL;
130 this->ctype = NULL;
133 const char *Type::kind()
135 assert(false); // should be overridden
136 return NULL;
139 Type *Type::copy()
141 void *pt = mem.xmalloc(sizeTy[ty]);
142 Type *t = (Type *)memcpy(pt, (void *)this, sizeTy[ty]);
143 return t;
146 Type *Type::syntaxCopy()
148 print();
149 fprintf(stderr, "ty = %d\n", ty);
150 assert(0);
151 return this;
154 bool Type::equals(RootObject *o)
156 Type *t = (Type *)o;
157 //printf("Type::equals(%s, %s)\n", toChars(), t->toChars());
158 // deco strings are unique
159 // and semantic() has been run
160 if (this == o || ((t && deco == t->deco) && deco != NULL))
162 //printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
163 return true;
165 //if (deco && t && t->deco) printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
166 return false;
169 bool Type::equivalent(Type *t)
171 return immutableOf()->equals(t->immutableOf());
174 void Type::_init()
176 stringtable._init(14000);
178 for (size_t i = 0; i < TMAX; i++)
179 sizeTy[i] = sizeof(TypeBasic);
180 sizeTy[Tsarray] = sizeof(TypeSArray);
181 sizeTy[Tarray] = sizeof(TypeDArray);
182 sizeTy[Taarray] = sizeof(TypeAArray);
183 sizeTy[Tpointer] = sizeof(TypePointer);
184 sizeTy[Treference] = sizeof(TypeReference);
185 sizeTy[Tfunction] = sizeof(TypeFunction);
186 sizeTy[Tdelegate] = sizeof(TypeDelegate);
187 sizeTy[Tident] = sizeof(TypeIdentifier);
188 sizeTy[Tinstance] = sizeof(TypeInstance);
189 sizeTy[Ttypeof] = sizeof(TypeTypeof);
190 sizeTy[Tenum] = sizeof(TypeEnum);
191 sizeTy[Tstruct] = sizeof(TypeStruct);
192 sizeTy[Tclass] = sizeof(TypeClass);
193 sizeTy[Ttuple] = sizeof(TypeTuple);
194 sizeTy[Tslice] = sizeof(TypeSlice);
195 sizeTy[Treturn] = sizeof(TypeReturn);
196 sizeTy[Terror] = sizeof(TypeError);
197 sizeTy[Tnull] = sizeof(TypeNull);
198 sizeTy[Tvector] = sizeof(TypeVector);
199 sizeTy[Ttraits] = sizeof(TypeTraits);
200 sizeTy[Tmixin] = sizeof(TypeMixin);
201 sizeTy[Tnoreturn] = sizeof(TypeNoreturn);
203 initTypeMangle();
205 // Set basic types
206 static TY basetab[] =
207 { Tvoid, Tint8, Tuns8, Tint16, Tuns16, Tint32, Tuns32, Tint64, Tuns64,
208 Tint128, Tuns128,
209 Tfloat32, Tfloat64, Tfloat80,
210 Timaginary32, Timaginary64, Timaginary80,
211 Tcomplex32, Tcomplex64, Tcomplex80,
212 Tbool,
213 Tchar, Twchar, Tdchar, Terror };
215 for (size_t i = 0; basetab[i] != Terror; i++)
217 Type *t = new TypeBasic(basetab[i]);
218 t = t->merge();
219 basic[basetab[i]] = t;
221 basic[Terror] = new TypeError();
223 tnoreturn = new TypeNoreturn();
224 tnoreturn->deco = tnoreturn->merge()->deco;
225 basic[Tnoreturn] = tnoreturn;
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];
242 timaginary32 = basic[Timaginary32];
243 timaginary64 = basic[Timaginary64];
244 timaginary80 = basic[Timaginary80];
246 tcomplex32 = basic[Tcomplex32];
247 tcomplex64 = basic[Tcomplex64];
248 tcomplex80 = basic[Tcomplex80];
250 tbool = basic[Tbool];
251 tchar = basic[Tchar];
252 twchar = basic[Twchar];
253 tdchar = basic[Tdchar];
255 tshiftcnt = tint32;
256 terror = basic[Terror];
257 tnoreturn = basic[Tnoreturn];
258 tnull = new TypeNull();
259 tnull->deco = tnull->merge()->deco;
261 tvoidptr = tvoid->pointerTo();
262 tstring = tchar->immutableOf()->arrayOf();
263 twstring = twchar->immutableOf()->arrayOf();
264 tdstring = tdchar->immutableOf()->arrayOf();
266 const bool isLP64 = global.params.isLP64;
268 tsize_t = basic[isLP64 ? Tuns64 : Tuns32];
269 tptrdiff_t = basic[isLP64 ? Tint64 : Tint32];
270 thash_t = tsize_t;
273 d_uns64 Type::size()
275 return size(Loc());
278 d_uns64 Type::size(Loc loc)
280 error(loc, "no size for type %s", toChars());
281 return SIZE_INVALID;
284 unsigned Type::alignsize()
286 return (unsigned)size(Loc());
289 Type *Type::trySemantic(Loc loc, Scope *sc)
291 //printf("+trySemantic(%s) %d\n", toChars(), global.errors);
292 unsigned errors = global.startGagging();
293 Type *t = typeSemantic(this, loc, sc);
294 if (global.endGagging(errors) || t->ty == Terror) // if any errors happened
296 t = NULL;
298 //printf("-trySemantic(%s) %d\n", toChars(), global.errors);
299 return t;
302 /********************************
303 * Return a copy of this type with all attributes null-initialized.
304 * Useful for creating a type with different modifiers.
307 Type *Type::nullAttributes()
309 unsigned sz = sizeTy[ty];
310 void *pt = mem.xmalloc(sz);
311 Type *t = (Type *)memcpy(pt, (void *)this, sz);
312 t->deco = NULL;
313 t->arrayof = NULL;
314 t->pto = NULL;
315 t->rto = NULL;
316 t->cto = NULL;
317 t->ito = NULL;
318 t->sto = NULL;
319 t->scto = NULL;
320 t->wto = NULL;
321 t->wcto = NULL;
322 t->swto = NULL;
323 t->swcto = NULL;
324 t->vtinfo = NULL;
325 t->ctype = NULL;
326 if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref;
327 if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref;
328 return t;
331 /********************************
332 * Convert to 'const'.
335 Type *Type::constOf()
337 //printf("Type::constOf() %p %s\n", this, toChars());
338 if (mod == MODconst)
339 return this;
340 if (cto)
342 assert(cto->mod == MODconst);
343 return cto;
345 Type *t = makeConst();
346 t = t->merge();
347 t->fixTo(this);
348 //printf("-Type::constOf() %p %s\n", t, t->toChars());
349 return t;
352 /********************************
353 * Convert to 'immutable'.
356 Type *Type::immutableOf()
358 //printf("Type::immutableOf() %p %s\n", this, toChars());
359 if (isImmutable())
360 return this;
361 if (ito)
363 assert(ito->isImmutable());
364 return ito;
366 Type *t = makeImmutable();
367 t = t->merge();
368 t->fixTo(this);
369 //printf("\t%p\n", t);
370 return t;
373 /********************************
374 * Make type mutable.
377 Type *Type::mutableOf()
379 //printf("Type::mutableOf() %p, %s\n", this, toChars());
380 Type *t = this;
381 if (isImmutable())
383 t = ito; // immutable => naked
384 assert(!t || (t->isMutable() && !t->isShared()));
386 else if (isConst())
388 if (isShared())
390 if (isWild())
391 t = swcto; // shared wild const -> shared
392 else
393 t = sto; // shared const => shared
395 else
397 if (isWild())
398 t = wcto; // wild const -> naked
399 else
400 t = cto; // const => naked
402 assert(!t || t->isMutable());
404 else if (isWild())
406 if (isShared())
407 t = sto; // shared wild => shared
408 else
409 t = wto; // wild => naked
410 assert(!t || t->isMutable());
412 if (!t)
414 t = makeMutable();
415 t = t->merge();
416 t->fixTo(this);
418 else
419 t = t->merge();
420 assert(t->isMutable());
421 return t;
424 Type *Type::sharedOf()
426 //printf("Type::sharedOf() %p, %s\n", this, toChars());
427 if (mod == MODshared)
428 return this;
429 if (sto)
431 assert(sto->mod == MODshared);
432 return sto;
434 Type *t = makeShared();
435 t = t->merge();
436 t->fixTo(this);
437 //printf("\t%p\n", t);
438 return t;
441 Type *Type::sharedConstOf()
443 //printf("Type::sharedConstOf() %p, %s\n", this, toChars());
444 if (mod == (MODshared | MODconst))
445 return this;
446 if (scto)
448 assert(scto->mod == (MODshared | MODconst));
449 return scto;
451 Type *t = makeSharedConst();
452 t = t->merge();
453 t->fixTo(this);
454 //printf("\t%p\n", t);
455 return t;
459 /********************************
460 * Make type unshared.
461 * 0 => 0
462 * const => const
463 * immutable => immutable
464 * shared => 0
465 * shared const => const
466 * wild => wild
467 * wild const => wild const
468 * shared wild => wild
469 * shared wild const => wild const
472 Type *Type::unSharedOf()
474 //printf("Type::unSharedOf() %p, %s\n", this, toChars());
475 Type *t = this;
477 if (isShared())
479 if (isWild())
481 if (isConst())
482 t = wcto; // shared wild const => wild const
483 else
484 t = wto; // shared wild => wild
486 else
488 if (isConst())
489 t = cto; // shared const => const
490 else
491 t = sto; // shared => naked
493 assert(!t || !t->isShared());
496 if (!t)
498 t = this->nullAttributes();
499 t->mod = mod & ~MODshared;
500 t->ctype = ctype;
501 t = t->merge();
503 t->fixTo(this);
505 else
506 t = t->merge();
507 assert(!t->isShared());
508 return t;
511 /********************************
512 * Convert to 'wild'.
515 Type *Type::wildOf()
517 //printf("Type::wildOf() %p %s\n", this, toChars());
518 if (mod == MODwild)
519 return this;
520 if (wto)
522 assert(wto->mod == MODwild);
523 return wto;
525 Type *t = makeWild();
526 t = t->merge();
527 t->fixTo(this);
528 //printf("\t%p %s\n", t, t->toChars());
529 return t;
532 Type *Type::wildConstOf()
534 //printf("Type::wildConstOf() %p %s\n", this, toChars());
535 if (mod == MODwildconst)
536 return this;
537 if (wcto)
539 assert(wcto->mod == MODwildconst);
540 return wcto;
542 Type *t = makeWildConst();
543 t = t->merge();
544 t->fixTo(this);
545 //printf("\t%p %s\n", t, t->toChars());
546 return t;
549 Type *Type::sharedWildOf()
551 //printf("Type::sharedWildOf() %p, %s\n", this, toChars());
552 if (mod == (MODshared | MODwild))
553 return this;
554 if (swto)
556 assert(swto->mod == (MODshared | MODwild));
557 return swto;
559 Type *t = makeSharedWild();
560 t = t->merge();
561 t->fixTo(this);
562 //printf("\t%p %s\n", t, t->toChars());
563 return t;
566 Type *Type::sharedWildConstOf()
568 //printf("Type::sharedWildConstOf() %p, %s\n", this, toChars());
569 if (mod == (MODshared | MODwildconst))
570 return this;
571 if (swcto)
573 assert(swcto->mod == (MODshared | MODwildconst));
574 return swcto;
576 Type *t = makeSharedWildConst();
577 t = t->merge();
578 t->fixTo(this);
579 //printf("\t%p %s\n", t, t->toChars());
580 return t;
583 /**********************************
584 * For our new type 'this', which is type-constructed from t,
585 * fill in the cto, ito, sto, scto, wto shortcuts.
588 void Type::fixTo(Type *t)
590 // If fixing this: immutable(T*) by t: immutable(T)*,
591 // cache t to this->xto won't break transitivity.
592 Type *mto = NULL;
593 Type *tn = nextOf();
594 if (!tn || (ty != Tsarray && tn->mod == t->nextOf()->mod))
596 switch (t->mod)
598 case 0: mto = t; break;
599 case MODconst: cto = t; break;
600 case MODwild: wto = t; break;
601 case MODwildconst: wcto = t; break;
602 case MODshared: sto = t; break;
603 case MODshared | MODconst: scto = t; break;
604 case MODshared | MODwild: swto = t; break;
605 case MODshared | MODwildconst: swcto = t; break;
606 case MODimmutable: ito = t; break;
610 assert(mod != t->mod);
611 #define X(m, n) (((m) << 4) | (n))
612 switch (mod)
614 case 0:
615 break;
617 case MODconst:
618 cto = mto;
619 t->cto = this;
620 break;
622 case MODwild:
623 wto = mto;
624 t->wto = this;
625 break;
627 case MODwildconst:
628 wcto = mto;
629 t->wcto = this;
630 break;
632 case MODshared:
633 sto = mto;
634 t->sto = this;
635 break;
637 case MODshared | MODconst:
638 scto = mto;
639 t->scto = this;
640 break;
642 case MODshared | MODwild:
643 swto = mto;
644 t->swto = this;
645 break;
647 case MODshared | MODwildconst:
648 swcto = mto;
649 t->swcto = this;
650 break;
652 case MODimmutable:
653 t->ito = this;
654 if (t-> cto) t-> cto->ito = this;
655 if (t-> sto) t-> sto->ito = this;
656 if (t-> scto) t-> scto->ito = this;
657 if (t-> wto) t-> wto->ito = this;
658 if (t-> wcto) t-> wcto->ito = this;
659 if (t-> swto) t-> swto->ito = this;
660 if (t->swcto) t->swcto->ito = this;
661 break;
663 default:
664 assert(0);
666 #undef X
668 check();
669 t->check();
670 //printf("fixTo: %s, %s\n", toChars(), t->toChars());
673 /***************************
674 * Look for bugs in constructing types.
677 void Type::check()
679 switch (mod)
681 case 0:
682 if (cto) assert(cto->mod == MODconst);
683 if (ito) assert(ito->mod == MODimmutable);
684 if (sto) assert(sto->mod == MODshared);
685 if (scto) assert(scto->mod == (MODshared | MODconst));
686 if (wto) assert(wto->mod == MODwild);
687 if (wcto) assert(wcto->mod == MODwildconst);
688 if (swto) assert(swto->mod == (MODshared | MODwild));
689 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
690 break;
692 case MODconst:
693 if (cto) assert(cto->mod == 0);
694 if (ito) assert(ito->mod == MODimmutable);
695 if (sto) assert(sto->mod == MODshared);
696 if (scto) assert(scto->mod == (MODshared | MODconst));
697 if (wto) assert(wto->mod == MODwild);
698 if (wcto) assert(wcto->mod == MODwildconst);
699 if (swto) assert(swto->mod == (MODshared | MODwild));
700 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
701 break;
703 case MODwild:
704 if (cto) assert(cto->mod == MODconst);
705 if (ito) assert(ito->mod == MODimmutable);
706 if (sto) assert(sto->mod == MODshared);
707 if (scto) assert(scto->mod == (MODshared | MODconst));
708 if (wto) assert(wto->mod == 0);
709 if (wcto) assert(wcto->mod == MODwildconst);
710 if (swto) assert(swto->mod == (MODshared | MODwild));
711 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
712 break;
714 case MODwildconst:
715 assert(! cto || cto->mod == MODconst);
716 assert(! ito || ito->mod == MODimmutable);
717 assert(! sto || sto->mod == MODshared);
718 assert(! scto || scto->mod == (MODshared | MODconst));
719 assert(! wto || wto->mod == MODwild);
720 assert(! wcto || wcto->mod == 0);
721 assert(! swto || swto->mod == (MODshared | MODwild));
722 assert(!swcto || swcto->mod == (MODshared | MODwildconst));
723 break;
725 case MODshared:
726 if (cto) assert(cto->mod == MODconst);
727 if (ito) assert(ito->mod == MODimmutable);
728 if (sto) assert(sto->mod == 0);
729 if (scto) assert(scto->mod == (MODshared | MODconst));
730 if (wto) assert(wto->mod == MODwild);
731 if (wcto) assert(wcto->mod == MODwildconst);
732 if (swto) assert(swto->mod == (MODshared | MODwild));
733 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
734 break;
736 case MODshared | MODconst:
737 if (cto) assert(cto->mod == MODconst);
738 if (ito) assert(ito->mod == MODimmutable);
739 if (sto) assert(sto->mod == MODshared);
740 if (scto) assert(scto->mod == 0);
741 if (wto) assert(wto->mod == MODwild);
742 if (wcto) assert(wcto->mod == MODwildconst);
743 if (swto) assert(swto->mod == (MODshared | MODwild));
744 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
745 break;
747 case MODshared | MODwild:
748 if (cto) assert(cto->mod == MODconst);
749 if (ito) assert(ito->mod == MODimmutable);
750 if (sto) assert(sto->mod == MODshared);
751 if (scto) assert(scto->mod == (MODshared | MODconst));
752 if (wto) assert(wto->mod == MODwild);
753 if (wcto) assert(wcto->mod == MODwildconst);
754 if (swto) assert(swto->mod == 0);
755 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
756 break;
758 case MODshared | MODwildconst:
759 assert(! cto || cto->mod == MODconst);
760 assert(! ito || ito->mod == MODimmutable);
761 assert(! sto || sto->mod == MODshared);
762 assert(! scto || scto->mod == (MODshared | MODconst));
763 assert(! wto || wto->mod == MODwild);
764 assert(! wcto || wcto->mod == MODwildconst);
765 assert(! swto || swto->mod == (MODshared | MODwild));
766 assert(!swcto || swcto->mod == 0);
767 break;
769 case MODimmutable:
770 if (cto) assert(cto->mod == MODconst);
771 if (ito) assert(ito->mod == 0);
772 if (sto) assert(sto->mod == MODshared);
773 if (scto) assert(scto->mod == (MODshared | MODconst));
774 if (wto) assert(wto->mod == MODwild);
775 if (wcto) assert(wcto->mod == MODwildconst);
776 if (swto) assert(swto->mod == (MODshared | MODwild));
777 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
778 break;
780 default:
781 assert(0);
784 Type *tn = nextOf();
785 if (tn && ty != Tfunction && tn->ty != Tfunction && ty != Tenum)
787 // Verify transitivity
788 switch (mod)
790 case 0:
791 case MODconst:
792 case MODwild:
793 case MODwildconst:
794 case MODshared:
795 case MODshared | MODconst:
796 case MODshared | MODwild:
797 case MODshared | MODwildconst:
798 case MODimmutable:
799 assert(tn->mod == MODimmutable || (tn->mod & mod) == mod);
800 break;
802 default:
803 assert(0);
805 tn->check();
809 Type *Type::makeConst()
811 //printf("Type::makeConst() %p, %s\n", this, toChars());
812 if (cto) return cto;
813 Type *t = this->nullAttributes();
814 t->mod = MODconst;
815 //printf("-Type::makeConst() %p, %s\n", t, toChars());
816 return t;
819 Type *Type::makeImmutable()
821 if (ito) return ito;
822 Type *t = this->nullAttributes();
823 t->mod = MODimmutable;
824 return t;
827 Type *Type::makeShared()
829 if (sto) return sto;
830 Type *t = this->nullAttributes();
831 t->mod = MODshared;
832 return t;
835 Type *Type::makeSharedConst()
837 if (scto) return scto;
838 Type *t = this->nullAttributes();
839 t->mod = MODshared | MODconst;
840 return t;
843 Type *Type::makeWild()
845 if (wto) return wto;
846 Type *t = this->nullAttributes();
847 t->mod = MODwild;
848 return t;
851 Type *Type::makeWildConst()
853 if (wcto) return wcto;
854 Type *t = this->nullAttributes();
855 t->mod = MODwildconst;
856 return t;
859 Type *Type::makeSharedWild()
861 if (swto) return swto;
862 Type *t = this->nullAttributes();
863 t->mod = MODshared | MODwild;
864 return t;
867 Type *Type::makeSharedWildConst()
869 if (swcto) return swcto;
870 Type *t = this->nullAttributes();
871 t->mod = MODshared | MODwildconst;
872 return t;
875 Type *Type::makeMutable()
877 Type *t = this->nullAttributes();
878 t->mod = mod & MODshared;
879 return t;
882 /*************************************
883 * Apply STCxxxx bits to existing type.
884 * Use *before* semantic analysis is run.
887 Type *Type::addSTC(StorageClass stc)
889 Type *t = this;
890 if (t->isImmutable())
892 else if (stc & STCimmutable)
894 t = t->makeImmutable();
896 else
898 if ((stc & STCshared) && !t->isShared())
900 if (t->isWild())
902 if (t->isConst())
903 t = t->makeSharedWildConst();
904 else
905 t = t->makeSharedWild();
907 else
909 if (t->isConst())
910 t = t->makeSharedConst();
911 else
912 t = t->makeShared();
915 if ((stc & STCconst) && !t->isConst())
917 if (t->isShared())
919 if (t->isWild())
920 t = t->makeSharedWildConst();
921 else
922 t = t->makeSharedConst();
924 else
926 if (t->isWild())
927 t = t->makeWildConst();
928 else
929 t = t->makeConst();
932 if ((stc & STCwild) && !t->isWild())
934 if (t->isShared())
936 if (t->isConst())
937 t = t->makeSharedWildConst();
938 else
939 t = t->makeSharedWild();
941 else
943 if (t->isConst())
944 t = t->makeWildConst();
945 else
946 t = t->makeWild();
950 return t;
953 /************************************
954 * Convert MODxxxx to STCxxx
957 StorageClass ModToStc(unsigned mod)
959 StorageClass stc = 0;
960 if (mod & MODimmutable) stc |= STCimmutable;
961 if (mod & MODconst) stc |= STCconst;
962 if (mod & MODwild) stc |= STCwild;
963 if (mod & MODshared) stc |= STCshared;
964 return stc;
967 /************************************
968 * Apply MODxxxx bits to existing type.
971 Type *Type::castMod(MOD mod)
972 { Type *t;
974 switch (mod)
976 case 0:
977 t = unSharedOf()->mutableOf();
978 break;
980 case MODconst:
981 t = unSharedOf()->constOf();
982 break;
984 case MODwild:
985 t = unSharedOf()->wildOf();
986 break;
988 case MODwildconst:
989 t = unSharedOf()->wildConstOf();
990 break;
992 case MODshared:
993 t = mutableOf()->sharedOf();
994 break;
996 case MODshared | MODconst:
997 t = sharedConstOf();
998 break;
1000 case MODshared | MODwild:
1001 t = sharedWildOf();
1002 break;
1004 case MODshared | MODwildconst:
1005 t = sharedWildConstOf();
1006 break;
1008 case MODimmutable:
1009 t = immutableOf();
1010 break;
1012 default:
1013 assert(0);
1015 return t;
1018 /************************************
1019 * Add MODxxxx bits to existing type.
1020 * We're adding, not replacing, so adding const to
1021 * a shared type => "shared const"
1024 Type *Type::addMod(MOD mod)
1026 /* Add anything to immutable, and it remains immutable
1028 Type *t = this;
1029 if (!t->isImmutable())
1031 //printf("addMod(%x) %s\n", mod, toChars());
1032 switch (mod)
1034 case 0:
1035 break;
1037 case MODconst:
1038 if (isShared())
1040 if (isWild())
1041 t = sharedWildConstOf();
1042 else
1043 t = sharedConstOf();
1045 else
1047 if (isWild())
1048 t = wildConstOf();
1049 else
1050 t = constOf();
1052 break;
1054 case MODwild:
1055 if (isShared())
1057 if (isConst())
1058 t = sharedWildConstOf();
1059 else
1060 t = sharedWildOf();
1062 else
1064 if (isConst())
1065 t = wildConstOf();
1066 else
1067 t = wildOf();
1069 break;
1071 case MODwildconst:
1072 if (isShared())
1073 t = sharedWildConstOf();
1074 else
1075 t = wildConstOf();
1076 break;
1078 case MODshared:
1079 if (isWild())
1081 if (isConst())
1082 t = sharedWildConstOf();
1083 else
1084 t = sharedWildOf();
1086 else
1088 if (isConst())
1089 t = sharedConstOf();
1090 else
1091 t = sharedOf();
1093 break;
1095 case MODshared | MODconst:
1096 if (isWild())
1097 t = sharedWildConstOf();
1098 else
1099 t = sharedConstOf();
1100 break;
1102 case MODshared | MODwild:
1103 if (isConst())
1104 t = sharedWildConstOf();
1105 else
1106 t = sharedWildOf();
1107 break;
1109 case MODshared | MODwildconst:
1110 t = sharedWildConstOf();
1111 break;
1113 case MODimmutable:
1114 t = immutableOf();
1115 break;
1117 default:
1118 assert(0);
1121 return t;
1124 /************************************
1125 * Add storage class modifiers to type.
1128 Type *Type::addStorageClass(StorageClass stc)
1130 /* Just translate to MOD bits and let addMod() do the work
1132 MOD mod = 0;
1134 if (stc & STCimmutable)
1135 mod = MODimmutable;
1136 else
1138 if (stc & (STCconst | STCin))
1139 mod |= MODconst;
1140 if (stc & STCwild)
1141 mod |= MODwild;
1142 if (stc & STCshared)
1143 mod |= MODshared;
1145 return addMod(mod);
1148 Type *Type::pointerTo()
1150 if (ty == Terror)
1151 return this;
1152 if (!pto)
1154 Type *t = new TypePointer(this);
1155 if (ty == Tfunction)
1157 t->deco = t->merge()->deco;
1158 pto = t;
1160 else
1161 pto = t->merge();
1163 return pto;
1166 Type *Type::referenceTo()
1168 if (ty == Terror)
1169 return this;
1170 if (!rto)
1172 Type *t = new TypeReference(this);
1173 rto = t->merge();
1175 return rto;
1178 Type *Type::arrayOf()
1180 if (ty == Terror)
1181 return this;
1182 if (!arrayof)
1184 Type *t = new TypeDArray(this);
1185 arrayof = t->merge();
1187 return arrayof;
1190 // Make corresponding static array type without semantic
1191 Type *Type::sarrayOf(dinteger_t dim)
1193 assert(deco);
1194 Type *t = new TypeSArray(this, new IntegerExp(Loc(), dim, Type::tsize_t));
1196 // according to TypeSArray::semantic()
1197 t = t->addMod(mod);
1198 t = t->merge();
1200 return t;
1203 Type *Type::aliasthisOf()
1205 AggregateDeclaration *ad = isAggregate(this);
1206 if (ad && ad->aliasthis)
1208 Dsymbol *s = ad->aliasthis;
1209 if (s->isAliasDeclaration())
1210 s = s->toAlias();
1211 Declaration *d = s->isDeclaration();
1212 if (d && !d->isTupleDeclaration())
1214 assert(d->type);
1215 Type *t = d->type;
1216 if (d->isVarDeclaration() && d->needThis())
1218 t = t->addMod(this->mod);
1220 else if (d->isFuncDeclaration())
1222 FuncDeclaration *fd = resolveFuncCall(Loc(), NULL, d, NULL, this, NULL, 1);
1223 if (fd && fd->errors)
1224 return Type::terror;
1225 if (fd && !fd->type->nextOf() && !fd->functionSemantic())
1226 fd = NULL;
1227 if (fd)
1229 t = fd->type->nextOf();
1230 if (!t) // issue 14185
1231 return Type::terror;
1232 t = t->substWildTo(mod == 0 ? MODmutable : (MODFlags)mod);
1234 else
1235 return Type::terror;
1237 return t;
1239 EnumDeclaration *ed = s->isEnumDeclaration();
1240 if (ed)
1242 Type *t = ed->type;
1243 return t;
1245 TemplateDeclaration *td = s->isTemplateDeclaration();
1246 if (td)
1248 assert(td->_scope);
1249 FuncDeclaration *fd = resolveFuncCall(Loc(), NULL, td, NULL, this, NULL, 1);
1250 if (fd && fd->errors)
1251 return Type::terror;
1252 if (fd && fd->functionSemantic())
1254 Type *t = fd->type->nextOf();
1255 t = t->substWildTo(mod == 0 ? MODmutable : (MODFlags)mod);
1256 return t;
1258 else
1259 return Type::terror;
1261 //printf("%s\n", s->kind());
1263 return NULL;
1266 bool Type::checkAliasThisRec()
1268 Type *tb = toBasetype();
1269 AliasThisRec* pflag;
1270 if (tb->ty == Tstruct)
1271 pflag = &((TypeStruct *)tb)->att;
1272 else if (tb->ty == Tclass)
1273 pflag = &((TypeClass *)tb)->att;
1274 else
1275 return false;
1277 AliasThisRec flag = (AliasThisRec)(*pflag & RECtypeMask);
1278 if (flag == RECfwdref)
1280 Type *att = aliasthisOf();
1281 flag = att && att->implicitConvTo(this) ? RECyes : RECno;
1283 *pflag = (AliasThisRec)(flag | (*pflag & ~RECtypeMask));
1284 return flag == RECyes;
1287 Dsymbol *Type::toDsymbol(Scope *)
1289 return NULL;
1292 /*******************************
1293 * If this is a shell around another type,
1294 * get that other type.
1297 Type *Type::toBasetype()
1299 return this;
1302 /***************************
1303 * Return !=0 if modfrom can be implicitly converted to modto
1305 bool MODimplicitConv(MOD modfrom, MOD modto)
1307 if (modfrom == modto)
1308 return true;
1310 //printf("MODimplicitConv(from = %x, to = %x)\n", modfrom, modto);
1311 #define X(m, n) (((m) << 4) | (n))
1312 switch (X(modfrom & ~MODshared, modto & ~MODshared))
1314 case X(0, MODconst):
1315 case X(MODwild, MODconst):
1316 case X(MODwild, MODwildconst):
1317 case X(MODwildconst, MODconst):
1318 return (modfrom & MODshared) == (modto & MODshared);
1320 case X(MODimmutable, MODconst):
1321 case X(MODimmutable, MODwildconst):
1322 return true;
1324 default:
1325 return false;
1327 #undef X
1330 /***************************
1331 * Return MATCHexact or MATCHconst if a method of type '() modfrom' can call a method of type '() modto'.
1333 MATCH MODmethodConv(MOD modfrom, MOD modto)
1335 if (modfrom == modto)
1336 return MATCHexact;
1337 if (MODimplicitConv(modfrom, modto))
1338 return MATCHconst;
1340 #define X(m, n) (((m) << 4) | (n))
1341 switch (X(modfrom, modto))
1343 case X(0, MODwild):
1344 case X(MODimmutable, MODwild):
1345 case X(MODconst, MODwild):
1346 case X(MODwildconst, MODwild):
1347 case X(MODshared, MODshared|MODwild):
1348 case X(MODshared|MODimmutable, MODshared|MODwild):
1349 case X(MODshared|MODconst, MODshared|MODwild):
1350 case X(MODshared|MODwildconst, MODshared|MODwild):
1351 return MATCHconst;
1353 default:
1354 return MATCHnomatch;
1356 #undef X
1359 /***************************
1360 * Merge mod bits to form common mod.
1362 MOD MODmerge(MOD mod1, MOD mod2)
1364 if (mod1 == mod2)
1365 return mod1;
1367 //printf("MODmerge(1 = %x, 2 = %x)\n", mod1, mod2);
1368 MOD result = 0;
1369 if ((mod1 | mod2) & MODshared)
1371 // If either type is shared, the result will be shared
1372 result |= MODshared;
1373 mod1 &= ~MODshared;
1374 mod2 &= ~MODshared;
1376 if (mod1 == 0 || mod1 == MODmutable || mod1 == MODconst ||
1377 mod2 == 0 || mod2 == MODmutable || mod2 == MODconst)
1379 // If either type is mutable or const, the result will be const.
1380 result |= MODconst;
1382 else
1384 // MODimmutable vs MODwild
1385 // MODimmutable vs MODwildconst
1386 // MODwild vs MODwildconst
1387 assert(mod1 & MODwild || mod2 & MODwild);
1388 result |= MODwildconst;
1390 return result;
1393 /*********************************
1394 * Store modifier name into buf.
1396 void MODtoBuffer(OutBuffer *buf, MOD mod)
1398 switch (mod)
1400 case 0:
1401 break;
1403 case MODimmutable:
1404 buf->writestring(Token::tochars[TOKimmutable]);
1405 break;
1407 case MODshared:
1408 buf->writestring(Token::tochars[TOKshared]);
1409 break;
1411 case MODshared | MODconst:
1412 buf->writestring(Token::tochars[TOKshared]);
1413 buf->writeByte(' ');
1414 /* fall through */
1415 case MODconst:
1416 buf->writestring(Token::tochars[TOKconst]);
1417 break;
1419 case MODshared | MODwild:
1420 buf->writestring(Token::tochars[TOKshared]);
1421 buf->writeByte(' ');
1422 /* fall through */
1423 case MODwild:
1424 buf->writestring(Token::tochars[TOKwild]);
1425 break;
1427 case MODshared | MODwildconst:
1428 buf->writestring(Token::tochars[TOKshared]);
1429 buf->writeByte(' ');
1430 /* fall through */
1431 case MODwildconst:
1432 buf->writestring(Token::tochars[TOKwild]);
1433 buf->writeByte(' ');
1434 buf->writestring(Token::tochars[TOKconst]);
1435 break;
1437 default:
1438 assert(0);
1443 /*********************************
1444 * Return modifier name.
1446 char *MODtoChars(MOD mod)
1448 OutBuffer buf;
1449 buf.reserve(16);
1450 MODtoBuffer(&buf, mod);
1451 return buf.extractChars();
1454 /********************************
1455 * For pretty-printing a type.
1458 const char *Type::toChars()
1460 OutBuffer buf;
1461 buf.reserve(16);
1462 HdrGenState hgs;
1463 hgs.fullQual = (ty == Tclass && !mod);
1465 ::toCBuffer(this, &buf, NULL, &hgs);
1466 return buf.extractChars();
1469 char *Type::toPrettyChars(bool QualifyTypes)
1471 OutBuffer buf;
1472 buf.reserve(16);
1473 HdrGenState hgs;
1474 hgs.fullQual = QualifyTypes;
1476 ::toCBuffer(this, &buf, NULL, &hgs);
1477 return buf.extractChars();
1480 /*********************************
1481 * Store this type's modifier name into buf.
1483 void Type::modToBuffer(OutBuffer *buf)
1485 if (mod)
1487 buf->writeByte(' ');
1488 MODtoBuffer(buf, mod);
1492 /*********************************
1493 * Return this type's modifier name.
1495 char *Type::modToChars()
1497 OutBuffer buf;
1498 buf.reserve(16);
1499 modToBuffer(&buf);
1500 return buf.extractChars();
1503 /** For each active modifier (MODconst, MODimmutable, etc) call fp with a
1504 void* for the work param and a string representation of the attribute. */
1505 int Type::modifiersApply(void *param, int (*fp)(void *, const char *))
1507 static unsigned char modsArr[] = { MODconst, MODimmutable, MODwild, MODshared };
1509 for (size_t idx = 0; idx < 4; ++idx)
1511 if (mod & modsArr[idx])
1513 if (int res = fp(param, MODtoChars(modsArr[idx])))
1514 return res;
1517 return 0;
1520 /************************************
1521 * Strip all parameter's idenfiers and their default arguments for merging types.
1522 * If some of parameter types or return type are function pointer, delegate, or
1523 * the types which contains either, then strip also from them.
1526 Type *stripDefaultArgs(Type *t)
1528 struct N
1530 static Parameters *stripParams(Parameters *parameters)
1532 Parameters *params = parameters;
1533 if (params && params->length > 0)
1535 for (size_t i = 0; i < params->length; i++)
1537 Parameter *p = (*params)[i];
1538 Type *ta = stripDefaultArgs(p->type);
1539 if (ta != p->type || p->defaultArg || p->ident || p->userAttribDecl)
1541 if (params == parameters)
1543 params = new Parameters();
1544 params->setDim(parameters->length);
1545 for (size_t j = 0; j < params->length; j++)
1546 (*params)[j] = (*parameters)[j];
1548 (*params)[i] = new Parameter(p->storageClass, ta, NULL, NULL, NULL);
1552 return params;
1556 if (t == NULL)
1557 return t;
1559 if (t->ty == Tfunction)
1561 TypeFunction *tf = (TypeFunction *)t;
1562 Type *tret = stripDefaultArgs(tf->next);
1563 Parameters *params = N::stripParams(tf->parameterList.parameters);
1564 if (tret == tf->next && params == tf->parameterList.parameters)
1565 goto Lnot;
1566 tf = (TypeFunction *)tf->copy();
1567 tf->parameterList.parameters = params;
1568 tf->next = tret;
1569 //printf("strip %s\n <- %s\n", tf->toChars(), t->toChars());
1570 t = tf;
1572 else if (t->ty == Ttuple)
1574 TypeTuple *tt = (TypeTuple *)t;
1575 Parameters *args = N::stripParams(tt->arguments);
1576 if (args == tt->arguments)
1577 goto Lnot;
1578 t = t->copy();
1579 ((TypeTuple *)t)->arguments = args;
1581 else if (t->ty == Tenum)
1583 // TypeEnum::nextOf() may be != NULL, but it's not necessary here.
1584 goto Lnot;
1586 else
1588 Type *tn = t->nextOf();
1589 Type *n = stripDefaultArgs(tn);
1590 if (n == tn)
1591 goto Lnot;
1592 t = t->copy();
1593 ((TypeNext *)t)->next = n;
1595 //printf("strip %s\n", t->toChars());
1596 Lnot:
1597 return t;
1600 /************************************
1603 Type *Type::merge()
1605 if (ty == Terror) return this;
1606 if (ty == Ttypeof) return this;
1607 if (ty == Tident) return this;
1608 if (ty == Tinstance) return this;
1609 if (ty == Taarray && !((TypeAArray *)this)->index->merge()->deco)
1610 return this;
1611 if (ty != Tenum && nextOf() && !nextOf()->deco)
1612 return this;
1614 //printf("merge(%s)\n", toChars());
1615 Type *t = this;
1616 assert(t);
1617 if (!deco)
1619 OutBuffer buf;
1620 buf.reserve(32);
1622 mangleToBuffer(this, &buf);
1624 StringValue *sv = stringtable.update((char *)buf.slice().ptr, buf.length());
1625 if (sv->ptrvalue)
1627 t = (Type *) sv->ptrvalue;
1628 assert(t->deco);
1629 //printf("old value, deco = '%s' %p\n", t->deco, t->deco);
1631 else
1633 sv->ptrvalue = (char *)(t = stripDefaultArgs(t));
1634 deco = t->deco = const_cast<char *>(sv->toDchars());
1635 //printf("new value, deco = '%s' %p\n", t->deco, t->deco);
1638 return t;
1641 /*************************************
1642 * This version does a merge even if the deco is already computed.
1643 * Necessary for types that have a deco, but are not merged.
1645 Type *Type::merge2()
1647 //printf("merge2(%s)\n", toChars());
1648 Type *t = this;
1649 assert(t);
1650 if (!t->deco)
1651 return t->merge();
1653 StringValue *sv = stringtable.lookup((char *)t->deco, strlen(t->deco));
1654 if (sv && sv->ptrvalue)
1655 { t = (Type *) sv->ptrvalue;
1656 assert(t->deco);
1658 else
1659 assert(0);
1660 return t;
1663 bool Type::isintegral()
1665 return false;
1668 bool Type::isfloating()
1670 return false;
1673 bool Type::isreal()
1675 return false;
1678 bool Type::isimaginary()
1680 return false;
1683 bool Type::iscomplex()
1685 return false;
1688 bool Type::isscalar()
1690 return false;
1693 bool Type::isunsigned()
1695 return false;
1698 ClassDeclaration *Type::isClassHandle()
1700 return NULL;
1703 bool Type::isscope()
1705 return false;
1708 bool Type::isString()
1710 return false;
1713 /**************************
1714 * When T is mutable,
1715 * Given:
1716 * T a, b;
1717 * Can we bitwise assign:
1718 * a = b;
1721 bool Type::isAssignable()
1723 return true;
1726 /**************************
1727 * Returns true if T can be converted to boolean value.
1729 bool Type::isBoolean()
1731 return isscalar();
1734 /********************************
1735 * true if when type goes out of scope, it needs a destructor applied.
1736 * Only applies to value types, not ref types.
1738 bool Type::needsDestruction()
1740 return false;
1743 /*********************************
1747 bool Type::needsNested()
1749 return false;
1752 /*********************************
1753 * Check type to see if it is based on a deprecated symbol.
1756 void Type::checkDeprecated(Loc loc, Scope *sc)
1758 if (Dsymbol *s = toDsymbol(sc))
1760 s->checkDeprecated(loc, sc);
1765 Expression *Type::defaultInit(Loc)
1767 return NULL;
1770 /***************************************
1771 * Use when we prefer the default initializer to be a literal,
1772 * rather than a global immutable variable.
1774 Expression *Type::defaultInitLiteral(Loc loc)
1776 return defaultInit(loc);
1779 bool Type::isZeroInit(Loc)
1781 return false; // assume not
1784 bool Type::isBaseOf(Type *, int *)
1786 return 0; // assume not
1789 /********************************
1790 * Determine if 'this' can be implicitly converted
1791 * to type 'to'.
1792 * Returns:
1793 * MATCHnomatch, MATCHconvert, MATCHconst, MATCHexact
1796 MATCH Type::implicitConvTo(Type *to)
1798 //printf("Type::implicitConvTo(this=%p, to=%p)\n", this, to);
1799 //printf("from: %s\n", toChars());
1800 //printf("to : %s\n", to->toChars());
1801 if (this->equals(to))
1802 return MATCHexact;
1803 return MATCHnomatch;
1806 /*******************************
1807 * Determine if converting 'this' to 'to' is an identity operation,
1808 * a conversion to const operation, or the types aren't the same.
1809 * Returns:
1810 * MATCHexact 'this' == 'to'
1811 * MATCHconst 'to' is const
1812 * MATCHnomatch conversion to mutable or invariant
1815 MATCH Type::constConv(Type *to)
1817 //printf("Type::constConv(this = %s, to = %s)\n", toChars(), to->toChars());
1818 if (equals(to))
1819 return MATCHexact;
1820 if (ty == to->ty && MODimplicitConv(mod, to->mod))
1821 return MATCHconst;
1822 return MATCHnomatch;
1825 /***************************************
1826 * Return MOD bits matching this type to wild parameter type (tprm).
1829 unsigned char Type::deduceWild(Type *t, bool)
1831 //printf("Type::deduceWild this = '%s', tprm = '%s'\n", toChars(), tprm->toChars());
1833 if (t->isWild())
1835 if (isImmutable())
1836 return MODimmutable;
1837 else if (isWildConst())
1839 if (t->isWildConst())
1840 return MODwild;
1841 else
1842 return MODwildconst;
1844 else if (isWild())
1845 return MODwild;
1846 else if (isConst())
1847 return MODconst;
1848 else if (isMutable())
1849 return MODmutable;
1850 else
1851 assert(0);
1853 return 0;
1856 Type *Type::unqualify(unsigned m)
1858 Type *t = mutableOf()->unSharedOf();
1860 Type *tn = ty == Tenum ? NULL : nextOf();
1861 if (tn && tn->ty != Tfunction)
1863 Type *utn = tn->unqualify(m);
1864 if (utn != tn)
1866 if (ty == Tpointer)
1867 t = utn->pointerTo();
1868 else if (ty == Tarray)
1869 t = utn->arrayOf();
1870 else if (ty == Tsarray)
1871 t = new TypeSArray(utn, ((TypeSArray *)this)->dim);
1872 else if (ty == Taarray)
1874 t = new TypeAArray(utn, ((TypeAArray *)this)->index);
1875 ((TypeAArray *)t)->sc = ((TypeAArray *)this)->sc; // duplicate scope
1877 else
1878 assert(0);
1880 t = t->merge();
1883 t = t->addMod(mod & ~m);
1884 return t;
1887 Type *Type::substWildTo(unsigned mod)
1889 //printf("+Type::substWildTo this = %s, mod = x%x\n", toChars(), mod);
1890 Type *t;
1892 if (Type *tn = nextOf())
1894 // substitution has no effect on function pointer type.
1895 if (ty == Tpointer && tn->ty == Tfunction)
1897 t = this;
1898 goto L1;
1901 t = tn->substWildTo(mod);
1902 if (t == tn)
1903 t = this;
1904 else
1906 if (ty == Tpointer)
1907 t = t->pointerTo();
1908 else if (ty == Tarray)
1909 t = t->arrayOf();
1910 else if (ty == Tsarray)
1911 t = new TypeSArray(t, ((TypeSArray *)this)->dim->syntaxCopy());
1912 else if (ty == Taarray)
1914 t = new TypeAArray(t, ((TypeAArray *)this)->index->syntaxCopy());
1915 ((TypeAArray *)t)->sc = ((TypeAArray *)this)->sc; // duplicate scope
1917 else if (ty == Tdelegate)
1919 t = new TypeDelegate(t);
1921 else
1922 assert(0);
1924 t = t->merge();
1927 else
1928 t = this;
1931 if (isWild())
1933 if (mod == MODimmutable)
1935 t = t->immutableOf();
1937 else if (mod == MODwildconst)
1939 t = t->wildConstOf();
1941 else if (mod == MODwild)
1943 if (isWildConst())
1944 t = t->wildConstOf();
1945 else
1946 t = t->wildOf();
1948 else if (mod == MODconst)
1950 t = t->constOf();
1952 else
1954 if (isWildConst())
1955 t = t->constOf();
1956 else
1957 t = t->mutableOf();
1960 if (isConst())
1961 t = t->addMod(MODconst);
1962 if (isShared())
1963 t = t->addMod(MODshared);
1965 //printf("-Type::substWildTo t = %s\n", t->toChars());
1966 return t;
1969 Type *TypeFunction::substWildTo(unsigned)
1971 if (!iswild && !(mod & MODwild))
1972 return this;
1974 // Substitude inout qualifier of function type to mutable or immutable
1975 // would break type system. Instead substitude inout to the most weak
1976 // qualifer - const.
1977 unsigned m = MODconst;
1979 assert(next);
1980 Type *tret = next->substWildTo(m);
1981 Parameters *params = parameterList.parameters;
1982 if (mod & MODwild)
1983 params = parameterList.parameters->copy();
1984 for (size_t i = 0; i < params->length; i++)
1986 Parameter *p = (*params)[i];
1987 Type *t = p->type->substWildTo(m);
1988 if (t == p->type)
1989 continue;
1990 if (params == parameterList.parameters)
1991 params = parameterList.parameters->copy();
1992 (*params)[i] = new Parameter(p->storageClass, t, NULL, NULL, NULL);
1994 if (next == tret && params == parameterList.parameters)
1995 return this;
1997 // Similar to TypeFunction::syntaxCopy;
1998 TypeFunction *t = new TypeFunction(ParameterList(params, parameterList.varargs),
1999 tret, linkage);
2000 t->mod = ((mod & MODwild) ? (mod & ~MODwild) | MODconst : mod);
2001 t->isnothrow = isnothrow;
2002 t->isnogc = isnogc;
2003 t->purity = purity;
2004 t->isproperty = isproperty;
2005 t->isref = isref;
2006 t->isreturn = isreturn;
2007 t->isscope = isscope;
2008 t->isscopeinferred = isscopeinferred;
2009 t->iswild = 0;
2010 t->trust = trust;
2011 t->fargs = fargs;
2012 return t->merge();
2015 /**************************
2016 * Return type with the top level of it being mutable.
2018 Type *Type::toHeadMutable()
2020 if (!mod)
2021 return this;
2022 return mutableOf();
2025 /***************************************
2026 * Calculate built-in properties which just the type is necessary.
2028 * If flag & 1, don't report "not a property" error and just return NULL.
2030 Expression *Type::getProperty(Loc loc, Identifier *ident, int flag)
2032 Expression *e;
2034 if (ident == Id::__sizeof)
2036 d_uns64 sz = size(loc);
2037 if (sz == SIZE_INVALID)
2038 return new ErrorExp();
2039 e = new IntegerExp(loc, sz, Type::tsize_t);
2041 else if (ident == Id::__xalignof)
2043 e = new IntegerExp(loc, alignsize(), Type::tsize_t);
2045 else if (ident == Id::_init)
2047 Type *tb = toBasetype();
2048 e = defaultInitLiteral(loc);
2049 if (tb->ty == Tstruct && tb->needsNested())
2051 StructLiteralExp *se = (StructLiteralExp *)e;
2052 se->useStaticInit = true;
2055 else if (ident == Id::_mangleof)
2057 if (!deco)
2059 error(loc, "forward reference of type %s.mangleof", toChars());
2060 e = new ErrorExp();
2062 else
2064 e = new StringExp(loc, (char *)deco, strlen(deco));
2065 Scope sc;
2066 e = expressionSemantic(e, &sc);
2069 else if (ident == Id::stringof)
2071 const char *s = toChars();
2072 e = new StringExp(loc, const_cast<char *>(s), strlen(s));
2073 Scope sc;
2074 e = expressionSemantic(e, &sc);
2076 else if (flag && this != Type::terror)
2078 return NULL;
2080 else
2082 Dsymbol *s = NULL;
2083 if (ty == Tstruct || ty == Tclass || ty == Tenum)
2084 s = toDsymbol(NULL);
2085 if (s)
2086 s = s->search_correct(ident);
2087 if (this != Type::terror)
2089 if (s)
2090 error(loc, "no property `%s` for type `%s`, did you mean `%s`?", ident->toChars(), toChars(), s->toPrettyChars());
2091 else
2092 error(loc, "no property `%s` for type `%s`", ident->toChars(), toChars());
2094 e = new ErrorExp();
2096 return e;
2099 /***************************************
2100 * Access the members of the object e. This type is same as e->type.
2102 * If flag & 1, don't report "not a property" error and just return NULL.
2104 Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
2106 VarDeclaration *v = NULL;
2108 Expression *ex = e;
2109 while (ex->op == TOKcomma)
2110 ex = ((CommaExp *)ex)->e2;
2111 if (ex->op == TOKdotvar)
2113 DotVarExp *dv = (DotVarExp *)ex;
2114 v = dv->var->isVarDeclaration();
2116 else if (ex->op == TOKvar)
2118 VarExp *ve = (VarExp *)ex;
2119 v = ve->var->isVarDeclaration();
2121 if (v)
2123 if (ident == Id::offsetof)
2125 if (v->isField())
2127 AggregateDeclaration *ad = v->toParent()->isAggregateDeclaration();
2128 ad->size(e->loc);
2129 if (ad->sizeok != SIZEOKdone)
2130 return new ErrorExp();
2131 e = new IntegerExp(e->loc, v->offset, Type::tsize_t);
2132 return e;
2135 else if (ident == Id::_init)
2137 Type *tb = toBasetype();
2138 e = defaultInitLiteral(e->loc);
2139 if (tb->ty == Tstruct && tb->needsNested())
2141 StructLiteralExp *se = (StructLiteralExp *)e;
2142 se->useStaticInit = true;
2144 goto Lreturn;
2147 if (ident == Id::stringof)
2149 /* Bugzilla 3796: this should demangle e->type->deco rather than
2150 * pretty-printing the type.
2152 const char *s = e->toChars();
2153 e = new StringExp(e->loc, const_cast<char *>(s), strlen(s));
2155 else
2156 e = getProperty(e->loc, ident, flag & 1);
2158 Lreturn:
2159 if (e)
2160 e = expressionSemantic(e, sc);
2161 return e;
2164 /************************************
2165 * Return alignment to use for this type.
2168 structalign_t Type::alignment()
2170 return STRUCTALIGN_DEFAULT;
2173 /***************************************
2174 * Figures out what to do with an undefined member reference
2175 * for classes and structs.
2177 * If flag & 1, don't report "not a property" error and just return NULL.
2179 Expression *Type::noMember(Scope *sc, Expression *e, Identifier *ident, int flag)
2181 //printf("Type::noMember(e: %s ident: %s flag: %d)\n", e->toChars(), ident->toChars(), flag);
2183 static int nest; // https://issues.dlang.org/show_bug.cgi?id=17380
2185 if (++nest > global.recursionLimit)
2187 ::error(e->loc, "cannot resolve identifier `%s`", ident->toChars());
2188 --nest;
2189 return (flag & 1) ? NULL : new ErrorExp();
2192 assert(ty == Tstruct || ty == Tclass);
2193 AggregateDeclaration *sym = toDsymbol(sc)->isAggregateDeclaration();
2194 assert(sym);
2196 if (ident != Id::__sizeof &&
2197 ident != Id::__xalignof &&
2198 ident != Id::_init &&
2199 ident != Id::_mangleof &&
2200 ident != Id::stringof &&
2201 ident != Id::offsetof &&
2202 // Bugzilla 15045: Don't forward special built-in member functions.
2203 ident != Id::ctor &&
2204 ident != Id::dtor &&
2205 ident != Id::__xdtor &&
2206 ident != Id::postblit &&
2207 ident != Id::__xpostblit)
2209 /* Look for overloaded opDot() to see if we should forward request
2210 * to it.
2212 if (Dsymbol *fd = search_function(sym, Id::opDot))
2214 /* Rewrite e.ident as:
2215 * e.opDot().ident
2217 e = build_overload(e->loc, sc, e, NULL, fd);
2218 e = new DotIdExp(e->loc, e, ident);
2219 e = expressionSemantic(e, sc);
2220 --nest;
2221 return e;
2224 /* Look for overloaded opDispatch to see if we should forward request
2225 * to it.
2227 if (Dsymbol *fd = search_function(sym, Id::opDispatch))
2229 /* Rewrite e.ident as:
2230 * e.opDispatch!("ident")
2232 TemplateDeclaration *td = fd->isTemplateDeclaration();
2233 if (!td)
2235 fd->error("must be a template opDispatch(string s), not a %s", fd->kind());
2236 --nest;
2237 return new ErrorExp();
2239 StringExp *se = new StringExp(e->loc, const_cast<char *>(ident->toChars()));
2240 Objects *tiargs = new Objects();
2241 tiargs->push(se);
2242 DotTemplateInstanceExp *dti = new DotTemplateInstanceExp(e->loc, e, Id::opDispatch, tiargs);
2243 dti->ti->tempdecl = td;
2245 /* opDispatch, which doesn't need IFTI, may occur instantiate error.
2246 * It should be gagged if flag & 1.
2247 * e.g.
2248 * template opDispatch(name) if (isValid!name) { ... }
2250 unsigned errors = flag & 1 ? global.startGagging() : 0;
2251 e = semanticY(dti, sc, 0);
2252 if (flag & 1 && global.endGagging(errors))
2253 e = NULL;
2254 --nest;
2255 return e;
2258 /* See if we should forward to the alias this.
2260 if (sym->aliasthis)
2261 { /* Rewrite e.ident as:
2262 * e.aliasthis.ident
2264 e = resolveAliasThis(sc, e);
2265 DotIdExp *die = new DotIdExp(e->loc, e, ident);
2266 e = semanticY(die, sc, flag & 1);
2267 --nest;
2268 return e;
2272 e = Type::dotExp(sc, e, ident, flag);
2273 --nest;
2274 return e;
2277 void Type::error(Loc loc, const char *format, ...)
2279 va_list ap;
2280 va_start(ap, format);
2281 ::verror(loc, format, ap);
2282 va_end( ap );
2285 void Type::warning(Loc loc, const char *format, ...)
2287 va_list ap;
2288 va_start(ap, format);
2289 ::vwarning(loc, format, ap);
2290 va_end( ap );
2293 Identifier *Type::getTypeInfoIdent()
2295 // _init_10TypeInfo_%s
2296 OutBuffer buf;
2297 buf.reserve(32);
2298 mangleToBuffer(this, &buf);
2300 size_t len = buf.length();
2301 buf.writeByte(0);
2303 // Allocate buffer on stack, fail over to using malloc()
2304 char namebuf[128];
2305 size_t namelen = 19 + sizeof(len) * 3 + len + 1;
2306 char *name = namelen <= sizeof(namebuf) ? namebuf : (char *)mem.xmalloc(namelen);
2308 int length = sprintf(name, "_D%lluTypeInfo_%s6__initZ", (unsigned long long) 9 + len, buf.slice().ptr);
2309 //printf("%p, deco = %s, name = %s\n", this, deco, name);
2310 assert(0 < length && (size_t)length < namelen); // don't overflow the buffer
2312 Identifier *id = Identifier::idPool(name, length);
2314 if (name != namebuf)
2315 free(name);
2316 return id;
2319 TypeBasic *Type::isTypeBasic()
2321 return NULL;
2324 TypeError *Type::isTypeError()
2326 return ty == Terror ? (TypeError *)this : NULL;
2329 TypeVector *Type::isTypeVector()
2331 return ty == Tvector ? (TypeVector *)this : NULL;
2334 TypeSArray *Type::isTypeSArray()
2336 return ty == Tsarray ? (TypeSArray *)this : NULL;
2339 TypeDArray *Type::isTypeDArray()
2341 return ty == Tarray ? (TypeDArray *)this : NULL;
2344 TypeAArray *Type::isTypeAArray()
2346 return ty == Taarray ? (TypeAArray *)this : NULL;
2349 TypePointer *Type::isTypePointer()
2351 return ty == Tpointer ? (TypePointer *)this : NULL;
2354 TypeReference *Type::isTypeReference()
2356 return ty == Treference ? (TypeReference *)this : NULL;
2359 TypeFunction *Type::isTypeFunction()
2361 return ty == Tfunction ? (TypeFunction *)this : NULL;
2364 TypeDelegate *Type::isTypeDelegate()
2366 return ty == Tdelegate ? (TypeDelegate *)this : NULL;
2369 TypeIdentifier *Type::isTypeIdentifier()
2371 return ty == Tident ? (TypeIdentifier *)this : NULL;
2374 TypeInstance *Type::isTypeInstance()
2376 return ty == Tinstance ? (TypeInstance *)this : NULL;
2379 TypeTypeof *Type::isTypeTypeof()
2381 return ty == Ttypeof ? (TypeTypeof *)this : NULL;
2384 TypeReturn *Type::isTypeReturn()
2386 return ty == Treturn ? (TypeReturn *)this : NULL;
2389 TypeStruct *Type::isTypeStruct()
2391 return ty == Tstruct ? (TypeStruct *)this : NULL;
2394 TypeEnum *Type::isTypeEnum()
2396 return ty == Tenum ? (TypeEnum *)this : NULL;
2399 TypeClass *Type::isTypeClass()
2401 return ty == Tclass ? (TypeClass *)this : NULL;
2404 TypeTuple *Type::isTypeTuple()
2406 return ty == Ttuple ? (TypeTuple *)this : NULL;
2409 TypeSlice *Type::isTypeSlice()
2411 return ty == Tslice ? (TypeSlice *)this : NULL;
2414 TypeNull *Type::isTypeNull()
2416 return ty == Tnull ? (TypeNull *)this : NULL;
2419 TypeTraits *Type::isTypeTraits()
2421 return ty == Ttraits ? (TypeTraits *)this : NULL;
2424 TypeMixin *Type::isTypeMixin()
2426 return ty == Tmixin ? (TypeMixin *)this : NULL;
2429 TypeNoreturn *Type::isTypeNoreturn()
2431 return ty == Tnoreturn ? (TypeNoreturn *)this : NULL;
2434 TypeFunction *Type::toTypeFunction()
2436 if (ty != Tfunction)
2437 assert(0);
2438 return (TypeFunction *)this;
2441 /***************************************
2442 * Resolve 'this' type to either type, symbol, or expression.
2443 * If errors happened, resolved to Type.terror.
2445 void Type::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool)
2447 //printf("Type::resolve() %s, %d\n", toChars(), ty);
2448 Type *t = typeSemantic(this, loc, sc);
2449 *pt = t;
2450 *pe = NULL;
2451 *ps = NULL;
2454 /***************************************
2455 * Normalize `e` as the result of Type::resolve() process.
2457 void Type::resolveExp(Expression *e, Type **pt, Expression **pe, Dsymbol **ps)
2459 *pt = NULL;
2460 *pe = NULL;
2461 *ps = NULL;
2463 Dsymbol *s;
2464 switch (e->op)
2466 case TOKerror:
2467 *pt = Type::terror;
2468 return;
2470 case TOKtype:
2471 *pt = e->type;
2472 return;
2474 case TOKvar:
2475 s = ((VarExp *)e)->var;
2476 if (s->isVarDeclaration())
2477 goto Ldefault;
2478 //if (s->isOverDeclaration())
2479 // todo;
2480 break;
2482 case TOKtemplate:
2483 // TemplateDeclaration
2484 s = ((TemplateExp *)e)->td;
2485 break;
2487 case TOKimport:
2488 s = ((ScopeExp *)e)->sds;
2489 // TemplateDeclaration, TemplateInstance, Import, Package, Module
2490 break;
2492 case TOKfunction:
2493 s = getDsymbol(e);
2494 break;
2496 //case TOKthis:
2497 //case TOKsuper:
2499 //case TOKtuple:
2501 //case TOKoverloadset:
2503 //case TOKdotvar:
2504 //case TOKdottd:
2505 //case TOKdotti:
2506 //case TOKdottype:
2507 //case TOKdot:
2509 default:
2510 Ldefault:
2511 *pe = e;
2512 return;
2515 *ps = s;
2518 /***************************************
2519 * Return !=0 if the type or any of its subtypes is wild.
2522 int Type::hasWild() const
2524 return mod & MODwild;
2527 /***************************************
2528 * Return !=0 if type has pointers that need to
2529 * be scanned by the GC during a collection cycle.
2531 bool Type::hasPointers()
2533 //printf("Type::hasPointers() %s, %d\n", toChars(), ty);
2534 return false;
2537 /*************************************
2538 * Detect if type has pointer fields that are initialized to void.
2539 * Local stack variables with such void fields can remain uninitialized,
2540 * leading to pointer bugs.
2541 * Returns:
2542 * true if so
2544 bool Type::hasVoidInitPointers()
2546 return false;
2549 /*************************************
2550 * If this is a type of something, return that something.
2553 Type *Type::nextOf()
2555 return NULL;
2558 /*************************************
2559 * If this is a type of static array, return its base element type.
2562 Type *Type::baseElemOf()
2564 Type *t = toBasetype();
2565 while (t->ty == Tsarray)
2566 t = ((TypeSArray *)t)->next->toBasetype();
2567 return t;
2570 /*************************************
2571 * Bugzilla 14488: Check if the inner most base type is complex or imaginary.
2572 * Should only give alerts when set to emit transitional messages.
2575 void Type::checkComplexTransition(Loc loc)
2577 Type *t = baseElemOf();
2578 while (t->ty == Tpointer || t->ty == Tarray)
2579 t = t->nextOf()->baseElemOf();
2581 if (t->isimaginary() || t->iscomplex())
2583 Type *rt;
2584 switch (t->ty)
2586 case Tcomplex32:
2587 case Timaginary32:
2588 rt = Type::tfloat32; break;
2589 case Tcomplex64:
2590 case Timaginary64:
2591 rt = Type::tfloat64; break;
2592 case Tcomplex80:
2593 case Timaginary80:
2594 rt = Type::tfloat80; break;
2595 default:
2596 assert(0);
2598 if (t->iscomplex())
2600 message(loc, "use of complex type `%s` is scheduled for deprecation, "
2601 "use `std.complex.Complex!(%s)` instead", toChars(), rt->toChars());
2603 else
2605 message(loc, "use of imaginary type `%s` is scheduled for deprecation, "
2606 "use `%s` instead\n", toChars(), rt->toChars());
2611 /*******************************************
2612 * Compute number of elements for a (possibly multidimensional) static array,
2613 * or 1 for other types.
2614 * Params:
2615 * loc = for error message
2616 * Returns:
2617 * number of elements, uint.max on overflow
2619 unsigned Type::numberOfElems(const Loc &loc)
2621 //printf("Type::numberOfElems()\n");
2622 uinteger_t n = 1;
2623 Type *tb = this;
2624 while ((tb = tb->toBasetype())->ty == Tsarray)
2626 bool overflow = false;
2627 n = mulu(n, ((TypeSArray *)tb)->dim->toUInteger(), overflow);
2628 if (overflow || n >= UINT32_MAX)
2630 error(loc, "static array `%s` size overflowed to %llu", toChars(), (unsigned long long)n);
2631 return UINT32_MAX;
2633 tb = ((TypeSArray *)tb)->next;
2635 return (unsigned)n;
2638 /****************************************
2639 * Return the mask that an integral type will
2640 * fit into.
2642 uinteger_t Type::sizemask()
2643 { uinteger_t m;
2645 switch (toBasetype()->ty)
2647 case Tbool: m = 1; break;
2648 case Tchar:
2649 case Tint8:
2650 case Tuns8: m = 0xFF; break;
2651 case Twchar:
2652 case Tint16:
2653 case Tuns16: m = 0xFFFFUL; break;
2654 case Tdchar:
2655 case Tint32:
2656 case Tuns32: m = 0xFFFFFFFFUL; break;
2657 case Tint64:
2658 case Tuns64: m = 0xFFFFFFFFFFFFFFFFULL; break;
2659 default:
2660 assert(0);
2662 return m;
2665 /* ============================= TypeError =========================== */
2667 TypeError::TypeError()
2668 : Type(Terror)
2672 Type *TypeError::syntaxCopy()
2674 // No semantic analysis done, no need to copy
2675 return this;
2678 d_uns64 TypeError::size(Loc) { return SIZE_INVALID; }
2679 Expression *TypeError::getProperty(Loc, Identifier *, int) { return new ErrorExp(); }
2680 Expression *TypeError::dotExp(Scope *, Expression *, Identifier *, int) { return new ErrorExp(); }
2681 Expression *TypeError::defaultInit(Loc) { return new ErrorExp(); }
2682 Expression *TypeError::defaultInitLiteral(Loc) { return new ErrorExp(); }
2684 /* ============================= TypeNext =========================== */
2686 TypeNext::TypeNext(TY ty, Type *next)
2687 : Type(ty)
2689 this->next = next;
2692 void TypeNext::checkDeprecated(Loc loc, Scope *sc)
2694 Type::checkDeprecated(loc, sc);
2695 if (next) // next can be NULL if TypeFunction and auto return type
2696 next->checkDeprecated(loc, sc);
2699 int TypeNext::hasWild() const
2701 if (ty == Tfunction)
2702 return 0;
2703 if (ty == Tdelegate)
2704 return Type::hasWild();
2705 return mod & MODwild || (next && next->hasWild());
2709 /*******************************
2710 * For TypeFunction, nextOf() can return NULL if the function return
2711 * type is meant to be inferred, and semantic() hasn't yet ben run
2712 * on the function. After semantic(), it must no longer be NULL.
2715 Type *TypeNext::nextOf()
2717 return next;
2720 Type *TypeNext::makeConst()
2722 //printf("TypeNext::makeConst() %p, %s\n", this, toChars());
2723 if (cto)
2725 assert(cto->mod == MODconst);
2726 return cto;
2728 TypeNext *t = (TypeNext *)Type::makeConst();
2729 if (ty != Tfunction && next->ty != Tfunction &&
2730 !next->isImmutable())
2732 if (next->isShared())
2734 if (next->isWild())
2735 t->next = next->sharedWildConstOf();
2736 else
2737 t->next = next->sharedConstOf();
2739 else
2741 if (next->isWild())
2742 t->next = next->wildConstOf();
2743 else
2744 t->next = next->constOf();
2747 //printf("TypeNext::makeConst() returns %p, %s\n", t, t->toChars());
2748 return t;
2751 Type *TypeNext::makeImmutable()
2753 //printf("TypeNext::makeImmutable() %s\n", toChars());
2754 if (ito)
2756 assert(ito->isImmutable());
2757 return ito;
2759 TypeNext *t = (TypeNext *)Type::makeImmutable();
2760 if (ty != Tfunction && next->ty != Tfunction &&
2761 !next->isImmutable())
2763 t->next = next->immutableOf();
2765 return t;
2768 Type *TypeNext::makeShared()
2770 //printf("TypeNext::makeShared() %s\n", toChars());
2771 if (sto)
2773 assert(sto->mod == MODshared);
2774 return sto;
2776 TypeNext *t = (TypeNext *)Type::makeShared();
2777 if (ty != Tfunction && next->ty != Tfunction &&
2778 !next->isImmutable())
2780 if (next->isWild())
2782 if (next->isConst())
2783 t->next = next->sharedWildConstOf();
2784 else
2785 t->next = next->sharedWildOf();
2787 else
2789 if (next->isConst())
2790 t->next = next->sharedConstOf();
2791 else
2792 t->next = next->sharedOf();
2795 //printf("TypeNext::makeShared() returns %p, %s\n", t, t->toChars());
2796 return t;
2799 Type *TypeNext::makeSharedConst()
2801 //printf("TypeNext::makeSharedConst() %s\n", toChars());
2802 if (scto)
2804 assert(scto->mod == (MODshared | MODconst));
2805 return scto;
2807 TypeNext *t = (TypeNext *)Type::makeSharedConst();
2808 if (ty != Tfunction && next->ty != Tfunction &&
2809 !next->isImmutable())
2811 if (next->isWild())
2812 t->next = next->sharedWildConstOf();
2813 else
2814 t->next = next->sharedConstOf();
2816 //printf("TypeNext::makeSharedConst() returns %p, %s\n", t, t->toChars());
2817 return t;
2820 Type *TypeNext::makeWild()
2822 //printf("TypeNext::makeWild() %s\n", toChars());
2823 if (wto)
2825 assert(wto->mod == MODwild);
2826 return wto;
2828 TypeNext *t = (TypeNext *)Type::makeWild();
2829 if (ty != Tfunction && next->ty != Tfunction &&
2830 !next->isImmutable())
2832 if (next->isShared())
2834 if (next->isConst())
2835 t->next = next->sharedWildConstOf();
2836 else
2837 t->next = next->sharedWildOf();
2839 else
2841 if (next->isConst())
2842 t->next = next->wildConstOf();
2843 else
2844 t->next = next->wildOf();
2847 //printf("TypeNext::makeWild() returns %p, %s\n", t, t->toChars());
2848 return t;
2851 Type *TypeNext::makeWildConst()
2853 //printf("TypeNext::makeWildConst() %s\n", toChars());
2854 if (wcto)
2856 assert(wcto->mod == MODwildconst);
2857 return wcto;
2859 TypeNext *t = (TypeNext *)Type::makeWildConst();
2860 if (ty != Tfunction && next->ty != Tfunction &&
2861 !next->isImmutable())
2863 if (next->isShared())
2864 t->next = next->sharedWildConstOf();
2865 else
2866 t->next = next->wildConstOf();
2868 //printf("TypeNext::makeWildConst() returns %p, %s\n", t, t->toChars());
2869 return t;
2872 Type *TypeNext::makeSharedWild()
2874 //printf("TypeNext::makeSharedWild() %s\n", toChars());
2875 if (swto)
2877 assert(swto->isSharedWild());
2878 return swto;
2880 TypeNext *t = (TypeNext *)Type::makeSharedWild();
2881 if (ty != Tfunction && next->ty != Tfunction &&
2882 !next->isImmutable())
2884 if (next->isConst())
2885 t->next = next->sharedWildConstOf();
2886 else
2887 t->next = next->sharedWildOf();
2889 //printf("TypeNext::makeSharedWild() returns %p, %s\n", t, t->toChars());
2890 return t;
2893 Type *TypeNext::makeSharedWildConst()
2895 //printf("TypeNext::makeSharedWildConst() %s\n", toChars());
2896 if (swcto)
2898 assert(swcto->mod == (MODshared | MODwildconst));
2899 return swcto;
2901 TypeNext *t = (TypeNext *)Type::makeSharedWildConst();
2902 if (ty != Tfunction && next->ty != Tfunction &&
2903 !next->isImmutable())
2905 t->next = next->sharedWildConstOf();
2907 //printf("TypeNext::makeSharedWildConst() returns %p, %s\n", t, t->toChars());
2908 return t;
2911 Type *TypeNext::makeMutable()
2913 //printf("TypeNext::makeMutable() %p, %s\n", this, toChars());
2914 TypeNext *t = (TypeNext *)Type::makeMutable();
2915 if (ty == Tsarray)
2917 t->next = next->mutableOf();
2919 //printf("TypeNext::makeMutable() returns %p, %s\n", t, t->toChars());
2920 return t;
2923 MATCH TypeNext::constConv(Type *to)
2925 //printf("TypeNext::constConv from = %s, to = %s\n", toChars(), to->toChars());
2926 if (equals(to))
2927 return MATCHexact;
2929 if (!(ty == to->ty && MODimplicitConv(mod, to->mod)))
2930 return MATCHnomatch;
2932 Type *tn = to->nextOf();
2933 if (!(tn && next->ty == tn->ty))
2934 return MATCHnomatch;
2936 MATCH m;
2937 if (to->isConst()) // whole tail const conversion
2938 { // Recursive shared level check
2939 m = next->constConv(tn);
2940 if (m == MATCHexact)
2941 m = MATCHconst;
2943 else
2944 { //printf("\tnext => %s, to->next => %s\n", next->toChars(), tn->toChars());
2945 m = next->equals(tn) ? MATCHconst : MATCHnomatch;
2947 return m;
2950 unsigned char TypeNext::deduceWild(Type *t, bool isRef)
2952 if (ty == Tfunction)
2953 return 0;
2955 unsigned char wm;
2957 Type *tn = t->nextOf();
2958 if (!isRef && (ty == Tarray || ty == Tpointer) && tn)
2960 wm = next->deduceWild(tn, true);
2961 if (!wm)
2962 wm = Type::deduceWild(t, true);
2964 else
2966 wm = Type::deduceWild(t, isRef);
2967 if (!wm && tn)
2968 wm = next->deduceWild(tn, true);
2971 return wm;
2975 void TypeNext::transitive()
2977 /* Invoke transitivity of type attributes
2979 next = next->addMod(mod);
2982 /* ============================= TypeBasic =========================== */
2984 #define TFLAGSintegral 1
2985 #define TFLAGSfloating 2
2986 #define TFLAGSunsigned 4
2987 #define TFLAGSreal 8
2988 #define TFLAGSimaginary 0x10
2989 #define TFLAGScomplex 0x20
2991 TypeBasic::TypeBasic(TY ty)
2992 : Type(ty)
2993 { const char *d;
2994 unsigned flags;
2996 flags = 0;
2997 switch (ty)
2999 case Tvoid: d = Token::toChars(TOKvoid);
3000 break;
3002 case Tint8: d = Token::toChars(TOKint8);
3003 flags |= TFLAGSintegral;
3004 break;
3006 case Tuns8: d = Token::toChars(TOKuns8);
3007 flags |= TFLAGSintegral | TFLAGSunsigned;
3008 break;
3010 case Tint16: d = Token::toChars(TOKint16);
3011 flags |= TFLAGSintegral;
3012 break;
3014 case Tuns16: d = Token::toChars(TOKuns16);
3015 flags |= TFLAGSintegral | TFLAGSunsigned;
3016 break;
3018 case Tint32: d = Token::toChars(TOKint32);
3019 flags |= TFLAGSintegral;
3020 break;
3022 case Tuns32: d = Token::toChars(TOKuns32);
3023 flags |= TFLAGSintegral | TFLAGSunsigned;
3024 break;
3026 case Tfloat32: d = Token::toChars(TOKfloat32);
3027 flags |= TFLAGSfloating | TFLAGSreal;
3028 break;
3030 case Tint64: d = Token::toChars(TOKint64);
3031 flags |= TFLAGSintegral;
3032 break;
3034 case Tuns64: d = Token::toChars(TOKuns64);
3035 flags |= TFLAGSintegral | TFLAGSunsigned;
3036 break;
3038 case Tint128: d = Token::toChars(TOKint128);
3039 flags |= TFLAGSintegral;
3040 break;
3042 case Tuns128: d = Token::toChars(TOKuns128);
3043 flags |= TFLAGSintegral | TFLAGSunsigned;
3044 break;
3046 case Tfloat64: d = Token::toChars(TOKfloat64);
3047 flags |= TFLAGSfloating | TFLAGSreal;
3048 break;
3050 case Tfloat80: d = Token::toChars(TOKfloat80);
3051 flags |= TFLAGSfloating | TFLAGSreal;
3052 break;
3054 case Timaginary32: d = Token::toChars(TOKimaginary32);
3055 flags |= TFLAGSfloating | TFLAGSimaginary;
3056 break;
3058 case Timaginary64: d = Token::toChars(TOKimaginary64);
3059 flags |= TFLAGSfloating | TFLAGSimaginary;
3060 break;
3062 case Timaginary80: d = Token::toChars(TOKimaginary80);
3063 flags |= TFLAGSfloating | TFLAGSimaginary;
3064 break;
3066 case Tcomplex32: d = Token::toChars(TOKcomplex32);
3067 flags |= TFLAGSfloating | TFLAGScomplex;
3068 break;
3070 case Tcomplex64: d = Token::toChars(TOKcomplex64);
3071 flags |= TFLAGSfloating | TFLAGScomplex;
3072 break;
3074 case Tcomplex80: d = Token::toChars(TOKcomplex80);
3075 flags |= TFLAGSfloating | TFLAGScomplex;
3076 break;
3078 case Tbool: d = "bool";
3079 flags |= TFLAGSintegral | TFLAGSunsigned;
3080 break;
3082 case Tchar: d = Token::toChars(TOKchar);
3083 flags |= TFLAGSintegral | TFLAGSunsigned;
3084 break;
3086 case Twchar: d = Token::toChars(TOKwchar);
3087 flags |= TFLAGSintegral | TFLAGSunsigned;
3088 break;
3090 case Tdchar: d = Token::toChars(TOKdchar);
3091 flags |= TFLAGSintegral | TFLAGSunsigned;
3092 break;
3094 default: assert(0);
3096 this->dstring = d;
3097 this->flags = flags;
3098 merge();
3101 const char *TypeBasic::kind()
3103 return dstring;
3106 Type *TypeBasic::syntaxCopy()
3108 // No semantic analysis done on basic types, no need to copy
3109 return this;
3112 d_uns64 TypeBasic::size(Loc)
3113 { unsigned size;
3115 //printf("TypeBasic::size()\n");
3116 switch (ty)
3118 case Tint8:
3119 case Tuns8: size = 1; break;
3120 case Tint16:
3121 case Tuns16: size = 2; break;
3122 case Tint32:
3123 case Tuns32:
3124 case Tfloat32:
3125 case Timaginary32:
3126 size = 4; break;
3127 case Tint64:
3128 case Tuns64:
3129 case Tfloat64:
3130 case Timaginary64:
3131 size = 8; break;
3132 case Tfloat80:
3133 case Timaginary80:
3134 size = target.realsize; break;
3135 case Tcomplex32:
3136 size = 8; break;
3137 case Tcomplex64:
3138 case Tint128:
3139 case Tuns128:
3140 size = 16; break;
3141 case Tcomplex80:
3142 size = target.realsize * 2; break;
3144 case Tvoid:
3145 //size = Type::size(); // error message
3146 size = 1;
3147 break;
3149 case Tbool: size = 1; break;
3150 case Tchar: size = 1; break;
3151 case Twchar: size = 2; break;
3152 case Tdchar: size = 4; break;
3154 default:
3155 assert(0);
3156 break;
3158 //printf("TypeBasic::size() = %d\n", size);
3159 return size;
3162 unsigned TypeBasic::alignsize()
3164 return target.alignsize(this);
3168 Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
3170 Expression *e;
3171 dinteger_t ivalue;
3172 real_t fvalue;
3174 //printf("TypeBasic::getProperty('%s')\n", ident->toChars());
3175 if (ident == Id::max)
3177 switch (ty)
3179 case Tint8:
3180 ivalue = 0x7F;
3181 goto Livalue;
3182 case Tuns8:
3183 ivalue = 0xFF;
3184 goto Livalue;
3185 case Tint16:
3186 ivalue = 0x7FFFUL;
3187 goto Livalue;
3188 case Tuns16:
3189 ivalue = 0xFFFFUL;
3190 goto Livalue;
3191 case Tint32:
3192 ivalue = 0x7FFFFFFFUL;
3193 goto Livalue;
3194 case Tuns32:
3195 ivalue = 0xFFFFFFFFUL;
3196 goto Livalue;
3197 case Tint64:
3198 ivalue = 0x7FFFFFFFFFFFFFFFLL;
3199 goto Livalue;
3200 case Tuns64:
3201 ivalue = 0xFFFFFFFFFFFFFFFFULL;
3202 goto Livalue;
3203 case Tbool:
3204 ivalue = 1;
3205 goto Livalue;
3206 case Tchar:
3207 ivalue = 0xFF;
3208 goto Livalue;
3209 case Twchar:
3210 ivalue = 0xFFFFUL;
3211 goto Livalue;
3212 case Tdchar:
3213 ivalue = 0x10FFFFUL;
3214 goto Livalue;
3215 case Tcomplex32:
3216 case Timaginary32:
3217 case Tfloat32:
3218 fvalue = target.FloatProperties.max;
3219 goto Lfvalue;
3220 case Tcomplex64:
3221 case Timaginary64:
3222 case Tfloat64:
3223 fvalue = target.DoubleProperties.max;
3224 goto Lfvalue;
3225 case Tcomplex80:
3226 case Timaginary80:
3227 case Tfloat80:
3228 fvalue = target.RealProperties.max;
3229 goto Lfvalue;
3232 else if (ident == Id::min)
3234 switch (ty)
3236 case Tint8:
3237 ivalue = -128;
3238 goto Livalue;
3239 case Tuns8:
3240 ivalue = 0;
3241 goto Livalue;
3242 case Tint16:
3243 ivalue = -32768;
3244 goto Livalue;
3245 case Tuns16:
3246 ivalue = 0;
3247 goto Livalue;
3248 case Tint32:
3249 ivalue = -2147483647L - 1;
3250 goto Livalue;
3251 case Tuns32:
3252 ivalue = 0;
3253 goto Livalue;
3254 case Tint64:
3255 ivalue = (-9223372036854775807LL-1LL);
3256 goto Livalue;
3257 case Tuns64:
3258 ivalue = 0;
3259 goto Livalue;
3260 case Tbool:
3261 ivalue = 0;
3262 goto Livalue;
3263 case Tchar:
3264 ivalue = 0;
3265 goto Livalue;
3266 case Twchar:
3267 ivalue = 0;
3268 goto Livalue;
3269 case Tdchar:
3270 ivalue = 0;
3271 goto Livalue;
3273 case Tcomplex32:
3274 case Timaginary32:
3275 case Tfloat32:
3276 case Tcomplex64:
3277 case Timaginary64:
3278 case Tfloat64:
3279 case Tcomplex80:
3280 case Timaginary80:
3281 case Tfloat80:
3282 error(loc, "use .min_normal property instead of .min");
3283 return new ErrorExp();
3286 else if (ident == Id::min_normal)
3288 switch (ty)
3290 case Tcomplex32:
3291 case Timaginary32:
3292 case Tfloat32:
3293 fvalue = target.FloatProperties.min_normal;
3294 goto Lfvalue;
3295 case Tcomplex64:
3296 case Timaginary64:
3297 case Tfloat64:
3298 fvalue = target.DoubleProperties.min_normal;
3299 goto Lfvalue;
3300 case Tcomplex80:
3301 case Timaginary80:
3302 case Tfloat80:
3303 fvalue = target.RealProperties.min_normal;
3304 goto Lfvalue;
3307 else if (ident == Id::nan)
3309 switch (ty)
3311 case Tcomplex32:
3312 case Tcomplex64:
3313 case Tcomplex80:
3314 case Timaginary32:
3315 case Timaginary64:
3316 case Timaginary80:
3317 case Tfloat32:
3318 case Tfloat64:
3319 case Tfloat80:
3320 fvalue = target.RealProperties.nan;
3321 goto Lfvalue;
3324 else if (ident == Id::infinity)
3326 switch (ty)
3328 case Tcomplex32:
3329 case Tcomplex64:
3330 case Tcomplex80:
3331 case Timaginary32:
3332 case Timaginary64:
3333 case Timaginary80:
3334 case Tfloat32:
3335 case Tfloat64:
3336 case Tfloat80:
3337 fvalue = target.RealProperties.infinity;
3338 goto Lfvalue;
3341 else if (ident == Id::dig)
3343 switch (ty)
3345 case Tcomplex32:
3346 case Timaginary32:
3347 case Tfloat32:
3348 ivalue = target.FloatProperties.dig;
3349 goto Lint;
3350 case Tcomplex64:
3351 case Timaginary64:
3352 case Tfloat64:
3353 ivalue = target.DoubleProperties.dig;
3354 goto Lint;
3355 case Tcomplex80:
3356 case Timaginary80:
3357 case Tfloat80:
3358 ivalue = target.RealProperties.dig;
3359 goto Lint;
3362 else if (ident == Id::epsilon)
3364 switch (ty)
3366 case Tcomplex32:
3367 case Timaginary32:
3368 case Tfloat32:
3369 fvalue = target.FloatProperties.epsilon;
3370 goto Lfvalue;
3371 case Tcomplex64:
3372 case Timaginary64:
3373 case Tfloat64:
3374 fvalue = target.DoubleProperties.epsilon;
3375 goto Lfvalue;
3376 case Tcomplex80:
3377 case Timaginary80:
3378 case Tfloat80:
3379 fvalue = target.RealProperties.epsilon;
3380 goto Lfvalue;
3383 else if (ident == Id::mant_dig)
3385 switch (ty)
3387 case Tcomplex32:
3388 case Timaginary32:
3389 case Tfloat32:
3390 ivalue = target.FloatProperties.mant_dig;
3391 goto Lint;
3392 case Tcomplex64:
3393 case Timaginary64:
3394 case Tfloat64:
3395 ivalue = target.DoubleProperties.mant_dig;
3396 goto Lint;
3397 case Tcomplex80:
3398 case Timaginary80:
3399 case Tfloat80:
3400 ivalue = target.RealProperties.mant_dig;
3401 goto Lint;
3404 else if (ident == Id::max_10_exp)
3406 switch (ty)
3408 case Tcomplex32:
3409 case Timaginary32:
3410 case Tfloat32:
3411 ivalue = target.FloatProperties.max_10_exp;
3412 goto Lint;
3413 case Tcomplex64:
3414 case Timaginary64:
3415 case Tfloat64:
3416 ivalue = target.DoubleProperties.max_10_exp;
3417 goto Lint;
3418 case Tcomplex80:
3419 case Timaginary80:
3420 case Tfloat80:
3421 ivalue = target.RealProperties.max_10_exp;
3422 goto Lint;
3425 else if (ident == Id::max_exp)
3427 switch (ty)
3429 case Tcomplex32:
3430 case Timaginary32:
3431 case Tfloat32:
3432 ivalue = target.FloatProperties.max_exp;
3433 goto Lint;
3434 case Tcomplex64:
3435 case Timaginary64:
3436 case Tfloat64:
3437 ivalue = target.DoubleProperties.max_exp;
3438 goto Lint;
3439 case Tcomplex80:
3440 case Timaginary80:
3441 case Tfloat80:
3442 ivalue = target.RealProperties.max_exp;
3443 goto Lint;
3446 else if (ident == Id::min_10_exp)
3448 switch (ty)
3450 case Tcomplex32:
3451 case Timaginary32:
3452 case Tfloat32:
3453 ivalue = target.FloatProperties.min_10_exp;
3454 goto Lint;
3455 case Tcomplex64:
3456 case Timaginary64:
3457 case Tfloat64:
3458 ivalue = target.DoubleProperties.min_10_exp;
3459 goto Lint;
3460 case Tcomplex80:
3461 case Timaginary80:
3462 case Tfloat80:
3463 ivalue = target.RealProperties.min_10_exp;
3464 goto Lint;
3467 else if (ident == Id::min_exp)
3469 switch (ty)
3471 case Tcomplex32:
3472 case Timaginary32:
3473 case Tfloat32:
3474 ivalue = target.FloatProperties.min_exp;
3475 goto Lint;
3476 case Tcomplex64:
3477 case Timaginary64:
3478 case Tfloat64:
3479 ivalue = target.DoubleProperties.min_exp;
3480 goto Lint;
3481 case Tcomplex80:
3482 case Timaginary80:
3483 case Tfloat80:
3484 ivalue = target.RealProperties.min_exp;
3485 goto Lint;
3489 return Type::getProperty(loc, ident, flag);
3491 Livalue:
3492 e = new IntegerExp(loc, ivalue, this);
3493 return e;
3495 Lfvalue:
3496 if (isreal() || isimaginary())
3497 e = new RealExp(loc, fvalue, this);
3498 else
3500 complex_t cvalue = complex_t(fvalue, fvalue);
3501 //for (int i = 0; i < 20; i++)
3502 // printf("%02x ", ((unsigned char *)&cvalue)[i]);
3503 //printf("\n");
3504 e = new ComplexExp(loc, cvalue, this);
3506 return e;
3508 Lint:
3509 e = new IntegerExp(loc, ivalue, Type::tint32);
3510 return e;
3513 Expression *TypeBasic::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
3515 Type *t;
3517 if (ident == Id::re)
3519 switch (ty)
3521 case Tcomplex32: t = tfloat32; goto L1;
3522 case Tcomplex64: t = tfloat64; goto L1;
3523 case Tcomplex80: t = tfloat80; goto L1;
3525 e = e->castTo(sc, t);
3526 break;
3528 case Tfloat32:
3529 case Tfloat64:
3530 case Tfloat80:
3531 break;
3533 case Timaginary32: t = tfloat32; goto L2;
3534 case Timaginary64: t = tfloat64; goto L2;
3535 case Timaginary80: t = tfloat80; goto L2;
3537 e = new RealExp(e->loc, CTFloat::zero, t);
3538 break;
3540 default:
3541 e = Type::getProperty(e->loc, ident, flag);
3542 break;
3545 else if (ident == Id::im)
3546 { Type *t2;
3548 switch (ty)
3550 case Tcomplex32: t = timaginary32; t2 = tfloat32; goto L3;
3551 case Tcomplex64: t = timaginary64; t2 = tfloat64; goto L3;
3552 case Tcomplex80: t = timaginary80; t2 = tfloat80; goto L3;
3554 e = e->castTo(sc, t);
3555 e->type = t2;
3556 break;
3558 case Timaginary32: t = tfloat32; goto L4;
3559 case Timaginary64: t = tfloat64; goto L4;
3560 case Timaginary80: t = tfloat80; goto L4;
3562 e = e->copy();
3563 e->type = t;
3564 break;
3566 case Tfloat32:
3567 case Tfloat64:
3568 case Tfloat80:
3569 e = new RealExp(e->loc, CTFloat::zero, this);
3570 break;
3572 default:
3573 e = Type::getProperty(e->loc, ident, flag);
3574 break;
3577 else
3579 return Type::dotExp(sc, e, ident, flag);
3581 if (!(flag & 1) || e)
3582 e = expressionSemantic(e, sc);
3583 return e;
3586 Expression *TypeBasic::defaultInit(Loc loc)
3588 dinteger_t value = 0;
3590 switch (ty)
3592 case Tchar:
3593 value = 0xFF;
3594 break;
3596 case Twchar:
3597 case Tdchar:
3598 value = 0xFFFF;
3599 break;
3601 case Timaginary32:
3602 case Timaginary64:
3603 case Timaginary80:
3604 case Tfloat32:
3605 case Tfloat64:
3606 case Tfloat80:
3607 return new RealExp(loc, target.RealProperties.snan, this);
3609 case Tcomplex32:
3610 case Tcomplex64:
3611 case Tcomplex80:
3612 { // Can't use fvalue + I*fvalue (the im part becomes a quiet NaN).
3613 complex_t cvalue = complex_t(target.RealProperties.snan, target.RealProperties.snan);
3614 return new ComplexExp(loc, cvalue, this);
3617 case Tvoid:
3618 error(loc, "void does not have a default initializer");
3619 return new ErrorExp();
3621 return new IntegerExp(loc, value, this);
3624 bool TypeBasic::isZeroInit(Loc)
3626 switch (ty)
3628 case Tchar:
3629 case Twchar:
3630 case Tdchar:
3631 case Timaginary32:
3632 case Timaginary64:
3633 case Timaginary80:
3634 case Tfloat32:
3635 case Tfloat64:
3636 case Tfloat80:
3637 case Tcomplex32:
3638 case Tcomplex64:
3639 case Tcomplex80:
3640 return false; // no
3641 default:
3642 return true; // yes
3646 bool TypeBasic::isintegral()
3648 //printf("TypeBasic::isintegral('%s') x%x\n", toChars(), flags);
3649 return (flags & TFLAGSintegral) != 0;
3652 bool TypeBasic::isfloating()
3654 return (flags & TFLAGSfloating) != 0;
3657 bool TypeBasic::isreal()
3659 return (flags & TFLAGSreal) != 0;
3662 bool TypeBasic::isimaginary()
3664 return (flags & TFLAGSimaginary) != 0;
3667 bool TypeBasic::iscomplex()
3669 return (flags & TFLAGScomplex) != 0;
3672 bool TypeBasic::isunsigned()
3674 return (flags & TFLAGSunsigned) != 0;
3677 bool TypeBasic::isscalar()
3679 return (flags & (TFLAGSintegral | TFLAGSfloating)) != 0;
3682 MATCH TypeBasic::implicitConvTo(Type *to)
3684 //printf("TypeBasic::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
3685 if (this == to)
3686 return MATCHexact;
3688 if (ty == to->ty)
3690 if (mod == to->mod)
3691 return MATCHexact;
3692 else if (MODimplicitConv(mod, to->mod))
3693 return MATCHconst;
3694 else if (!((mod ^ to->mod) & MODshared)) // for wild matching
3695 return MATCHconst;
3696 else
3697 return MATCHconvert;
3700 if (ty == Tvoid || to->ty == Tvoid)
3701 return MATCHnomatch;
3702 if (to->ty == Tbool)
3703 return MATCHnomatch;
3705 TypeBasic *tob;
3706 if (to->ty == Tvector && to->deco)
3708 TypeVector *tv = (TypeVector *)to;
3709 tob = tv->elementType();
3711 else if (to->ty == Tenum)
3713 EnumDeclaration *ed = ((TypeEnum *)to)->sym;
3714 if (ed->isSpecial())
3716 /* Special enums that allow implicit conversions to them. */
3717 tob = to->toBasetype()->isTypeBasic();
3718 if (tob)
3719 return implicitConvTo(tob);
3721 else
3722 return MATCHnomatch;
3724 else
3725 tob = to->isTypeBasic();
3726 if (!tob)
3727 return MATCHnomatch;
3729 if (flags & TFLAGSintegral)
3731 // Disallow implicit conversion of integers to imaginary or complex
3732 if (tob->flags & (TFLAGSimaginary | TFLAGScomplex))
3733 return MATCHnomatch;
3735 // If converting from integral to integral
3736 if (tob->flags & TFLAGSintegral)
3737 { d_uns64 sz = size(Loc());
3738 d_uns64 tosz = tob->size(Loc());
3740 /* Can't convert to smaller size
3742 if (sz > tosz)
3743 return MATCHnomatch;
3745 /* Can't change sign if same size
3747 /*if (sz == tosz && (flags ^ tob->flags) & TFLAGSunsigned)
3748 return MATCHnomatch;*/
3751 else if (flags & TFLAGSfloating)
3753 // Disallow implicit conversion of floating point to integer
3754 if (tob->flags & TFLAGSintegral)
3755 return MATCHnomatch;
3757 assert(tob->flags & TFLAGSfloating || to->ty == Tvector);
3759 // Disallow implicit conversion from complex to non-complex
3760 if (flags & TFLAGScomplex && !(tob->flags & TFLAGScomplex))
3761 return MATCHnomatch;
3763 // Disallow implicit conversion of real or imaginary to complex
3764 if (flags & (TFLAGSreal | TFLAGSimaginary) &&
3765 tob->flags & TFLAGScomplex)
3766 return MATCHnomatch;
3768 // Disallow implicit conversion to-from real and imaginary
3769 if ((flags & (TFLAGSreal | TFLAGSimaginary)) !=
3770 (tob->flags & (TFLAGSreal | TFLAGSimaginary)))
3771 return MATCHnomatch;
3773 return MATCHconvert;
3776 TypeBasic *TypeBasic::isTypeBasic()
3778 return (TypeBasic *)this;
3781 /* ============================= TypeVector =========================== */
3783 /* The basetype must be one of:
3784 * byte[16],ubyte[16],short[8],ushort[8],int[4],uint[4],long[2],ulong[2],float[4],double[2]
3785 * For AVX:
3786 * byte[32],ubyte[32],short[16],ushort[16],int[8],uint[8],long[4],ulong[4],float[8],double[4]
3788 TypeVector::TypeVector(Type *basetype)
3789 : Type(Tvector)
3791 this->basetype = basetype;
3794 TypeVector *TypeVector::create(Type *basetype)
3796 return new TypeVector(basetype);
3799 const char *TypeVector::kind()
3801 return "vector";
3804 Type *TypeVector::syntaxCopy()
3806 return new TypeVector(basetype->syntaxCopy());
3809 TypeBasic *TypeVector::elementType()
3811 assert(basetype->ty == Tsarray);
3812 TypeSArray *t = (TypeSArray *)basetype;
3813 TypeBasic *tb = t->nextOf()->isTypeBasic();
3814 assert(tb);
3815 return tb;
3818 bool TypeVector::isBoolean()
3820 return false;
3823 d_uns64 TypeVector::size(Loc)
3825 return basetype->size();
3828 unsigned TypeVector::alignsize()
3830 return (unsigned)basetype->size();
3833 Expression *TypeVector::getProperty(Loc loc, Identifier *ident, int flag)
3835 return Type::getProperty(loc, ident, flag);
3838 Expression *TypeVector::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
3840 if (ident == Id::ptr && e->op == TOKcall)
3842 /* The trouble with TOKcall is the return ABI for float[4] is different from
3843 * __vector(float[4]), and a type paint won't do.
3845 e = new AddrExp(e->loc, e);
3846 e = expressionSemantic(e, sc);
3847 e = e->castTo(sc, basetype->nextOf()->pointerTo());
3848 return e;
3850 if (ident == Id::array)
3852 //e = e->castTo(sc, basetype);
3853 // Keep lvalue-ness
3854 e = new VectorArrayExp(e->loc, e);
3855 e = expressionSemantic(e, sc);
3856 return e;
3858 if (ident == Id::_init || ident == Id::offsetof || ident == Id::stringof || ident == Id::__xalignof)
3860 // init should return a new VectorExp (Bugzilla 12776)
3861 // offsetof does not work on a cast expression, so use e directly
3862 // stringof should not add a cast to the output
3863 return Type::dotExp(sc, e, ident, flag);
3865 return basetype->dotExp(sc, e->castTo(sc, basetype), ident, flag);
3868 Expression *TypeVector::defaultInit(Loc loc)
3870 //printf("TypeVector::defaultInit()\n");
3871 assert(basetype->ty == Tsarray);
3872 Expression *e = basetype->defaultInit(loc);
3873 VectorExp *ve = new VectorExp(loc, e, this);
3874 ve->type = this;
3875 ve->dim = (int)(basetype->size(loc) / elementType()->size(loc));
3876 return ve;
3879 Expression *TypeVector::defaultInitLiteral(Loc loc)
3881 //printf("TypeVector::defaultInitLiteral()\n");
3882 assert(basetype->ty == Tsarray);
3883 Expression *e = basetype->defaultInitLiteral(loc);
3884 VectorExp *ve = new VectorExp(loc, e, this);
3885 ve->type = this;
3886 ve->dim = (int)(basetype->size(loc) / elementType()->size(loc));
3887 return ve;
3890 bool TypeVector::isZeroInit(Loc loc)
3892 return basetype->isZeroInit(loc);
3895 bool TypeVector::isintegral()
3897 //printf("TypeVector::isintegral('%s') x%x\n", toChars(), flags);
3898 return basetype->nextOf()->isintegral();
3901 bool TypeVector::isfloating()
3903 return basetype->nextOf()->isfloating();
3906 bool TypeVector::isunsigned()
3908 return basetype->nextOf()->isunsigned();
3911 bool TypeVector::isscalar()
3913 return basetype->nextOf()->isscalar();
3916 MATCH TypeVector::implicitConvTo(Type *to)
3918 //printf("TypeVector::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
3919 if (this == to)
3920 return MATCHexact;
3921 #ifdef IN_GCC
3922 if (to->ty == Tvector)
3924 TypeVector *tv = (TypeVector *)to;
3925 assert(basetype->ty == Tsarray && tv->basetype->ty == Tsarray);
3927 // Can't convert to a vector which has different size.
3928 if (basetype->size() != tv->basetype->size())
3929 return MATCHnomatch;
3931 // Allow conversion to void[]
3932 if (tv->basetype->nextOf()->ty == Tvoid)
3933 return MATCHconvert;
3935 // Otherwise implicitly convertible only if basetypes are.
3936 return basetype->implicitConvTo(tv->basetype);
3938 #else
3939 if (ty == to->ty)
3940 return MATCHconvert;
3941 #endif
3942 return MATCHnomatch;
3945 /***************************** TypeArray *****************************/
3947 TypeArray::TypeArray(TY ty, Type *next)
3948 : TypeNext(ty, next)
3952 Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
3954 e = Type::dotExp(sc, e, ident, flag);
3956 if (!(flag & 1) || e)
3957 e = expressionSemantic(e, sc);
3958 return e;
3962 /***************************** TypeSArray *****************************/
3964 TypeSArray::TypeSArray(Type *t, Expression *dim)
3965 : TypeArray(Tsarray, t)
3967 //printf("TypeSArray(%s)\n", dim->toChars());
3968 this->dim = dim;
3971 const char *TypeSArray::kind()
3973 return "sarray";
3976 Type *TypeSArray::syntaxCopy()
3978 Type *t = next->syntaxCopy();
3979 Expression *e = dim->syntaxCopy();
3980 t = new TypeSArray(t, e);
3981 t->mod = mod;
3982 return t;
3985 d_uns64 TypeSArray::size(Loc loc)
3987 //printf("TypeSArray::size()\n");
3988 uinteger_t n = numberOfElems(loc);
3989 uinteger_t elemsize = baseElemOf()->size();
3990 bool overflow = false;
3991 uinteger_t sz = mulu(n, elemsize, overflow);
3992 if (overflow || sz >= UINT32_MAX)
3994 if (elemsize != SIZE_INVALID && n != UINT32_MAX)
3995 error(loc, "static array `%s` size overflowed to %lld", toChars(), (long long)sz);
3996 return SIZE_INVALID;
3998 return sz;
4001 unsigned TypeSArray::alignsize()
4003 return next->alignsize();
4006 void TypeSArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
4008 //printf("TypeSArray::resolve() %s\n", toChars());
4009 next->resolve(loc, sc, pe, pt, ps, intypeid);
4010 //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
4011 if (*pe)
4013 // It's really an index expression
4014 if (Dsymbol *s = getDsymbol(*pe))
4015 *pe = new DsymbolExp(loc, s);
4016 *pe = new ArrayExp(loc, *pe, dim);
4018 else if (*ps)
4020 Dsymbol *s = *ps;
4021 TupleDeclaration *td = s->isTupleDeclaration();
4022 if (td)
4024 ScopeDsymbol *sym = new ArrayScopeSymbol(sc, td);
4025 sym->parent = sc->scopesym;
4026 sc = sc->push(sym);
4027 sc = sc->startCTFE();
4028 dim = expressionSemantic(dim, sc);
4029 sc = sc->endCTFE();
4030 sc = sc->pop();
4032 dim = dim->ctfeInterpret();
4033 uinteger_t d = dim->toUInteger();
4035 if (d >= td->objects->length)
4037 error(loc, "tuple index %llu exceeds length %u", d, td->objects->length);
4038 *ps = NULL;
4039 *pt = Type::terror;
4040 return;
4042 RootObject *o = (*td->objects)[(size_t)d];
4043 if (o->dyncast() == DYNCAST_DSYMBOL)
4045 *ps = (Dsymbol *)o;
4046 return;
4048 if (o->dyncast() == DYNCAST_EXPRESSION)
4050 Expression *e = (Expression *)o;
4051 if (e->op == TOKdsymbol)
4053 *ps = ((DsymbolExp *)e)->s;
4054 *pe = NULL;
4056 else
4058 *ps = NULL;
4059 *pe = e;
4061 return;
4063 if (o->dyncast() == DYNCAST_TYPE)
4065 *ps = NULL;
4066 *pt = ((Type *)o)->addMod(this->mod);
4067 return;
4070 /* Create a new TupleDeclaration which
4071 * is a slice [d..d+1] out of the old one.
4072 * Do it this way because TemplateInstance::semanticTiargs()
4073 * can handle unresolved Objects this way.
4075 Objects *objects = new Objects;
4076 objects->setDim(1);
4077 (*objects)[0] = o;
4079 TupleDeclaration *tds = new TupleDeclaration(loc, td->ident, objects);
4080 *ps = tds;
4082 else
4083 goto Ldefault;
4085 else
4087 if ((*pt)->ty != Terror)
4088 next = *pt; // prevent re-running semantic() on 'next'
4089 Ldefault:
4090 Type::resolve(loc, sc, pe, pt, ps, intypeid);
4094 Expression *TypeSArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
4096 if (ident == Id::length)
4098 Loc oldLoc = e->loc;
4099 e = dim->copy();
4100 e->loc = oldLoc;
4102 else if (ident == Id::ptr)
4104 if (e->op == TOKtype)
4106 e->error("%s is not an expression", e->toChars());
4107 return new ErrorExp();
4109 else if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
4111 e->deprecation("%s.ptr cannot be used in @safe code, use &%s[0] instead", e->toChars(), e->toChars());
4112 // return new ErrorExp();
4114 e = e->castTo(sc, e->type->nextOf()->pointerTo());
4116 else
4118 e = TypeArray::dotExp(sc, e, ident, flag);
4120 if (!(flag & 1) || e)
4121 e = expressionSemantic(e, sc);
4122 return e;
4125 structalign_t TypeSArray::alignment()
4127 return next->alignment();
4130 bool TypeSArray::isString()
4132 TY nty = next->toBasetype()->ty;
4133 return nty == Tchar || nty == Twchar || nty == Tdchar;
4136 MATCH TypeSArray::constConv(Type *to)
4138 if (to->ty == Tsarray)
4140 TypeSArray *tsa = (TypeSArray *)to;
4141 if (!dim->equals(tsa->dim))
4142 return MATCHnomatch;
4144 return TypeNext::constConv(to);
4147 MATCH TypeSArray::implicitConvTo(Type *to)
4149 //printf("TypeSArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4151 if (to->ty == Tarray)
4153 TypeDArray *ta = (TypeDArray *)to;
4155 if (!MODimplicitConv(next->mod, ta->next->mod))
4156 return MATCHnomatch;
4158 /* Allow conversion to void[]
4160 if (ta->next->ty == Tvoid)
4162 return MATCHconvert;
4165 MATCH m = next->constConv(ta->next);
4166 if (m > MATCHnomatch)
4168 return MATCHconvert;
4170 return MATCHnomatch;
4173 if (to->ty == Tsarray)
4175 if (this == to)
4176 return MATCHexact;
4178 TypeSArray *tsa = (TypeSArray *)to;
4180 if (dim->equals(tsa->dim))
4182 /* Since static arrays are value types, allow
4183 * conversions from const elements to non-const
4184 * ones, just like we allow conversion from const int
4185 * to int.
4187 MATCH m = next->implicitConvTo(tsa->next);
4188 if (m >= MATCHconst)
4190 if (mod != to->mod)
4191 m = MATCHconst;
4192 return m;
4196 return MATCHnomatch;
4199 Expression *TypeSArray::defaultInit(Loc loc)
4201 if (next->ty == Tvoid)
4202 return tuns8->defaultInit(loc);
4203 else
4204 return next->defaultInit(loc);
4207 bool TypeSArray::isZeroInit(Loc loc)
4209 return next->isZeroInit(loc);
4212 bool TypeSArray::needsDestruction()
4214 return next->needsDestruction();
4217 /*********************************
4221 bool TypeSArray::needsNested()
4223 return next->needsNested();
4226 Expression *TypeSArray::defaultInitLiteral(Loc loc)
4228 size_t d = (size_t)dim->toInteger();
4229 Expression *elementinit;
4230 if (next->ty == Tvoid)
4231 elementinit = tuns8->defaultInitLiteral(loc);
4232 else
4233 elementinit = next->defaultInitLiteral(loc);
4234 Expressions *elements = new Expressions();
4235 elements->setDim(d);
4236 for (size_t i = 0; i < d; i++)
4237 (*elements)[i] = NULL;
4238 ArrayLiteralExp *ae = new ArrayLiteralExp(Loc(), this, elementinit, elements);
4239 return ae;
4242 bool TypeSArray::hasPointers()
4244 /* Don't want to do this, because:
4245 * struct S { T* array[0]; }
4246 * may be a variable length struct.
4248 //if (dim->toInteger() == 0)
4249 // return false;
4251 if (next->ty == Tvoid)
4253 // Arrays of void contain arbitrary data, which may include pointers
4254 return true;
4256 else
4257 return next->hasPointers();
4260 /***************************** TypeDArray *****************************/
4262 TypeDArray::TypeDArray(Type *t)
4263 : TypeArray(Tarray, t)
4265 //printf("TypeDArray(t = %p)\n", t);
4268 const char *TypeDArray::kind()
4270 return "darray";
4273 Type *TypeDArray::syntaxCopy()
4275 Type *t = next->syntaxCopy();
4276 if (t == next)
4277 t = this;
4278 else
4280 t = new TypeDArray(t);
4281 t->mod = mod;
4283 return t;
4286 d_uns64 TypeDArray::size(Loc)
4288 //printf("TypeDArray::size()\n");
4289 return target.ptrsize * 2;
4292 unsigned TypeDArray::alignsize()
4294 // A DArray consists of two ptr-sized values, so align it on pointer size
4295 // boundary
4296 return target.ptrsize;
4299 void TypeDArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
4301 //printf("TypeDArray::resolve() %s\n", toChars());
4302 next->resolve(loc, sc, pe, pt, ps, intypeid);
4303 //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
4304 if (*pe)
4306 // It's really a slice expression
4307 if (Dsymbol *s = getDsymbol(*pe))
4308 *pe = new DsymbolExp(loc, s);
4309 *pe = new ArrayExp(loc, *pe);
4311 else if (*ps)
4313 TupleDeclaration *td = (*ps)->isTupleDeclaration();
4314 if (td)
4315 ; // keep *ps
4316 else
4317 goto Ldefault;
4319 else
4321 if ((*pt)->ty != Terror)
4322 next = *pt; // prevent re-running semantic() on 'next'
4323 Ldefault:
4324 Type::resolve(loc, sc, pe, pt, ps, intypeid);
4328 Expression *TypeDArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
4330 if (e->op == TOKtype &&
4331 (ident == Id::length || ident == Id::ptr))
4333 e->error("%s is not an expression", e->toChars());
4334 return new ErrorExp();
4336 if (ident == Id::length)
4338 if (e->op == TOKstring)
4340 StringExp *se = (StringExp *)e;
4341 return new IntegerExp(se->loc, se->len, Type::tsize_t);
4343 if (e->op == TOKnull)
4344 return new IntegerExp(e->loc, 0, Type::tsize_t);
4345 if (checkNonAssignmentArrayOp(e))
4346 return new ErrorExp();
4347 e = new ArrayLengthExp(e->loc, e);
4348 e->type = Type::tsize_t;
4349 return e;
4351 else if (ident == Id::ptr)
4353 if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
4355 e->deprecation("%s.ptr cannot be used in @safe code, use &%s[0] instead", e->toChars(), e->toChars());
4356 // return new ErrorExp();
4358 e = e->castTo(sc, next->pointerTo());
4359 return e;
4361 else
4363 e = TypeArray::dotExp(sc, e, ident, flag);
4365 return e;
4368 bool TypeDArray::isString()
4370 TY nty = next->toBasetype()->ty;
4371 return nty == Tchar || nty == Twchar || nty == Tdchar;
4374 MATCH TypeDArray::implicitConvTo(Type *to)
4376 //printf("TypeDArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4377 if (equals(to))
4378 return MATCHexact;
4380 if (to->ty == Tarray)
4382 TypeDArray *ta = (TypeDArray *)to;
4384 if (!MODimplicitConv(next->mod, ta->next->mod))
4385 return MATCHnomatch; // not const-compatible
4387 /* Allow conversion to void[]
4389 if (next->ty != Tvoid && ta->next->ty == Tvoid)
4391 return MATCHconvert;
4394 MATCH m = next->constConv(ta->next);
4395 if (m > MATCHnomatch)
4397 if (m == MATCHexact && mod != to->mod)
4398 m = MATCHconst;
4399 return m;
4402 return Type::implicitConvTo(to);
4405 Expression *TypeDArray::defaultInit(Loc loc)
4407 return new NullExp(loc, this);
4410 bool TypeDArray::isZeroInit(Loc)
4412 return true;
4415 bool TypeDArray::isBoolean()
4417 return true;
4420 bool TypeDArray::hasPointers()
4422 return true;
4426 /***************************** TypeAArray *****************************/
4428 TypeAArray::TypeAArray(Type *t, Type *index)
4429 : TypeArray(Taarray, t)
4431 this->index = index;
4432 this->loc = Loc();
4433 this->sc = NULL;
4436 TypeAArray *TypeAArray::create(Type *t, Type *index)
4438 return new TypeAArray(t, index);
4441 const char *TypeAArray::kind()
4443 return "aarray";
4446 Type *TypeAArray::syntaxCopy()
4448 Type *t = next->syntaxCopy();
4449 Type *ti = index->syntaxCopy();
4450 if (t == next && ti == index)
4451 t = this;
4452 else
4454 t = new TypeAArray(t, ti);
4455 t->mod = mod;
4457 return t;
4460 d_uns64 TypeAArray::size(Loc)
4462 return target.ptrsize;
4465 void TypeAArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
4467 //printf("TypeAArray::resolve() %s\n", toChars());
4469 // Deal with the case where we thought the index was a type, but
4470 // in reality it was an expression.
4471 if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray)
4473 Expression *e;
4474 Type *t;
4475 Dsymbol *s;
4477 index->resolve(loc, sc, &e, &t, &s, intypeid);
4478 if (e)
4480 // It was an expression -
4481 // Rewrite as a static array
4482 TypeSArray *tsa = new TypeSArray(next, e);
4483 tsa->mod = this->mod; // just copy mod field so tsa's semantic is not yet done
4484 return tsa->resolve(loc, sc, pe, pt, ps, intypeid);
4486 else if (t)
4487 index = t;
4488 else
4489 index->error(loc, "index is not a type or an expression");
4491 Type::resolve(loc, sc, pe, pt, ps, intypeid);
4495 Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
4497 if (ident == Id::length)
4499 static FuncDeclaration *fd_aaLen = NULL;
4500 if (fd_aaLen == NULL)
4502 Parameters *fparams = new Parameters();
4503 fparams->push(new Parameter(STCin, this, NULL, NULL, NULL));
4504 fd_aaLen = FuncDeclaration::genCfunc(fparams, Type::tsize_t, Id::aaLen);
4505 TypeFunction *tf = fd_aaLen->type->toTypeFunction();
4506 tf->purity = PUREconst;
4507 tf->isnothrow = true;
4508 tf->isnogc = false;
4510 Expression *ev = new VarExp(e->loc, fd_aaLen, false);
4511 e = new CallExp(e->loc, ev, e);
4512 e->type = fd_aaLen->type->toTypeFunction()->next;
4514 else
4515 e = Type::dotExp(sc, e, ident, flag);
4516 return e;
4519 Expression *TypeAArray::defaultInit(Loc loc)
4521 return new NullExp(loc, this);
4524 bool TypeAArray::isZeroInit(Loc)
4526 return true;
4529 bool TypeAArray::isBoolean()
4531 return true;
4534 bool TypeAArray::hasPointers()
4536 return true;
4539 MATCH TypeAArray::implicitConvTo(Type *to)
4541 //printf("TypeAArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4542 if (equals(to))
4543 return MATCHexact;
4545 if (to->ty == Taarray)
4546 { TypeAArray *ta = (TypeAArray *)to;
4548 if (!MODimplicitConv(next->mod, ta->next->mod))
4549 return MATCHnomatch; // not const-compatible
4551 if (!MODimplicitConv(index->mod, ta->index->mod))
4552 return MATCHnomatch; // not const-compatible
4554 MATCH m = next->constConv(ta->next);
4555 MATCH mi = index->constConv(ta->index);
4556 if (m > MATCHnomatch && mi > MATCHnomatch)
4558 return MODimplicitConv(mod, to->mod) ? MATCHconst : MATCHnomatch;
4561 return Type::implicitConvTo(to);
4564 MATCH TypeAArray::constConv(Type *to)
4566 if (to->ty == Taarray)
4568 TypeAArray *taa = (TypeAArray *)to;
4569 MATCH mindex = index->constConv(taa->index);
4570 MATCH mkey = next->constConv(taa->next);
4571 // Pick the worst match
4572 return mkey < mindex ? mkey : mindex;
4574 return Type::constConv(to);
4577 /***************************** TypePointer *****************************/
4579 TypePointer::TypePointer(Type *t)
4580 : TypeNext(Tpointer, t)
4584 TypePointer *TypePointer::create(Type *t)
4586 return new TypePointer(t);
4589 const char *TypePointer::kind()
4591 return "pointer";
4594 Type *TypePointer::syntaxCopy()
4596 Type *t = next->syntaxCopy();
4597 if (t == next)
4598 t = this;
4599 else
4601 t = new TypePointer(t);
4602 t->mod = mod;
4604 return t;
4607 d_uns64 TypePointer::size(Loc)
4609 return target.ptrsize;
4612 MATCH TypePointer::implicitConvTo(Type *to)
4614 //printf("TypePointer::implicitConvTo(to = %s) %s\n", to->toChars(), toChars());
4616 if (equals(to))
4617 return MATCHexact;
4618 if (next->ty == Tfunction)
4620 if (to->ty == Tpointer)
4622 TypePointer *tp = (TypePointer *)to;
4623 if (tp->next->ty == Tfunction)
4625 if (next->equals(tp->next))
4626 return MATCHconst;
4628 if (next->covariant(tp->next) == 1)
4630 Type *tret = this->next->nextOf();
4631 Type *toret = tp->next->nextOf();
4632 if (tret->ty == Tclass && toret->ty == Tclass)
4634 /* Bugzilla 10219: Check covariant interface return with offset tweaking.
4635 * interface I {}
4636 * class C : Object, I {}
4637 * I function() dg = function C() {} // should be error
4639 int offset = 0;
4640 if (toret->isBaseOf(tret, &offset) && offset != 0)
4641 return MATCHnomatch;
4643 return MATCHconvert;
4646 else if (tp->next->ty == Tvoid)
4648 // Allow conversions to void*
4649 return MATCHconvert;
4652 return MATCHnomatch;
4654 else if (to->ty == Tpointer)
4656 TypePointer *tp = (TypePointer *)to;
4657 assert(tp->next);
4659 if (!MODimplicitConv(next->mod, tp->next->mod))
4660 return MATCHnomatch; // not const-compatible
4662 /* Alloc conversion to void*
4664 if (next->ty != Tvoid && tp->next->ty == Tvoid)
4666 return MATCHconvert;
4669 MATCH m = next->constConv(tp->next);
4670 if (m > MATCHnomatch)
4672 if (m == MATCHexact && mod != to->mod)
4673 m = MATCHconst;
4674 return m;
4677 return MATCHnomatch;
4680 MATCH TypePointer::constConv(Type *to)
4682 if (next->ty == Tfunction)
4684 if (to->nextOf() && next->equals(((TypeNext *)to)->next))
4685 return Type::constConv(to);
4686 else
4687 return MATCHnomatch;
4689 return TypeNext::constConv(to);
4692 bool TypePointer::isscalar()
4694 return true;
4697 Expression *TypePointer::defaultInit(Loc loc)
4699 return new NullExp(loc, this);
4702 bool TypePointer::isZeroInit(Loc)
4704 return true;
4707 bool TypePointer::hasPointers()
4709 return true;
4713 /***************************** TypeReference *****************************/
4715 TypeReference::TypeReference(Type *t)
4716 : TypeNext(Treference, t)
4718 // BUG: what about references to static arrays?
4721 const char *TypeReference::kind()
4723 return "reference";
4726 Type *TypeReference::syntaxCopy()
4728 Type *t = next->syntaxCopy();
4729 if (t == next)
4730 t = this;
4731 else
4733 t = new TypeReference(t);
4734 t->mod = mod;
4736 return t;
4739 d_uns64 TypeReference::size(Loc)
4741 return target.ptrsize;
4744 Expression *TypeReference::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
4746 // References just forward things along
4747 return next->dotExp(sc, e, ident, flag);
4750 Expression *TypeReference::defaultInit(Loc loc)
4752 return new NullExp(loc, this);
4755 bool TypeReference::isZeroInit(Loc)
4757 return true;
4761 /***************************** TypeFunction *****************************/
4763 TypeFunction::TypeFunction(const ParameterList &pl, Type *treturn, LINK linkage, StorageClass stc)
4764 : TypeNext(Tfunction, treturn)
4766 //if (!treturn) *(char*)0=0;
4767 // assert(treturn);
4768 assert(VARARGnone <= pl.varargs && pl.varargs <= VARARGtypesafe);
4769 this->parameterList = pl;
4770 this->linkage = linkage;
4771 this->inuse = 0;
4772 this->isnothrow = false;
4773 this->isnogc = false;
4774 this->purity = PUREimpure;
4775 this->isproperty = false;
4776 this->isref = false;
4777 this->isreturn = false;
4778 this->isscope = false;
4779 this->isscopeinferred = false;
4780 this->iswild = 0;
4781 this->fargs = NULL;
4783 if (stc & STCpure)
4784 this->purity = PUREfwdref;
4785 if (stc & STCnothrow)
4786 this->isnothrow = true;
4787 if (stc & STCnogc)
4788 this->isnogc = true;
4789 if (stc & STCproperty)
4790 this->isproperty = true;
4792 if (stc & STCref)
4793 this->isref = true;
4794 if (stc & STCreturn)
4795 this->isreturn = true;
4796 if (stc & STCscope)
4797 this->isscope = true;
4798 if (stc & STCscopeinferred)
4799 this->isscopeinferred = true;
4801 this->trust = TRUSTdefault;
4802 if (stc & STCsafe)
4803 this->trust = TRUSTsafe;
4804 if (stc & STCsystem)
4805 this->trust = TRUSTsystem;
4806 if (stc & STCtrusted)
4807 this->trust = TRUSTtrusted;
4810 TypeFunction *TypeFunction::create(Parameters *parameters, Type *treturn, VarArg varargs, LINK linkage, StorageClass stc)
4812 return new TypeFunction(ParameterList(parameters, varargs), treturn, linkage, stc);
4815 const char *TypeFunction::kind()
4817 return "function";
4820 Type *TypeFunction::syntaxCopy()
4822 Type *treturn = next ? next->syntaxCopy() : NULL;
4823 Parameters *parameters = Parameter::arraySyntaxCopy(parameterList.parameters);
4824 TypeFunction *t = new TypeFunction(ParameterList(parameters, parameterList.varargs),
4825 treturn, linkage);
4826 t->mod = mod;
4827 t->isnothrow = isnothrow;
4828 t->isnogc = isnogc;
4829 t->purity = purity;
4830 t->isproperty = isproperty;
4831 t->isref = isref;
4832 t->isreturn = isreturn;
4833 t->isscope = isscope;
4834 t->isscopeinferred = isscopeinferred;
4835 t->iswild = iswild;
4836 t->trust = trust;
4837 t->fargs = fargs;
4838 return t;
4841 /*******************************
4842 * Covariant means that 'this' can substitute for 't',
4843 * i.e. a pure function is a match for an impure type.
4844 * Params:
4845 * t = type 'this' is covariant with
4846 * pstc = if not null, store STCxxxx which would make it covariant
4847 * fix17349 = enable fix https://issues.dlang.org/show_bug.cgi?id=17349
4848 * Returns:
4849 * 0 types are distinct
4850 * 1 this is covariant with t
4851 * 2 arguments match as far as overloading goes,
4852 * but types are not covariant
4853 * 3 cannot determine covariance because of forward references
4854 * *pstc STCxxxx which would make it covariant
4857 int Type::covariant(Type *t, StorageClass *pstc, bool fix17349)
4859 if (pstc)
4860 *pstc = 0;
4861 StorageClass stc = 0;
4863 bool notcovariant = false;
4865 TypeFunction *t1;
4866 TypeFunction *t2;
4868 if (equals(t))
4869 return 1; // covariant
4871 if (ty != Tfunction || t->ty != Tfunction)
4872 goto Ldistinct;
4874 t1 = (TypeFunction *)this;
4875 t2 = (TypeFunction *)t;
4877 if (t1->parameterList.varargs != t2->parameterList.varargs)
4878 goto Ldistinct;
4880 if (t1->parameterList.parameters && t2->parameterList.parameters)
4882 size_t dim = t1->parameterList.length();
4883 if (dim != t2->parameterList.length())
4884 goto Ldistinct;
4886 for (size_t i = 0; i < dim; i++)
4888 Parameter *fparam1 = t1->parameterList[i];
4889 Parameter *fparam2 = t2->parameterList[i];
4891 if (!fparam1->type->equals(fparam2->type))
4893 if (!fix17349)
4894 goto Ldistinct;
4895 Type *tp1 = fparam1->type;
4896 Type *tp2 = fparam2->type;
4897 if (tp1->ty == tp2->ty)
4899 if (tp1->ty == Tclass)
4901 if (((TypeClass *)tp1)->sym == ((TypeClass *)tp2)->sym && MODimplicitConv(tp2->mod, tp1->mod))
4902 goto Lcov;
4904 else if (tp1->ty == Tstruct)
4906 if (((TypeStruct *)tp1)->sym == ((TypeStruct *)tp2)->sym && MODimplicitConv(tp2->mod, tp1->mod))
4907 goto Lcov;
4909 else if (tp1->ty == Tpointer)
4911 if (tp2->implicitConvTo(tp1))
4912 goto Lcov;
4914 else if (tp1->ty == Tarray)
4916 if (tp2->implicitConvTo(tp1))
4917 goto Lcov;
4919 else if (tp1->ty == Tdelegate)
4921 if (tp1->implicitConvTo(tp2))
4922 goto Lcov;
4925 goto Ldistinct;
4927 Lcov:
4928 notcovariant |= !fparam1->isCovariant(t1->isref, fparam2);
4931 else if (t1->parameterList.parameters != t2->parameterList.parameters)
4933 size_t dim1 = t1->parameterList.length();
4934 size_t dim2 = t2->parameterList.length();
4935 if (dim1 || dim2)
4936 goto Ldistinct;
4939 // The argument lists match
4940 if (notcovariant)
4941 goto Lnotcovariant;
4942 if (t1->linkage != t2->linkage)
4943 goto Lnotcovariant;
4946 // Return types
4947 Type *t1n = t1->next;
4948 Type *t2n = t2->next;
4950 if (!t1n || !t2n) // happens with return type inference
4951 goto Lnotcovariant;
4953 if (t1n->equals(t2n))
4954 goto Lcovariant;
4955 if (t1n->ty == Tclass && t2n->ty == Tclass)
4957 /* If same class type, but t2n is const, then it's
4958 * covariant. Do this test first because it can work on
4959 * forward references.
4961 if (((TypeClass *)t1n)->sym == ((TypeClass *)t2n)->sym &&
4962 MODimplicitConv(t1n->mod, t2n->mod))
4963 goto Lcovariant;
4965 // If t1n is forward referenced:
4966 ClassDeclaration *cd = ((TypeClass *)t1n)->sym;
4967 if (cd->semanticRun < PASSsemanticdone && !cd->isBaseInfoComplete())
4968 dsymbolSemantic(cd, NULL);
4969 if (!cd->isBaseInfoComplete())
4971 return 3; // forward references
4974 if (t1n->ty == Tstruct && t2n->ty == Tstruct)
4976 if (((TypeStruct *)t1n)->sym == ((TypeStruct *)t2n)->sym &&
4977 MODimplicitConv(t1n->mod, t2n->mod))
4978 goto Lcovariant;
4980 else if (t1n->ty == t2n->ty && t1n->implicitConvTo(t2n))
4981 goto Lcovariant;
4982 else if (t1n->ty == Tnull)
4984 // NULL is covariant with any pointer type, but not with any
4985 // dynamic arrays, associative arrays or delegates.
4986 // https://issues.dlang.org/show_bug.cgi?id=8589
4987 // https://issues.dlang.org/show_bug.cgi?id=19618
4988 Type *t2bn = t2n->toBasetype();
4989 if (t2bn->ty == Tnull || t2bn->ty == Tpointer || t2bn->ty == Tclass)
4990 goto Lcovariant;
4993 goto Lnotcovariant;
4995 Lcovariant:
4996 if (t1->isref != t2->isref)
4997 goto Lnotcovariant;
4999 if (!t1->isref && (t1->isscope || t2->isscope))
5001 StorageClass stc1 = t1->isscope ? STCscope : 0;
5002 StorageClass stc2 = t2->isscope ? STCscope : 0;
5003 if (t1->isreturn)
5005 stc1 |= STCreturn;
5006 if (!t1->isscope)
5007 stc1 |= STCref;
5009 if (t2->isreturn)
5011 stc2 |= STCreturn;
5012 if (!t2->isscope)
5013 stc2 |= STCref;
5015 if (!Parameter::isCovariantScope(t1->isref, stc1, stc2))
5016 goto Lnotcovariant;
5019 // We can subtract 'return ref' from 'this', but cannot add it
5020 else if (t1->isreturn && !t2->isreturn)
5021 goto Lnotcovariant;
5023 /* Can convert mutable to const
5025 if (!MODimplicitConv(t2->mod, t1->mod))
5027 goto Ldistinct;
5030 /* Can convert pure to impure, nothrow to throw, and nogc to gc
5032 if (!t1->purity && t2->purity)
5033 stc |= STCpure;
5035 if (!t1->isnothrow && t2->isnothrow)
5036 stc |= STCnothrow;
5038 if (!t1->isnogc && t2->isnogc)
5039 stc |= STCnogc;
5041 /* Can convert safe/trusted to system
5043 if (t1->trust <= TRUSTsystem && t2->trust >= TRUSTtrusted)
5045 // Should we infer trusted or safe? Go with safe.
5046 stc |= STCsafe;
5049 if (stc)
5050 { if (pstc)
5051 *pstc = stc;
5052 goto Lnotcovariant;
5055 //printf("\tcovaraint: 1\n");
5056 return 1;
5058 Ldistinct:
5059 //printf("\tcovaraint: 0\n");
5060 return 0;
5062 Lnotcovariant:
5063 //printf("\tcovaraint: 2\n");
5064 return 2;
5067 bool TypeFunction::checkRetType(Loc loc)
5069 Type *tb = next->toBasetype();
5070 if (tb->ty == Tfunction)
5072 error(loc, "functions cannot return a function");
5073 next = Type::terror;
5075 if (tb->ty == Ttuple)
5077 error(loc, "functions cannot return a tuple");
5078 next = Type::terror;
5080 if (!isref && (tb->ty == Tstruct || tb->ty == Tsarray))
5082 Type *tb2 = tb->baseElemOf();
5083 if (tb2->ty == Tstruct && !((TypeStruct *)tb2)->sym->members)
5085 error(loc, "functions cannot return opaque type %s by value", tb->toChars());
5086 next = Type::terror;
5089 if (tb->ty == Terror)
5090 return true;
5092 return false;
5095 /* Determine purity level based on mutability of t
5096 * and whether it is a 'ref' type or not.
5098 static PURE purityOfType(bool isref, Type *t)
5100 if (isref)
5102 if (t->mod & MODimmutable)
5103 return PUREstrong;
5104 if (t->mod & (MODconst | MODwild))
5105 return PUREconst;
5106 return PUREweak;
5109 t = t->baseElemOf();
5111 if (!t->hasPointers() || t->mod & MODimmutable)
5112 return PUREstrong;
5114 /* Accept immutable(T)[] and immutable(T)* as being strongly pure
5116 if (t->ty == Tarray || t->ty == Tpointer)
5118 Type *tn = t->nextOf()->toBasetype();
5119 if (tn->mod & MODimmutable)
5120 return PUREstrong;
5121 if (tn->mod & (MODconst | MODwild))
5122 return PUREconst;
5125 /* The rest of this is too strict; fix later.
5126 * For example, the only pointer members of a struct may be immutable,
5127 * which would maintain strong purity.
5128 * (Just like for dynamic arrays and pointers above.)
5130 if (t->mod & (MODconst | MODwild))
5131 return PUREconst;
5133 /* Should catch delegates and function pointers, and fold in their purity
5135 return PUREweak;
5138 /********************************************
5139 * Set 'purity' field of 'this'.
5140 * Do this lazily, as the parameter types might be forward referenced.
5142 void TypeFunction::purityLevel()
5144 TypeFunction *tf = this;
5145 if (tf->purity != PUREfwdref)
5146 return;
5148 purity = PUREstrong; // assume strong until something weakens it
5150 /* Evaluate what kind of purity based on the modifiers for the parameters
5152 const size_t dim = tf->parameterList.length();
5153 for (size_t i = 0; i < dim; i++)
5155 Parameter *fparam = tf->parameterList[i];
5156 Type *t = fparam->type;
5157 if (!t)
5158 continue;
5160 if (fparam->storageClass & (STClazy | STCout))
5162 purity = PUREweak;
5163 break;
5165 switch (purityOfType((fparam->storageClass & STCref) != 0, t))
5167 case PUREweak:
5168 purity = PUREweak;
5169 break;
5171 case PUREconst:
5172 purity = PUREconst;
5173 continue;
5175 case PUREstrong:
5176 continue;
5178 default:
5179 assert(0);
5181 break; // since PUREweak, no need to check further
5184 if (purity > PUREweak && tf->nextOf())
5186 /* Adjust purity based on mutability of return type.
5187 * https://issues.dlang.org/show_bug.cgi?id=15862
5189 const PURE purity2 = purityOfType(tf->isref, tf->nextOf());
5190 if (purity2 < purity)
5191 purity = purity2;
5193 tf->purity = purity;
5196 // arguments get specially formatted
5197 static const char *getParamError(TypeFunction *tf, Expression *arg, Parameter *par)
5199 if (global.gag && !global.params.showGaggedErrors)
5200 return NULL;
5201 // show qualification when toChars() is the same but types are different
5202 const char *at = arg->type->toChars();
5203 bool qual = !arg->type->equals(par->type) && strcmp(at, par->type->toChars()) == 0;
5204 if (qual)
5205 at = arg->type->toPrettyChars(true);
5206 OutBuffer buf;
5207 // only mention rvalue if it's relevant
5208 const bool rv = !arg->isLvalue() && (par->storageClass & (STCref | STCout)) != 0;
5209 buf.printf("cannot pass %sargument `%s` of type `%s` to parameter `%s`",
5210 rv ? "rvalue " : "", arg->toChars(), at,
5211 parameterToChars(par, tf, qual));
5212 return buf.extractChars();
5215 static const char *getMatchError(const char *format, ...)
5217 if (global.gag && !global.params.showGaggedErrors)
5218 return NULL;
5219 OutBuffer buf;
5220 va_list ap;
5221 va_start(ap, format);
5222 buf.vprintf(format, ap);
5223 va_end(ap);
5224 return buf.extractChars();
5227 /********************************
5228 * 'args' are being matched to function 'this'
5229 * Determine match level.
5230 * Input:
5231 * flag 1 performing a partial ordering match
5232 * pMessage address to store error message, or null
5233 * Returns:
5234 * MATCHxxxx
5237 MATCH TypeFunction::callMatch(Type *tthis, Expressions *args, int flag, const char **pMessage)
5239 //printf("TypeFunction::callMatch() %s\n", toChars());
5240 MATCH match = MATCHexact; // assume exact match
5241 unsigned char wildmatch = 0;
5243 if (tthis)
5245 Type *t = tthis;
5246 if (t->toBasetype()->ty == Tpointer)
5247 t = t->toBasetype()->nextOf(); // change struct* to struct
5248 if (t->mod != mod)
5250 if (MODimplicitConv(t->mod, mod))
5251 match = MATCHconst;
5252 else if ((mod & MODwild) && MODimplicitConv(t->mod, (mod & ~MODwild) | MODconst))
5254 match = MATCHconst;
5256 else
5257 return MATCHnomatch;
5259 if (isWild())
5261 if (t->isWild())
5262 wildmatch |= MODwild;
5263 else if (t->isConst())
5264 wildmatch |= MODconst;
5265 else if (t->isImmutable())
5266 wildmatch |= MODimmutable;
5267 else
5268 wildmatch |= MODmutable;
5272 size_t nparams = parameterList.length();
5273 size_t nargs = args ? args->length : 0;
5274 if (nargs > nparams)
5276 if (parameterList.varargs == VARARGnone)
5278 // suppress early exit if an error message is wanted,
5279 // so we can check any matching args are valid
5280 if (!pMessage)
5281 goto Nomatch; // too many args; no match
5283 match = MATCHconvert; // match ... with a "conversion" match level
5286 for (size_t u = 0; u < nargs; u++)
5288 if (u >= nparams)
5289 break;
5290 Parameter *p = parameterList[u];
5291 Expression *arg = (*args)[u];
5292 assert(arg);
5293 Type *tprm = p->type;
5294 Type *targ = arg->type;
5296 if (!(p->storageClass & STClazy && tprm->ty == Tvoid && targ->ty != Tvoid))
5298 bool isRef = (p->storageClass & (STCref | STCout)) != 0;
5299 wildmatch |= targ->deduceWild(tprm, isRef);
5302 if (wildmatch)
5304 /* Calculate wild matching modifier
5306 if (wildmatch & MODconst || wildmatch & (wildmatch - 1))
5307 wildmatch = MODconst;
5308 else if (wildmatch & MODimmutable)
5309 wildmatch = MODimmutable;
5310 else if (wildmatch & MODwild)
5311 wildmatch = MODwild;
5312 else
5314 assert(wildmatch & MODmutable);
5315 wildmatch = MODmutable;
5319 for (size_t u = 0; u < nparams; u++)
5321 MATCH m;
5323 Parameter *p = parameterList[u];
5324 assert(p);
5325 if (u >= nargs)
5327 if (p->defaultArg)
5328 continue;
5329 goto L1; // try typesafe variadics
5332 Expression *arg = (*args)[u];
5333 assert(arg);
5334 //printf("arg: %s, type: %s\n", arg->toChars(), arg->type->toChars());
5336 Type *targ = arg->type;
5337 Type *tprm = wildmatch ? p->type->substWildTo(wildmatch) : p->type;
5339 if (p->storageClass & STClazy && tprm->ty == Tvoid && targ->ty != Tvoid)
5340 m = MATCHconvert;
5341 else
5343 //printf("%s of type %s implicitConvTo %s\n", arg->toChars(), targ->toChars(), tprm->toChars());
5344 if (flag)
5346 // for partial ordering, value is an irrelevant mockup, just look at the type
5347 m = targ->implicitConvTo(tprm);
5349 else
5350 m = arg->implicitConvTo(tprm);
5351 //printf("match %d\n", m);
5354 // Non-lvalues do not match ref or out parameters
5355 if (p->storageClass & (STCref | STCout))
5357 // Bugzilla 13783: Don't use toBasetype() to handle enum types.
5358 Type *ta = targ;
5359 Type *tp = tprm;
5360 //printf("fparam[%d] ta = %s, tp = %s\n", u, ta->toChars(), tp->toChars());
5362 if (m && !arg->isLvalue())
5364 if (p->storageClass & STCout)
5366 if (pMessage) *pMessage = getParamError(this, arg, p);
5367 goto Nomatch;
5370 if (arg->op == TOKstring && tp->ty == Tsarray)
5372 if (ta->ty != Tsarray)
5374 Type *tn = tp->nextOf()->castMod(ta->nextOf()->mod);
5375 dinteger_t dim = ((StringExp *)arg)->len;
5376 ta = tn->sarrayOf(dim);
5379 else if (arg->op == TOKslice && tp->ty == Tsarray)
5381 // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
5382 if (ta->ty != Tsarray)
5384 Type *tn = ta->nextOf();
5385 dinteger_t dim = ((TypeSArray *)tp)->dim->toUInteger();
5386 ta = tn->sarrayOf(dim);
5389 else
5391 if (pMessage) *pMessage = getParamError(this, arg, p);
5392 goto Nomatch;
5396 /* Find most derived alias this type being matched.
5397 * Bugzilla 15674: Allow on both ref and out parameters.
5399 while (1)
5401 Type *tat = ta->toBasetype()->aliasthisOf();
5402 if (!tat || !tat->implicitConvTo(tprm))
5403 break;
5404 ta = tat;
5407 /* A ref variable should work like a head-const reference.
5408 * e.g. disallows:
5409 * ref T <- an lvalue of const(T) argument
5410 * ref T[dim] <- an lvalue of const(T[dim]) argument
5412 if (!ta->constConv(tp))
5414 if (pMessage) *pMessage = getParamError(this, arg, p);
5415 goto Nomatch;
5420 /* prefer matching the element type rather than the array
5421 * type when more arguments are present with T[]...
5423 if (parameterList.varargs == VARARGtypesafe && u + 1 == nparams && nargs > nparams)
5424 goto L1;
5426 //printf("\tm = %d\n", m);
5427 if (m == MATCHnomatch) // if no match
5430 if (parameterList.varargs == VARARGtypesafe && u + 1 == nparams) // if last varargs param
5432 Type *tb = p->type->toBasetype();
5433 TypeSArray *tsa;
5434 dinteger_t sz;
5436 switch (tb->ty)
5438 case Tsarray:
5439 tsa = (TypeSArray *)tb;
5440 sz = tsa->dim->toInteger();
5441 if (sz != nargs - u)
5443 if (pMessage)
5444 *pMessage = getMatchError("expected %llu variadic argument(s), not %zu", sz, nargs - u);
5445 goto Nomatch;
5447 /* fall through */
5448 case Tarray:
5450 TypeArray *ta = (TypeArray *)tb;
5451 for (; u < nargs; u++)
5453 Expression *arg = (*args)[u];
5454 assert(arg);
5456 /* If lazy array of delegates,
5457 * convert arg(s) to delegate(s)
5459 Type *tret = p->isLazyArray();
5460 if (tret)
5462 if (ta->next->equals(arg->type))
5463 m = MATCHexact;
5464 else if (tret->toBasetype()->ty == Tvoid)
5465 m = MATCHconvert;
5466 else
5468 m = arg->implicitConvTo(tret);
5469 if (m == MATCHnomatch)
5470 m = arg->implicitConvTo(ta->next);
5473 else
5474 m = arg->implicitConvTo(ta->next);
5476 if (m == MATCHnomatch)
5478 if (pMessage) *pMessage = getParamError(this, arg, p);
5479 goto Nomatch;
5481 if (m < match)
5482 match = m;
5484 goto Ldone;
5486 case Tclass:
5487 // Should see if there's a constructor match?
5488 // Or just leave it ambiguous?
5489 goto Ldone;
5491 default:
5492 break;
5495 if (pMessage && u < nargs)
5496 *pMessage = getParamError(this, (*args)[u], p);
5497 else if (pMessage)
5498 *pMessage = getMatchError("missing argument for parameter #%d: `%s`",
5499 u + 1, parameterToChars(p, this, false));
5500 goto Nomatch;
5502 if (m < match)
5503 match = m; // pick worst match
5506 Ldone:
5507 if (pMessage && !parameterList.varargs && nargs > nparams)
5509 // all parameters had a match, but there are surplus args
5510 *pMessage = getMatchError("expected %d argument(s), not %d", nparams, nargs);
5511 goto Nomatch;
5513 //printf("match = %d\n", match);
5514 return match;
5516 Nomatch:
5517 //printf("no match\n");
5518 return MATCHnomatch;
5521 /********************************************
5522 * Return true if there are lazy parameters.
5524 bool TypeFunction::hasLazyParameters()
5526 size_t dim = parameterList.length();
5527 for (size_t i = 0; i < dim; i++)
5529 Parameter *fparam = parameterList[i];
5530 if (fparam->storageClass & STClazy)
5531 return true;
5533 return false;
5536 /*******************************
5537 * Check for `extern (D) U func(T t, ...)` variadic function type,
5538 * which has `_arguments[]` added as the first argument.
5539 * Returns:
5540 * true if D-style variadic
5542 bool TypeFunction::isDstyleVariadic() const
5544 return linkage == LINKd && parameterList.varargs == VARARGvariadic;
5547 /***************************
5548 * Examine function signature for parameter p and see if
5549 * the value of p can 'escape' the scope of the function.
5550 * This is useful to minimize the needed annotations for the parameters.
5551 * Params:
5552 * p = parameter to this function
5553 * Returns:
5554 * true if escapes via assignment to global or through a parameter
5557 bool TypeFunction::parameterEscapes(Parameter *p)
5559 /* Scope parameters do not escape.
5560 * Allow 'lazy' to imply 'scope' -
5561 * lazy parameters can be passed along
5562 * as lazy parameters to the next function, but that isn't
5563 * escaping.
5565 if (parameterStorageClass(p) & (STCscope | STClazy))
5566 return false;
5567 return true;
5570 /************************************
5571 * Take the specified storage class for p,
5572 * and use the function signature to infer whether
5573 * STCscope and STCreturn should be OR'd in.
5574 * (This will not affect the name mangling.)
5575 * Params:
5576 * p = one of the parameters to 'this'
5577 * Returns:
5578 * storage class with STCscope or STCreturn OR'd in
5580 StorageClass TypeFunction::parameterStorageClass(Parameter *p)
5582 StorageClass stc = p->storageClass;
5583 if (!global.params.vsafe)
5584 return stc;
5586 if (stc & (STCscope | STCreturn | STClazy) || purity == PUREimpure)
5587 return stc;
5589 /* If haven't inferred the return type yet, can't infer storage classes
5591 if (!nextOf())
5592 return stc;
5594 purityLevel();
5596 // See if p can escape via any of the other parameters
5597 if (purity == PUREweak)
5599 const size_t dim = parameterList.length();
5600 for (size_t i = 0; i < dim; i++)
5602 Parameter *fparam = parameterList[i];
5603 Type *t = fparam->type;
5604 if (!t)
5605 continue;
5606 t = t->baseElemOf();
5607 if (t->isMutable() && t->hasPointers())
5609 if (fparam->storageClass & (STCref | STCout))
5612 else if (t->ty == Tarray || t->ty == Tpointer)
5614 Type *tn = t->nextOf()->toBasetype();
5615 if (!(tn->isMutable() && tn->hasPointers()))
5616 continue;
5618 return stc;
5623 stc |= STCscope;
5625 /* Inferring STCreturn here has false positives
5626 * for pure functions, producing spurious error messages
5627 * about escaping references.
5628 * Give up on it for now.
5630 return stc;
5633 Expression *TypeFunction::defaultInit(Loc loc)
5635 error(loc, "function does not have a default initializer");
5636 return new ErrorExp();
5639 Type *TypeFunction::addStorageClass(StorageClass stc)
5641 //printf("addStorageClass(%llx) %d\n", stc, (stc & STCscope) != 0);
5642 TypeFunction *t = Type::addStorageClass(stc)->toTypeFunction();
5643 if ((stc & STCpure && !t->purity) ||
5644 (stc & STCnothrow && !t->isnothrow) ||
5645 (stc & STCnogc && !t->isnogc) ||
5646 (stc & STCscope && !t->isscope) ||
5647 (stc & STCsafe && t->trust < TRUSTtrusted))
5649 // Klunky to change these
5650 TypeFunction *tf = new TypeFunction(t->parameterList, t->next, t->linkage, 0);
5651 tf->mod = t->mod;
5652 tf->fargs = fargs;
5653 tf->purity = t->purity;
5654 tf->isnothrow = t->isnothrow;
5655 tf->isnogc = t->isnogc;
5656 tf->isproperty = t->isproperty;
5657 tf->isref = t->isref;
5658 tf->isreturn = t->isreturn;
5659 tf->isscope = t->isscope;
5660 tf->isscopeinferred = t->isscopeinferred;
5661 tf->trust = t->trust;
5662 tf->iswild = t->iswild;
5664 if (stc & STCpure)
5665 tf->purity = PUREfwdref;
5666 if (stc & STCnothrow)
5667 tf->isnothrow = true;
5668 if (stc & STCnogc)
5669 tf->isnogc = true;
5670 if (stc & STCsafe)
5671 tf->trust = TRUSTsafe;
5672 if (stc & STCscope)
5674 tf->isscope = true;
5675 if (stc & STCscopeinferred)
5676 tf->isscopeinferred = true;
5679 tf->deco = tf->merge()->deco;
5680 t = tf;
5682 return t;
5685 /** For each active attribute (ref/const/nogc/etc) call fp with a void* for the
5686 work param and a string representation of the attribute. */
5687 int TypeFunction::attributesApply(void *param, int (*fp)(void *, const char *), TRUSTformat trustFormat)
5689 int res = 0;
5691 if (purity) res = fp(param, "pure");
5692 if (res) return res;
5694 if (isnothrow) res = fp(param, "nothrow");
5695 if (res) return res;
5697 if (isnogc) res = fp(param, "@nogc");
5698 if (res) return res;
5700 if (isproperty) res = fp(param, "@property");
5701 if (res) return res;
5703 if (isref) res = fp(param, "ref");
5704 if (res) return res;
5706 if (isreturn) res = fp(param, "return");
5707 if (res) return res;
5709 if (isscope && !isscopeinferred) res = fp(param, "scope");
5710 if (res) return res;
5712 TRUST trustAttrib = trust;
5714 if (trustAttrib == TRUSTdefault)
5716 // Print out "@system" when trust equals TRUSTdefault (if desired).
5717 if (trustFormat == TRUSTformatSystem)
5718 trustAttrib = TRUSTsystem;
5719 else
5720 return res; // avoid calling with an empty string
5723 return fp(param, trustToChars(trustAttrib));
5726 /***************************** TypeDelegate *****************************/
5728 TypeDelegate::TypeDelegate(Type *t)
5729 : TypeNext(Tfunction, t)
5731 ty = Tdelegate;
5734 TypeDelegate *TypeDelegate::create(Type *t)
5736 return new TypeDelegate(t);
5739 const char *TypeDelegate::kind()
5741 return "delegate";
5744 Type *TypeDelegate::syntaxCopy()
5746 Type *t = next->syntaxCopy();
5747 if (t == next)
5748 t = this;
5749 else
5751 t = new TypeDelegate(t);
5752 t->mod = mod;
5754 return t;
5757 Type *TypeDelegate::addStorageClass(StorageClass stc)
5759 TypeDelegate *t = (TypeDelegate*)Type::addStorageClass(stc);
5760 if (!global.params.vsafe)
5761 return t;
5763 /* The rest is meant to add 'scope' to a delegate declaration if it is of the form:
5764 * alias dg_t = void* delegate();
5765 * scope dg_t dg = ...;
5767 if (stc & STCscope)
5769 Type *n = t->next->addStorageClass(STCscope | STCscopeinferred);
5770 if (n != t->next)
5772 t->next = n;
5773 t->deco = t->merge()->deco; // mangling supposed to not be changed due to STCscopeinferrred
5776 return t;
5779 d_uns64 TypeDelegate::size(Loc)
5781 return target.ptrsize * 2;
5784 unsigned TypeDelegate::alignsize()
5786 return target.ptrsize;
5789 MATCH TypeDelegate::implicitConvTo(Type *to)
5791 //printf("TypeDelegate::implicitConvTo(this=%p, to=%p)\n", this, to);
5792 //printf("from: %s\n", toChars());
5793 //printf("to : %s\n", to->toChars());
5794 if (this == to)
5795 return MATCHexact;
5796 #if 1 // not allowing covariant conversions because it interferes with overriding
5797 if (to->ty == Tdelegate && this->nextOf()->covariant(to->nextOf()) == 1)
5799 Type *tret = this->next->nextOf();
5800 Type *toret = ((TypeDelegate *)to)->next->nextOf();
5801 if (tret->ty == Tclass && toret->ty == Tclass)
5803 /* Bugzilla 10219: Check covariant interface return with offset tweaking.
5804 * interface I {}
5805 * class C : Object, I {}
5806 * I delegate() dg = delegate C() {} // should be error
5808 int offset = 0;
5809 if (toret->isBaseOf(tret, &offset) && offset != 0)
5810 return MATCHnomatch;
5812 return MATCHconvert;
5814 #endif
5815 return MATCHnomatch;
5818 Expression *TypeDelegate::defaultInit(Loc loc)
5820 return new NullExp(loc, this);
5823 bool TypeDelegate::isZeroInit(Loc)
5825 return true;
5828 bool TypeDelegate::isBoolean()
5830 return true;
5833 Expression *TypeDelegate::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
5835 if (ident == Id::ptr)
5837 e = new DelegatePtrExp(e->loc, e);
5838 e = expressionSemantic(e, sc);
5840 else if (ident == Id::funcptr)
5842 if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
5844 e->error("%s.funcptr cannot be used in @safe code", e->toChars());
5845 return new ErrorExp();
5847 e = new DelegateFuncptrExp(e->loc, e);
5848 e = expressionSemantic(e, sc);
5850 else
5852 e = Type::dotExp(sc, e, ident, flag);
5854 return e;
5857 bool TypeDelegate::hasPointers()
5859 return true;
5862 /***************************** TypeTraits ********************************/
5864 TypeTraits::TypeTraits(const Loc &loc, TraitsExp *exp)
5865 : Type(Ttraits)
5867 this->loc = loc;
5868 this->exp = exp;
5869 this->sym = NULL;
5872 Type *TypeTraits::syntaxCopy()
5874 TraitsExp *te = (TraitsExp *) exp->syntaxCopy();
5875 TypeTraits *tt = new TypeTraits(loc, te);
5876 tt->mod = mod;
5877 return tt;
5880 Dsymbol *TypeTraits::toDsymbol(Scope *sc)
5882 Type *t = NULL;
5883 Expression *e = NULL;
5884 Dsymbol *s = NULL;
5885 resolve(loc, sc, &e, &t, &s);
5886 if (t && t->ty != Terror)
5887 s = t->toDsymbol(sc);
5888 else if (e)
5889 s = getDsymbol(e);
5891 return s;
5894 void TypeTraits::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool)
5896 *pt = NULL;
5897 *pe = NULL;
5898 *ps = NULL;
5900 if (Type *t = typeSemantic(this, loc, sc))
5901 *pt = t;
5902 else if (sym)
5903 *ps = sym;
5904 else
5905 *pt = Type::terror;
5908 d_uns64 TypeTraits::size(Loc)
5910 return SIZE_INVALID;
5913 /***************************** TypeMixin *****************************/
5915 /******
5916 * Implements mixin types.
5918 * Semantic analysis will convert it to a real type.
5920 TypeMixin::TypeMixin(const Loc &loc, Expressions *exps)
5921 : Type(Tmixin)
5923 this->loc = loc;
5924 this->exps = exps;
5925 this->obj = NULL; // cached result of semantic analysis.
5928 const char *TypeMixin::kind()
5930 return "mixin";
5933 Type *TypeMixin::syntaxCopy()
5935 return new TypeMixin(loc, Expression::arraySyntaxCopy(exps));
5938 Dsymbol *TypeMixin::toDsymbol(Scope *sc)
5940 Type *t = NULL;
5941 Expression *e = NULL;
5942 Dsymbol *s = NULL;
5943 resolve(loc, sc, &e, &t, &s);
5944 if (t)
5945 s = t->toDsymbol(sc);
5946 else if (e)
5947 s = getDsymbol(e);
5949 return s;
5952 void TypeMixin::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
5954 // if already resolved just set pe/pt/ps and return.
5955 if (obj)
5957 *pe = isExpression(obj);
5958 *pt = isType(obj);
5959 *ps = isDsymbol(obj);
5960 return;
5963 RootObject *o = compileTypeMixin(this, loc, sc);
5964 if (Type *t = isType(o))
5966 t->resolve(loc, sc, pe, pt, ps, intypeid);
5967 if (*pt)
5968 (*pt) = (*pt)->addMod(mod);
5970 else if (Expression *e = isExpression(o))
5972 e = expressionSemantic(e, sc);
5973 if (TypeExp *et = e->isTypeExp())
5975 *pe = NULL;
5976 *pt = et->type->addMod(mod);
5977 *ps = NULL;
5979 else
5981 *pe = e;
5982 *pt = NULL;
5983 *ps = NULL;
5986 else
5988 *pe = NULL;
5989 *pt = Type::terror;
5990 *ps = NULL;
5993 // save the result
5994 obj = *pe ? (RootObject *)*pe : (*pt ? (RootObject *)*pt : (RootObject *)*ps);
5997 /***************************** TypeQualified *****************************/
5999 TypeQualified::TypeQualified(TY ty, Loc loc)
6000 : Type(ty)
6002 this->loc = loc;
6005 void TypeQualified::syntaxCopyHelper(TypeQualified *t)
6007 //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars());
6008 idents.setDim(t->idents.length);
6009 for (size_t i = 0; i < idents.length; i++)
6011 RootObject *id = t->idents[i];
6012 if (id->dyncast() == DYNCAST_DSYMBOL)
6014 TemplateInstance *ti = (TemplateInstance *)id;
6016 ti = (TemplateInstance *)ti->syntaxCopy(NULL);
6017 id = ti;
6019 else if (id->dyncast() == DYNCAST_EXPRESSION)
6021 Expression *e = (Expression *)id;
6022 e = e->syntaxCopy();
6023 id = e;
6025 else if (id->dyncast() == DYNCAST_TYPE)
6027 Type *tx = (Type *)id;
6028 tx = tx->syntaxCopy();
6029 id = tx;
6031 idents[i] = id;
6035 void TypeQualified::addIdent(Identifier *ident)
6037 idents.push(ident);
6040 void TypeQualified::addInst(TemplateInstance *inst)
6042 idents.push(inst);
6045 void TypeQualified::addIndex(RootObject *e)
6047 idents.push(e);
6050 d_uns64 TypeQualified::size(Loc)
6052 error(this->loc, "size of type %s is not known", toChars());
6053 return SIZE_INVALID;
6056 /*************************************
6057 * Resolve a tuple index.
6059 void TypeQualified::resolveTupleIndex(Loc loc, Scope *sc, Dsymbol *s,
6060 Expression **pe, Type **pt, Dsymbol **ps, RootObject *oindex)
6062 *pt = NULL;
6063 *ps = NULL;
6064 *pe = NULL;
6066 TupleDeclaration *td = s->isTupleDeclaration();
6068 Expression *eindex = isExpression(oindex);
6069 Type *tindex = isType(oindex);
6070 Dsymbol *sindex = isDsymbol(oindex);
6072 if (!td)
6074 // It's really an index expression
6075 if (tindex)
6076 eindex = new TypeExp(loc, tindex);
6077 else if (sindex)
6078 eindex = ::resolve(loc, sc, sindex, false);
6079 Expression *e = new IndexExp(loc, ::resolve(loc, sc, s, false), eindex);
6080 e = expressionSemantic(e, sc);
6081 resolveExp(e, pt, pe, ps);
6082 return;
6085 // Convert oindex to Expression, then try to resolve to constant.
6086 if (tindex)
6087 tindex->resolve(loc, sc, &eindex, &tindex, &sindex);
6088 if (sindex)
6089 eindex = ::resolve(loc, sc, sindex, false);
6090 if (!eindex)
6092 ::error(loc, "index is %s not an expression", oindex->toChars());
6093 *pt = Type::terror;
6094 return;
6096 sc = sc->startCTFE();
6097 eindex = expressionSemantic(eindex, sc);
6098 sc = sc->endCTFE();
6100 eindex = eindex->ctfeInterpret();
6101 if (eindex->op == TOKerror)
6103 *pt = Type::terror;
6104 return;
6107 const uinteger_t d = eindex->toUInteger();
6108 if (d >= td->objects->length)
6110 ::error(loc, "tuple index %llu exceeds length %u", (ulonglong)d, (unsigned)td->objects->length);
6111 *pt = Type::terror;
6112 return;
6115 RootObject *o = (*td->objects)[(size_t)d];
6116 *pt = isType(o);
6117 *ps = isDsymbol(o);
6118 *pe = isExpression(o);
6120 if (*pt)
6121 *pt = typeSemantic(*pt, loc, sc);
6122 if (*pe)
6123 resolveExp(*pe, pt, pe, ps);
6126 /*************************************
6127 * Takes an array of Identifiers and figures out if
6128 * it represents a Type or an Expression.
6129 * Output:
6130 * if expression, *pe is set
6131 * if type, *pt is set
6133 void TypeQualified::resolveHelper(Loc loc, Scope *sc,
6134 Dsymbol *s, Dsymbol *,
6135 Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
6137 *pe = NULL;
6138 *pt = NULL;
6139 *ps = NULL;
6140 if (s)
6142 //printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
6143 Declaration *d = s->isDeclaration();
6144 if (d && (d->storage_class & STCtemplateparameter))
6145 s = s->toAlias();
6146 else
6148 // check for deprecated aliases
6149 s->checkDeprecated(loc, sc);
6150 if (d)
6151 d->checkDisabled(loc, sc, true);
6154 s = s->toAlias();
6155 //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
6156 for (size_t i = 0; i < idents.length; i++)
6158 RootObject *id = idents[i];
6160 if (id->dyncast() == DYNCAST_EXPRESSION ||
6161 id->dyncast() == DYNCAST_TYPE)
6163 Type *tx;
6164 Expression *ex;
6165 Dsymbol *sx;
6166 resolveTupleIndex(loc, sc, s, &ex, &tx, &sx, id);
6167 if (sx)
6169 s = sx->toAlias();
6170 continue;
6172 if (tx)
6173 ex = new TypeExp(loc, tx);
6174 assert(ex);
6176 ex = typeToExpressionHelper(this, ex, i + 1);
6177 ex = expressionSemantic(ex, sc);
6178 resolveExp(ex, pt, pe, ps);
6179 return;
6182 Type *t = s->getType(); // type symbol, type alias, or type tuple?
6183 unsigned errorsave = global.errors;
6184 int flags = t == NULL ? SearchLocalsOnly : IgnorePrivateImports;
6185 Dsymbol *sm = s->searchX(loc, sc, id, flags);
6186 if (sm)
6188 if (!(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, sm))
6190 ::error(loc, "`%s` is not visible from module `%s`", sm->toPrettyChars(), sc->_module->toChars());
6191 sm = NULL;
6193 // Same check as in Expression::semanticY(DotIdExp)
6194 else if (sm->isPackage() && checkAccess(sc, (Package *)sm))
6196 // @@@DEPRECATED_2.096@@@
6197 // Should be an error in 2.106. Just remove the deprecation call
6198 // and uncomment the null assignment
6199 ::deprecation(loc, "%s %s is not accessible here, perhaps add 'static import %s;'",
6200 sm->kind(), sm->toPrettyChars(), sm->toPrettyChars());
6201 //sm = null;
6204 if (global.errors != errorsave)
6206 *pt = Type::terror;
6207 return;
6209 //printf("\t3: s = %p %s %s, sm = %p\n", s, s->kind(), s->toChars(), sm);
6210 if (intypeid && !t && sm && sm->needThis())
6211 goto L3;
6212 if (VarDeclaration *v = s->isVarDeclaration())
6214 // https://issues.dlang.org/show_bug.cgi?id=19913
6215 // v->type would be null if it is a forward referenced member.
6216 if (v->type == NULL)
6217 dsymbolSemantic(v, sc);
6218 if (v->storage_class & (STCconst | STCimmutable | STCmanifest) ||
6219 v->type->isConst() || v->type->isImmutable())
6221 // Bugzilla 13087: this.field is not constant always
6222 if (!v->isThisDeclaration())
6223 goto L3;
6226 if (!sm)
6228 if (!t)
6230 if (s->isDeclaration()) // var, func, or tuple declaration?
6232 t = s->isDeclaration()->type;
6233 if (!t && s->isTupleDeclaration()) // expression tuple?
6234 goto L3;
6236 else if (s->isTemplateInstance() ||
6237 s->isImport() || s->isPackage() || s->isModule())
6239 goto L3;
6242 if (t)
6244 sm = t->toDsymbol(sc);
6245 if (sm && id->dyncast() == DYNCAST_IDENTIFIER)
6247 sm = sm->search(loc, (Identifier *)id, IgnorePrivateImports);
6248 if (sm)
6249 goto L2;
6252 Expression *e;
6253 VarDeclaration *v = s->isVarDeclaration();
6254 FuncDeclaration *f = s->isFuncDeclaration();
6255 if (intypeid || (!v && !f))
6256 e = ::resolve(loc, sc, s, true);
6257 else
6258 e = new VarExp(loc, s->isDeclaration(), true);
6260 e = typeToExpressionHelper(this, e, i);
6261 e = expressionSemantic(e, sc);
6262 resolveExp(e, pt, pe, ps);
6263 return;
6265 else
6267 if (id->dyncast() == DYNCAST_DSYMBOL)
6269 // searchX already handles errors for template instances
6270 assert(global.errors);
6272 else
6274 assert(id->dyncast() == DYNCAST_IDENTIFIER);
6275 sm = s->search_correct((Identifier *)id);
6276 if (sm)
6277 error(loc, "identifier `%s` of `%s` is not defined, did you mean %s `%s`?",
6278 id->toChars(), toChars(), sm->kind(), sm->toChars());
6279 else
6280 error(loc, "identifier `%s` of `%s` is not defined", id->toChars(), toChars());
6282 *pe = new ErrorExp();
6284 return;
6287 s = sm->toAlias();
6290 if (EnumMember *em = s->isEnumMember())
6292 // It's not a type, it's an expression
6293 *pe = em->getVarExp(loc, sc);
6294 return;
6296 if (VarDeclaration *v = s->isVarDeclaration())
6298 /* This is mostly same with DsymbolExp::semantic(), but we cannot use it
6299 * because some variables used in type context need to prevent lowering
6300 * to a literal or contextful expression. For example:
6302 * enum a = 1; alias b = a;
6303 * template X(alias e){ alias v = e; } alias x = X!(1);
6304 * struct S { int v; alias w = v; }
6305 * // TypeIdentifier 'a', 'e', and 'v' should be TOKvar,
6306 * // because getDsymbol() need to work in AliasDeclaration::semantic().
6308 if (!v->type ||
6309 (!v->type->deco && v->inuse))
6311 if (v->inuse) // Bugzilla 9494
6312 error(loc, "circular reference to %s `%s`", v->kind(), v->toPrettyChars());
6313 else
6314 error(loc, "forward reference to %s `%s`", v->kind(), v->toPrettyChars());
6315 *pt = Type::terror;
6316 return;
6318 if (v->type->ty == Terror)
6319 *pt = Type::terror;
6320 else
6321 *pe = new VarExp(loc, v);
6322 return;
6324 if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
6326 //printf("'%s' is a function literal\n", fld->toChars());
6327 *pe = new FuncExp(loc, fld);
6328 *pe = expressionSemantic(*pe, sc);
6329 return;
6332 Type *t = s->getType();
6333 if (!t)
6335 // If the symbol is an import, try looking inside the import
6336 if (Import *si = s->isImport())
6338 s = si->search(loc, s->ident);
6339 if (s && s != si)
6340 goto L1;
6341 s = si;
6343 *ps = s;
6344 return;
6346 if (t->ty == Tinstance && t != this && !t->deco)
6348 if (!((TypeInstance *)t)->tempinst->errors)
6349 error(loc, "forward reference to `%s`", t->toChars());
6350 *pt = Type::terror;
6351 return;
6354 if (t->ty == Ttuple)
6355 *pt = t;
6356 else
6357 *pt = t->merge();
6359 if (!s)
6361 /* Look for what user might have intended
6363 const char *p = mutableOf()->unSharedOf()->toChars();
6364 Identifier *id = Identifier::idPool(p, strlen(p));
6365 if (const char *n = importHint(p))
6366 error(loc, "`%s` is not defined, perhaps `import %s;` ?", p, n);
6367 else if (Dsymbol *s2 = sc->search_correct(id))
6368 error(loc, "undefined identifier `%s`, did you mean %s `%s`?", p, s2->kind(), s2->toChars());
6369 else if (const char *q = Scope::search_correct_C(id))
6370 error(loc, "undefined identifier `%s`, did you mean `%s`?", p, q);
6371 else
6372 error(loc, "undefined identifier `%s`", p);
6374 *pt = Type::terror;
6378 /***************************** TypeIdentifier *****************************/
6380 TypeIdentifier::TypeIdentifier(Loc loc, Identifier *ident)
6381 : TypeQualified(Tident, loc)
6383 this->ident = ident;
6386 const char *TypeIdentifier::kind()
6388 return "identifier";
6391 Type *TypeIdentifier::syntaxCopy()
6393 TypeIdentifier *t = new TypeIdentifier(loc, ident);
6394 t->syntaxCopyHelper(this);
6395 t->mod = mod;
6396 return t;
6399 /*************************************
6400 * Takes an array of Identifiers and figures out if
6401 * it represents a Type or an Expression.
6402 * Output:
6403 * if expression, *pe is set
6404 * if type, *pt is set
6407 void TypeIdentifier::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
6409 //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars());
6411 if ((ident->equals(Id::_super) || ident->equals(Id::This)) && !hasThis(sc))
6413 AggregateDeclaration *ad = sc->getStructClassScope();
6414 if (ad)
6416 ClassDeclaration *cd = ad->isClassDeclaration();
6417 if (cd)
6419 if (ident->equals(Id::This))
6420 ident = cd->ident;
6421 else if (cd->baseClass && ident->equals(Id::_super))
6422 ident = cd->baseClass->ident;
6424 else
6426 StructDeclaration *sd = ad->isStructDeclaration();
6427 if (sd && ident->equals(Id::This))
6428 ident = sd->ident;
6432 if (ident == Id::ctfe)
6434 error(loc, "variable __ctfe cannot be read at compile time");
6435 *pe = NULL;
6436 *ps = NULL;
6437 *pt = Type::terror;
6438 return;
6441 Dsymbol *scopesym;
6442 Dsymbol *s = sc->search(loc, ident, &scopesym);
6443 resolveHelper(loc, sc, s, scopesym, pe, pt, ps, intypeid);
6444 if (*pt)
6445 (*pt) = (*pt)->addMod(mod);
6448 /*****************************************
6449 * See if type resolves to a symbol, if so,
6450 * return that symbol.
6453 Dsymbol *TypeIdentifier::toDsymbol(Scope *sc)
6455 //printf("TypeIdentifier::toDsymbol('%s')\n", toChars());
6456 if (!sc)
6457 return NULL;
6459 Type *t;
6460 Expression *e;
6461 Dsymbol *s;
6463 resolve(loc, sc, &e, &t, &s);
6464 if (t && t->ty != Tident)
6465 s = t->toDsymbol(sc);
6466 if (e)
6467 s = getDsymbol(e);
6469 return s;
6472 /***************************** TypeInstance *****************************/
6474 TypeInstance::TypeInstance(Loc loc, TemplateInstance *tempinst)
6475 : TypeQualified(Tinstance, loc)
6477 this->tempinst = tempinst;
6480 const char *TypeInstance::kind()
6482 return "instance";
6485 Type *TypeInstance::syntaxCopy()
6487 //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.length);
6488 TypeInstance *t = new TypeInstance(loc, (TemplateInstance *)tempinst->syntaxCopy(NULL));
6489 t->syntaxCopyHelper(this);
6490 t->mod = mod;
6491 return t;
6494 void TypeInstance::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
6496 // Note close similarity to TypeIdentifier::resolve()
6497 *pe = NULL;
6498 *pt = NULL;
6499 *ps = NULL;
6500 //printf("TypeInstance::resolve(sc = %p, tempinst = '%s')\n", sc, tempinst->toChars());
6501 dsymbolSemantic(tempinst, sc);
6502 if (!global.gag && tempinst->errors)
6504 *pt = terror;
6505 return;
6508 resolveHelper(loc, sc, tempinst, NULL, pe, pt, ps, intypeid);
6509 if (*pt)
6510 *pt = (*pt)->addMod(mod);
6511 //if (*pt) printf("pt = '%s'\n", (*pt)->toChars());
6514 Dsymbol *TypeInstance::toDsymbol(Scope *sc)
6516 Type *t;
6517 Expression *e;
6518 Dsymbol *s;
6520 //printf("TypeInstance::semantic(%s)\n", toChars());
6521 resolve(loc, sc, &e, &t, &s);
6522 if (t && t->ty != Tinstance)
6523 s = t->toDsymbol(sc);
6525 return s;
6529 /***************************** TypeTypeof *****************************/
6531 TypeTypeof::TypeTypeof(Loc loc, Expression *exp)
6532 : TypeQualified(Ttypeof, loc)
6534 this->exp = exp;
6535 inuse = 0;
6538 const char *TypeTypeof::kind()
6540 return "typeof";
6543 Type *TypeTypeof::syntaxCopy()
6545 //printf("TypeTypeof::syntaxCopy() %s\n", toChars());
6546 TypeTypeof *t = new TypeTypeof(loc, exp->syntaxCopy());
6547 t->syntaxCopyHelper(this);
6548 t->mod = mod;
6549 return t;
6552 Dsymbol *TypeTypeof::toDsymbol(Scope *sc)
6554 //printf("TypeTypeof::toDsymbol('%s')\n", toChars());
6555 Expression *e;
6556 Type *t;
6557 Dsymbol *s;
6558 resolve(loc, sc, &e, &t, &s);
6560 return s;
6563 void TypeTypeof::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
6565 *pe = NULL;
6566 *pt = NULL;
6567 *ps = NULL;
6569 //printf("TypeTypeof::resolve(sc = %p, idents = '%s')\n", sc, toChars());
6570 //static int nest; if (++nest == 50) *(char*)0=0;
6571 if (sc == NULL)
6573 *pt = Type::terror;
6574 error(loc, "Invalid scope.");
6575 return;
6577 if (inuse)
6579 inuse = 2;
6580 error(loc, "circular typeof definition");
6581 Lerr:
6582 *pt = Type::terror;
6583 inuse--;
6584 return;
6586 inuse++;
6588 Type *t;
6590 /* Currently we cannot evalute 'exp' in speculative context, because
6591 * the type implementation may leak to the final execution. Consider:
6593 * struct S(T) {
6594 * string toString() const { return "x"; }
6596 * void main() {
6597 * alias X = typeof(S!int());
6598 * assert(typeid(X).xtoString(null) == "x");
6601 Scope *sc2 = sc->push();
6602 sc2->intypeof = 1;
6603 Expression *exp2 = expressionSemantic(exp, sc2);
6604 exp2 = resolvePropertiesOnly(sc2, exp2);
6605 sc2->pop();
6607 if (exp2->op == TOKerror)
6609 if (!global.gag)
6610 exp = exp2;
6611 goto Lerr;
6613 exp = exp2;
6615 if (exp->op == TOKtype ||
6616 exp->op == TOKscope)
6618 if (exp->checkType())
6619 goto Lerr;
6621 /* Today, 'typeof(func)' returns void if func is a
6622 * function template (TemplateExp), or
6623 * template lambda (FuncExp).
6624 * It's actually used in Phobos as an idiom, to branch code for
6625 * template functions.
6628 if (FuncDeclaration *f = exp->op == TOKvar ? (( VarExp *)exp)->var->isFuncDeclaration()
6629 : exp->op == TOKdotvar ? ((DotVarExp *)exp)->var->isFuncDeclaration() : NULL)
6631 if (f->checkForwardRef(loc))
6632 goto Lerr;
6634 if (FuncDeclaration *f = isFuncAddress(exp))
6636 if (f->checkForwardRef(loc))
6637 goto Lerr;
6640 t = exp->type;
6641 if (!t)
6643 error(loc, "expression (%s) has no type", exp->toChars());
6644 goto Lerr;
6646 if (t->ty == Ttypeof)
6648 error(loc, "forward reference to %s", toChars());
6649 goto Lerr;
6652 if (idents.length == 0)
6653 *pt = t;
6654 else
6656 if (Dsymbol *s = t->toDsymbol(sc))
6657 resolveHelper(loc, sc, s, NULL, pe, pt, ps, intypeid);
6658 else
6660 Expression *e = typeToExpressionHelper(this, new TypeExp(loc, t));
6661 e = expressionSemantic(e, sc);
6662 resolveExp(e, pt, pe, ps);
6665 if (*pt)
6666 (*pt) = (*pt)->addMod(mod);
6667 inuse--;
6668 return;
6671 d_uns64 TypeTypeof::size(Loc loc)
6673 if (exp->type)
6674 return exp->type->size(loc);
6675 else
6676 return TypeQualified::size(loc);
6681 /***************************** TypeReturn *****************************/
6683 TypeReturn::TypeReturn(Loc loc)
6684 : TypeQualified(Treturn, loc)
6688 const char *TypeReturn::kind()
6690 return "return";
6693 Type *TypeReturn::syntaxCopy()
6695 TypeReturn *t = new TypeReturn(loc);
6696 t->syntaxCopyHelper(this);
6697 t->mod = mod;
6698 return t;
6701 Dsymbol *TypeReturn::toDsymbol(Scope *sc)
6703 Expression *e;
6704 Type *t;
6705 Dsymbol *s;
6706 resolve(loc, sc, &e, &t, &s);
6708 return s;
6711 void TypeReturn::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
6713 *pe = NULL;
6714 *pt = NULL;
6715 *ps = NULL;
6717 //printf("TypeReturn::resolve(sc = %p, idents = '%s')\n", sc, toChars());
6718 Type *t;
6720 FuncDeclaration *func = sc->func;
6721 if (!func)
6723 error(loc, "typeof(return) must be inside function");
6724 goto Lerr;
6726 if (func->fes)
6727 func = func->fes->func;
6729 t = func->type->nextOf();
6730 if (!t)
6732 error(loc, "cannot use typeof(return) inside function %s with inferred return type", sc->func->toChars());
6733 goto Lerr;
6736 if (idents.length == 0)
6737 *pt = t;
6738 else
6740 if (Dsymbol *s = t->toDsymbol(sc))
6741 resolveHelper(loc, sc, s, NULL, pe, pt, ps, intypeid);
6742 else
6744 Expression *e = typeToExpressionHelper(this, new TypeExp(loc, t));
6745 e = expressionSemantic(e, sc);
6746 resolveExp(e, pt, pe, ps);
6749 if (*pt)
6750 (*pt) = (*pt)->addMod(mod);
6751 return;
6753 Lerr:
6754 *pt = Type::terror;
6755 return;
6758 /***************************** TypeEnum *****************************/
6760 TypeEnum::TypeEnum(EnumDeclaration *sym)
6761 : Type(Tenum)
6763 this->sym = sym;
6766 const char *TypeEnum::kind()
6768 return "enum";
6771 Type *TypeEnum::syntaxCopy()
6773 return this;
6776 d_uns64 TypeEnum::size(Loc loc)
6778 return sym->getMemtype(loc)->size(loc);
6781 unsigned TypeEnum::alignsize()
6783 Type *t = sym->getMemtype(Loc());
6784 if (t->ty == Terror)
6785 return 4;
6786 return t->alignsize();
6789 Dsymbol *TypeEnum::toDsymbol(Scope *)
6791 return sym;
6794 Type *TypeEnum::toBasetype()
6796 if (!sym->members && !sym->memtype)
6797 return this;
6798 Type *tb = sym->getMemtype(Loc())->toBasetype();
6799 return tb->castMod(mod); // retain modifier bits from 'this'
6802 Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
6804 // Bugzilla 14010
6805 if (ident == Id::_mangleof)
6806 return getProperty(e->loc, ident, flag & 1);
6808 if (sym->semanticRun < PASSsemanticdone)
6809 dsymbolSemantic(sym, NULL);
6811 Dsymbol *s = sym->search(e->loc, ident);
6812 if (!s)
6814 if (ident == Id::max ||
6815 ident == Id::min ||
6816 ident == Id::_init)
6818 return getProperty(e->loc, ident, flag & 1);
6820 Expression *res = sym->getMemtype(Loc())->dotExp(sc, e, ident, 1);
6821 if (!(flag & 1) && !res)
6823 if (Dsymbol *ns = sym->search_correct(ident))
6824 e->error("no property `%s` for type `%s`. Did you mean `%s.%s` ?",
6825 ident->toChars(), toChars(), toChars(), ns->toChars());
6826 else
6827 e->error("no property `%s` for type `%s`",
6828 ident->toChars(), toChars());
6830 return new ErrorExp();
6832 return res;
6834 EnumMember *m = s->isEnumMember();
6835 return m->getVarExp(e->loc, sc);
6838 Expression *TypeEnum::getProperty(Loc loc, Identifier *ident, int flag)
6840 Expression *e;
6841 if (ident == Id::max || ident == Id::min)
6843 return sym->getMaxMinValue(loc, ident);
6845 else if (ident == Id::_init)
6847 e = defaultInitLiteral(loc);
6849 else if (ident == Id::stringof)
6851 const char *s = toChars();
6852 e = new StringExp(loc, const_cast<char *>(s), strlen(s));
6853 Scope sc;
6854 e = expressionSemantic(e, &sc);
6856 else if (ident == Id::_mangleof)
6858 e = Type::getProperty(loc, ident, flag);
6860 else
6862 e = toBasetype()->getProperty(loc, ident, flag);
6864 return e;
6867 bool TypeEnum::isintegral()
6869 return sym->getMemtype(Loc())->isintegral();
6872 bool TypeEnum::isfloating()
6874 return sym->getMemtype(Loc())->isfloating();
6877 bool TypeEnum::isreal()
6879 return sym->getMemtype(Loc())->isreal();
6882 bool TypeEnum::isimaginary()
6884 return sym->getMemtype(Loc())->isimaginary();
6887 bool TypeEnum::iscomplex()
6889 return sym->getMemtype(Loc())->iscomplex();
6892 bool TypeEnum::isunsigned()
6894 return sym->getMemtype(Loc())->isunsigned();
6897 bool TypeEnum::isscalar()
6899 return sym->getMemtype(Loc())->isscalar();
6902 bool TypeEnum::isString()
6904 return sym->getMemtype(Loc())->isString();
6907 bool TypeEnum::isAssignable()
6909 return sym->getMemtype(Loc())->isAssignable();
6912 bool TypeEnum::isBoolean()
6914 return sym->getMemtype(Loc())->isBoolean();
6917 bool TypeEnum::needsDestruction()
6919 return sym->getMemtype(Loc())->needsDestruction();
6922 bool TypeEnum::needsNested()
6924 return sym->getMemtype(Loc())->needsNested();
6927 MATCH TypeEnum::implicitConvTo(Type *to)
6929 MATCH m;
6931 //printf("TypeEnum::implicitConvTo()\n");
6932 if (ty == to->ty && sym == ((TypeEnum *)to)->sym)
6933 m = (mod == to->mod) ? MATCHexact : MATCHconst;
6934 else if (sym->getMemtype(Loc())->implicitConvTo(to))
6935 m = MATCHconvert; // match with conversions
6936 else
6937 m = MATCHnomatch; // no match
6938 return m;
6941 MATCH TypeEnum::constConv(Type *to)
6943 if (equals(to))
6944 return MATCHexact;
6945 if (ty == to->ty && sym == ((TypeEnum *)to)->sym &&
6946 MODimplicitConv(mod, to->mod))
6947 return MATCHconst;
6948 return MATCHnomatch;
6952 Expression *TypeEnum::defaultInit(Loc loc)
6954 // Initialize to first member of enum
6955 Expression *e = sym->getDefaultValue(loc);
6956 e = e->copy();
6957 e->loc = loc;
6958 e->type = this; // to deal with const, immutable, etc., variants
6959 return e;
6962 bool TypeEnum::isZeroInit(Loc loc)
6964 return sym->getDefaultValue(loc)->isBool(false);
6967 bool TypeEnum::hasPointers()
6969 return sym->getMemtype(Loc())->hasPointers();
6972 bool TypeEnum::hasVoidInitPointers()
6974 return sym->getMemtype(Loc())->hasVoidInitPointers();
6977 Type *TypeEnum::nextOf()
6979 return sym->getMemtype(Loc())->nextOf();
6982 /***************************** TypeStruct *****************************/
6984 TypeStruct::TypeStruct(StructDeclaration *sym)
6985 : Type(Tstruct)
6987 this->sym = sym;
6988 this->att = RECfwdref;
6989 this->cppmangle = CPPMANGLEdefault;
6992 TypeStruct *TypeStruct::create(StructDeclaration *sym)
6994 return new TypeStruct(sym);
6997 const char *TypeStruct::kind()
6999 return "struct";
7002 Type *TypeStruct::syntaxCopy()
7004 return this;
7007 d_uns64 TypeStruct::size(Loc loc)
7009 return sym->size(loc);
7012 unsigned TypeStruct::alignsize()
7014 sym->size(Loc()); // give error for forward references
7015 return sym->alignsize;
7018 Dsymbol *TypeStruct::toDsymbol(Scope *)
7020 return sym;
7023 Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
7025 Dsymbol *s;
7027 assert(e->op != TOKdot);
7029 // Bugzilla 14010
7030 if (ident == Id::_mangleof)
7031 return getProperty(e->loc, ident, flag & 1);
7033 /* If e.tupleof
7035 if (ident == Id::_tupleof)
7037 /* Create a TupleExp out of the fields of the struct e:
7038 * (e.field0, e.field1, e.field2, ...)
7040 e = expressionSemantic(e, sc); // do this before turning on noaccesscheck
7042 sym->size(e->loc); // do semantic of type
7044 Expression *e0 = NULL;
7045 Expression *ev = e->op == TOKtype ? NULL : e;
7046 if (ev)
7047 ev = extractSideEffect(sc, "__tup", &e0, ev);
7049 Expressions *exps = new Expressions;
7050 exps->reserve(sym->fields.length);
7051 for (size_t i = 0; i < sym->fields.length; i++)
7053 VarDeclaration *v = sym->fields[i];
7054 Expression *ex;
7055 if (ev)
7056 ex = new DotVarExp(e->loc, ev, v);
7057 else
7059 ex = new VarExp(e->loc, v);
7060 ex->type = ex->type->addMod(e->type->mod);
7062 exps->push(ex);
7065 e = new TupleExp(e->loc, e0, exps);
7066 Scope *sc2 = sc->push();
7067 sc2->flags = sc->flags | SCOPEnoaccesscheck;
7068 e = expressionSemantic(e, sc2);
7069 sc2->pop();
7070 return e;
7073 const int flags = sc->flags & SCOPEignoresymbolvisibility ? IgnoreSymbolVisibility : 0;
7074 s = sym->search(e->loc, ident, flags | IgnorePrivateImports);
7076 if (!s)
7078 return noMember(sc, e, ident, flag);
7080 if (!(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, s))
7082 return noMember(sc, e, ident, flag);
7084 if (!s->isFuncDeclaration()) // because of overloading
7086 s->checkDeprecated(e->loc, sc);
7087 if (Declaration *d = s->isDeclaration())
7088 d->checkDisabled(e->loc, sc);
7090 s = s->toAlias();
7092 EnumMember *em = s->isEnumMember();
7093 if (em)
7095 return em->getVarExp(e->loc, sc);
7098 if (VarDeclaration *v = s->isVarDeclaration())
7100 if (!v->type ||
7101 (!v->type->deco && v->inuse))
7103 if (v->inuse) // Bugzilla 9494
7104 e->error("circular reference to %s `%s`", v->kind(), v->toPrettyChars());
7105 else
7106 e->error("forward reference to %s `%s`", v->kind(), v->toPrettyChars());
7107 return new ErrorExp();
7109 if (v->type->ty == Terror)
7110 return new ErrorExp();
7112 if ((v->storage_class & STCmanifest) && v->_init)
7114 if (v->inuse)
7116 e->error("circular initialization of %s `%s`", v->kind(), v->toPrettyChars());
7117 return new ErrorExp();
7119 checkAccess(e->loc, sc, NULL, v);
7120 Expression *ve = new VarExp(e->loc, v);
7121 ve = expressionSemantic(ve, sc);
7122 return ve;
7126 if (Type *t = s->getType())
7128 return expressionSemantic(new TypeExp(e->loc, t), sc);
7131 TemplateMixin *tm = s->isTemplateMixin();
7132 if (tm)
7134 Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, tm));
7135 de->type = e->type;
7136 return de;
7139 TemplateDeclaration *td = s->isTemplateDeclaration();
7140 if (td)
7142 if (e->op == TOKtype)
7143 e = new TemplateExp(e->loc, td);
7144 else
7145 e = new DotTemplateExp(e->loc, e, td);
7146 e = expressionSemantic(e, sc);
7147 return e;
7150 TemplateInstance *ti = s->isTemplateInstance();
7151 if (ti)
7153 if (!ti->semanticRun)
7155 dsymbolSemantic(ti, sc);
7156 if (!ti->inst || ti->errors) // if template failed to expand
7157 return new ErrorExp();
7159 s = ti->inst->toAlias();
7160 if (!s->isTemplateInstance())
7161 goto L1;
7162 if (e->op == TOKtype)
7163 e = new ScopeExp(e->loc, ti);
7164 else
7165 e = new DotExp(e->loc, e, new ScopeExp(e->loc, ti));
7166 return expressionSemantic(e, sc);
7169 if (s->isImport() || s->isModule() || s->isPackage())
7171 e = ::resolve(e->loc, sc, s, false);
7172 return e;
7175 OverloadSet *o = s->isOverloadSet();
7176 if (o)
7178 OverExp *oe = new OverExp(e->loc, o);
7179 if (e->op == TOKtype)
7180 return oe;
7181 return new DotExp(e->loc, e, oe);
7184 Declaration *d = s->isDeclaration();
7185 if (!d)
7187 e->error("%s.%s is not a declaration", e->toChars(), ident->toChars());
7188 return new ErrorExp();
7191 if (e->op == TOKtype)
7193 /* It's:
7194 * Struct.d
7196 if (TupleDeclaration *tup = d->isTupleDeclaration())
7198 e = new TupleExp(e->loc, tup);
7199 e = expressionSemantic(e, sc);
7200 return e;
7202 if (d->needThis() && sc->intypeof != 1)
7204 /* Rewrite as:
7205 * this.d
7207 if (hasThis(sc))
7209 e = new DotVarExp(e->loc, new ThisExp(e->loc), d);
7210 e = expressionSemantic(e, sc);
7211 return e;
7214 if (d->semanticRun == PASSinit)
7215 dsymbolSemantic(d, NULL);
7216 checkAccess(e->loc, sc, e, d);
7217 VarExp *ve = new VarExp(e->loc, d);
7218 if (d->isVarDeclaration() && d->needThis())
7219 ve->type = d->type->addMod(e->type->mod);
7220 return ve;
7223 bool unreal = e->op == TOKvar && ((VarExp *)e)->var->isField();
7224 if (d->isDataseg() || (unreal && d->isField()))
7226 // (e, d)
7227 checkAccess(e->loc, sc, e, d);
7228 Expression *ve = new VarExp(e->loc, d);
7229 e = unreal ? ve : new CommaExp(e->loc, e, ve);
7230 e = expressionSemantic(e, sc);
7231 return e;
7234 e = new DotVarExp(e->loc, e, d);
7235 e = expressionSemantic(e, sc);
7236 return e;
7239 structalign_t TypeStruct::alignment()
7241 if (sym->alignment == 0)
7242 sym->size(sym->loc);
7243 return sym->alignment;
7246 Expression *TypeStruct::defaultInit(Loc)
7248 Declaration *d = new SymbolDeclaration(sym->loc, sym);
7249 assert(d);
7250 d->type = this;
7251 d->storage_class |= STCrvalue; // Bugzilla 14398
7252 return new VarExp(sym->loc, d);
7255 /***************************************
7256 * Use when we prefer the default initializer to be a literal,
7257 * rather than a global immutable variable.
7259 Expression *TypeStruct::defaultInitLiteral(Loc loc)
7261 sym->size(loc);
7262 if (sym->sizeok != SIZEOKdone)
7263 return new ErrorExp();
7264 Expressions *structelems = new Expressions();
7265 structelems->setDim(sym->fields.length - sym->isNested());
7266 unsigned offset = 0;
7267 for (size_t j = 0; j < structelems->length; j++)
7269 VarDeclaration *vd = sym->fields[j];
7270 Expression *e;
7271 if (vd->inuse)
7273 error(loc, "circular reference to `%s`", vd->toPrettyChars());
7274 return new ErrorExp();
7276 if (vd->offset < offset || vd->type->size() == 0)
7277 e = NULL;
7278 else if (vd->_init)
7280 if (vd->_init->isVoidInitializer())
7281 e = NULL;
7282 else
7283 e = vd->getConstInitializer(false);
7285 else
7286 e = vd->type->defaultInitLiteral(loc);
7287 if (e && e->op == TOKerror)
7288 return e;
7289 if (e)
7290 offset = vd->offset + (unsigned)vd->type->size();
7291 (*structelems)[j] = e;
7293 StructLiteralExp *structinit = new StructLiteralExp(loc, (StructDeclaration *)sym, structelems);
7295 /* Copy from the initializer symbol for larger symbols,
7296 * otherwise the literals expressed as code get excessively large.
7298 if (size(loc) > target.ptrsize * 4U && !needsNested())
7299 structinit->useStaticInit = true;
7301 structinit->type = this;
7302 return structinit;
7306 bool TypeStruct::isZeroInit(Loc)
7308 return sym->zeroInit != 0;
7311 bool TypeStruct::isBoolean()
7313 return false;
7316 bool TypeStruct::needsDestruction()
7318 return sym->dtor != NULL;
7321 bool TypeStruct::needsNested()
7323 if (sym->isNested())
7324 return true;
7326 for (size_t i = 0; i < sym->fields.length; i++)
7328 VarDeclaration *v = sym->fields[i];
7329 if (!v->isDataseg() && v->type->needsNested())
7330 return true;
7332 return false;
7335 bool TypeStruct::isAssignable()
7337 bool assignable = true;
7338 unsigned offset = ~0; // dead-store initialize to prevent spurious warning
7340 /* If any of the fields are const or immutable,
7341 * then one cannot assign this struct.
7343 for (size_t i = 0; i < sym->fields.length; i++)
7345 VarDeclaration *v = sym->fields[i];
7346 //printf("%s [%d] v = (%s) %s, v->offset = %d, v->parent = %s", sym->toChars(), i, v->kind(), v->toChars(), v->offset, v->parent->kind());
7347 if (i == 0)
7349 else if (v->offset == offset)
7351 /* If any fields of anonymous union are assignable,
7352 * then regard union as assignable.
7353 * This is to support unsafe things like Rebindable templates.
7355 if (assignable)
7356 continue;
7358 else
7360 if (!assignable)
7361 return false;
7363 assignable = v->type->isMutable() && v->type->isAssignable();
7364 offset = v->offset;
7365 //printf(" -> assignable = %d\n", assignable);
7368 return assignable;
7371 bool TypeStruct::hasPointers()
7373 // Probably should cache this information in sym rather than recompute
7374 StructDeclaration *s = sym;
7376 sym->size(Loc()); // give error for forward references
7377 for (size_t i = 0; i < s->fields.length; i++)
7379 Declaration *d = s->fields[i];
7380 if (d->storage_class & STCref || d->hasPointers())
7381 return true;
7383 return false;
7386 bool TypeStruct::hasVoidInitPointers()
7388 // Probably should cache this information in sym rather than recompute
7389 StructDeclaration *s = sym;
7391 sym->size(Loc()); // give error for forward references
7392 for (size_t i = 0; i < s->fields.length; i++)
7394 VarDeclaration *v = s->fields[i];
7395 if (v->_init && v->_init->isVoidInitializer() && v->type->hasPointers())
7396 return true;
7397 if (!v->_init && v->type->hasVoidInitPointers())
7398 return true;
7400 return false;
7403 MATCH TypeStruct::implicitConvTo(Type *to)
7404 { MATCH m;
7406 //printf("TypeStruct::implicitConvTo(%s => %s)\n", toChars(), to->toChars());
7408 if (ty == to->ty && sym == ((TypeStruct *)to)->sym)
7410 m = MATCHexact; // exact match
7411 if (mod != to->mod)
7413 m = MATCHconst;
7414 if (MODimplicitConv(mod, to->mod))
7416 else
7418 /* Check all the fields. If they can all be converted,
7419 * allow the conversion.
7421 unsigned offset = ~0; // dead-store to prevent spurious warning
7422 for (size_t i = 0; i < sym->fields.length; i++)
7424 VarDeclaration *v = sym->fields[i];
7425 if (i == 0)
7427 else if (v->offset == offset)
7429 if (m > MATCHnomatch)
7430 continue;
7432 else
7434 if (m <= MATCHnomatch)
7435 return m;
7438 // 'from' type
7439 Type *tvf = v->type->addMod(mod);
7441 // 'to' type
7442 Type *tv = v->type->addMod(to->mod);
7444 // field match
7445 MATCH mf = tvf->implicitConvTo(tv);
7446 //printf("\t%s => %s, match = %d\n", v->type->toChars(), tv->toChars(), mf);
7448 if (mf <= MATCHnomatch)
7449 return mf;
7450 if (mf < m) // if field match is worse
7451 m = mf;
7452 offset = v->offset;
7457 else if (sym->aliasthis && !(att & RECtracing))
7459 att = (AliasThisRec)(att | RECtracing);
7460 m = aliasthisOf()->implicitConvTo(to);
7461 att = (AliasThisRec)(att & ~RECtracing);
7463 else
7464 m = MATCHnomatch; // no match
7465 return m;
7468 MATCH TypeStruct::constConv(Type *to)
7470 if (equals(to))
7471 return MATCHexact;
7472 if (ty == to->ty && sym == ((TypeStruct *)to)->sym &&
7473 MODimplicitConv(mod, to->mod))
7474 return MATCHconst;
7475 return MATCHnomatch;
7478 unsigned char TypeStruct::deduceWild(Type *t, bool isRef)
7480 if (ty == t->ty && sym == ((TypeStruct *)t)->sym)
7481 return Type::deduceWild(t, isRef);
7483 unsigned char wm = 0;
7485 if (t->hasWild() && sym->aliasthis && !(att & RECtracing))
7487 att = (AliasThisRec)(att | RECtracing);
7488 wm = aliasthisOf()->deduceWild(t, isRef);
7489 att = (AliasThisRec)(att & ~RECtracing);
7492 return wm;
7495 Type *TypeStruct::toHeadMutable()
7497 return this;
7501 /***************************** TypeClass *****************************/
7503 TypeClass::TypeClass(ClassDeclaration *sym)
7504 : Type(Tclass)
7506 this->sym = sym;
7507 this->att = RECfwdref;
7508 this->cppmangle = CPPMANGLEdefault;
7511 const char *TypeClass::kind()
7513 return "class";
7516 Type *TypeClass::syntaxCopy()
7518 return this;
7521 d_uns64 TypeClass::size(Loc)
7523 return target.ptrsize;
7526 Dsymbol *TypeClass::toDsymbol(Scope *)
7528 return sym;
7531 Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
7533 Dsymbol *s;
7534 assert(e->op != TOKdot);
7536 // Bugzilla 12543
7537 if (ident == Id::__sizeof || ident == Id::__xalignof || ident == Id::_mangleof)
7539 return Type::getProperty(e->loc, ident, 0);
7542 /* If e.tupleof
7544 if (ident == Id::_tupleof)
7546 /* Create a TupleExp
7548 e = expressionSemantic(e, sc); // do this before turning on noaccesscheck
7550 sym->size(e->loc); // do semantic of type
7552 Expression *e0 = NULL;
7553 Expression *ev = e->op == TOKtype ? NULL : e;
7554 if (ev)
7555 ev = extractSideEffect(sc, "__tup", &e0, ev);
7557 Expressions *exps = new Expressions;
7558 exps->reserve(sym->fields.length);
7559 for (size_t i = 0; i < sym->fields.length; i++)
7561 VarDeclaration *v = sym->fields[i];
7562 // Don't include hidden 'this' pointer
7563 if (v->isThisDeclaration())
7564 continue;
7565 Expression *ex;
7566 if (ev)
7567 ex = new DotVarExp(e->loc, ev, v);
7568 else
7570 ex = new VarExp(e->loc, v);
7571 ex->type = ex->type->addMod(e->type->mod);
7573 exps->push(ex);
7576 e = new TupleExp(e->loc, e0, exps);
7577 Scope *sc2 = sc->push();
7578 sc2->flags = sc->flags | SCOPEnoaccesscheck;
7579 e = expressionSemantic(e, sc2);
7580 sc2->pop();
7581 return e;
7584 int flags = sc->flags & SCOPEignoresymbolvisibility ? IgnoreSymbolVisibility : 0;
7585 s = sym->search(e->loc, ident, flags | IgnorePrivateImports);
7588 if (!s)
7590 // See if it's 'this' class or a base class
7591 if (sym->ident == ident)
7593 if (e->op == TOKtype)
7594 return Type::getProperty(e->loc, ident, 0);
7595 e = new DotTypeExp(e->loc, e, sym);
7596 e = expressionSemantic(e, sc);
7597 return e;
7599 if (ClassDeclaration *cbase = sym->searchBase(ident))
7601 if (e->op == TOKtype)
7602 return Type::getProperty(e->loc, ident, 0);
7603 if (InterfaceDeclaration *ifbase = cbase->isInterfaceDeclaration())
7604 e = new CastExp(e->loc, e, ifbase->type);
7605 else
7606 e = new DotTypeExp(e->loc, e, cbase);
7607 e = expressionSemantic(e, sc);
7608 return e;
7611 if (ident == Id::classinfo)
7613 if (!Type::typeinfoclass)
7615 error(e->loc, "`object.TypeInfo_Class` could not be found, but is implicitly used");
7616 return new ErrorExp();
7619 Type *t = Type::typeinfoclass->type;
7620 if (e->op == TOKtype || e->op == TOKdottype)
7622 /* For type.classinfo, we know the classinfo
7623 * at compile time.
7625 if (!sym->vclassinfo)
7626 sym->vclassinfo = new TypeInfoClassDeclaration(sym->type);
7627 e = new VarExp(e->loc, sym->vclassinfo);
7628 e = e->addressOf();
7629 e->type = t; // do this so we don't get redundant dereference
7631 else
7633 /* For class objects, the classinfo reference is the first
7634 * entry in the vtbl[]
7636 e = new PtrExp(e->loc, e);
7637 e->type = t->pointerTo();
7638 if (sym->isInterfaceDeclaration())
7640 if (sym->isCPPinterface())
7642 /* C++ interface vtbl[]s are different in that the
7643 * first entry is always pointer to the first virtual
7644 * function, not classinfo.
7645 * We can't get a .classinfo for it.
7647 error(e->loc, "no .classinfo for C++ interface objects");
7649 /* For an interface, the first entry in the vtbl[]
7650 * is actually a pointer to an instance of struct Interface.
7651 * The first member of Interface is the .classinfo,
7652 * so add an extra pointer indirection.
7654 e->type = e->type->pointerTo();
7655 e = new PtrExp(e->loc, e);
7656 e->type = t->pointerTo();
7658 e = new PtrExp(e->loc, e, t);
7660 return e;
7663 if (ident == Id::__vptr)
7665 /* The pointer to the vtbl[]
7666 * *cast(immutable(void*)**)e
7668 e = e->castTo(sc, tvoidptr->immutableOf()->pointerTo()->pointerTo());
7669 e = new PtrExp(e->loc, e);
7670 e = expressionSemantic(e, sc);
7671 return e;
7674 if (ident == Id::__monitor && sym->hasMonitor())
7676 /* The handle to the monitor (call it a void*)
7677 * *(cast(void**)e + 1)
7679 e = e->castTo(sc, tvoidptr->pointerTo());
7680 e = new AddExp(e->loc, e, new IntegerExp(1));
7681 e = new PtrExp(e->loc, e);
7682 e = expressionSemantic(e, sc);
7683 return e;
7686 if (ident == Id::outer && sym->vthis)
7688 if (sym->vthis->semanticRun == PASSinit)
7689 dsymbolSemantic(sym->vthis, NULL);
7691 if (ClassDeclaration *cdp = sym->toParent2()->isClassDeclaration())
7693 DotVarExp *dve = new DotVarExp(e->loc, e, sym->vthis);
7694 dve->type = cdp->type->addMod(e->type->mod);
7695 return dve;
7698 /* Bugzilla 15839: Find closest parent class through nested functions.
7700 for (Dsymbol *p = sym->toParent2(); p; p = p->toParent2())
7702 FuncDeclaration *fd = p->isFuncDeclaration();
7703 if (!fd)
7704 break;
7705 if (fd->isNested())
7706 continue;
7707 AggregateDeclaration *ad = fd->isThis();
7708 if (!ad)
7709 break;
7710 if (ad->isClassDeclaration())
7712 ThisExp *ve = new ThisExp(e->loc);
7714 ve->var = fd->vthis;
7715 const bool nestedError = fd->vthis->checkNestedReference(sc, e->loc);
7716 assert(!nestedError);
7718 ve->type = fd->vthis->type->addMod(e->type->mod);
7719 return ve;
7721 break;
7724 // Continue to show enclosing function's frame (stack or closure).
7725 DotVarExp *dve = new DotVarExp(e->loc, e, sym->vthis);
7726 dve->type = sym->vthis->type->addMod(e->type->mod);
7727 return dve;
7730 return noMember(sc, e, ident, flag & 1);
7732 if (!(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, s))
7734 return noMember(sc, e, ident, flag);
7736 if (!s->isFuncDeclaration()) // because of overloading
7738 s->checkDeprecated(e->loc, sc);
7739 if (Declaration *d = s->isDeclaration())
7740 d->checkDisabled(e->loc, sc);
7742 s = s->toAlias();
7744 EnumMember *em = s->isEnumMember();
7745 if (em)
7747 return em->getVarExp(e->loc, sc);
7750 if (VarDeclaration *v = s->isVarDeclaration())
7752 if (!v->type ||
7753 (!v->type->deco && v->inuse))
7755 if (v->inuse) // Bugzilla 9494
7756 e->error("circular reference to %s `%s`", v->kind(), v->toPrettyChars());
7757 else
7758 e->error("forward reference to %s `%s`", v->kind(), v->toPrettyChars());
7759 return new ErrorExp();
7761 if (v->type->ty == Terror)
7762 return new ErrorExp();
7764 if ((v->storage_class & STCmanifest) && v->_init)
7766 if (v->inuse)
7768 e->error("circular initialization of %s `%s`", v->kind(), v->toPrettyChars());
7769 return new ErrorExp();
7771 checkAccess(e->loc, sc, NULL, v);
7772 Expression *ve = new VarExp(e->loc, v);
7773 ve = expressionSemantic(ve, sc);
7774 return ve;
7778 if (Type *t = s->getType())
7780 return expressionSemantic(new TypeExp(e->loc, t), sc);
7783 TemplateMixin *tm = s->isTemplateMixin();
7784 if (tm)
7786 Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, tm));
7787 de->type = e->type;
7788 return de;
7791 TemplateDeclaration *td = s->isTemplateDeclaration();
7792 if (td)
7794 if (e->op == TOKtype)
7795 e = new TemplateExp(e->loc, td);
7796 else
7797 e = new DotTemplateExp(e->loc, e, td);
7798 e = expressionSemantic(e, sc);
7799 return e;
7802 TemplateInstance *ti = s->isTemplateInstance();
7803 if (ti)
7805 if (!ti->semanticRun)
7807 dsymbolSemantic(ti, sc);
7808 if (!ti->inst || ti->errors) // if template failed to expand
7809 return new ErrorExp();
7811 s = ti->inst->toAlias();
7812 if (!s->isTemplateInstance())
7813 goto L1;
7814 if (e->op == TOKtype)
7815 e = new ScopeExp(e->loc, ti);
7816 else
7817 e = new DotExp(e->loc, e, new ScopeExp(e->loc, ti));
7818 return expressionSemantic(e, sc);
7821 if (s->isImport() || s->isModule() || s->isPackage())
7823 e = ::resolve(e->loc, sc, s, false);
7824 return e;
7827 OverloadSet *o = s->isOverloadSet();
7828 if (o)
7830 OverExp *oe = new OverExp(e->loc, o);
7831 if (e->op == TOKtype)
7832 return oe;
7833 return new DotExp(e->loc, e, oe);
7836 Declaration *d = s->isDeclaration();
7837 if (!d)
7839 e->error("%s.%s is not a declaration", e->toChars(), ident->toChars());
7840 return new ErrorExp();
7843 if (e->op == TOKtype)
7845 /* It's:
7846 * Class.d
7848 if (TupleDeclaration *tup = d->isTupleDeclaration())
7850 e = new TupleExp(e->loc, tup);
7851 e = expressionSemantic(e, sc);
7852 return e;
7854 if (d->needThis() && sc->intypeof != 1)
7856 /* Rewrite as:
7857 * this.d
7859 if (hasThis(sc))
7861 // This is almost same as getRightThis() in expression.c
7862 Expression *e1 = new ThisExp(e->loc);
7863 e1 = expressionSemantic(e1, sc);
7865 Type *t = e1->type->toBasetype();
7866 ClassDeclaration *cd = e->type->isClassHandle();
7867 ClassDeclaration *tcd = t->isClassHandle();
7868 if (cd && tcd && (tcd == cd || cd->isBaseOf(tcd, NULL)))
7870 e = new DotTypeExp(e1->loc, e1, cd);
7871 e = new DotVarExp(e->loc, e, d);
7872 e = expressionSemantic(e, sc);
7873 return e;
7875 if (tcd && tcd->isNested())
7876 { /* e1 is the 'this' pointer for an inner class: tcd.
7877 * Rewrite it as the 'this' pointer for the outer class.
7880 e1 = new DotVarExp(e->loc, e1, tcd->vthis);
7881 e1->type = tcd->vthis->type;
7882 e1->type = e1->type->addMod(t->mod);
7883 // Do not call checkNestedRef()
7884 //e1 = expressionSemantic(e1, sc);
7886 // Skip up over nested functions, and get the enclosing
7887 // class type.
7888 int n = 0;
7889 for (s = tcd->toParent();
7890 s && s->isFuncDeclaration();
7891 s = s->toParent())
7892 { FuncDeclaration *f = s->isFuncDeclaration();
7893 if (f->vthis)
7895 //printf("rewriting e1 to %s's this\n", f->toChars());
7896 n++;
7897 e1 = new VarExp(e->loc, f->vthis);
7899 else
7901 e = new VarExp(e->loc, d);
7902 return e;
7905 if (s && s->isClassDeclaration())
7906 { e1->type = s->isClassDeclaration()->type;
7907 e1->type = e1->type->addMod(t->mod);
7908 if (n > 1)
7909 e1 = expressionSemantic(e1, sc);
7911 else
7912 e1 = expressionSemantic(e1, sc);
7913 goto L2;
7917 //printf("e = %s, d = %s\n", e->toChars(), d->toChars());
7918 if (d->semanticRun == PASSinit)
7919 dsymbolSemantic(d, NULL);
7920 checkAccess(e->loc, sc, e, d);
7921 VarExp *ve = new VarExp(e->loc, d);
7922 if (d->isVarDeclaration() && d->needThis())
7923 ve->type = d->type->addMod(e->type->mod);
7924 return ve;
7927 bool unreal = e->op == TOKvar && ((VarExp *)e)->var->isField();
7928 if (d->isDataseg() || (unreal && d->isField()))
7930 // (e, d)
7931 checkAccess(e->loc, sc, e, d);
7932 Expression *ve = new VarExp(e->loc, d);
7933 e = unreal ? ve : new CommaExp(e->loc, e, ve);
7934 e = expressionSemantic(e, sc);
7935 return e;
7938 e = new DotVarExp(e->loc, e, d);
7939 e = expressionSemantic(e, sc);
7940 return e;
7943 ClassDeclaration *TypeClass::isClassHandle()
7945 return sym;
7948 bool TypeClass::isscope()
7950 return sym->isscope;
7953 bool TypeClass::isBaseOf(Type *t, int *poffset)
7955 if (t && t->ty == Tclass)
7957 ClassDeclaration *cd = ((TypeClass *)t)->sym;
7958 if (sym->isBaseOf(cd, poffset))
7959 return true;
7961 return false;
7964 MATCH TypeClass::implicitConvTo(Type *to)
7966 //printf("TypeClass::implicitConvTo(to = '%s') %s\n", to->toChars(), toChars());
7967 MATCH m = constConv(to);
7968 if (m > MATCHnomatch)
7969 return m;
7971 ClassDeclaration *cdto = to->isClassHandle();
7972 if (cdto)
7974 //printf("TypeClass::implicitConvTo(to = '%s') %s, isbase = %d %d\n", to->toChars(), toChars(), cdto->isBaseInfoComplete(), sym->isBaseInfoComplete());
7975 if (cdto->semanticRun < PASSsemanticdone && !cdto->isBaseInfoComplete())
7976 dsymbolSemantic(cdto, NULL);
7977 if (sym->semanticRun < PASSsemanticdone && !sym->isBaseInfoComplete())
7978 dsymbolSemantic(sym, NULL);
7979 if (cdto->isBaseOf(sym, NULL) && MODimplicitConv(mod, to->mod))
7981 //printf("'to' is base\n");
7982 return MATCHconvert;
7986 m = MATCHnomatch;
7987 if (sym->aliasthis && !(att & RECtracing))
7989 att = (AliasThisRec)(att | RECtracing);
7990 m = aliasthisOf()->implicitConvTo(to);
7991 att = (AliasThisRec)(att & ~RECtracing);
7994 return m;
7997 MATCH TypeClass::constConv(Type *to)
7999 if (equals(to))
8000 return MATCHexact;
8001 if (ty == to->ty && sym == ((TypeClass *)to)->sym &&
8002 MODimplicitConv(mod, to->mod))
8003 return MATCHconst;
8005 /* Conversion derived to const(base)
8007 int offset = 0;
8008 if (to->isBaseOf(this, &offset) && offset == 0 &&
8009 MODimplicitConv(mod, to->mod))
8011 // Disallow:
8012 // derived to base
8013 // inout(derived) to inout(base)
8014 if (!to->isMutable() && !to->isWild())
8015 return MATCHconvert;
8018 return MATCHnomatch;
8021 unsigned char TypeClass::deduceWild(Type *t, bool isRef)
8023 ClassDeclaration *cd = t->isClassHandle();
8024 if (cd && (sym == cd || cd->isBaseOf(sym, NULL)))
8025 return Type::deduceWild(t, isRef);
8027 unsigned char wm = 0;
8029 if (t->hasWild() && sym->aliasthis && !(att & RECtracing))
8031 att = (AliasThisRec)(att | RECtracing);
8032 wm = aliasthisOf()->deduceWild(t, isRef);
8033 att = (AliasThisRec)(att & ~RECtracing);
8036 return wm;
8039 Type *TypeClass::toHeadMutable()
8041 return this;
8044 Expression *TypeClass::defaultInit(Loc loc)
8046 return new NullExp(loc, this);
8049 bool TypeClass::isZeroInit(Loc)
8051 return true;
8054 bool TypeClass::isBoolean()
8056 return true;
8059 bool TypeClass::hasPointers()
8061 return true;
8064 /***************************** TypeTuple *****************************/
8066 TypeTuple::TypeTuple(Parameters *arguments)
8067 : Type(Ttuple)
8069 //printf("TypeTuple(this = %p)\n", this);
8070 this->arguments = arguments;
8071 //printf("TypeTuple() %p, %s\n", this, toChars());
8074 /****************
8075 * Form TypeTuple from the types of the expressions.
8076 * Assume exps[] is already tuple expanded.
8079 TypeTuple::TypeTuple(Expressions *exps)
8080 : Type(Ttuple)
8082 Parameters *arguments = new Parameters;
8083 if (exps)
8085 arguments->setDim(exps->length);
8086 for (size_t i = 0; i < exps->length; i++)
8087 { Expression *e = (*exps)[i];
8088 if (e->type->ty == Ttuple)
8089 e->error("cannot form tuple of tuples");
8090 Parameter *arg = new Parameter(STCundefined, e->type, NULL, NULL, NULL);
8091 (*arguments)[i] = arg;
8094 this->arguments = arguments;
8095 //printf("TypeTuple() %p, %s\n", this, toChars());
8098 TypeTuple *TypeTuple::create(Parameters *arguments)
8100 return new TypeTuple(arguments);
8103 /*******************************************
8104 * Type tuple with 0, 1 or 2 types in it.
8106 TypeTuple::TypeTuple()
8107 : Type(Ttuple)
8109 arguments = new Parameters();
8112 TypeTuple::TypeTuple(Type *t1)
8113 : Type(Ttuple)
8115 arguments = new Parameters();
8116 arguments->push(new Parameter(0, t1, NULL, NULL, NULL));
8119 TypeTuple::TypeTuple(Type *t1, Type *t2)
8120 : Type(Ttuple)
8122 arguments = new Parameters();
8123 arguments->push(new Parameter(0, t1, NULL, NULL, NULL));
8124 arguments->push(new Parameter(0, t2, NULL, NULL, NULL));
8127 const char *TypeTuple::kind()
8129 return "tuple";
8132 Type *TypeTuple::syntaxCopy()
8134 Parameters *args = Parameter::arraySyntaxCopy(arguments);
8135 Type *t = new TypeTuple(args);
8136 t->mod = mod;
8137 return t;
8140 bool TypeTuple::equals(RootObject *o)
8142 Type *t = (Type *)o;
8143 //printf("TypeTuple::equals(%s, %s)\n", toChars(), t->toChars());
8144 if (this == t)
8145 return true;
8146 if (t->ty == Ttuple)
8148 TypeTuple *tt = (TypeTuple *)t;
8149 if (arguments->length == tt->arguments->length)
8151 for (size_t i = 0; i < tt->arguments->length; i++)
8153 Parameter *arg1 = (*arguments)[i];
8154 Parameter *arg2 = (*tt->arguments)[i];
8155 if (!arg1->type->equals(arg2->type))
8156 return false;
8158 return true;
8161 return false;
8164 Expression *TypeTuple::getProperty(Loc loc, Identifier *ident, int flag)
8166 Expression *e;
8168 if (ident == Id::length)
8170 e = new IntegerExp(loc, arguments->length, Type::tsize_t);
8172 else if (ident == Id::_init)
8174 e = defaultInitLiteral(loc);
8176 else if (flag)
8178 e = NULL;
8180 else
8182 error(loc, "no property `%s` for tuple `%s`", ident->toChars(), toChars());
8183 e = new ErrorExp();
8185 return e;
8188 Expression *TypeTuple::defaultInit(Loc loc)
8190 Expressions *exps = new Expressions();
8191 exps->setDim(arguments->length);
8192 for (size_t i = 0; i < arguments->length; i++)
8194 Parameter *p = (*arguments)[i];
8195 assert(p->type);
8196 Expression *e = p->type->defaultInitLiteral(loc);
8197 if (e->op == TOKerror)
8198 return e;
8199 (*exps)[i] = e;
8201 return new TupleExp(loc, exps);
8204 /***************************** TypeSlice *****************************/
8206 /* This is so we can slice a TypeTuple */
8208 TypeSlice::TypeSlice(Type *next, Expression *lwr, Expression *upr)
8209 : TypeNext(Tslice, next)
8211 //printf("TypeSlice[%s .. %s]\n", lwr->toChars(), upr->toChars());
8212 this->lwr = lwr;
8213 this->upr = upr;
8216 const char *TypeSlice::kind()
8218 return "slice";
8221 Type *TypeSlice::syntaxCopy()
8223 Type *t = new TypeSlice(next->syntaxCopy(), lwr->syntaxCopy(), upr->syntaxCopy());
8224 t->mod = mod;
8225 return t;
8228 void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
8230 next->resolve(loc, sc, pe, pt, ps, intypeid);
8231 if (*pe)
8233 // It's really a slice expression
8234 if (Dsymbol *s = getDsymbol(*pe))
8235 *pe = new DsymbolExp(loc, s);
8236 *pe = new ArrayExp(loc, *pe, new IntervalExp(loc, lwr, upr));
8238 else if (*ps)
8240 Dsymbol *s = *ps;
8241 TupleDeclaration *td = s->isTupleDeclaration();
8242 if (td)
8244 /* It's a slice of a TupleDeclaration
8246 ScopeDsymbol *sym = new ArrayScopeSymbol(sc, td);
8247 sym->parent = sc->scopesym;
8248 sc = sc->push(sym);
8249 sc = sc->startCTFE();
8250 lwr = expressionSemantic(lwr, sc);
8251 upr = expressionSemantic(upr, sc);
8252 sc = sc->endCTFE();
8253 sc = sc->pop();
8255 lwr = lwr->ctfeInterpret();
8256 upr = upr->ctfeInterpret();
8257 uinteger_t i1 = lwr->toUInteger();
8258 uinteger_t i2 = upr->toUInteger();
8260 if (!(i1 <= i2 && i2 <= td->objects->length))
8262 error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, td->objects->length);
8263 *ps = NULL;
8264 *pt = Type::terror;
8265 return;
8268 if (i1 == 0 && i2 == td->objects->length)
8270 *ps = td;
8271 return;
8274 /* Create a new TupleDeclaration which
8275 * is a slice [i1..i2] out of the old one.
8277 Objects *objects = new Objects;
8278 objects->setDim((size_t)(i2 - i1));
8279 for (size_t i = 0; i < objects->length; i++)
8281 (*objects)[i] = (*td->objects)[(size_t)i1 + i];
8284 TupleDeclaration *tds = new TupleDeclaration(loc, td->ident, objects);
8285 *ps = tds;
8287 else
8288 goto Ldefault;
8290 else
8292 if ((*pt)->ty != Terror)
8293 next = *pt; // prevent re-running semantic() on 'next'
8294 Ldefault:
8295 Type::resolve(loc, sc, pe, pt, ps, intypeid);
8299 /***************************** TypeNull *****************************/
8301 TypeNull::TypeNull()
8302 : Type(Tnull)
8306 const char *TypeNull::kind()
8308 return "null";
8311 Type *TypeNull::syntaxCopy()
8313 // No semantic analysis done, no need to copy
8314 return this;
8317 MATCH TypeNull::implicitConvTo(Type *to)
8319 //printf("TypeNull::implicitConvTo(this=%p, to=%p)\n", this, to);
8320 //printf("from: %s\n", toChars());
8321 //printf("to : %s\n", to->toChars());
8322 MATCH m = Type::implicitConvTo(to);
8323 if (m != MATCHnomatch)
8324 return m;
8326 // NULL implicitly converts to any pointer type or dynamic array
8327 //if (type->ty == Tpointer && type->nextOf()->ty == Tvoid)
8329 Type *tb = to->toBasetype();
8330 if (tb->ty == Tnull ||
8331 tb->ty == Tpointer || tb->ty == Tarray ||
8332 tb->ty == Taarray || tb->ty == Tclass ||
8333 tb->ty == Tdelegate)
8334 return MATCHconst;
8337 return MATCHnomatch;
8340 bool TypeNull::isBoolean()
8342 return true;
8345 d_uns64 TypeNull::size(Loc loc)
8347 return tvoidptr->size(loc);
8350 Expression *TypeNull::defaultInit(Loc)
8352 return new NullExp(Loc(), Type::tnull);
8355 /***************************** TypeNoreturn *****************************/
8357 TypeNoreturn::TypeNoreturn()
8358 : Type(Tnoreturn)
8360 //printf("TypeNoreturn %p\n", this);
8363 const char *TypeNoreturn::kind()
8365 return "noreturn";
8368 Type *TypeNoreturn::syntaxCopy()
8370 // No semantic analysis done, no need to copy
8371 return this;
8374 MATCH TypeNoreturn::implicitConvTo(Type *to)
8376 //printf("TypeNoreturn::implicitConvTo(this=%p, to=%p)\n", this, to);
8377 //printf("from: %s\n", toChars());
8378 //printf("to : %s\n", to.toChars());
8379 MATCH m = Type::implicitConvTo(to);
8380 return (m == MATCHexact) ? MATCHexact : MATCHconvert;
8383 bool TypeNoreturn::isBoolean()
8385 return true; // bottom type can be implicitly converted to any other type
8388 d_uns64 TypeNoreturn::size(Loc)
8390 return 0;
8393 unsigned TypeNoreturn::alignsize()
8395 return 0;
8398 /***********************************************************
8399 * Encapsulate Parameters* so .length and [i] can be used on it.
8400 * https://dlang.org/spec/function.html#ParameterList
8403 ParameterList::ParameterList(Parameters *parameters, VarArg varargs)
8405 this->parameters = parameters;
8406 this->varargs = varargs;
8409 size_t ParameterList::length()
8411 return Parameter::dim(parameters);
8414 /***************************** Parameter *****************************/
8416 Parameter::Parameter(StorageClass storageClass, Type *type, Identifier *ident,
8417 Expression *defaultArg, UserAttributeDeclaration *userAttribDecl)
8419 this->type = type;
8420 this->ident = ident;
8421 this->storageClass = storageClass;
8422 this->defaultArg = defaultArg;
8423 this->userAttribDecl = userAttribDecl;
8426 Parameter *Parameter::create(StorageClass storageClass, Type *type, Identifier *ident,
8427 Expression *defaultArg, UserAttributeDeclaration *userAttribDecl)
8429 return new Parameter(storageClass, type, ident, defaultArg, userAttribDecl);
8432 Parameter *Parameter::syntaxCopy()
8434 return new Parameter(storageClass,
8435 type ? type->syntaxCopy() : NULL,
8436 ident,
8437 defaultArg ? defaultArg->syntaxCopy() : NULL,
8438 userAttribDecl ? (UserAttributeDeclaration *) userAttribDecl->syntaxCopy(NULL) : NULL);
8441 Parameters *Parameter::arraySyntaxCopy(Parameters *parameters)
8443 Parameters *params = NULL;
8444 if (parameters)
8446 params = new Parameters();
8447 params->setDim(parameters->length);
8448 for (size_t i = 0; i < params->length; i++)
8449 (*params)[i] = (*parameters)[i]->syntaxCopy();
8451 return params;
8454 /****************************************************
8455 * Determine if parameter is a lazy array of delegates.
8456 * If so, return the return type of those delegates.
8457 * If not, return NULL.
8459 * Returns T if the type is one of the following forms:
8460 * T delegate()[]
8461 * T delegate()[dim]
8464 Type *Parameter::isLazyArray()
8466 Type *tb = type->toBasetype();
8467 if (tb->ty == Tsarray || tb->ty == Tarray)
8469 Type *tel = ((TypeArray *)tb)->next->toBasetype();
8470 if (tel->ty == Tdelegate)
8472 TypeDelegate *td = (TypeDelegate *)tel;
8473 TypeFunction *tf = td->next->toTypeFunction();
8475 if (tf->parameterList.varargs == VARARGnone && tf->parameterList.length() == 0)
8477 return tf->next; // return type of delegate
8481 return NULL;
8484 /***************************************
8485 * Determine number of arguments, folding in tuples.
8488 static int dimDg(void *ctx, size_t, Parameter *)
8490 ++*(size_t *)ctx;
8491 return 0;
8494 size_t Parameter::dim(Parameters *parameters)
8496 size_t n = 0;
8497 Parameter_foreach(parameters, &dimDg, &n);
8498 return n;
8501 /***************************************
8502 * Get nth Parameter, folding in tuples.
8503 * Returns:
8504 * Parameter* nth Parameter
8505 * NULL not found, *pn gets incremented by the number
8506 * of Parameters
8509 struct GetNthParamCtx
8511 size_t nth;
8512 Parameter *param;
8515 static int getNthParamDg(void *ctx, size_t n, Parameter *p)
8517 GetNthParamCtx *c = (GetNthParamCtx *)ctx;
8518 if (n == c->nth)
8520 c->param = p;
8521 return 1;
8523 return 0;
8526 Parameter *Parameter::getNth(Parameters *parameters, size_t nth, size_t *)
8528 GetNthParamCtx ctx = { nth, NULL };
8529 int res = Parameter_foreach(parameters, &getNthParamDg, &ctx);
8530 return res ? ctx.param : NULL;
8533 /***************************************
8534 * Expands tuples in args in depth first order. Calls
8535 * dg(void *ctx, size_t argidx, Parameter *arg) for each Parameter.
8536 * If dg returns !=0, stops and returns that value else returns 0.
8537 * Use this function to avoid the O(N + N^2/2) complexity of
8538 * calculating dim and calling N times getNth.
8541 int Parameter_foreach(Parameters *parameters, ForeachDg dg, void *ctx, size_t *pn)
8543 assert(dg);
8544 if (!parameters)
8545 return 0;
8547 size_t n = pn ? *pn : 0; // take over index
8548 int result = 0;
8549 for (size_t i = 0; i < parameters->length; i++)
8551 Parameter *p = (*parameters)[i];
8552 Type *t = p->type->toBasetype();
8554 if (t->ty == Ttuple)
8556 TypeTuple *tu = (TypeTuple *)t;
8557 result = Parameter_foreach(tu->arguments, dg, ctx, &n);
8559 else
8560 result = dg(ctx, n++, p);
8562 if (result)
8563 break;
8566 if (pn)
8567 *pn = n; // update index
8568 return result;
8572 const char *Parameter::toChars()
8574 return ident ? ident->toChars() : "__anonymous_param";
8577 /*********************************
8578 * Compute covariance of parameters `this` and `p`
8579 * as determined by the storage classes of both.
8580 * Params:
8581 * p = Parameter to compare with
8582 * Returns:
8583 * true = `this` can be used in place of `p`
8584 * false = nope
8586 bool Parameter::isCovariant(bool returnByRef, const Parameter *p) const
8588 const StorageClass stc = STCref | STCin | STCout | STClazy;
8589 if ((this->storageClass & stc) != (p->storageClass & stc))
8590 return false;
8592 return isCovariantScope(returnByRef, this->storageClass, p->storageClass);
8595 bool Parameter::isCovariantScope(bool returnByRef, StorageClass from, StorageClass to)
8597 if (from == to)
8598 return true;
8600 struct SR
8602 /* Classification of 'scope-return-ref' possibilities
8604 enum
8606 SRNone,
8607 SRScope,
8608 SRReturnScope,
8609 SRRef,
8610 SRReturnRef,
8611 SRRefScope,
8612 SRReturnRef_Scope,
8613 SRRef_ReturnScope,
8614 SRMAX,
8617 /* Shrinking the representation is necessary because StorageClass is so wide
8618 * Params:
8619 * returnByRef = true if the function returns by ref
8620 * stc = storage class of parameter
8622 static unsigned buildSR(bool returnByRef, StorageClass stc)
8624 unsigned result;
8625 StorageClass stc2 = stc & (STCref | STCscope | STCreturn);
8626 if (stc2 == 0)
8627 result = SRNone;
8628 else if (stc2 == STCref)
8629 result = SRRef;
8630 else if (stc2 == STCscope)
8631 result = SRScope;
8632 else if (stc2 == (STCscope | STCreturn))
8633 result = SRReturnScope;
8634 else if (stc2 == (STCref | STCreturn))
8635 result = SRReturnRef;
8636 else if (stc2 == (STCscope | STCref))
8637 result = SRRefScope;
8638 else if (stc2 == (STCscope | STCref | STCreturn))
8639 result = returnByRef ? SRReturnRef_Scope : SRRef_ReturnScope;
8640 else
8641 assert(0);
8642 return result;
8645 static void covariantInit(bool covariant[SRMAX][SRMAX])
8647 /* Initialize covariant[][] with this:
8649 From\To n rs s
8650 None X
8651 ReturnScope X X
8652 Scope X X X
8654 From\To r rr rs rr-s r-rs
8655 Ref X X
8656 ReturnRef X
8657 RefScope X X X X X
8658 ReturnRef-Scope X X
8659 Ref-ReturnScope X X X
8661 for (int i = 0; i < SRMAX; i++)
8663 covariant[i][i] = true;
8664 covariant[SRRefScope][i] = true;
8666 covariant[SRReturnScope][SRNone] = true;
8667 covariant[SRScope ][SRNone] = true;
8668 covariant[SRScope ][SRReturnScope] = true;
8670 covariant[SRRef ][SRReturnRef] = true;
8671 covariant[SRReturnRef_Scope][SRReturnRef] = true;
8672 covariant[SRRef_ReturnScope][SRRef ] = true;
8673 covariant[SRRef_ReturnScope][SRReturnRef] = true;
8677 /* result is true if the 'from' can be used as a 'to'
8680 if ((from ^ to) & STCref) // differing in 'ref' means no covariance
8681 return false;
8683 static bool covariant[SR::SRMAX][SR::SRMAX];
8684 static bool init = false;
8685 if (!init)
8687 SR::covariantInit(covariant);
8688 init = true;
8691 return covariant[SR::buildSR(returnByRef, from)][SR::buildSR(returnByRef, to)];
8695 * For printing two types with qualification when necessary.
8696 * Params:
8697 * t1 = The first type to receive the type name for
8698 * t2 = The second type to receive the type name for
8699 * Returns:
8700 * The fully-qualified names of both types if the two type names are not the same,
8701 * or the unqualified names of both types if the two type names are the same.
8703 void toAutoQualChars(const char **result, Type *t1, Type *t2)
8705 const char *s1 = t1->toChars();
8706 const char *s2 = t2->toChars();
8707 if (strcmp(s1, s2) == 0)
8709 s1 = t1->toPrettyChars(true);
8710 s2 = t2->toPrettyChars(true);
8712 result[0] = s1;
8713 result[1] = s2;