Merge dmd upstream e2fe2687b
[official-gcc.git] / gcc / d / dmd / mtype.c
blobb35b7af3201bae6a7dd066a783a5aca18da0e7aa
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 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 *semantic(Expression *e, Scope *sc);
41 Expression *semanticY(DotIdExp *exp, Scope *sc, int flag);
42 Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag);
43 Expression *typeToExpression(Type *t);
44 Expression *typeToExpressionHelper(TypeQualified *t, Expression *e, size_t i = 0);
45 Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret);
47 int Tsize_t = Tuns32;
48 int Tptrdiff_t = Tint32;
50 /***************************** Type *****************************/
52 ClassDeclaration *Type::dtypeinfo;
53 ClassDeclaration *Type::typeinfoclass;
54 ClassDeclaration *Type::typeinfointerface;
55 ClassDeclaration *Type::typeinfostruct;
56 ClassDeclaration *Type::typeinfopointer;
57 ClassDeclaration *Type::typeinfoarray;
58 ClassDeclaration *Type::typeinfostaticarray;
59 ClassDeclaration *Type::typeinfoassociativearray;
60 ClassDeclaration *Type::typeinfovector;
61 ClassDeclaration *Type::typeinfoenum;
62 ClassDeclaration *Type::typeinfofunction;
63 ClassDeclaration *Type::typeinfodelegate;
64 ClassDeclaration *Type::typeinfotypelist;
65 ClassDeclaration *Type::typeinfoconst;
66 ClassDeclaration *Type::typeinfoinvariant;
67 ClassDeclaration *Type::typeinfoshared;
68 ClassDeclaration *Type::typeinfowild;
70 TemplateDeclaration *Type::rtinfo;
72 Type *Type::tvoid;
73 Type *Type::tint8;
74 Type *Type::tuns8;
75 Type *Type::tint16;
76 Type *Type::tuns16;
77 Type *Type::tint32;
78 Type *Type::tuns32;
79 Type *Type::tint64;
80 Type *Type::tuns64;
81 Type *Type::tint128;
82 Type *Type::tuns128;
83 Type *Type::tfloat32;
84 Type *Type::tfloat64;
85 Type *Type::tfloat80;
87 Type *Type::timaginary32;
88 Type *Type::timaginary64;
89 Type *Type::timaginary80;
91 Type *Type::tcomplex32;
92 Type *Type::tcomplex64;
93 Type *Type::tcomplex80;
95 Type *Type::tbool;
96 Type *Type::tchar;
97 Type *Type::twchar;
98 Type *Type::tdchar;
100 Type *Type::tshiftcnt;
101 Type *Type::terror;
102 Type *Type::tnull;
104 Type *Type::tsize_t;
105 Type *Type::tptrdiff_t;
106 Type *Type::thash_t;
108 Type *Type::tvoidptr;
109 Type *Type::tstring;
110 Type *Type::twstring;
111 Type *Type::tdstring;
112 Type *Type::tvalist;
113 Type *Type::basic[TMAX];
114 unsigned char Type::sizeTy[TMAX];
115 StringTable Type::stringtable;
117 void initTypeMangle();
119 Type::Type(TY ty)
121 this->ty = ty;
122 this->mod = 0;
123 this->deco = NULL;
124 this->cto = NULL;
125 this->ito = NULL;
126 this->sto = NULL;
127 this->scto = NULL;
128 this->wto = NULL;
129 this->wcto = NULL;
130 this->swto = NULL;
131 this->swcto = NULL;
132 this->pto = NULL;
133 this->rto = NULL;
134 this->arrayof = NULL;
135 this->vtinfo = NULL;
136 this->ctype = NULL;
139 const char *Type::kind()
141 assert(false); // should be overridden
142 return NULL;
145 Type *Type::copy()
147 void *pt = mem.xmalloc(sizeTy[ty]);
148 Type *t = (Type *)memcpy(pt, (void *)this, sizeTy[ty]);
149 return t;
152 Type *Type::syntaxCopy()
154 print();
155 fprintf(stderr, "ty = %d\n", ty);
156 assert(0);
157 return this;
160 bool Type::equals(RootObject *o)
162 Type *t = (Type *)o;
163 //printf("Type::equals(%s, %s)\n", toChars(), t->toChars());
164 // deco strings are unique
165 // and semantic() has been run
166 if (this == o || ((t && deco == t->deco) && deco != NULL))
168 //printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
169 return true;
171 //if (deco && t && t->deco) printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
172 return false;
175 bool Type::equivalent(Type *t)
177 return immutableOf()->equals(t->immutableOf());
180 void Type::_init()
182 stringtable._init(14000);
184 for (size_t i = 0; i < TMAX; i++)
185 sizeTy[i] = sizeof(TypeBasic);
186 sizeTy[Tsarray] = sizeof(TypeSArray);
187 sizeTy[Tarray] = sizeof(TypeDArray);
188 sizeTy[Taarray] = sizeof(TypeAArray);
189 sizeTy[Tpointer] = sizeof(TypePointer);
190 sizeTy[Treference] = sizeof(TypeReference);
191 sizeTy[Tfunction] = sizeof(TypeFunction);
192 sizeTy[Tdelegate] = sizeof(TypeDelegate);
193 sizeTy[Tident] = sizeof(TypeIdentifier);
194 sizeTy[Tinstance] = sizeof(TypeInstance);
195 sizeTy[Ttypeof] = sizeof(TypeTypeof);
196 sizeTy[Tenum] = sizeof(TypeEnum);
197 sizeTy[Tstruct] = sizeof(TypeStruct);
198 sizeTy[Tclass] = sizeof(TypeClass);
199 sizeTy[Ttuple] = sizeof(TypeTuple);
200 sizeTy[Tslice] = sizeof(TypeSlice);
201 sizeTy[Treturn] = sizeof(TypeReturn);
202 sizeTy[Terror] = sizeof(TypeError);
203 sizeTy[Tnull] = sizeof(TypeNull);
204 sizeTy[Tvector] = sizeof(TypeVector);
206 initTypeMangle();
208 // Set basic types
209 static TY basetab[] =
210 { Tvoid, Tint8, Tuns8, Tint16, Tuns16, Tint32, Tuns32, Tint64, Tuns64,
211 Tint128, Tuns128,
212 Tfloat32, Tfloat64, Tfloat80,
213 Timaginary32, Timaginary64, Timaginary80,
214 Tcomplex32, Tcomplex64, Tcomplex80,
215 Tbool,
216 Tchar, Twchar, Tdchar, Terror };
218 for (size_t i = 0; basetab[i] != Terror; i++)
220 Type *t = new TypeBasic(basetab[i]);
221 t = t->merge();
222 basic[basetab[i]] = t;
224 basic[Terror] = new TypeError();
226 tvoid = basic[Tvoid];
227 tint8 = basic[Tint8];
228 tuns8 = basic[Tuns8];
229 tint16 = basic[Tint16];
230 tuns16 = basic[Tuns16];
231 tint32 = basic[Tint32];
232 tuns32 = basic[Tuns32];
233 tint64 = basic[Tint64];
234 tuns64 = basic[Tuns64];
235 tint128 = basic[Tint128];
236 tuns128 = basic[Tuns128];
237 tfloat32 = basic[Tfloat32];
238 tfloat64 = basic[Tfloat64];
239 tfloat80 = basic[Tfloat80];
241 timaginary32 = basic[Timaginary32];
242 timaginary64 = basic[Timaginary64];
243 timaginary80 = basic[Timaginary80];
245 tcomplex32 = basic[Tcomplex32];
246 tcomplex64 = basic[Tcomplex64];
247 tcomplex80 = basic[Tcomplex80];
249 tbool = basic[Tbool];
250 tchar = basic[Tchar];
251 twchar = basic[Twchar];
252 tdchar = basic[Tdchar];
254 tshiftcnt = tint32;
255 terror = basic[Terror];
256 tnull = basic[Tnull];
257 tnull = new TypeNull();
258 tnull->deco = tnull->merge()->deco;
260 tvoidptr = tvoid->pointerTo();
261 tstring = tchar->immutableOf()->arrayOf();
262 twstring = twchar->immutableOf()->arrayOf();
263 tdstring = tdchar->immutableOf()->arrayOf();
264 tvalist = Target::va_listType();
266 if (global.params.isLP64)
268 Tsize_t = Tuns64;
269 Tptrdiff_t = Tint64;
271 else
273 Tsize_t = Tuns32;
274 Tptrdiff_t = Tint32;
277 tsize_t = basic[Tsize_t];
278 tptrdiff_t = basic[Tptrdiff_t];
279 thash_t = tsize_t;
282 d_uns64 Type::size()
284 return size(Loc());
287 d_uns64 Type::size(Loc loc)
289 error(loc, "no size for type %s", toChars());
290 return SIZE_INVALID;
293 unsigned Type::alignsize()
295 return (unsigned)size(Loc());
298 Type *Type::semantic(Loc loc, Scope *)
300 if (ty == Tint128 || ty == Tuns128)
302 error(loc, "cent and ucent types not implemented");
303 return terror;
306 return merge();
309 Type *Type::trySemantic(Loc loc, Scope *sc)
311 //printf("+trySemantic(%s) %d\n", toChars(), global.errors);
312 unsigned errors = global.startGagging();
313 Type *t = semantic(loc, sc);
314 if (global.endGagging(errors) || t->ty == Terror) // if any errors happened
316 t = NULL;
318 //printf("-trySemantic(%s) %d\n", toChars(), global.errors);
319 return t;
322 /********************************
323 * Return a copy of this type with all attributes null-initialized.
324 * Useful for creating a type with different modifiers.
327 Type *Type::nullAttributes()
329 unsigned sz = sizeTy[ty];
330 void *pt = mem.xmalloc(sz);
331 Type *t = (Type *)memcpy(pt, (void *)this, sz);
332 t->deco = NULL;
333 t->arrayof = NULL;
334 t->pto = NULL;
335 t->rto = NULL;
336 t->cto = NULL;
337 t->ito = NULL;
338 t->sto = NULL;
339 t->scto = NULL;
340 t->wto = NULL;
341 t->wcto = NULL;
342 t->swto = NULL;
343 t->swcto = NULL;
344 t->vtinfo = NULL;
345 t->ctype = NULL;
346 if (t->ty == Tstruct) ((TypeStruct *)t)->att = RECfwdref;
347 if (t->ty == Tclass) ((TypeClass *)t)->att = RECfwdref;
348 return t;
351 /********************************
352 * Convert to 'const'.
355 Type *Type::constOf()
357 //printf("Type::constOf() %p %s\n", this, toChars());
358 if (mod == MODconst)
359 return this;
360 if (cto)
362 assert(cto->mod == MODconst);
363 return cto;
365 Type *t = makeConst();
366 t = t->merge();
367 t->fixTo(this);
368 //printf("-Type::constOf() %p %s\n", t, t->toChars());
369 return t;
372 /********************************
373 * Convert to 'immutable'.
376 Type *Type::immutableOf()
378 //printf("Type::immutableOf() %p %s\n", this, toChars());
379 if (isImmutable())
380 return this;
381 if (ito)
383 assert(ito->isImmutable());
384 return ito;
386 Type *t = makeImmutable();
387 t = t->merge();
388 t->fixTo(this);
389 //printf("\t%p\n", t);
390 return t;
393 /********************************
394 * Make type mutable.
397 Type *Type::mutableOf()
399 //printf("Type::mutableOf() %p, %s\n", this, toChars());
400 Type *t = this;
401 if (isImmutable())
403 t = ito; // immutable => naked
404 assert(!t || (t->isMutable() && !t->isShared()));
406 else if (isConst())
408 if (isShared())
410 if (isWild())
411 t = swcto; // shared wild const -> shared
412 else
413 t = sto; // shared const => shared
415 else
417 if (isWild())
418 t = wcto; // wild const -> naked
419 else
420 t = cto; // const => naked
422 assert(!t || t->isMutable());
424 else if (isWild())
426 if (isShared())
427 t = sto; // shared wild => shared
428 else
429 t = wto; // wild => naked
430 assert(!t || t->isMutable());
432 if (!t)
434 t = makeMutable();
435 t = t->merge();
436 t->fixTo(this);
438 else
439 t = t->merge();
440 assert(t->isMutable());
441 return t;
444 Type *Type::sharedOf()
446 //printf("Type::sharedOf() %p, %s\n", this, toChars());
447 if (mod == MODshared)
448 return this;
449 if (sto)
451 assert(sto->mod == MODshared);
452 return sto;
454 Type *t = makeShared();
455 t = t->merge();
456 t->fixTo(this);
457 //printf("\t%p\n", t);
458 return t;
461 Type *Type::sharedConstOf()
463 //printf("Type::sharedConstOf() %p, %s\n", this, toChars());
464 if (mod == (MODshared | MODconst))
465 return this;
466 if (scto)
468 assert(scto->mod == (MODshared | MODconst));
469 return scto;
471 Type *t = makeSharedConst();
472 t = t->merge();
473 t->fixTo(this);
474 //printf("\t%p\n", t);
475 return t;
479 /********************************
480 * Make type unshared.
481 * 0 => 0
482 * const => const
483 * immutable => immutable
484 * shared => 0
485 * shared const => const
486 * wild => wild
487 * wild const => wild const
488 * shared wild => wild
489 * shared wild const => wild const
492 Type *Type::unSharedOf()
494 //printf("Type::unSharedOf() %p, %s\n", this, toChars());
495 Type *t = this;
497 if (isShared())
499 if (isWild())
501 if (isConst())
502 t = wcto; // shared wild const => wild const
503 else
504 t = wto; // shared wild => wild
506 else
508 if (isConst())
509 t = cto; // shared const => const
510 else
511 t = sto; // shared => naked
513 assert(!t || !t->isShared());
516 if (!t)
518 t = this->nullAttributes();
519 t->mod = mod & ~MODshared;
520 t->ctype = ctype;
521 t = t->merge();
523 t->fixTo(this);
525 else
526 t = t->merge();
527 assert(!t->isShared());
528 return t;
531 /********************************
532 * Convert to 'wild'.
535 Type *Type::wildOf()
537 //printf("Type::wildOf() %p %s\n", this, toChars());
538 if (mod == MODwild)
539 return this;
540 if (wto)
542 assert(wto->mod == MODwild);
543 return wto;
545 Type *t = makeWild();
546 t = t->merge();
547 t->fixTo(this);
548 //printf("\t%p %s\n", t, t->toChars());
549 return t;
552 Type *Type::wildConstOf()
554 //printf("Type::wildConstOf() %p %s\n", this, toChars());
555 if (mod == MODwildconst)
556 return this;
557 if (wcto)
559 assert(wcto->mod == MODwildconst);
560 return wcto;
562 Type *t = makeWildConst();
563 t = t->merge();
564 t->fixTo(this);
565 //printf("\t%p %s\n", t, t->toChars());
566 return t;
569 Type *Type::sharedWildOf()
571 //printf("Type::sharedWildOf() %p, %s\n", this, toChars());
572 if (mod == (MODshared | MODwild))
573 return this;
574 if (swto)
576 assert(swto->mod == (MODshared | MODwild));
577 return swto;
579 Type *t = makeSharedWild();
580 t = t->merge();
581 t->fixTo(this);
582 //printf("\t%p %s\n", t, t->toChars());
583 return t;
586 Type *Type::sharedWildConstOf()
588 //printf("Type::sharedWildConstOf() %p, %s\n", this, toChars());
589 if (mod == (MODshared | MODwildconst))
590 return this;
591 if (swcto)
593 assert(swcto->mod == (MODshared | MODwildconst));
594 return swcto;
596 Type *t = makeSharedWildConst();
597 t = t->merge();
598 t->fixTo(this);
599 //printf("\t%p %s\n", t, t->toChars());
600 return t;
603 /**********************************
604 * For our new type 'this', which is type-constructed from t,
605 * fill in the cto, ito, sto, scto, wto shortcuts.
608 void Type::fixTo(Type *t)
610 // If fixing this: immutable(T*) by t: immutable(T)*,
611 // cache t to this->xto won't break transitivity.
612 Type *mto = NULL;
613 Type *tn = nextOf();
614 if (!tn || (ty != Tsarray && tn->mod == t->nextOf()->mod))
616 switch (t->mod)
618 case 0: mto = t; break;
619 case MODconst: cto = t; break;
620 case MODwild: wto = t; break;
621 case MODwildconst: wcto = t; break;
622 case MODshared: sto = t; break;
623 case MODshared | MODconst: scto = t; break;
624 case MODshared | MODwild: swto = t; break;
625 case MODshared | MODwildconst: swcto = t; break;
626 case MODimmutable: ito = t; break;
630 assert(mod != t->mod);
631 #define X(m, n) (((m) << 4) | (n))
632 switch (mod)
634 case 0:
635 break;
637 case MODconst:
638 cto = mto;
639 t->cto = this;
640 break;
642 case MODwild:
643 wto = mto;
644 t->wto = this;
645 break;
647 case MODwildconst:
648 wcto = mto;
649 t->wcto = this;
650 break;
652 case MODshared:
653 sto = mto;
654 t->sto = this;
655 break;
657 case MODshared | MODconst:
658 scto = mto;
659 t->scto = this;
660 break;
662 case MODshared | MODwild:
663 swto = mto;
664 t->swto = this;
665 break;
667 case MODshared | MODwildconst:
668 swcto = mto;
669 t->swcto = this;
670 break;
672 case MODimmutable:
673 t->ito = this;
674 if (t-> cto) t-> cto->ito = this;
675 if (t-> sto) t-> sto->ito = this;
676 if (t-> scto) t-> scto->ito = this;
677 if (t-> wto) t-> wto->ito = this;
678 if (t-> wcto) t-> wcto->ito = this;
679 if (t-> swto) t-> swto->ito = this;
680 if (t->swcto) t->swcto->ito = this;
681 break;
683 default:
684 assert(0);
686 #undef X
688 check();
689 t->check();
690 //printf("fixTo: %s, %s\n", toChars(), t->toChars());
693 /***************************
694 * Look for bugs in constructing types.
697 void Type::check()
699 switch (mod)
701 case 0:
702 if (cto) assert(cto->mod == MODconst);
703 if (ito) assert(ito->mod == MODimmutable);
704 if (sto) assert(sto->mod == MODshared);
705 if (scto) assert(scto->mod == (MODshared | MODconst));
706 if (wto) assert(wto->mod == MODwild);
707 if (wcto) assert(wcto->mod == MODwildconst);
708 if (swto) assert(swto->mod == (MODshared | MODwild));
709 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
710 break;
712 case MODconst:
713 if (cto) assert(cto->mod == 0);
714 if (ito) assert(ito->mod == MODimmutable);
715 if (sto) assert(sto->mod == MODshared);
716 if (scto) assert(scto->mod == (MODshared | MODconst));
717 if (wto) assert(wto->mod == MODwild);
718 if (wcto) assert(wcto->mod == MODwildconst);
719 if (swto) assert(swto->mod == (MODshared | MODwild));
720 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
721 break;
723 case MODwild:
724 if (cto) assert(cto->mod == MODconst);
725 if (ito) assert(ito->mod == MODimmutable);
726 if (sto) assert(sto->mod == MODshared);
727 if (scto) assert(scto->mod == (MODshared | MODconst));
728 if (wto) assert(wto->mod == 0);
729 if (wcto) assert(wcto->mod == MODwildconst);
730 if (swto) assert(swto->mod == (MODshared | MODwild));
731 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
732 break;
734 case MODwildconst:
735 assert(! cto || cto->mod == MODconst);
736 assert(! ito || ito->mod == MODimmutable);
737 assert(! sto || sto->mod == MODshared);
738 assert(! scto || scto->mod == (MODshared | MODconst));
739 assert(! wto || wto->mod == MODwild);
740 assert(! wcto || wcto->mod == 0);
741 assert(! swto || swto->mod == (MODshared | MODwild));
742 assert(!swcto || swcto->mod == (MODshared | MODwildconst));
743 break;
745 case MODshared:
746 if (cto) assert(cto->mod == MODconst);
747 if (ito) assert(ito->mod == MODimmutable);
748 if (sto) assert(sto->mod == 0);
749 if (scto) assert(scto->mod == (MODshared | MODconst));
750 if (wto) assert(wto->mod == MODwild);
751 if (wcto) assert(wcto->mod == MODwildconst);
752 if (swto) assert(swto->mod == (MODshared | MODwild));
753 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
754 break;
756 case MODshared | MODconst:
757 if (cto) assert(cto->mod == MODconst);
758 if (ito) assert(ito->mod == MODimmutable);
759 if (sto) assert(sto->mod == MODshared);
760 if (scto) assert(scto->mod == 0);
761 if (wto) assert(wto->mod == MODwild);
762 if (wcto) assert(wcto->mod == MODwildconst);
763 if (swto) assert(swto->mod == (MODshared | MODwild));
764 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
765 break;
767 case MODshared | MODwild:
768 if (cto) assert(cto->mod == MODconst);
769 if (ito) assert(ito->mod == MODimmutable);
770 if (sto) assert(sto->mod == MODshared);
771 if (scto) assert(scto->mod == (MODshared | MODconst));
772 if (wto) assert(wto->mod == MODwild);
773 if (wcto) assert(wcto->mod == MODwildconst);
774 if (swto) assert(swto->mod == 0);
775 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
776 break;
778 case MODshared | MODwildconst:
779 assert(! cto || cto->mod == MODconst);
780 assert(! ito || ito->mod == MODimmutable);
781 assert(! sto || sto->mod == MODshared);
782 assert(! scto || scto->mod == (MODshared | MODconst));
783 assert(! wto || wto->mod == MODwild);
784 assert(! wcto || wcto->mod == MODwildconst);
785 assert(! swto || swto->mod == (MODshared | MODwild));
786 assert(!swcto || swcto->mod == 0);
787 break;
789 case MODimmutable:
790 if (cto) assert(cto->mod == MODconst);
791 if (ito) assert(ito->mod == 0);
792 if (sto) assert(sto->mod == MODshared);
793 if (scto) assert(scto->mod == (MODshared | MODconst));
794 if (wto) assert(wto->mod == MODwild);
795 if (wcto) assert(wcto->mod == MODwildconst);
796 if (swto) assert(swto->mod == (MODshared | MODwild));
797 if (swcto) assert(swcto->mod == (MODshared | MODwildconst));
798 break;
800 default:
801 assert(0);
804 Type *tn = nextOf();
805 if (tn && ty != Tfunction && tn->ty != Tfunction && ty != Tenum)
807 // Verify transitivity
808 switch (mod)
810 case 0:
811 case MODconst:
812 case MODwild:
813 case MODwildconst:
814 case MODshared:
815 case MODshared | MODconst:
816 case MODshared | MODwild:
817 case MODshared | MODwildconst:
818 case MODimmutable:
819 assert(tn->mod == MODimmutable || (tn->mod & mod) == mod);
820 break;
822 default:
823 assert(0);
825 tn->check();
829 Type *Type::makeConst()
831 //printf("Type::makeConst() %p, %s\n", this, toChars());
832 if (cto) return cto;
833 Type *t = this->nullAttributes();
834 t->mod = MODconst;
835 //printf("-Type::makeConst() %p, %s\n", t, toChars());
836 return t;
839 Type *Type::makeImmutable()
841 if (ito) return ito;
842 Type *t = this->nullAttributes();
843 t->mod = MODimmutable;
844 return t;
847 Type *Type::makeShared()
849 if (sto) return sto;
850 Type *t = this->nullAttributes();
851 t->mod = MODshared;
852 return t;
855 Type *Type::makeSharedConst()
857 if (scto) return scto;
858 Type *t = this->nullAttributes();
859 t->mod = MODshared | MODconst;
860 return t;
863 Type *Type::makeWild()
865 if (wto) return wto;
866 Type *t = this->nullAttributes();
867 t->mod = MODwild;
868 return t;
871 Type *Type::makeWildConst()
873 if (wcto) return wcto;
874 Type *t = this->nullAttributes();
875 t->mod = MODwildconst;
876 return t;
879 Type *Type::makeSharedWild()
881 if (swto) return swto;
882 Type *t = this->nullAttributes();
883 t->mod = MODshared | MODwild;
884 return t;
887 Type *Type::makeSharedWildConst()
889 if (swcto) return swcto;
890 Type *t = this->nullAttributes();
891 t->mod = MODshared | MODwildconst;
892 return t;
895 Type *Type::makeMutable()
897 Type *t = this->nullAttributes();
898 t->mod = mod & MODshared;
899 return t;
902 /*************************************
903 * Apply STCxxxx bits to existing type.
904 * Use *before* semantic analysis is run.
907 Type *Type::addSTC(StorageClass stc)
909 Type *t = this;
910 if (t->isImmutable())
912 else if (stc & STCimmutable)
914 t = t->makeImmutable();
916 else
918 if ((stc & STCshared) && !t->isShared())
920 if (t->isWild())
922 if (t->isConst())
923 t = t->makeSharedWildConst();
924 else
925 t = t->makeSharedWild();
927 else
929 if (t->isConst())
930 t = t->makeSharedConst();
931 else
932 t = t->makeShared();
935 if ((stc & STCconst) && !t->isConst())
937 if (t->isShared())
939 if (t->isWild())
940 t = t->makeSharedWildConst();
941 else
942 t = t->makeSharedConst();
944 else
946 if (t->isWild())
947 t = t->makeWildConst();
948 else
949 t = t->makeConst();
952 if ((stc & STCwild) && !t->isWild())
954 if (t->isShared())
956 if (t->isConst())
957 t = t->makeSharedWildConst();
958 else
959 t = t->makeSharedWild();
961 else
963 if (t->isConst())
964 t = t->makeWildConst();
965 else
966 t = t->makeWild();
970 return t;
973 /************************************
974 * Convert MODxxxx to STCxxx
977 StorageClass ModToStc(unsigned mod)
979 StorageClass stc = 0;
980 if (mod & MODimmutable) stc |= STCimmutable;
981 if (mod & MODconst) stc |= STCconst;
982 if (mod & MODwild) stc |= STCwild;
983 if (mod & MODshared) stc |= STCshared;
984 return stc;
987 /************************************
988 * Apply MODxxxx bits to existing type.
991 Type *Type::castMod(MOD mod)
992 { Type *t;
994 switch (mod)
996 case 0:
997 t = unSharedOf()->mutableOf();
998 break;
1000 case MODconst:
1001 t = unSharedOf()->constOf();
1002 break;
1004 case MODwild:
1005 t = unSharedOf()->wildOf();
1006 break;
1008 case MODwildconst:
1009 t = unSharedOf()->wildConstOf();
1010 break;
1012 case MODshared:
1013 t = mutableOf()->sharedOf();
1014 break;
1016 case MODshared | MODconst:
1017 t = sharedConstOf();
1018 break;
1020 case MODshared | MODwild:
1021 t = sharedWildOf();
1022 break;
1024 case MODshared | MODwildconst:
1025 t = sharedWildConstOf();
1026 break;
1028 case MODimmutable:
1029 t = immutableOf();
1030 break;
1032 default:
1033 assert(0);
1035 return t;
1038 /************************************
1039 * Add MODxxxx bits to existing type.
1040 * We're adding, not replacing, so adding const to
1041 * a shared type => "shared const"
1044 Type *Type::addMod(MOD mod)
1046 /* Add anything to immutable, and it remains immutable
1048 Type *t = this;
1049 if (!t->isImmutable())
1051 //printf("addMod(%x) %s\n", mod, toChars());
1052 switch (mod)
1054 case 0:
1055 break;
1057 case MODconst:
1058 if (isShared())
1060 if (isWild())
1061 t = sharedWildConstOf();
1062 else
1063 t = sharedConstOf();
1065 else
1067 if (isWild())
1068 t = wildConstOf();
1069 else
1070 t = constOf();
1072 break;
1074 case MODwild:
1075 if (isShared())
1077 if (isConst())
1078 t = sharedWildConstOf();
1079 else
1080 t = sharedWildOf();
1082 else
1084 if (isConst())
1085 t = wildConstOf();
1086 else
1087 t = wildOf();
1089 break;
1091 case MODwildconst:
1092 if (isShared())
1093 t = sharedWildConstOf();
1094 else
1095 t = wildConstOf();
1096 break;
1098 case MODshared:
1099 if (isWild())
1101 if (isConst())
1102 t = sharedWildConstOf();
1103 else
1104 t = sharedWildOf();
1106 else
1108 if (isConst())
1109 t = sharedConstOf();
1110 else
1111 t = sharedOf();
1113 break;
1115 case MODshared | MODconst:
1116 if (isWild())
1117 t = sharedWildConstOf();
1118 else
1119 t = sharedConstOf();
1120 break;
1122 case MODshared | MODwild:
1123 if (isConst())
1124 t = sharedWildConstOf();
1125 else
1126 t = sharedWildOf();
1127 break;
1129 case MODshared | MODwildconst:
1130 t = sharedWildConstOf();
1131 break;
1133 case MODimmutable:
1134 t = immutableOf();
1135 break;
1137 default:
1138 assert(0);
1141 return t;
1144 /************************************
1145 * Add storage class modifiers to type.
1148 Type *Type::addStorageClass(StorageClass stc)
1150 /* Just translate to MOD bits and let addMod() do the work
1152 MOD mod = 0;
1154 if (stc & STCimmutable)
1155 mod = MODimmutable;
1156 else
1158 if (stc & (STCconst | STCin))
1159 mod |= MODconst;
1160 if (stc & STCwild)
1161 mod |= MODwild;
1162 if (stc & STCshared)
1163 mod |= MODshared;
1165 return addMod(mod);
1168 Type *Type::pointerTo()
1170 if (ty == Terror)
1171 return this;
1172 if (!pto)
1174 Type *t = new TypePointer(this);
1175 if (ty == Tfunction)
1177 t->deco = t->merge()->deco;
1178 pto = t;
1180 else
1181 pto = t->merge();
1183 return pto;
1186 Type *Type::referenceTo()
1188 if (ty == Terror)
1189 return this;
1190 if (!rto)
1192 Type *t = new TypeReference(this);
1193 rto = t->merge();
1195 return rto;
1198 Type *Type::arrayOf()
1200 if (ty == Terror)
1201 return this;
1202 if (!arrayof)
1204 Type *t = new TypeDArray(this);
1205 arrayof = t->merge();
1207 return arrayof;
1210 // Make corresponding static array type without semantic
1211 Type *Type::sarrayOf(dinteger_t dim)
1213 assert(deco);
1214 Type *t = new TypeSArray(this, new IntegerExp(Loc(), dim, Type::tsize_t));
1216 // according to TypeSArray::semantic()
1217 t = t->addMod(mod);
1218 t = t->merge();
1220 return t;
1223 Type *Type::aliasthisOf()
1225 AggregateDeclaration *ad = isAggregate(this);
1226 if (ad && ad->aliasthis)
1228 Dsymbol *s = ad->aliasthis;
1229 if (s->isAliasDeclaration())
1230 s = s->toAlias();
1231 Declaration *d = s->isDeclaration();
1232 if (d && !d->isTupleDeclaration())
1234 assert(d->type);
1235 Type *t = d->type;
1236 if (d->isVarDeclaration() && d->needThis())
1238 t = t->addMod(this->mod);
1240 else if (d->isFuncDeclaration())
1242 FuncDeclaration *fd = resolveFuncCall(Loc(), NULL, d, NULL, this, NULL, 1);
1243 if (fd && fd->errors)
1244 return Type::terror;
1245 if (fd && !fd->type->nextOf() && !fd->functionSemantic())
1246 fd = NULL;
1247 if (fd)
1249 t = fd->type->nextOf();
1250 if (!t) // issue 14185
1251 return Type::terror;
1252 t = t->substWildTo(mod == 0 ? MODmutable : (MODFlags)mod);
1254 else
1255 return Type::terror;
1257 return t;
1259 EnumDeclaration *ed = s->isEnumDeclaration();
1260 if (ed)
1262 Type *t = ed->type;
1263 return t;
1265 TemplateDeclaration *td = s->isTemplateDeclaration();
1266 if (td)
1268 assert(td->_scope);
1269 FuncDeclaration *fd = resolveFuncCall(Loc(), NULL, td, NULL, this, NULL, 1);
1270 if (fd && fd->errors)
1271 return Type::terror;
1272 if (fd && fd->functionSemantic())
1274 Type *t = fd->type->nextOf();
1275 t = t->substWildTo(mod == 0 ? MODmutable : (MODFlags)mod);
1276 return t;
1278 else
1279 return Type::terror;
1281 //printf("%s\n", s->kind());
1283 return NULL;
1286 bool Type::checkAliasThisRec()
1288 Type *tb = toBasetype();
1289 AliasThisRec* pflag;
1290 if (tb->ty == Tstruct)
1291 pflag = &((TypeStruct *)tb)->att;
1292 else if (tb->ty == Tclass)
1293 pflag = &((TypeClass *)tb)->att;
1294 else
1295 return false;
1297 AliasThisRec flag = (AliasThisRec)(*pflag & RECtypeMask);
1298 if (flag == RECfwdref)
1300 Type *att = aliasthisOf();
1301 flag = att && att->implicitConvTo(this) ? RECyes : RECno;
1303 *pflag = (AliasThisRec)(flag | (*pflag & ~RECtypeMask));
1304 return flag == RECyes;
1307 Dsymbol *Type::toDsymbol(Scope *)
1309 return NULL;
1312 /*******************************
1313 * If this is a shell around another type,
1314 * get that other type.
1317 Type *Type::toBasetype()
1319 return this;
1322 /***************************
1323 * Return !=0 if modfrom can be implicitly converted to modto
1325 bool MODimplicitConv(MOD modfrom, MOD modto)
1327 if (modfrom == modto)
1328 return true;
1330 //printf("MODimplicitConv(from = %x, to = %x)\n", modfrom, modto);
1331 #define X(m, n) (((m) << 4) | (n))
1332 switch (X(modfrom & ~MODshared, modto & ~MODshared))
1334 case X(0, MODconst):
1335 case X(MODwild, MODconst):
1336 case X(MODwild, MODwildconst):
1337 case X(MODwildconst, MODconst):
1338 return (modfrom & MODshared) == (modto & MODshared);
1340 case X(MODimmutable, MODconst):
1341 case X(MODimmutable, MODwildconst):
1342 return true;
1344 default:
1345 return false;
1347 #undef X
1350 /***************************
1351 * Return MATCHexact or MATCHconst if a method of type '() modfrom' can call a method of type '() modto'.
1353 MATCH MODmethodConv(MOD modfrom, MOD modto)
1355 if (modfrom == modto)
1356 return MATCHexact;
1357 if (MODimplicitConv(modfrom, modto))
1358 return MATCHconst;
1360 #define X(m, n) (((m) << 4) | (n))
1361 switch (X(modfrom, modto))
1363 case X(0, MODwild):
1364 case X(MODimmutable, MODwild):
1365 case X(MODconst, MODwild):
1366 case X(MODwildconst, MODwild):
1367 case X(MODshared, MODshared|MODwild):
1368 case X(MODshared|MODimmutable, MODshared|MODwild):
1369 case X(MODshared|MODconst, MODshared|MODwild):
1370 case X(MODshared|MODwildconst, MODshared|MODwild):
1371 return MATCHconst;
1373 default:
1374 return MATCHnomatch;
1376 #undef X
1379 /***************************
1380 * Merge mod bits to form common mod.
1382 MOD MODmerge(MOD mod1, MOD mod2)
1384 if (mod1 == mod2)
1385 return mod1;
1387 //printf("MODmerge(1 = %x, 2 = %x)\n", mod1, mod2);
1388 MOD result = 0;
1389 if ((mod1 | mod2) & MODshared)
1391 // If either type is shared, the result will be shared
1392 result |= MODshared;
1393 mod1 &= ~MODshared;
1394 mod2 &= ~MODshared;
1396 if (mod1 == 0 || mod1 == MODmutable || mod1 == MODconst ||
1397 mod2 == 0 || mod2 == MODmutable || mod2 == MODconst)
1399 // If either type is mutable or const, the result will be const.
1400 result |= MODconst;
1402 else
1404 // MODimmutable vs MODwild
1405 // MODimmutable vs MODwildconst
1406 // MODwild vs MODwildconst
1407 assert(mod1 & MODwild || mod2 & MODwild);
1408 result |= MODwildconst;
1410 return result;
1413 /*********************************
1414 * Store modifier name into buf.
1416 void MODtoBuffer(OutBuffer *buf, MOD mod)
1418 switch (mod)
1420 case 0:
1421 break;
1423 case MODimmutable:
1424 buf->writestring(Token::tochars[TOKimmutable]);
1425 break;
1427 case MODshared:
1428 buf->writestring(Token::tochars[TOKshared]);
1429 break;
1431 case MODshared | MODconst:
1432 buf->writestring(Token::tochars[TOKshared]);
1433 buf->writeByte(' ');
1434 /* fall through */
1435 case MODconst:
1436 buf->writestring(Token::tochars[TOKconst]);
1437 break;
1439 case MODshared | MODwild:
1440 buf->writestring(Token::tochars[TOKshared]);
1441 buf->writeByte(' ');
1442 /* fall through */
1443 case MODwild:
1444 buf->writestring(Token::tochars[TOKwild]);
1445 break;
1447 case MODshared | MODwildconst:
1448 buf->writestring(Token::tochars[TOKshared]);
1449 buf->writeByte(' ');
1450 /* fall through */
1451 case MODwildconst:
1452 buf->writestring(Token::tochars[TOKwild]);
1453 buf->writeByte(' ');
1454 buf->writestring(Token::tochars[TOKconst]);
1455 break;
1457 default:
1458 assert(0);
1463 /*********************************
1464 * Return modifier name.
1466 char *MODtoChars(MOD mod)
1468 OutBuffer buf;
1469 buf.reserve(16);
1470 MODtoBuffer(&buf, mod);
1471 return buf.extractString();
1474 /********************************
1475 * For pretty-printing a type.
1478 const char *Type::toChars()
1480 OutBuffer buf;
1481 buf.reserve(16);
1482 HdrGenState hgs;
1483 hgs.fullQual = (ty == Tclass && !mod);
1485 ::toCBuffer(this, &buf, NULL, &hgs);
1486 return buf.extractString();
1489 char *Type::toPrettyChars(bool QualifyTypes)
1491 OutBuffer buf;
1492 buf.reserve(16);
1493 HdrGenState hgs;
1494 hgs.fullQual = QualifyTypes;
1496 ::toCBuffer(this, &buf, NULL, &hgs);
1497 return buf.extractString();
1500 /*********************************
1501 * Store this type's modifier name into buf.
1503 void Type::modToBuffer(OutBuffer *buf)
1505 if (mod)
1507 buf->writeByte(' ');
1508 MODtoBuffer(buf, mod);
1512 /*********************************
1513 * Return this type's modifier name.
1515 char *Type::modToChars()
1517 OutBuffer buf;
1518 buf.reserve(16);
1519 modToBuffer(&buf);
1520 return buf.extractString();
1523 /** For each active modifier (MODconst, MODimmutable, etc) call fp with a
1524 void* for the work param and a string representation of the attribute. */
1525 int Type::modifiersApply(void *param, int (*fp)(void *, const char *))
1527 static unsigned char modsArr[] = { MODconst, MODimmutable, MODwild, MODshared };
1529 for (size_t idx = 0; idx < 4; ++idx)
1531 if (mod & modsArr[idx])
1533 if (int res = fp(param, MODtoChars(modsArr[idx])))
1534 return res;
1537 return 0;
1540 /************************************
1541 * Strip all parameter's idenfiers and their default arguments for merging types.
1542 * If some of parameter types or return type are function pointer, delegate, or
1543 * the types which contains either, then strip also from them.
1546 Type *stripDefaultArgs(Type *t)
1548 struct N
1550 static Parameters *stripParams(Parameters *parameters)
1552 Parameters *params = parameters;
1553 if (params && params->dim > 0)
1555 for (size_t i = 0; i < params->dim; i++)
1557 Parameter *p = (*params)[i];
1558 Type *ta = stripDefaultArgs(p->type);
1559 if (ta != p->type || p->defaultArg || p->ident)
1561 if (params == parameters)
1563 params = new Parameters();
1564 params->setDim(parameters->dim);
1565 for (size_t j = 0; j < params->dim; j++)
1566 (*params)[j] = (*parameters)[j];
1568 (*params)[i] = new Parameter(p->storageClass, ta, NULL, NULL);
1572 return params;
1576 if (t == NULL)
1577 return t;
1579 if (t->ty == Tfunction)
1581 TypeFunction *tf = (TypeFunction *)t;
1582 Type *tret = stripDefaultArgs(tf->next);
1583 Parameters *params = N::stripParams(tf->parameters);
1584 if (tret == tf->next && params == tf->parameters)
1585 goto Lnot;
1586 tf = (TypeFunction *)tf->copy();
1587 tf->parameters = params;
1588 tf->next = tret;
1589 //printf("strip %s\n <- %s\n", tf->toChars(), t->toChars());
1590 t = tf;
1592 else if (t->ty == Ttuple)
1594 TypeTuple *tt = (TypeTuple *)t;
1595 Parameters *args = N::stripParams(tt->arguments);
1596 if (args == tt->arguments)
1597 goto Lnot;
1598 t = t->copy();
1599 ((TypeTuple *)t)->arguments = args;
1601 else if (t->ty == Tenum)
1603 // TypeEnum::nextOf() may be != NULL, but it's not necessary here.
1604 goto Lnot;
1606 else
1608 Type *tn = t->nextOf();
1609 Type *n = stripDefaultArgs(tn);
1610 if (n == tn)
1611 goto Lnot;
1612 t = t->copy();
1613 ((TypeNext *)t)->next = n;
1615 //printf("strip %s\n", t->toChars());
1616 Lnot:
1617 return t;
1620 /************************************
1623 Type *Type::merge()
1625 if (ty == Terror) return this;
1626 if (ty == Ttypeof) return this;
1627 if (ty == Tident) return this;
1628 if (ty == Tinstance) return this;
1629 if (ty == Taarray && !((TypeAArray *)this)->index->merge()->deco)
1630 return this;
1631 if (ty != Tenum && nextOf() && !nextOf()->deco)
1632 return this;
1634 //printf("merge(%s)\n", toChars());
1635 Type *t = this;
1636 assert(t);
1637 if (!deco)
1639 OutBuffer buf;
1640 buf.reserve(32);
1642 mangleToBuffer(this, &buf);
1644 StringValue *sv = stringtable.update((char *)buf.data, buf.offset);
1645 if (sv->ptrvalue)
1647 t = (Type *) sv->ptrvalue;
1648 assert(t->deco);
1649 //printf("old value, deco = '%s' %p\n", t->deco, t->deco);
1651 else
1653 sv->ptrvalue = (char *)(t = stripDefaultArgs(t));
1654 deco = t->deco = const_cast<char *>(sv->toDchars());
1655 //printf("new value, deco = '%s' %p\n", t->deco, t->deco);
1658 return t;
1661 /*************************************
1662 * This version does a merge even if the deco is already computed.
1663 * Necessary for types that have a deco, but are not merged.
1665 Type *Type::merge2()
1667 //printf("merge2(%s)\n", toChars());
1668 Type *t = this;
1669 assert(t);
1670 if (!t->deco)
1671 return t->merge();
1673 StringValue *sv = stringtable.lookup((char *)t->deco, strlen(t->deco));
1674 if (sv && sv->ptrvalue)
1675 { t = (Type *) sv->ptrvalue;
1676 assert(t->deco);
1678 else
1679 assert(0);
1680 return t;
1683 bool Type::isintegral()
1685 return false;
1688 bool Type::isfloating()
1690 return false;
1693 bool Type::isreal()
1695 return false;
1698 bool Type::isimaginary()
1700 return false;
1703 bool Type::iscomplex()
1705 return false;
1708 bool Type::isscalar()
1710 return false;
1713 bool Type::isunsigned()
1715 return false;
1718 ClassDeclaration *Type::isClassHandle()
1720 return NULL;
1723 bool Type::isscope()
1725 return false;
1728 bool Type::isString()
1730 return false;
1733 /**************************
1734 * When T is mutable,
1735 * Given:
1736 * T a, b;
1737 * Can we bitwise assign:
1738 * a = b;
1741 bool Type::isAssignable()
1743 return true;
1746 /**************************
1747 * Returns true if T can be converted to boolean value.
1749 bool Type::isBoolean()
1751 return isscalar();
1754 /********************************
1755 * true if when type goes out of scope, it needs a destructor applied.
1756 * Only applies to value types, not ref types.
1758 bool Type::needsDestruction()
1760 return false;
1763 /*********************************
1767 bool Type::needsNested()
1769 return false;
1772 /*********************************
1773 * Check type to see if it is based on a deprecated symbol.
1776 void Type::checkDeprecated(Loc loc, Scope *sc)
1778 Dsymbol *s = toDsymbol(sc);
1780 if (s)
1781 s->checkDeprecated(loc, sc);
1785 Expression *Type::defaultInit(Loc)
1787 return NULL;
1790 /***************************************
1791 * Use when we prefer the default initializer to be a literal,
1792 * rather than a global immutable variable.
1794 Expression *Type::defaultInitLiteral(Loc loc)
1796 return defaultInit(loc);
1799 bool Type::isZeroInit(Loc)
1801 return false; // assume not
1804 bool Type::isBaseOf(Type *, int *)
1806 return 0; // assume not
1809 /********************************
1810 * Determine if 'this' can be implicitly converted
1811 * to type 'to'.
1812 * Returns:
1813 * MATCHnomatch, MATCHconvert, MATCHconst, MATCHexact
1816 MATCH Type::implicitConvTo(Type *to)
1818 //printf("Type::implicitConvTo(this=%p, to=%p)\n", this, to);
1819 //printf("from: %s\n", toChars());
1820 //printf("to : %s\n", to->toChars());
1821 if (this->equals(to))
1822 return MATCHexact;
1823 return MATCHnomatch;
1826 /*******************************
1827 * Determine if converting 'this' to 'to' is an identity operation,
1828 * a conversion to const operation, or the types aren't the same.
1829 * Returns:
1830 * MATCHexact 'this' == 'to'
1831 * MATCHconst 'to' is const
1832 * MATCHnomatch conversion to mutable or invariant
1835 MATCH Type::constConv(Type *to)
1837 //printf("Type::constConv(this = %s, to = %s)\n", toChars(), to->toChars());
1838 if (equals(to))
1839 return MATCHexact;
1840 if (ty == to->ty && MODimplicitConv(mod, to->mod))
1841 return MATCHconst;
1842 return MATCHnomatch;
1845 /***************************************
1846 * Return MOD bits matching this type to wild parameter type (tprm).
1849 unsigned char Type::deduceWild(Type *t, bool)
1851 //printf("Type::deduceWild this = '%s', tprm = '%s'\n", toChars(), tprm->toChars());
1853 if (t->isWild())
1855 if (isImmutable())
1856 return MODimmutable;
1857 else if (isWildConst())
1859 if (t->isWildConst())
1860 return MODwild;
1861 else
1862 return MODwildconst;
1864 else if (isWild())
1865 return MODwild;
1866 else if (isConst())
1867 return MODconst;
1868 else if (isMutable())
1869 return MODmutable;
1870 else
1871 assert(0);
1873 return 0;
1876 Type *Type::unqualify(unsigned m)
1878 Type *t = mutableOf()->unSharedOf();
1880 Type *tn = ty == Tenum ? NULL : nextOf();
1881 if (tn && tn->ty != Tfunction)
1883 Type *utn = tn->unqualify(m);
1884 if (utn != tn)
1886 if (ty == Tpointer)
1887 t = utn->pointerTo();
1888 else if (ty == Tarray)
1889 t = utn->arrayOf();
1890 else if (ty == Tsarray)
1891 t = new TypeSArray(utn, ((TypeSArray *)this)->dim);
1892 else if (ty == Taarray)
1894 t = new TypeAArray(utn, ((TypeAArray *)this)->index);
1895 ((TypeAArray *)t)->sc = ((TypeAArray *)this)->sc; // duplicate scope
1897 else
1898 assert(0);
1900 t = t->merge();
1903 t = t->addMod(mod & ~m);
1904 return t;
1907 Type *Type::substWildTo(unsigned mod)
1909 //printf("+Type::substWildTo this = %s, mod = x%x\n", toChars(), mod);
1910 Type *t;
1912 if (Type *tn = nextOf())
1914 // substitution has no effect on function pointer type.
1915 if (ty == Tpointer && tn->ty == Tfunction)
1917 t = this;
1918 goto L1;
1921 t = tn->substWildTo(mod);
1922 if (t == tn)
1923 t = this;
1924 else
1926 if (ty == Tpointer)
1927 t = t->pointerTo();
1928 else if (ty == Tarray)
1929 t = t->arrayOf();
1930 else if (ty == Tsarray)
1931 t = new TypeSArray(t, ((TypeSArray *)this)->dim->syntaxCopy());
1932 else if (ty == Taarray)
1934 t = new TypeAArray(t, ((TypeAArray *)this)->index->syntaxCopy());
1935 ((TypeAArray *)t)->sc = ((TypeAArray *)this)->sc; // duplicate scope
1937 else if (ty == Tdelegate)
1939 t = new TypeDelegate(t);
1941 else
1942 assert(0);
1944 t = t->merge();
1947 else
1948 t = this;
1951 if (isWild())
1953 if (mod == MODimmutable)
1955 t = t->immutableOf();
1957 else if (mod == MODwildconst)
1959 t = t->wildConstOf();
1961 else if (mod == MODwild)
1963 if (isWildConst())
1964 t = t->wildConstOf();
1965 else
1966 t = t->wildOf();
1968 else if (mod == MODconst)
1970 t = t->constOf();
1972 else
1974 if (isWildConst())
1975 t = t->constOf();
1976 else
1977 t = t->mutableOf();
1980 if (isConst())
1981 t = t->addMod(MODconst);
1982 if (isShared())
1983 t = t->addMod(MODshared);
1985 //printf("-Type::substWildTo t = %s\n", t->toChars());
1986 return t;
1989 Type *TypeFunction::substWildTo(unsigned)
1991 if (!iswild && !(mod & MODwild))
1992 return this;
1994 // Substitude inout qualifier of function type to mutable or immutable
1995 // would break type system. Instead substitude inout to the most weak
1996 // qualifer - const.
1997 unsigned m = MODconst;
1999 assert(next);
2000 Type *tret = next->substWildTo(m);
2001 Parameters *params = parameters;
2002 if (mod & MODwild)
2003 params = parameters->copy();
2004 for (size_t i = 0; i < params->dim; i++)
2006 Parameter *p = (*params)[i];
2007 Type *t = p->type->substWildTo(m);
2008 if (t == p->type)
2009 continue;
2010 if (params == parameters)
2011 params = parameters->copy();
2012 (*params)[i] = new Parameter(p->storageClass, t, NULL, NULL);
2014 if (next == tret && params == parameters)
2015 return this;
2017 // Similar to TypeFunction::syntaxCopy;
2018 TypeFunction *t = new TypeFunction(params, tret, varargs, linkage);
2019 t->mod = ((mod & MODwild) ? (mod & ~MODwild) | MODconst : mod);
2020 t->isnothrow = isnothrow;
2021 t->isnogc = isnogc;
2022 t->purity = purity;
2023 t->isproperty = isproperty;
2024 t->isref = isref;
2025 t->isreturn = isreturn;
2026 t->isscope = isscope;
2027 t->isscopeinferred = isscopeinferred;
2028 t->iswild = 0;
2029 t->trust = trust;
2030 t->fargs = fargs;
2031 return t->merge();
2034 /**************************
2035 * Return type with the top level of it being mutable.
2037 Type *Type::toHeadMutable()
2039 if (!mod)
2040 return this;
2041 return mutableOf();
2044 /***************************************
2045 * Calculate built-in properties which just the type is necessary.
2047 * If flag & 1, don't report "not a property" error and just return NULL.
2049 Expression *Type::getProperty(Loc loc, Identifier *ident, int flag)
2051 Expression *e;
2053 if (ident == Id::__sizeof)
2055 d_uns64 sz = size(loc);
2056 if (sz == SIZE_INVALID)
2057 return new ErrorExp();
2058 e = new IntegerExp(loc, sz, Type::tsize_t);
2060 else if (ident == Id::__xalignof)
2062 e = new IntegerExp(loc, alignsize(), Type::tsize_t);
2064 else if (ident == Id::_init)
2066 Type *tb = toBasetype();
2067 e = defaultInitLiteral(loc);
2068 if (tb->ty == Tstruct && tb->needsNested())
2070 StructLiteralExp *se = (StructLiteralExp *)e;
2071 se->useStaticInit = true;
2074 else if (ident == Id::_mangleof)
2076 if (!deco)
2078 error(loc, "forward reference of type %s.mangleof", toChars());
2079 e = new ErrorExp();
2081 else
2083 e = new StringExp(loc, (char *)deco, strlen(deco));
2084 Scope sc;
2085 e = ::semantic(e, &sc);
2088 else if (ident == Id::stringof)
2090 const char *s = toChars();
2091 e = new StringExp(loc, const_cast<char *>(s), strlen(s));
2092 Scope sc;
2093 e = ::semantic(e, &sc);
2095 else if (flag && this != Type::terror)
2097 return NULL;
2099 else
2101 Dsymbol *s = NULL;
2102 if (ty == Tstruct || ty == Tclass || ty == Tenum)
2103 s = toDsymbol(NULL);
2104 if (s)
2105 s = s->search_correct(ident);
2106 if (this != Type::terror)
2108 if (s)
2109 error(loc, "no property '%s' for type '%s', did you mean '%s'?", ident->toChars(), toChars(), s->toChars());
2110 else
2111 error(loc, "no property '%s' for type '%s'", ident->toChars(), toChars());
2113 e = new ErrorExp();
2115 return e;
2118 /***************************************
2119 * Access the members of the object e. This type is same as e->type.
2121 * If flag & 1, don't report "not a property" error and just return NULL.
2123 Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
2125 VarDeclaration *v = NULL;
2127 Expression *ex = e;
2128 while (ex->op == TOKcomma)
2129 ex = ((CommaExp *)ex)->e2;
2130 if (ex->op == TOKdotvar)
2132 DotVarExp *dv = (DotVarExp *)ex;
2133 v = dv->var->isVarDeclaration();
2135 else if (ex->op == TOKvar)
2137 VarExp *ve = (VarExp *)ex;
2138 v = ve->var->isVarDeclaration();
2140 if (v)
2142 if (ident == Id::offsetof)
2144 if (v->isField())
2146 AggregateDeclaration *ad = v->toParent()->isAggregateDeclaration();
2147 ad->size(e->loc);
2148 if (ad->sizeok != SIZEOKdone)
2149 return new ErrorExp();
2150 e = new IntegerExp(e->loc, v->offset, Type::tsize_t);
2151 return e;
2154 else if (ident == Id::_init)
2156 Type *tb = toBasetype();
2157 e = defaultInitLiteral(e->loc);
2158 if (tb->ty == Tstruct && tb->needsNested())
2160 StructLiteralExp *se = (StructLiteralExp *)e;
2161 se->useStaticInit = true;
2163 goto Lreturn;
2166 if (ident == Id::stringof)
2168 /* Bugzilla 3796: this should demangle e->type->deco rather than
2169 * pretty-printing the type.
2171 const char *s = e->toChars();
2172 e = new StringExp(e->loc, const_cast<char *>(s), strlen(s));
2174 else
2175 e = getProperty(e->loc, ident, flag & 1);
2177 Lreturn:
2178 if (e)
2179 e = ::semantic(e, sc);
2180 return e;
2183 /************************************
2184 * Return alignment to use for this type.
2187 structalign_t Type::alignment()
2189 return STRUCTALIGN_DEFAULT;
2192 /***************************************
2193 * Figures out what to do with an undefined member reference
2194 * for classes and structs.
2196 * If flag & 1, don't report "not a property" error and just return NULL.
2198 Expression *Type::noMember(Scope *sc, Expression *e, Identifier *ident, int flag)
2200 //printf("Type::noMember(e: %s ident: %s flag: %d)\n", e->toChars(), ident->toChars(), flag);
2202 static int nest; // https://issues.dlang.org/show_bug.cgi?id=17380
2204 if (++nest > 500)
2206 ::error(e->loc, "cannot resolve identifier `%s`", ident->toChars());
2207 --nest;
2208 return (flag & 1) ? NULL : new ErrorExp();
2211 assert(ty == Tstruct || ty == Tclass);
2212 AggregateDeclaration *sym = toDsymbol(sc)->isAggregateDeclaration();
2213 assert(sym);
2215 if (ident != Id::__sizeof &&
2216 ident != Id::__xalignof &&
2217 ident != Id::_init &&
2218 ident != Id::_mangleof &&
2219 ident != Id::stringof &&
2220 ident != Id::offsetof &&
2221 // Bugzilla 15045: Don't forward special built-in member functions.
2222 ident != Id::ctor &&
2223 ident != Id::dtor &&
2224 ident != Id::__xdtor &&
2225 ident != Id::postblit &&
2226 ident != Id::__xpostblit)
2228 /* Look for overloaded opDot() to see if we should forward request
2229 * to it.
2231 if (Dsymbol *fd = search_function(sym, Id::opDot))
2233 /* Rewrite e.ident as:
2234 * e.opDot().ident
2236 e = build_overload(e->loc, sc, e, NULL, fd);
2237 e = new DotIdExp(e->loc, e, ident);
2238 e = ::semantic(e, sc);
2239 --nest;
2240 return e;
2243 /* Look for overloaded opDispatch to see if we should forward request
2244 * to it.
2246 if (Dsymbol *fd = search_function(sym, Id::opDispatch))
2248 /* Rewrite e.ident as:
2249 * e.opDispatch!("ident")
2251 TemplateDeclaration *td = fd->isTemplateDeclaration();
2252 if (!td)
2254 fd->error("must be a template opDispatch(string s), not a %s", fd->kind());
2255 --nest;
2256 return new ErrorExp();
2258 StringExp *se = new StringExp(e->loc, const_cast<char *>(ident->toChars()));
2259 Objects *tiargs = new Objects();
2260 tiargs->push(se);
2261 DotTemplateInstanceExp *dti = new DotTemplateInstanceExp(e->loc, e, Id::opDispatch, tiargs);
2262 dti->ti->tempdecl = td;
2264 /* opDispatch, which doesn't need IFTI, may occur instantiate error.
2265 * It should be gagged if flag & 1.
2266 * e.g.
2267 * template opDispatch(name) if (isValid!name) { ... }
2269 unsigned errors = flag & 1 ? global.startGagging() : 0;
2270 e = semanticY(dti, sc, 0);
2271 if (flag & 1 && global.endGagging(errors))
2272 e = NULL;
2273 --nest;
2274 return e;
2277 /* See if we should forward to the alias this.
2279 if (sym->aliasthis)
2280 { /* Rewrite e.ident as:
2281 * e.aliasthis.ident
2283 e = resolveAliasThis(sc, e);
2284 DotIdExp *die = new DotIdExp(e->loc, e, ident);
2285 e = semanticY(die, sc, flag & 1);
2286 --nest;
2287 return e;
2291 e = Type::dotExp(sc, e, ident, flag);
2292 --nest;
2293 return e;
2296 void Type::error(Loc loc, const char *format, ...)
2298 va_list ap;
2299 va_start(ap, format);
2300 ::verror(loc, format, ap);
2301 va_end( ap );
2304 void Type::warning(Loc loc, const char *format, ...)
2306 va_list ap;
2307 va_start(ap, format);
2308 ::vwarning(loc, format, ap);
2309 va_end( ap );
2312 Identifier *Type::getTypeInfoIdent()
2314 // _init_10TypeInfo_%s
2315 OutBuffer buf;
2316 buf.reserve(32);
2317 mangleToBuffer(this, &buf);
2319 size_t len = buf.offset;
2320 buf.writeByte(0);
2322 // Allocate buffer on stack, fail over to using malloc()
2323 char namebuf[128];
2324 size_t namelen = 19 + sizeof(len) * 3 + len + 1;
2325 char *name = namelen <= sizeof(namebuf) ? namebuf : (char *)mem.xmalloc(namelen);
2327 sprintf(name, "_D%lluTypeInfo_%s6__initZ", (unsigned long long) 9 + len, buf.data);
2328 //printf("%p, deco = %s, name = %s\n", this, deco, name);
2329 assert(strlen(name) < namelen); // don't overflow the buffer
2331 size_t off = 0;
2332 #ifndef IN_GCC
2333 if (global.params.isOSX || (global.params.isWindows && !global.params.is64bit))
2334 ++off; // C mangling will add '_' back in
2335 #endif
2336 Identifier *id = Identifier::idPool(name + off);
2338 if (name != namebuf)
2339 free(name);
2340 return id;
2343 TypeBasic *Type::isTypeBasic()
2345 return NULL;
2349 /***************************************
2350 * Resolve 'this' type to either type, symbol, or expression.
2351 * If errors happened, resolved to Type.terror.
2353 void Type::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool)
2355 //printf("Type::resolve() %s, %d\n", toChars(), ty);
2356 Type *t = semantic(loc, sc);
2357 *pt = t;
2358 *pe = NULL;
2359 *ps = NULL;
2362 /***************************************
2363 * Normalize `e` as the result of Type::resolve() process.
2365 void Type::resolveExp(Expression *e, Type **pt, Expression **pe, Dsymbol **ps)
2367 *pt = NULL;
2368 *pe = NULL;
2369 *ps = NULL;
2371 Dsymbol *s;
2372 switch (e->op)
2374 case TOKerror:
2375 *pt = Type::terror;
2376 return;
2378 case TOKtype:
2379 *pt = e->type;
2380 return;
2382 case TOKvar:
2383 s = ((VarExp *)e)->var;
2384 if (s->isVarDeclaration())
2385 goto Ldefault;
2386 //if (s->isOverDeclaration())
2387 // todo;
2388 break;
2390 case TOKtemplate:
2391 // TemplateDeclaration
2392 s = ((TemplateExp *)e)->td;
2393 break;
2395 case TOKimport:
2396 s = ((ScopeExp *)e)->sds;
2397 // TemplateDeclaration, TemplateInstance, Import, Package, Module
2398 break;
2400 case TOKfunction:
2401 s = getDsymbol(e);
2402 break;
2404 //case TOKthis:
2405 //case TOKsuper:
2407 //case TOKtuple:
2409 //case TOKoverloadset:
2411 //case TOKdotvar:
2412 //case TOKdottd:
2413 //case TOKdotti:
2414 //case TOKdottype:
2415 //case TOKdot:
2417 default:
2418 Ldefault:
2419 *pe = e;
2420 return;
2423 *ps = s;
2426 /***************************************
2427 * Return !=0 if the type or any of its subtypes is wild.
2430 int Type::hasWild() const
2432 return mod & MODwild;
2435 /***************************************
2436 * Return !=0 if type has pointers that need to
2437 * be scanned by the GC during a collection cycle.
2439 bool Type::hasPointers()
2441 //printf("Type::hasPointers() %s, %d\n", toChars(), ty);
2442 return false;
2445 /*************************************
2446 * Detect if type has pointer fields that are initialized to void.
2447 * Local stack variables with such void fields can remain uninitialized,
2448 * leading to pointer bugs.
2449 * Returns:
2450 * true if so
2452 bool Type::hasVoidInitPointers()
2454 return false;
2457 /*************************************
2458 * If this is a type of something, return that something.
2461 Type *Type::nextOf()
2463 return NULL;
2466 /*************************************
2467 * If this is a type of static array, return its base element type.
2470 Type *Type::baseElemOf()
2472 Type *t = toBasetype();
2473 while (t->ty == Tsarray)
2474 t = ((TypeSArray *)t)->next->toBasetype();
2475 return t;
2478 /*************************************
2479 * Bugzilla 14488: Check if the inner most base type is complex or imaginary.
2480 * Should only give alerts when set to emit transitional messages.
2483 void Type::checkComplexTransition(Loc loc)
2485 Type *t = baseElemOf();
2486 while (t->ty == Tpointer || t->ty == Tarray)
2487 t = t->nextOf()->baseElemOf();
2489 if (t->isimaginary() || t->iscomplex())
2491 Type *rt;
2492 switch (t->ty)
2494 case Tcomplex32:
2495 case Timaginary32:
2496 rt = Type::tfloat32; break;
2497 case Tcomplex64:
2498 case Timaginary64:
2499 rt = Type::tfloat64; break;
2500 case Tcomplex80:
2501 case Timaginary80:
2502 rt = Type::tfloat80; break;
2503 default:
2504 assert(0);
2506 if (t->iscomplex())
2508 message(loc, "use of complex type `%s` is scheduled for deprecation, "
2509 "use `std.complex.Complex!(%s)` instead", toChars(), rt->toChars());
2511 else
2513 message(loc, "use of imaginary type `%s` is scheduled for deprecation, "
2514 "use `%s` instead\n", toChars(), rt->toChars());
2519 /****************************************
2520 * Return the mask that an integral type will
2521 * fit into.
2523 uinteger_t Type::sizemask()
2524 { uinteger_t m;
2526 switch (toBasetype()->ty)
2528 case Tbool: m = 1; break;
2529 case Tchar:
2530 case Tint8:
2531 case Tuns8: m = 0xFF; break;
2532 case Twchar:
2533 case Tint16:
2534 case Tuns16: m = 0xFFFFUL; break;
2535 case Tdchar:
2536 case Tint32:
2537 case Tuns32: m = 0xFFFFFFFFUL; break;
2538 case Tint64:
2539 case Tuns64: m = 0xFFFFFFFFFFFFFFFFULL; break;
2540 default:
2541 assert(0);
2543 return m;
2546 /* ============================= TypeError =========================== */
2548 TypeError::TypeError()
2549 : Type(Terror)
2553 Type *TypeError::syntaxCopy()
2555 // No semantic analysis done, no need to copy
2556 return this;
2559 d_uns64 TypeError::size(Loc) { return SIZE_INVALID; }
2560 Expression *TypeError::getProperty(Loc, Identifier *, int) { return new ErrorExp(); }
2561 Expression *TypeError::dotExp(Scope *, Expression *, Identifier *, int) { return new ErrorExp(); }
2562 Expression *TypeError::defaultInit(Loc) { return new ErrorExp(); }
2563 Expression *TypeError::defaultInitLiteral(Loc) { return new ErrorExp(); }
2565 /* ============================= TypeNext =========================== */
2567 TypeNext::TypeNext(TY ty, Type *next)
2568 : Type(ty)
2570 this->next = next;
2573 void TypeNext::checkDeprecated(Loc loc, Scope *sc)
2575 Type::checkDeprecated(loc, sc);
2576 if (next) // next can be NULL if TypeFunction and auto return type
2577 next->checkDeprecated(loc, sc);
2580 int TypeNext::hasWild() const
2582 if (ty == Tfunction)
2583 return 0;
2584 if (ty == Tdelegate)
2585 return Type::hasWild();
2586 return mod & MODwild || (next && next->hasWild());
2590 /*******************************
2591 * For TypeFunction, nextOf() can return NULL if the function return
2592 * type is meant to be inferred, and semantic() hasn't yet ben run
2593 * on the function. After semantic(), it must no longer be NULL.
2596 Type *TypeNext::nextOf()
2598 return next;
2601 Type *TypeNext::makeConst()
2603 //printf("TypeNext::makeConst() %p, %s\n", this, toChars());
2604 if (cto)
2606 assert(cto->mod == MODconst);
2607 return cto;
2609 TypeNext *t = (TypeNext *)Type::makeConst();
2610 if (ty != Tfunction && next->ty != Tfunction &&
2611 !next->isImmutable())
2613 if (next->isShared())
2615 if (next->isWild())
2616 t->next = next->sharedWildConstOf();
2617 else
2618 t->next = next->sharedConstOf();
2620 else
2622 if (next->isWild())
2623 t->next = next->wildConstOf();
2624 else
2625 t->next = next->constOf();
2628 //printf("TypeNext::makeConst() returns %p, %s\n", t, t->toChars());
2629 return t;
2632 Type *TypeNext::makeImmutable()
2634 //printf("TypeNext::makeImmutable() %s\n", toChars());
2635 if (ito)
2637 assert(ito->isImmutable());
2638 return ito;
2640 TypeNext *t = (TypeNext *)Type::makeImmutable();
2641 if (ty != Tfunction && next->ty != Tfunction &&
2642 !next->isImmutable())
2644 t->next = next->immutableOf();
2646 return t;
2649 Type *TypeNext::makeShared()
2651 //printf("TypeNext::makeShared() %s\n", toChars());
2652 if (sto)
2654 assert(sto->mod == MODshared);
2655 return sto;
2657 TypeNext *t = (TypeNext *)Type::makeShared();
2658 if (ty != Tfunction && next->ty != Tfunction &&
2659 !next->isImmutable())
2661 if (next->isWild())
2663 if (next->isConst())
2664 t->next = next->sharedWildConstOf();
2665 else
2666 t->next = next->sharedWildOf();
2668 else
2670 if (next->isConst())
2671 t->next = next->sharedConstOf();
2672 else
2673 t->next = next->sharedOf();
2676 //printf("TypeNext::makeShared() returns %p, %s\n", t, t->toChars());
2677 return t;
2680 Type *TypeNext::makeSharedConst()
2682 //printf("TypeNext::makeSharedConst() %s\n", toChars());
2683 if (scto)
2685 assert(scto->mod == (MODshared | MODconst));
2686 return scto;
2688 TypeNext *t = (TypeNext *)Type::makeSharedConst();
2689 if (ty != Tfunction && next->ty != Tfunction &&
2690 !next->isImmutable())
2692 if (next->isWild())
2693 t->next = next->sharedWildConstOf();
2694 else
2695 t->next = next->sharedConstOf();
2697 //printf("TypeNext::makeSharedConst() returns %p, %s\n", t, t->toChars());
2698 return t;
2701 Type *TypeNext::makeWild()
2703 //printf("TypeNext::makeWild() %s\n", toChars());
2704 if (wto)
2706 assert(wto->mod == MODwild);
2707 return wto;
2709 TypeNext *t = (TypeNext *)Type::makeWild();
2710 if (ty != Tfunction && next->ty != Tfunction &&
2711 !next->isImmutable())
2713 if (next->isShared())
2715 if (next->isConst())
2716 t->next = next->sharedWildConstOf();
2717 else
2718 t->next = next->sharedWildOf();
2720 else
2722 if (next->isConst())
2723 t->next = next->wildConstOf();
2724 else
2725 t->next = next->wildOf();
2728 //printf("TypeNext::makeWild() returns %p, %s\n", t, t->toChars());
2729 return t;
2732 Type *TypeNext::makeWildConst()
2734 //printf("TypeNext::makeWildConst() %s\n", toChars());
2735 if (wcto)
2737 assert(wcto->mod == MODwildconst);
2738 return wcto;
2740 TypeNext *t = (TypeNext *)Type::makeWildConst();
2741 if (ty != Tfunction && next->ty != Tfunction &&
2742 !next->isImmutable())
2744 if (next->isShared())
2745 t->next = next->sharedWildConstOf();
2746 else
2747 t->next = next->wildConstOf();
2749 //printf("TypeNext::makeWildConst() returns %p, %s\n", t, t->toChars());
2750 return t;
2753 Type *TypeNext::makeSharedWild()
2755 //printf("TypeNext::makeSharedWild() %s\n", toChars());
2756 if (swto)
2758 assert(swto->isSharedWild());
2759 return swto;
2761 TypeNext *t = (TypeNext *)Type::makeSharedWild();
2762 if (ty != Tfunction && next->ty != Tfunction &&
2763 !next->isImmutable())
2765 if (next->isConst())
2766 t->next = next->sharedWildConstOf();
2767 else
2768 t->next = next->sharedWildOf();
2770 //printf("TypeNext::makeSharedWild() returns %p, %s\n", t, t->toChars());
2771 return t;
2774 Type *TypeNext::makeSharedWildConst()
2776 //printf("TypeNext::makeSharedWildConst() %s\n", toChars());
2777 if (swcto)
2779 assert(swcto->mod == (MODshared | MODwildconst));
2780 return swcto;
2782 TypeNext *t = (TypeNext *)Type::makeSharedWildConst();
2783 if (ty != Tfunction && next->ty != Tfunction &&
2784 !next->isImmutable())
2786 t->next = next->sharedWildConstOf();
2788 //printf("TypeNext::makeSharedWildConst() returns %p, %s\n", t, t->toChars());
2789 return t;
2792 Type *TypeNext::makeMutable()
2794 //printf("TypeNext::makeMutable() %p, %s\n", this, toChars());
2795 TypeNext *t = (TypeNext *)Type::makeMutable();
2796 if (ty == Tsarray)
2798 t->next = next->mutableOf();
2800 //printf("TypeNext::makeMutable() returns %p, %s\n", t, t->toChars());
2801 return t;
2804 MATCH TypeNext::constConv(Type *to)
2806 //printf("TypeNext::constConv from = %s, to = %s\n", toChars(), to->toChars());
2807 if (equals(to))
2808 return MATCHexact;
2810 if (!(ty == to->ty && MODimplicitConv(mod, to->mod)))
2811 return MATCHnomatch;
2813 Type *tn = to->nextOf();
2814 if (!(tn && next->ty == tn->ty))
2815 return MATCHnomatch;
2817 MATCH m;
2818 if (to->isConst()) // whole tail const conversion
2819 { // Recursive shared level check
2820 m = next->constConv(tn);
2821 if (m == MATCHexact)
2822 m = MATCHconst;
2824 else
2825 { //printf("\tnext => %s, to->next => %s\n", next->toChars(), tn->toChars());
2826 m = next->equals(tn) ? MATCHconst : MATCHnomatch;
2828 return m;
2831 unsigned char TypeNext::deduceWild(Type *t, bool isRef)
2833 if (ty == Tfunction)
2834 return 0;
2836 unsigned char wm;
2838 Type *tn = t->nextOf();
2839 if (!isRef && (ty == Tarray || ty == Tpointer) && tn)
2841 wm = next->deduceWild(tn, true);
2842 if (!wm)
2843 wm = Type::deduceWild(t, true);
2845 else
2847 wm = Type::deduceWild(t, isRef);
2848 if (!wm && tn)
2849 wm = next->deduceWild(tn, true);
2852 return wm;
2856 void TypeNext::transitive()
2858 /* Invoke transitivity of type attributes
2860 next = next->addMod(mod);
2863 /* ============================= TypeBasic =========================== */
2865 #define TFLAGSintegral 1
2866 #define TFLAGSfloating 2
2867 #define TFLAGSunsigned 4
2868 #define TFLAGSreal 8
2869 #define TFLAGSimaginary 0x10
2870 #define TFLAGScomplex 0x20
2872 TypeBasic::TypeBasic(TY ty)
2873 : Type(ty)
2874 { const char *d;
2875 unsigned flags;
2877 flags = 0;
2878 switch (ty)
2880 case Tvoid: d = Token::toChars(TOKvoid);
2881 break;
2883 case Tint8: d = Token::toChars(TOKint8);
2884 flags |= TFLAGSintegral;
2885 break;
2887 case Tuns8: d = Token::toChars(TOKuns8);
2888 flags |= TFLAGSintegral | TFLAGSunsigned;
2889 break;
2891 case Tint16: d = Token::toChars(TOKint16);
2892 flags |= TFLAGSintegral;
2893 break;
2895 case Tuns16: d = Token::toChars(TOKuns16);
2896 flags |= TFLAGSintegral | TFLAGSunsigned;
2897 break;
2899 case Tint32: d = Token::toChars(TOKint32);
2900 flags |= TFLAGSintegral;
2901 break;
2903 case Tuns32: d = Token::toChars(TOKuns32);
2904 flags |= TFLAGSintegral | TFLAGSunsigned;
2905 break;
2907 case Tfloat32: d = Token::toChars(TOKfloat32);
2908 flags |= TFLAGSfloating | TFLAGSreal;
2909 break;
2911 case Tint64: d = Token::toChars(TOKint64);
2912 flags |= TFLAGSintegral;
2913 break;
2915 case Tuns64: d = Token::toChars(TOKuns64);
2916 flags |= TFLAGSintegral | TFLAGSunsigned;
2917 break;
2919 case Tint128: d = Token::toChars(TOKint128);
2920 flags |= TFLAGSintegral;
2921 break;
2923 case Tuns128: d = Token::toChars(TOKuns128);
2924 flags |= TFLAGSintegral | TFLAGSunsigned;
2925 break;
2927 case Tfloat64: d = Token::toChars(TOKfloat64);
2928 flags |= TFLAGSfloating | TFLAGSreal;
2929 break;
2931 case Tfloat80: d = Token::toChars(TOKfloat80);
2932 flags |= TFLAGSfloating | TFLAGSreal;
2933 break;
2935 case Timaginary32: d = Token::toChars(TOKimaginary32);
2936 flags |= TFLAGSfloating | TFLAGSimaginary;
2937 break;
2939 case Timaginary64: d = Token::toChars(TOKimaginary64);
2940 flags |= TFLAGSfloating | TFLAGSimaginary;
2941 break;
2943 case Timaginary80: d = Token::toChars(TOKimaginary80);
2944 flags |= TFLAGSfloating | TFLAGSimaginary;
2945 break;
2947 case Tcomplex32: d = Token::toChars(TOKcomplex32);
2948 flags |= TFLAGSfloating | TFLAGScomplex;
2949 break;
2951 case Tcomplex64: d = Token::toChars(TOKcomplex64);
2952 flags |= TFLAGSfloating | TFLAGScomplex;
2953 break;
2955 case Tcomplex80: d = Token::toChars(TOKcomplex80);
2956 flags |= TFLAGSfloating | TFLAGScomplex;
2957 break;
2959 case Tbool: d = "bool";
2960 flags |= TFLAGSintegral | TFLAGSunsigned;
2961 break;
2963 case Tchar: d = Token::toChars(TOKchar);
2964 flags |= TFLAGSintegral | TFLAGSunsigned;
2965 break;
2967 case Twchar: d = Token::toChars(TOKwchar);
2968 flags |= TFLAGSintegral | TFLAGSunsigned;
2969 break;
2971 case Tdchar: d = Token::toChars(TOKdchar);
2972 flags |= TFLAGSintegral | TFLAGSunsigned;
2973 break;
2975 default: assert(0);
2977 this->dstring = d;
2978 this->flags = flags;
2979 merge();
2982 const char *TypeBasic::kind()
2984 return dstring;
2987 Type *TypeBasic::syntaxCopy()
2989 // No semantic analysis done on basic types, no need to copy
2990 return this;
2993 d_uns64 TypeBasic::size(Loc)
2994 { unsigned size;
2996 //printf("TypeBasic::size()\n");
2997 switch (ty)
2999 case Tint8:
3000 case Tuns8: size = 1; break;
3001 case Tint16:
3002 case Tuns16: size = 2; break;
3003 case Tint32:
3004 case Tuns32:
3005 case Tfloat32:
3006 case Timaginary32:
3007 size = 4; break;
3008 case Tint64:
3009 case Tuns64:
3010 case Tfloat64:
3011 case Timaginary64:
3012 size = 8; break;
3013 case Tfloat80:
3014 case Timaginary80:
3015 size = Target::realsize; break;
3016 case Tcomplex32:
3017 size = 8; break;
3018 case Tcomplex64:
3019 case Tint128:
3020 case Tuns128:
3021 size = 16; break;
3022 case Tcomplex80:
3023 size = Target::realsize * 2; break;
3025 case Tvoid:
3026 //size = Type::size(); // error message
3027 size = 1;
3028 break;
3030 case Tbool: size = 1; break;
3031 case Tchar: size = 1; break;
3032 case Twchar: size = 2; break;
3033 case Tdchar: size = 4; break;
3035 default:
3036 assert(0);
3037 break;
3039 //printf("TypeBasic::size() = %d\n", size);
3040 return size;
3043 unsigned TypeBasic::alignsize()
3045 return Target::alignsize(this);
3049 Expression *TypeBasic::getProperty(Loc loc, Identifier *ident, int flag)
3051 Expression *e;
3052 dinteger_t ivalue;
3053 real_t fvalue;
3055 //printf("TypeBasic::getProperty('%s')\n", ident->toChars());
3056 if (ident == Id::max)
3058 switch (ty)
3060 case Tint8:
3061 ivalue = 0x7F;
3062 goto Livalue;
3063 case Tuns8:
3064 ivalue = 0xFF;
3065 goto Livalue;
3066 case Tint16:
3067 ivalue = 0x7FFFUL;
3068 goto Livalue;
3069 case Tuns16:
3070 ivalue = 0xFFFFUL;
3071 goto Livalue;
3072 case Tint32:
3073 ivalue = 0x7FFFFFFFUL;
3074 goto Livalue;
3075 case Tuns32:
3076 ivalue = 0xFFFFFFFFUL;
3077 goto Livalue;
3078 case Tint64:
3079 ivalue = 0x7FFFFFFFFFFFFFFFLL;
3080 goto Livalue;
3081 case Tuns64:
3082 ivalue = 0xFFFFFFFFFFFFFFFFULL;
3083 goto Livalue;
3084 case Tbool:
3085 ivalue = 1;
3086 goto Livalue;
3087 case Tchar:
3088 ivalue = 0xFF;
3089 goto Livalue;
3090 case Twchar:
3091 ivalue = 0xFFFFUL;
3092 goto Livalue;
3093 case Tdchar:
3094 ivalue = 0x10FFFFUL;
3095 goto Livalue;
3096 case Tcomplex32:
3097 case Timaginary32:
3098 case Tfloat32:
3099 fvalue = Target::FloatProperties::max;
3100 goto Lfvalue;
3101 case Tcomplex64:
3102 case Timaginary64:
3103 case Tfloat64:
3104 fvalue = Target::DoubleProperties::max;
3105 goto Lfvalue;
3106 case Tcomplex80:
3107 case Timaginary80:
3108 case Tfloat80:
3109 fvalue = Target::RealProperties::max;
3110 goto Lfvalue;
3113 else if (ident == Id::min)
3115 switch (ty)
3117 case Tint8:
3118 ivalue = -128;
3119 goto Livalue;
3120 case Tuns8:
3121 ivalue = 0;
3122 goto Livalue;
3123 case Tint16:
3124 ivalue = -32768;
3125 goto Livalue;
3126 case Tuns16:
3127 ivalue = 0;
3128 goto Livalue;
3129 case Tint32:
3130 ivalue = -2147483647L - 1;
3131 goto Livalue;
3132 case Tuns32:
3133 ivalue = 0;
3134 goto Livalue;
3135 case Tint64:
3136 ivalue = (-9223372036854775807LL-1LL);
3137 goto Livalue;
3138 case Tuns64:
3139 ivalue = 0;
3140 goto Livalue;
3141 case Tbool:
3142 ivalue = 0;
3143 goto Livalue;
3144 case Tchar:
3145 ivalue = 0;
3146 goto Livalue;
3147 case Twchar:
3148 ivalue = 0;
3149 goto Livalue;
3150 case Tdchar:
3151 ivalue = 0;
3152 goto Livalue;
3154 case Tcomplex32:
3155 case Timaginary32:
3156 case Tfloat32:
3157 case Tcomplex64:
3158 case Timaginary64:
3159 case Tfloat64:
3160 case Tcomplex80:
3161 case Timaginary80:
3162 case Tfloat80:
3163 error(loc, "use .min_normal property instead of .min");
3164 return new ErrorExp();
3167 else if (ident == Id::min_normal)
3169 switch (ty)
3171 case Tcomplex32:
3172 case Timaginary32:
3173 case Tfloat32:
3174 fvalue = Target::FloatProperties::min_normal;
3175 goto Lfvalue;
3176 case Tcomplex64:
3177 case Timaginary64:
3178 case Tfloat64:
3179 fvalue = Target::DoubleProperties::min_normal;
3180 goto Lfvalue;
3181 case Tcomplex80:
3182 case Timaginary80:
3183 case Tfloat80:
3184 fvalue = Target::RealProperties::min_normal;
3185 goto Lfvalue;
3188 else if (ident == Id::nan)
3190 switch (ty)
3192 case Tcomplex32:
3193 case Tcomplex64:
3194 case Tcomplex80:
3195 case Timaginary32:
3196 case Timaginary64:
3197 case Timaginary80:
3198 case Tfloat32:
3199 case Tfloat64:
3200 case Tfloat80:
3201 fvalue = Target::RealProperties::nan;
3202 goto Lfvalue;
3205 else if (ident == Id::infinity)
3207 switch (ty)
3209 case Tcomplex32:
3210 case Tcomplex64:
3211 case Tcomplex80:
3212 case Timaginary32:
3213 case Timaginary64:
3214 case Timaginary80:
3215 case Tfloat32:
3216 case Tfloat64:
3217 case Tfloat80:
3218 fvalue = Target::RealProperties::infinity;
3219 goto Lfvalue;
3222 else if (ident == Id::dig)
3224 switch (ty)
3226 case Tcomplex32:
3227 case Timaginary32:
3228 case Tfloat32:
3229 ivalue = Target::FloatProperties::dig;
3230 goto Lint;
3231 case Tcomplex64:
3232 case Timaginary64:
3233 case Tfloat64:
3234 ivalue = Target::DoubleProperties::dig;
3235 goto Lint;
3236 case Tcomplex80:
3237 case Timaginary80:
3238 case Tfloat80:
3239 ivalue = Target::RealProperties::dig;
3240 goto Lint;
3243 else if (ident == Id::epsilon)
3245 switch (ty)
3247 case Tcomplex32:
3248 case Timaginary32:
3249 case Tfloat32:
3250 fvalue = Target::FloatProperties::epsilon;
3251 goto Lfvalue;
3252 case Tcomplex64:
3253 case Timaginary64:
3254 case Tfloat64:
3255 fvalue = Target::DoubleProperties::epsilon;
3256 goto Lfvalue;
3257 case Tcomplex80:
3258 case Timaginary80:
3259 case Tfloat80:
3260 fvalue = Target::RealProperties::epsilon;
3261 goto Lfvalue;
3264 else if (ident == Id::mant_dig)
3266 switch (ty)
3268 case Tcomplex32:
3269 case Timaginary32:
3270 case Tfloat32:
3271 ivalue = Target::FloatProperties::mant_dig;
3272 goto Lint;
3273 case Tcomplex64:
3274 case Timaginary64:
3275 case Tfloat64:
3276 ivalue = Target::DoubleProperties::mant_dig;
3277 goto Lint;
3278 case Tcomplex80:
3279 case Timaginary80:
3280 case Tfloat80:
3281 ivalue = Target::RealProperties::mant_dig;
3282 goto Lint;
3285 else if (ident == Id::max_10_exp)
3287 switch (ty)
3289 case Tcomplex32:
3290 case Timaginary32:
3291 case Tfloat32:
3292 ivalue = Target::FloatProperties::max_10_exp;
3293 goto Lint;
3294 case Tcomplex64:
3295 case Timaginary64:
3296 case Tfloat64:
3297 ivalue = Target::DoubleProperties::max_10_exp;
3298 goto Lint;
3299 case Tcomplex80:
3300 case Timaginary80:
3301 case Tfloat80:
3302 ivalue = Target::RealProperties::max_10_exp;
3303 goto Lint;
3306 else if (ident == Id::max_exp)
3308 switch (ty)
3310 case Tcomplex32:
3311 case Timaginary32:
3312 case Tfloat32:
3313 ivalue = Target::FloatProperties::max_exp;
3314 goto Lint;
3315 case Tcomplex64:
3316 case Timaginary64:
3317 case Tfloat64:
3318 ivalue = Target::DoubleProperties::max_exp;
3319 goto Lint;
3320 case Tcomplex80:
3321 case Timaginary80:
3322 case Tfloat80:
3323 ivalue = Target::RealProperties::max_exp;
3324 goto Lint;
3327 else if (ident == Id::min_10_exp)
3329 switch (ty)
3331 case Tcomplex32:
3332 case Timaginary32:
3333 case Tfloat32:
3334 ivalue = Target::FloatProperties::min_10_exp;
3335 goto Lint;
3336 case Tcomplex64:
3337 case Timaginary64:
3338 case Tfloat64:
3339 ivalue = Target::DoubleProperties::min_10_exp;
3340 goto Lint;
3341 case Tcomplex80:
3342 case Timaginary80:
3343 case Tfloat80:
3344 ivalue = Target::RealProperties::min_10_exp;
3345 goto Lint;
3348 else if (ident == Id::min_exp)
3350 switch (ty)
3352 case Tcomplex32:
3353 case Timaginary32:
3354 case Tfloat32:
3355 ivalue = Target::FloatProperties::min_exp;
3356 goto Lint;
3357 case Tcomplex64:
3358 case Timaginary64:
3359 case Tfloat64:
3360 ivalue = Target::DoubleProperties::min_exp;
3361 goto Lint;
3362 case Tcomplex80:
3363 case Timaginary80:
3364 case Tfloat80:
3365 ivalue = Target::RealProperties::min_exp;
3366 goto Lint;
3370 return Type::getProperty(loc, ident, flag);
3372 Livalue:
3373 e = new IntegerExp(loc, ivalue, this);
3374 return e;
3376 Lfvalue:
3377 if (isreal() || isimaginary())
3378 e = new RealExp(loc, fvalue, this);
3379 else
3381 complex_t cvalue = complex_t(fvalue, fvalue);
3382 //for (int i = 0; i < 20; i++)
3383 // printf("%02x ", ((unsigned char *)&cvalue)[i]);
3384 //printf("\n");
3385 e = new ComplexExp(loc, cvalue, this);
3387 return e;
3389 Lint:
3390 e = new IntegerExp(loc, ivalue, Type::tint32);
3391 return e;
3394 Expression *TypeBasic::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
3396 Type *t;
3398 if (ident == Id::re)
3400 switch (ty)
3402 case Tcomplex32: t = tfloat32; goto L1;
3403 case Tcomplex64: t = tfloat64; goto L1;
3404 case Tcomplex80: t = tfloat80; goto L1;
3406 e = e->castTo(sc, t);
3407 break;
3409 case Tfloat32:
3410 case Tfloat64:
3411 case Tfloat80:
3412 break;
3414 case Timaginary32: t = tfloat32; goto L2;
3415 case Timaginary64: t = tfloat64; goto L2;
3416 case Timaginary80: t = tfloat80; goto L2;
3418 e = new RealExp(e->loc, CTFloat::zero, t);
3419 break;
3421 default:
3422 e = Type::getProperty(e->loc, ident, flag);
3423 break;
3426 else if (ident == Id::im)
3427 { Type *t2;
3429 switch (ty)
3431 case Tcomplex32: t = timaginary32; t2 = tfloat32; goto L3;
3432 case Tcomplex64: t = timaginary64; t2 = tfloat64; goto L3;
3433 case Tcomplex80: t = timaginary80; t2 = tfloat80; goto L3;
3435 e = e->castTo(sc, t);
3436 e->type = t2;
3437 break;
3439 case Timaginary32: t = tfloat32; goto L4;
3440 case Timaginary64: t = tfloat64; goto L4;
3441 case Timaginary80: t = tfloat80; goto L4;
3443 e = e->copy();
3444 e->type = t;
3445 break;
3447 case Tfloat32:
3448 case Tfloat64:
3449 case Tfloat80:
3450 e = new RealExp(e->loc, CTFloat::zero, this);
3451 break;
3453 default:
3454 e = Type::getProperty(e->loc, ident, flag);
3455 break;
3458 else
3460 return Type::dotExp(sc, e, ident, flag);
3462 if (!(flag & 1) || e)
3463 e = ::semantic(e, sc);
3464 return e;
3467 Expression *TypeBasic::defaultInit(Loc loc)
3469 dinteger_t value = 0;
3471 switch (ty)
3473 case Tchar:
3474 value = 0xFF;
3475 break;
3477 case Twchar:
3478 case Tdchar:
3479 value = 0xFFFF;
3480 break;
3482 case Timaginary32:
3483 case Timaginary64:
3484 case Timaginary80:
3485 case Tfloat32:
3486 case Tfloat64:
3487 case Tfloat80:
3488 return new RealExp(loc, Target::RealProperties::snan, this);
3490 case Tcomplex32:
3491 case Tcomplex64:
3492 case Tcomplex80:
3493 { // Can't use fvalue + I*fvalue (the im part becomes a quiet NaN).
3494 complex_t cvalue = complex_t(Target::RealProperties::snan, Target::RealProperties::snan);
3495 return new ComplexExp(loc, cvalue, this);
3498 case Tvoid:
3499 error(loc, "void does not have a default initializer");
3500 return new ErrorExp();
3502 return new IntegerExp(loc, value, this);
3505 bool TypeBasic::isZeroInit(Loc)
3507 switch (ty)
3509 case Tchar:
3510 case Twchar:
3511 case Tdchar:
3512 case Timaginary32:
3513 case Timaginary64:
3514 case Timaginary80:
3515 case Tfloat32:
3516 case Tfloat64:
3517 case Tfloat80:
3518 case Tcomplex32:
3519 case Tcomplex64:
3520 case Tcomplex80:
3521 return false; // no
3522 default:
3523 return true; // yes
3527 bool TypeBasic::isintegral()
3529 //printf("TypeBasic::isintegral('%s') x%x\n", toChars(), flags);
3530 return (flags & TFLAGSintegral) != 0;
3533 bool TypeBasic::isfloating()
3535 return (flags & TFLAGSfloating) != 0;
3538 bool TypeBasic::isreal()
3540 return (flags & TFLAGSreal) != 0;
3543 bool TypeBasic::isimaginary()
3545 return (flags & TFLAGSimaginary) != 0;
3548 bool TypeBasic::iscomplex()
3550 return (flags & TFLAGScomplex) != 0;
3553 bool TypeBasic::isunsigned()
3555 return (flags & TFLAGSunsigned) != 0;
3558 bool TypeBasic::isscalar()
3560 return (flags & (TFLAGSintegral | TFLAGSfloating)) != 0;
3563 MATCH TypeBasic::implicitConvTo(Type *to)
3565 //printf("TypeBasic::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
3566 if (this == to)
3567 return MATCHexact;
3569 if (ty == to->ty)
3571 if (mod == to->mod)
3572 return MATCHexact;
3573 else if (MODimplicitConv(mod, to->mod))
3574 return MATCHconst;
3575 else if (!((mod ^ to->mod) & MODshared)) // for wild matching
3576 return MATCHconst;
3577 else
3578 return MATCHconvert;
3581 if (ty == Tvoid || to->ty == Tvoid)
3582 return MATCHnomatch;
3583 if (to->ty == Tbool)
3584 return MATCHnomatch;
3586 TypeBasic *tob;
3587 if (to->ty == Tvector && to->deco)
3589 TypeVector *tv = (TypeVector *)to;
3590 tob = tv->elementType();
3592 else if (to->ty == Tenum)
3594 EnumDeclaration *ed = ((TypeEnum *)to)->sym;
3595 if (ed->isSpecial())
3597 /* Special enums that allow implicit conversions to them. */
3598 tob = to->toBasetype()->isTypeBasic();
3599 if (tob)
3600 return implicitConvTo(tob);
3602 else
3603 return MATCHnomatch;
3605 else
3606 tob = to->isTypeBasic();
3607 if (!tob)
3608 return MATCHnomatch;
3610 if (flags & TFLAGSintegral)
3612 // Disallow implicit conversion of integers to imaginary or complex
3613 if (tob->flags & (TFLAGSimaginary | TFLAGScomplex))
3614 return MATCHnomatch;
3616 // If converting from integral to integral
3617 if (tob->flags & TFLAGSintegral)
3618 { d_uns64 sz = size(Loc());
3619 d_uns64 tosz = tob->size(Loc());
3621 /* Can't convert to smaller size
3623 if (sz > tosz)
3624 return MATCHnomatch;
3626 /* Can't change sign if same size
3628 /*if (sz == tosz && (flags ^ tob->flags) & TFLAGSunsigned)
3629 return MATCHnomatch;*/
3632 else if (flags & TFLAGSfloating)
3634 // Disallow implicit conversion of floating point to integer
3635 if (tob->flags & TFLAGSintegral)
3636 return MATCHnomatch;
3638 assert(tob->flags & TFLAGSfloating || to->ty == Tvector);
3640 // Disallow implicit conversion from complex to non-complex
3641 if (flags & TFLAGScomplex && !(tob->flags & TFLAGScomplex))
3642 return MATCHnomatch;
3644 // Disallow implicit conversion of real or imaginary to complex
3645 if (flags & (TFLAGSreal | TFLAGSimaginary) &&
3646 tob->flags & TFLAGScomplex)
3647 return MATCHnomatch;
3649 // Disallow implicit conversion to-from real and imaginary
3650 if ((flags & (TFLAGSreal | TFLAGSimaginary)) !=
3651 (tob->flags & (TFLAGSreal | TFLAGSimaginary)))
3652 return MATCHnomatch;
3654 return MATCHconvert;
3657 TypeBasic *TypeBasic::isTypeBasic()
3659 return (TypeBasic *)this;
3662 /* ============================= TypeVector =========================== */
3664 /* The basetype must be one of:
3665 * byte[16],ubyte[16],short[8],ushort[8],int[4],uint[4],long[2],ulong[2],float[4],double[2]
3666 * For AVX:
3667 * byte[32],ubyte[32],short[16],ushort[16],int[8],uint[8],long[4],ulong[4],float[8],double[4]
3669 TypeVector::TypeVector(Type *basetype)
3670 : Type(Tvector)
3672 this->basetype = basetype;
3675 TypeVector *TypeVector::create(Loc, Type *basetype)
3677 return new TypeVector(basetype);
3680 const char *TypeVector::kind()
3682 return "vector";
3685 Type *TypeVector::syntaxCopy()
3687 return new TypeVector(basetype->syntaxCopy());
3690 Type *TypeVector::semantic(Loc loc, Scope *sc)
3692 unsigned int errors = global.errors;
3693 basetype = basetype->semantic(loc, sc);
3694 if (errors != global.errors)
3695 return terror;
3696 basetype = basetype->toBasetype()->mutableOf();
3697 if (basetype->ty != Tsarray)
3699 error(loc, "T in __vector(T) must be a static array, not %s", basetype->toChars());
3700 return terror;
3702 TypeSArray *t = (TypeSArray *)basetype;
3703 int sz = (int)t->size(loc);
3704 switch (Target::isVectorTypeSupported(sz, t->nextOf()))
3706 case 0: // valid
3707 break;
3708 case 1: // no support at all
3709 error(loc, "SIMD vector types not supported on this platform");
3710 return terror;
3711 case 2: // invalid size
3712 error(loc, "%d byte vector type %s is not supported on this platform", sz, toChars());
3713 return terror;
3714 case 3: // invalid base type
3715 error(loc, "vector type %s is not supported on this platform", toChars());
3716 return terror;
3717 default:
3718 assert(0);
3720 return merge();
3723 TypeBasic *TypeVector::elementType()
3725 assert(basetype->ty == Tsarray);
3726 TypeSArray *t = (TypeSArray *)basetype;
3727 TypeBasic *tb = t->nextOf()->isTypeBasic();
3728 assert(tb);
3729 return tb;
3732 bool TypeVector::isBoolean()
3734 return false;
3737 d_uns64 TypeVector::size(Loc)
3739 return basetype->size();
3742 unsigned TypeVector::alignsize()
3744 return (unsigned)basetype->size();
3747 Expression *TypeVector::getProperty(Loc loc, Identifier *ident, int flag)
3749 return Type::getProperty(loc, ident, flag);
3752 Expression *TypeVector::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
3754 if (ident == Id::ptr && e->op == TOKcall)
3756 /* The trouble with TOKcall is the return ABI for float[4] is different from
3757 * __vector(float[4]), and a type paint won't do.
3759 e = new AddrExp(e->loc, e);
3760 e = ::semantic(e, sc);
3761 e = e->castTo(sc, basetype->nextOf()->pointerTo());
3762 return e;
3764 if (ident == Id::array)
3766 //e = e->castTo(sc, basetype);
3767 // Keep lvalue-ness
3768 e = e->copy();
3769 e->type = basetype;
3770 return e;
3772 if (ident == Id::_init || ident == Id::offsetof || ident == Id::stringof || ident == Id::__xalignof)
3774 // init should return a new VectorExp (Bugzilla 12776)
3775 // offsetof does not work on a cast expression, so use e directly
3776 // stringof should not add a cast to the output
3777 return Type::dotExp(sc, e, ident, flag);
3779 return basetype->dotExp(sc, e->castTo(sc, basetype), ident, flag);
3782 Expression *TypeVector::defaultInit(Loc loc)
3784 //printf("TypeVector::defaultInit()\n");
3785 assert(basetype->ty == Tsarray);
3786 Expression *e = basetype->defaultInit(loc);
3787 VectorExp *ve = new VectorExp(loc, e, this);
3788 ve->type = this;
3789 ve->dim = (int)(basetype->size(loc) / elementType()->size(loc));
3790 return ve;
3793 Expression *TypeVector::defaultInitLiteral(Loc loc)
3795 //printf("TypeVector::defaultInitLiteral()\n");
3796 assert(basetype->ty == Tsarray);
3797 Expression *e = basetype->defaultInitLiteral(loc);
3798 VectorExp *ve = new VectorExp(loc, e, this);
3799 ve->type = this;
3800 ve->dim = (int)(basetype->size(loc) / elementType()->size(loc));
3801 return ve;
3804 bool TypeVector::isZeroInit(Loc loc)
3806 return basetype->isZeroInit(loc);
3809 bool TypeVector::isintegral()
3811 //printf("TypeVector::isintegral('%s') x%x\n", toChars(), flags);
3812 return basetype->nextOf()->isintegral();
3815 bool TypeVector::isfloating()
3817 return basetype->nextOf()->isfloating();
3820 bool TypeVector::isunsigned()
3822 return basetype->nextOf()->isunsigned();
3825 bool TypeVector::isscalar()
3827 return basetype->nextOf()->isscalar();
3830 MATCH TypeVector::implicitConvTo(Type *to)
3832 //printf("TypeVector::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
3833 if (this == to)
3834 return MATCHexact;
3835 #ifdef IN_GCC
3836 if (to->ty == Tvector)
3838 TypeVector *tv = (TypeVector *)to;
3839 assert(basetype->ty == Tsarray && tv->basetype->ty == Tsarray);
3841 // Can't convert to a vector which has different size.
3842 if (basetype->size() != tv->basetype->size())
3843 return MATCHnomatch;
3845 // Allow conversion to void[]
3846 if (tv->basetype->nextOf()->ty == Tvoid)
3847 return MATCHconvert;
3849 // Otherwise implicitly convertible only if basetypes are.
3850 return basetype->implicitConvTo(tv->basetype);
3852 #else
3853 if (ty == to->ty)
3854 return MATCHconvert;
3855 #endif
3856 return MATCHnomatch;
3859 /***************************** TypeArray *****************************/
3861 TypeArray::TypeArray(TY ty, Type *next)
3862 : TypeNext(ty, next)
3866 Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
3868 e = Type::dotExp(sc, e, ident, flag);
3870 if (!(flag & 1) || e)
3871 e = ::semantic(e, sc);
3872 return e;
3876 /***************************** TypeSArray *****************************/
3878 TypeSArray::TypeSArray(Type *t, Expression *dim)
3879 : TypeArray(Tsarray, t)
3881 //printf("TypeSArray(%s)\n", dim->toChars());
3882 this->dim = dim;
3885 const char *TypeSArray::kind()
3887 return "sarray";
3890 Type *TypeSArray::syntaxCopy()
3892 Type *t = next->syntaxCopy();
3893 Expression *e = dim->syntaxCopy();
3894 t = new TypeSArray(t, e);
3895 t->mod = mod;
3896 return t;
3899 d_uns64 TypeSArray::size(Loc loc)
3901 //printf("TypeSArray::size()\n");
3902 dinteger_t sz;
3903 if (!dim)
3904 return Type::size(loc);
3905 sz = dim->toInteger();
3908 bool overflow = false;
3910 sz = mulu(next->size(), sz, overflow);
3911 if (overflow)
3912 goto Loverflow;
3914 if (sz > UINT32_MAX)
3915 goto Loverflow;
3916 return sz;
3918 Loverflow:
3919 error(loc, "static array %s size overflowed to %lld", toChars(), (long long)sz);
3920 return SIZE_INVALID;
3923 unsigned TypeSArray::alignsize()
3925 return next->alignsize();
3928 /**************************
3929 * This evaluates exp while setting length to be the number
3930 * of elements in the tuple t.
3932 Expression *semanticLength(Scope *sc, Type *t, Expression *exp)
3934 if (t->ty == Ttuple)
3936 ScopeDsymbol *sym = new ArrayScopeSymbol(sc, (TypeTuple *)t);
3937 sym->parent = sc->scopesym;
3938 sc = sc->push(sym);
3940 sc = sc->startCTFE();
3941 exp = ::semantic(exp, sc);
3942 sc = sc->endCTFE();
3944 sc->pop();
3946 else
3948 sc = sc->startCTFE();
3949 exp = ::semantic(exp, sc);
3950 sc = sc->endCTFE();
3953 return exp;
3956 Expression *semanticLength(Scope *sc, TupleDeclaration *s, Expression *exp)
3958 ScopeDsymbol *sym = new ArrayScopeSymbol(sc, s);
3959 sym->parent = sc->scopesym;
3960 sc = sc->push(sym);
3962 sc = sc->startCTFE();
3963 exp = ::semantic(exp, sc);
3964 sc = sc->endCTFE();
3966 sc->pop();
3967 return exp;
3970 void TypeSArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
3972 //printf("TypeSArray::resolve() %s\n", toChars());
3973 next->resolve(loc, sc, pe, pt, ps, intypeid);
3974 //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
3975 if (*pe)
3977 // It's really an index expression
3978 if (Dsymbol *s = getDsymbol(*pe))
3979 *pe = new DsymbolExp(loc, s);
3980 *pe = new ArrayExp(loc, *pe, dim);
3982 else if (*ps)
3984 Dsymbol *s = *ps;
3985 TupleDeclaration *td = s->isTupleDeclaration();
3986 if (td)
3988 ScopeDsymbol *sym = new ArrayScopeSymbol(sc, td);
3989 sym->parent = sc->scopesym;
3990 sc = sc->push(sym);
3991 sc = sc->startCTFE();
3992 dim = ::semantic(dim, sc);
3993 sc = sc->endCTFE();
3994 sc = sc->pop();
3996 dim = dim->ctfeInterpret();
3997 uinteger_t d = dim->toUInteger();
3999 if (d >= td->objects->dim)
4001 error(loc, "tuple index %llu exceeds length %u", d, td->objects->dim);
4002 *ps = NULL;
4003 *pt = Type::terror;
4004 return;
4006 RootObject *o = (*td->objects)[(size_t)d];
4007 if (o->dyncast() == DYNCAST_DSYMBOL)
4009 *ps = (Dsymbol *)o;
4010 return;
4012 if (o->dyncast() == DYNCAST_EXPRESSION)
4014 Expression *e = (Expression *)o;
4015 if (e->op == TOKdsymbol)
4017 *ps = ((DsymbolExp *)e)->s;
4018 *pe = NULL;
4020 else
4022 *ps = NULL;
4023 *pe = e;
4025 return;
4027 if (o->dyncast() == DYNCAST_TYPE)
4029 *ps = NULL;
4030 *pt = ((Type *)o)->addMod(this->mod);
4031 return;
4034 /* Create a new TupleDeclaration which
4035 * is a slice [d..d+1] out of the old one.
4036 * Do it this way because TemplateInstance::semanticTiargs()
4037 * can handle unresolved Objects this way.
4039 Objects *objects = new Objects;
4040 objects->setDim(1);
4041 (*objects)[0] = o;
4043 TupleDeclaration *tds = new TupleDeclaration(loc, td->ident, objects);
4044 *ps = tds;
4046 else
4047 goto Ldefault;
4049 else
4051 if ((*pt)->ty != Terror)
4052 next = *pt; // prevent re-running semantic() on 'next'
4053 Ldefault:
4054 Type::resolve(loc, sc, pe, pt, ps, intypeid);
4058 Type *TypeSArray::semantic(Loc loc, Scope *sc)
4060 //printf("TypeSArray::semantic() %s\n", toChars());
4062 Type *t;
4063 Expression *e;
4064 Dsymbol *s;
4065 next->resolve(loc, sc, &e, &t, &s);
4066 if (dim && s && s->isTupleDeclaration())
4067 { TupleDeclaration *sd = s->isTupleDeclaration();
4069 dim = semanticLength(sc, sd, dim);
4070 dim = dim->ctfeInterpret();
4071 uinteger_t d = dim->toUInteger();
4073 if (d >= sd->objects->dim)
4074 { error(loc, "tuple index %llu exceeds %u", d, sd->objects->dim);
4075 return Type::terror;
4077 RootObject *o = (*sd->objects)[(size_t)d];
4078 if (o->dyncast() != DYNCAST_TYPE)
4079 { error(loc, "%s is not a type", toChars());
4080 return Type::terror;
4082 t = ((Type *)o)->addMod(this->mod);
4083 return t;
4086 Type *tn = next->semantic(loc, sc);
4087 if (tn->ty == Terror)
4088 return terror;
4090 Type *tbn = tn->toBasetype();
4092 if (dim)
4094 unsigned int errors = global.errors;
4095 dim = semanticLength(sc, tbn, dim);
4096 if (errors != global.errors)
4097 goto Lerror;
4099 dim = dim->optimize(WANTvalue);
4100 dim = dim->ctfeInterpret();
4101 if (dim->op == TOKerror)
4102 goto Lerror;
4103 errors = global.errors;
4104 dinteger_t d1 = dim->toInteger();
4105 if (errors != global.errors)
4106 goto Lerror;
4108 dim = dim->implicitCastTo(sc, tsize_t);
4109 dim = dim->optimize(WANTvalue);
4110 if (dim->op == TOKerror)
4111 goto Lerror;
4112 errors = global.errors;
4113 dinteger_t d2 = dim->toInteger();
4114 if (errors != global.errors)
4115 goto Lerror;
4117 if (dim->op == TOKerror)
4118 goto Lerror;
4120 if (d1 != d2)
4122 Loverflow:
4123 error(loc, "%s size %llu * %llu exceeds 0x%llx size limit for static array",
4124 toChars(), (unsigned long long)tbn->size(loc), (unsigned long long)d1, Target::maxStaticDataSize);
4125 goto Lerror;
4128 Type *tbx = tbn->baseElemOf();
4129 if ((tbx->ty == Tstruct && !((TypeStruct *)tbx)->sym->members) ||
4130 (tbx->ty == Tenum && !((TypeEnum *)tbx)->sym->members))
4132 /* To avoid meaningless error message, skip the total size limit check
4133 * when the bottom of element type is opaque.
4136 else if (tbn->isintegral() ||
4137 tbn->isfloating() ||
4138 tbn->ty == Tpointer ||
4139 tbn->ty == Tarray ||
4140 tbn->ty == Tsarray ||
4141 tbn->ty == Taarray ||
4142 (tbn->ty == Tstruct && (((TypeStruct *)tbn)->sym->sizeok == SIZEOKdone)) ||
4143 tbn->ty == Tclass)
4145 /* Only do this for types that don't need to have semantic()
4146 * run on them for the size, since they may be forward referenced.
4148 bool overflow = false;
4149 if (mulu(tbn->size(loc), d2, overflow) >= Target::maxStaticDataSize || overflow)
4150 goto Loverflow;
4153 switch (tbn->ty)
4155 case Ttuple:
4156 { // Index the tuple to get the type
4157 assert(dim);
4158 TypeTuple *tt = (TypeTuple *)tbn;
4159 uinteger_t d = dim->toUInteger();
4161 if (d >= tt->arguments->dim)
4162 { error(loc, "tuple index %llu exceeds %u", d, tt->arguments->dim);
4163 goto Lerror;
4165 Type *telem = (*tt->arguments)[(size_t)d]->type;
4166 return telem->addMod(this->mod);
4168 case Tfunction:
4169 case Tnone:
4170 error(loc, "can't have array of %s", tbn->toChars());
4171 goto Lerror;
4172 default:
4173 break;
4175 if (tbn->isscope())
4176 { error(loc, "cannot have array of scope %s", tbn->toChars());
4177 goto Lerror;
4180 /* Ensure things like const(immutable(T)[3]) become immutable(T[3])
4181 * and const(T)[3] become const(T[3])
4183 next = tn;
4184 transitive();
4185 t = addMod(tn->mod);
4187 return t->merge();
4189 Lerror:
4190 return Type::terror;
4193 Expression *TypeSArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
4195 if (ident == Id::length)
4197 Loc oldLoc = e->loc;
4198 e = dim->copy();
4199 e->loc = oldLoc;
4201 else if (ident == Id::ptr)
4203 if (e->op == TOKtype)
4205 e->error("%s is not an expression", e->toChars());
4206 return new ErrorExp();
4208 else if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
4210 e->deprecation("%s.ptr cannot be used in @safe code, use &%s[0] instead", e->toChars(), e->toChars());
4211 // return new ErrorExp();
4213 e = e->castTo(sc, e->type->nextOf()->pointerTo());
4215 else
4217 e = TypeArray::dotExp(sc, e, ident, flag);
4219 if (!(flag & 1) || e)
4220 e = ::semantic(e, sc);
4221 return e;
4224 structalign_t TypeSArray::alignment()
4226 return next->alignment();
4229 bool TypeSArray::isString()
4231 TY nty = next->toBasetype()->ty;
4232 return nty == Tchar || nty == Twchar || nty == Tdchar;
4235 MATCH TypeSArray::constConv(Type *to)
4237 if (to->ty == Tsarray)
4239 TypeSArray *tsa = (TypeSArray *)to;
4240 if (!dim->equals(tsa->dim))
4241 return MATCHnomatch;
4243 return TypeNext::constConv(to);
4246 MATCH TypeSArray::implicitConvTo(Type *to)
4248 //printf("TypeSArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4250 if (to->ty == Tarray)
4252 TypeDArray *ta = (TypeDArray *)to;
4254 if (!MODimplicitConv(next->mod, ta->next->mod))
4255 return MATCHnomatch;
4257 /* Allow conversion to void[]
4259 if (ta->next->ty == Tvoid)
4261 return MATCHconvert;
4264 MATCH m = next->constConv(ta->next);
4265 if (m > MATCHnomatch)
4267 return MATCHconvert;
4269 return MATCHnomatch;
4272 if (to->ty == Tsarray)
4274 if (this == to)
4275 return MATCHexact;
4277 TypeSArray *tsa = (TypeSArray *)to;
4279 if (dim->equals(tsa->dim))
4281 /* Since static arrays are value types, allow
4282 * conversions from const elements to non-const
4283 * ones, just like we allow conversion from const int
4284 * to int.
4286 MATCH m = next->implicitConvTo(tsa->next);
4287 if (m >= MATCHconst)
4289 if (mod != to->mod)
4290 m = MATCHconst;
4291 return m;
4295 return MATCHnomatch;
4298 Expression *TypeSArray::defaultInit(Loc loc)
4300 if (next->ty == Tvoid)
4301 return tuns8->defaultInit(loc);
4302 else
4303 return next->defaultInit(loc);
4306 bool TypeSArray::isZeroInit(Loc loc)
4308 return next->isZeroInit(loc);
4311 bool TypeSArray::needsDestruction()
4313 return next->needsDestruction();
4316 /*********************************
4320 bool TypeSArray::needsNested()
4322 return next->needsNested();
4325 Expression *TypeSArray::defaultInitLiteral(Loc loc)
4327 size_t d = (size_t)dim->toInteger();
4328 Expression *elementinit;
4329 if (next->ty == Tvoid)
4330 elementinit = tuns8->defaultInitLiteral(loc);
4331 else
4332 elementinit = next->defaultInitLiteral(loc);
4333 Expressions *elements = new Expressions();
4334 elements->setDim(d);
4335 for (size_t i = 0; i < d; i++)
4336 (*elements)[i] = NULL;
4337 ArrayLiteralExp *ae = new ArrayLiteralExp(Loc(), elementinit, elements);
4338 ae->type = this;
4339 return ae;
4342 bool TypeSArray::hasPointers()
4344 /* Don't want to do this, because:
4345 * struct S { T* array[0]; }
4346 * may be a variable length struct.
4348 //if (dim->toInteger() == 0)
4349 // return false;
4351 if (next->ty == Tvoid)
4353 // Arrays of void contain arbitrary data, which may include pointers
4354 return true;
4356 else
4357 return next->hasPointers();
4360 /***************************** TypeDArray *****************************/
4362 TypeDArray::TypeDArray(Type *t)
4363 : TypeArray(Tarray, t)
4365 //printf("TypeDArray(t = %p)\n", t);
4368 const char *TypeDArray::kind()
4370 return "darray";
4373 Type *TypeDArray::syntaxCopy()
4375 Type *t = next->syntaxCopy();
4376 if (t == next)
4377 t = this;
4378 else
4380 t = new TypeDArray(t);
4381 t->mod = mod;
4383 return t;
4386 d_uns64 TypeDArray::size(Loc)
4388 //printf("TypeDArray::size()\n");
4389 return Target::ptrsize * 2;
4392 unsigned TypeDArray::alignsize()
4394 // A DArray consists of two ptr-sized values, so align it on pointer size
4395 // boundary
4396 return Target::ptrsize;
4399 Type *TypeDArray::semantic(Loc loc, Scope *sc)
4401 Type *tn = next->semantic(loc,sc);
4402 Type *tbn = tn->toBasetype();
4403 switch (tbn->ty)
4405 case Ttuple:
4406 return tbn;
4407 case Tfunction:
4408 case Tnone:
4409 error(loc, "can't have array of %s", tbn->toChars());
4410 return Type::terror;
4411 case Terror:
4412 return Type::terror;
4413 default:
4414 break;
4416 if (tn->isscope())
4417 { error(loc, "cannot have array of scope %s", tn->toChars());
4418 return Type::terror;
4420 next = tn;
4421 transitive();
4422 return merge();
4425 void TypeDArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
4427 //printf("TypeDArray::resolve() %s\n", toChars());
4428 next->resolve(loc, sc, pe, pt, ps, intypeid);
4429 //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
4430 if (*pe)
4432 // It's really a slice expression
4433 if (Dsymbol *s = getDsymbol(*pe))
4434 *pe = new DsymbolExp(loc, s);
4435 *pe = new ArrayExp(loc, *pe);
4437 else if (*ps)
4439 TupleDeclaration *td = (*ps)->isTupleDeclaration();
4440 if (td)
4441 ; // keep *ps
4442 else
4443 goto Ldefault;
4445 else
4447 if ((*pt)->ty != Terror)
4448 next = *pt; // prevent re-running semantic() on 'next'
4449 Ldefault:
4450 Type::resolve(loc, sc, pe, pt, ps, intypeid);
4454 Expression *TypeDArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
4456 if (e->op == TOKtype &&
4457 (ident == Id::length || ident == Id::ptr))
4459 e->error("%s is not an expression", e->toChars());
4460 return new ErrorExp();
4462 if (ident == Id::length)
4464 if (e->op == TOKstring)
4466 StringExp *se = (StringExp *)e;
4467 return new IntegerExp(se->loc, se->len, Type::tsize_t);
4469 if (e->op == TOKnull)
4470 return new IntegerExp(e->loc, 0, Type::tsize_t);
4471 e = new ArrayLengthExp(e->loc, e);
4472 e->type = Type::tsize_t;
4473 return e;
4475 else if (ident == Id::ptr)
4477 if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
4479 e->deprecation("%s.ptr cannot be used in @safe code, use &%s[0] instead", e->toChars(), e->toChars());
4480 // return new ErrorExp();
4482 e = e->castTo(sc, next->pointerTo());
4483 return e;
4485 else
4487 e = TypeArray::dotExp(sc, e, ident, flag);
4489 return e;
4492 bool TypeDArray::isString()
4494 TY nty = next->toBasetype()->ty;
4495 return nty == Tchar || nty == Twchar || nty == Tdchar;
4498 MATCH TypeDArray::implicitConvTo(Type *to)
4500 //printf("TypeDArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4501 if (equals(to))
4502 return MATCHexact;
4504 if (to->ty == Tarray)
4506 TypeDArray *ta = (TypeDArray *)to;
4508 if (!MODimplicitConv(next->mod, ta->next->mod))
4509 return MATCHnomatch; // not const-compatible
4511 /* Allow conversion to void[]
4513 if (next->ty != Tvoid && ta->next->ty == Tvoid)
4515 return MATCHconvert;
4518 MATCH m = next->constConv(ta->next);
4519 if (m > MATCHnomatch)
4521 if (m == MATCHexact && mod != to->mod)
4522 m = MATCHconst;
4523 return m;
4526 return Type::implicitConvTo(to);
4529 Expression *TypeDArray::defaultInit(Loc loc)
4531 return new NullExp(loc, this);
4534 bool TypeDArray::isZeroInit(Loc)
4536 return true;
4539 bool TypeDArray::isBoolean()
4541 return true;
4544 bool TypeDArray::hasPointers()
4546 return true;
4550 /***************************** TypeAArray *****************************/
4552 TypeAArray::TypeAArray(Type *t, Type *index)
4553 : TypeArray(Taarray, t)
4555 this->index = index;
4556 this->loc = Loc();
4557 this->sc = NULL;
4560 TypeAArray *TypeAArray::create(Type *t, Type *index)
4562 return new TypeAArray(t, index);
4565 const char *TypeAArray::kind()
4567 return "aarray";
4570 Type *TypeAArray::syntaxCopy()
4572 Type *t = next->syntaxCopy();
4573 Type *ti = index->syntaxCopy();
4574 if (t == next && ti == index)
4575 t = this;
4576 else
4578 t = new TypeAArray(t, ti);
4579 t->mod = mod;
4581 return t;
4584 d_uns64 TypeAArray::size(Loc)
4586 return Target::ptrsize;
4589 Type *TypeAArray::semantic(Loc loc, Scope *sc)
4591 //printf("TypeAArray::semantic() %s index->ty = %d\n", toChars(), index->ty);
4592 if (deco)
4593 return this;
4595 this->loc = loc;
4596 this->sc = sc;
4597 if (sc)
4598 sc->setNoFree();
4600 // Deal with the case where we thought the index was a type, but
4601 // in reality it was an expression.
4602 if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray ||
4603 index->ty == Ttypeof || index->ty == Treturn)
4605 Expression *e;
4606 Type *t;
4607 Dsymbol *s;
4609 index->resolve(loc, sc, &e, &t, &s);
4610 if (e)
4612 // It was an expression -
4613 // Rewrite as a static array
4614 TypeSArray *tsa = new TypeSArray(next, e);
4615 return tsa->semantic(loc, sc);
4617 else if (t)
4618 index = t->semantic(loc, sc);
4619 else
4621 index->error(loc, "index is not a type or an expression");
4622 return Type::terror;
4625 else
4626 index = index->semantic(loc,sc);
4627 index = index->merge2();
4629 if (index->nextOf() && !index->nextOf()->isImmutable())
4631 index = index->constOf()->mutableOf();
4634 switch (index->toBasetype()->ty)
4636 case Tfunction:
4637 case Tvoid:
4638 case Tnone:
4639 case Ttuple:
4640 error(loc, "can't have associative array key of %s", index->toBasetype()->toChars());
4641 /* fall through */
4642 case Terror:
4643 return Type::terror;
4644 default:
4645 break;
4647 Type *tbase = index->baseElemOf();
4648 while (tbase->ty == Tarray)
4649 tbase = tbase->nextOf()->baseElemOf();
4650 if (tbase->ty == Tstruct)
4652 /* AA's need typeid(index).equals() and getHash(). Issue error if not correctly set up.
4654 StructDeclaration *sd = ((TypeStruct *)tbase)->sym;
4655 if (sd->_scope)
4656 sd->semantic(NULL);
4658 // duplicate a part of StructDeclaration::semanticTypeInfoMembers
4659 //printf("AA = %s, key: xeq = %p, xerreq = %p xhash = %p\n", toChars(), sd->xeq, sd->xerreq, sd->xhash);
4660 if (sd->xeq &&
4661 sd->xeq->_scope &&
4662 sd->xeq->semanticRun < PASSsemantic3done)
4664 unsigned errors = global.startGagging();
4665 sd->xeq->semantic3(sd->xeq->_scope);
4666 if (global.endGagging(errors))
4667 sd->xeq = sd->xerreq;
4670 const char *s = (index->toBasetype()->ty != Tstruct) ? "bottom of " : "";
4671 if (!sd->xeq)
4673 // If sd->xhash != NULL:
4674 // sd or its fields have user-defined toHash.
4675 // AA assumes that its result is consistent with bitwise equality.
4676 // else:
4677 // bitwise equality & hashing
4679 else if (sd->xeq == sd->xerreq)
4681 if (search_function(sd, Id::eq))
4683 error(loc, "%sAA key type %s does not have 'bool opEquals(ref const %s) const'",
4684 s, sd->toChars(), sd->toChars());
4686 else
4688 error(loc, "%sAA key type %s does not support const equality",
4689 s, sd->toChars());
4691 return Type::terror;
4693 else if (!sd->xhash)
4695 if (search_function(sd, Id::eq))
4697 error(loc, "%sAA key type %s should have 'size_t toHash() const nothrow @safe' if opEquals defined",
4698 s, sd->toChars());
4700 else
4702 error(loc, "%sAA key type %s supports const equality but doesn't support const hashing",
4703 s, sd->toChars());
4705 return Type::terror;
4707 else
4709 // defined equality & hashing
4710 assert(sd->xeq && sd->xhash);
4712 /* xeq and xhash may be implicitly defined by compiler. For example:
4713 * struct S { int[] arr; }
4714 * With 'arr' field equality and hashing, compiler will implicitly
4715 * generate functions for xopEquals and xtoHash in TypeInfo_Struct.
4719 else if (tbase->ty == Tclass && !((TypeClass *)tbase)->sym->isInterfaceDeclaration())
4721 ClassDeclaration *cd = ((TypeClass *)tbase)->sym;
4722 if (cd->_scope)
4723 cd->semantic(NULL);
4725 if (!ClassDeclaration::object)
4727 error(Loc(), "missing or corrupt object.d");
4728 fatal();
4731 static FuncDeclaration *feq = NULL;
4732 static FuncDeclaration *fcmp = NULL;
4733 static FuncDeclaration *fhash = NULL;
4734 if (!feq) feq = search_function(ClassDeclaration::object, Id::eq)->isFuncDeclaration();
4735 if (!fcmp) fcmp = search_function(ClassDeclaration::object, Id::cmp)->isFuncDeclaration();
4736 if (!fhash) fhash = search_function(ClassDeclaration::object, Id::tohash)->isFuncDeclaration();
4737 assert(fcmp && feq && fhash);
4739 if (feq->vtblIndex < (int)cd->vtbl.dim && cd->vtbl[feq ->vtblIndex] == feq)
4741 if (fcmp->vtblIndex < (int)cd->vtbl.dim && cd->vtbl[fcmp->vtblIndex] != fcmp)
4743 const char *s = (index->toBasetype()->ty != Tclass) ? "bottom of " : "";
4744 error(loc, "%sAA key type %s now requires equality rather than comparison",
4745 s, cd->toChars());
4746 errorSupplemental(loc, "Please override Object.opEquals and toHash.");
4750 next = next->semantic(loc,sc)->merge2();
4751 transitive();
4753 switch (next->toBasetype()->ty)
4755 case Tfunction:
4756 case Tvoid:
4757 case Tnone:
4758 case Ttuple:
4759 error(loc, "can't have associative array of %s", next->toChars());
4760 /* fall through */
4761 case Terror:
4762 return Type::terror;
4764 if (next->isscope())
4765 { error(loc, "cannot have array of scope %s", next->toChars());
4766 return Type::terror;
4768 return merge();
4771 void TypeAArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
4773 //printf("TypeAArray::resolve() %s\n", toChars());
4775 // Deal with the case where we thought the index was a type, but
4776 // in reality it was an expression.
4777 if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray)
4779 Expression *e;
4780 Type *t;
4781 Dsymbol *s;
4783 index->resolve(loc, sc, &e, &t, &s, intypeid);
4784 if (e)
4786 // It was an expression -
4787 // Rewrite as a static array
4788 TypeSArray *tsa = new TypeSArray(next, e);
4789 tsa->mod = this->mod; // just copy mod field so tsa's semantic is not yet done
4790 return tsa->resolve(loc, sc, pe, pt, ps, intypeid);
4792 else if (t)
4793 index = t;
4794 else
4795 index->error(loc, "index is not a type or an expression");
4797 Type::resolve(loc, sc, pe, pt, ps, intypeid);
4801 Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
4803 if (ident == Id::length)
4805 static FuncDeclaration *fd_aaLen = NULL;
4806 if (fd_aaLen == NULL)
4808 Parameters *fparams = new Parameters();
4809 fparams->push(new Parameter(STCin, this, NULL, NULL));
4810 fd_aaLen = FuncDeclaration::genCfunc(fparams, Type::tsize_t, Id::aaLen);
4811 TypeFunction *tf = (TypeFunction *)fd_aaLen->type;
4812 tf->purity = PUREconst;
4813 tf->isnothrow = true;
4814 tf->isnogc = false;
4816 Expression *ev = new VarExp(e->loc, fd_aaLen, false);
4817 e = new CallExp(e->loc, ev, e);
4818 e->type = ((TypeFunction *)fd_aaLen->type)->next;
4820 else
4821 e = Type::dotExp(sc, e, ident, flag);
4822 return e;
4825 Expression *TypeAArray::defaultInit(Loc loc)
4827 return new NullExp(loc, this);
4830 bool TypeAArray::isZeroInit(Loc)
4832 return true;
4835 bool TypeAArray::isBoolean()
4837 return true;
4840 bool TypeAArray::hasPointers()
4842 return true;
4845 MATCH TypeAArray::implicitConvTo(Type *to)
4847 //printf("TypeAArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4848 if (equals(to))
4849 return MATCHexact;
4851 if (to->ty == Taarray)
4852 { TypeAArray *ta = (TypeAArray *)to;
4854 if (!MODimplicitConv(next->mod, ta->next->mod))
4855 return MATCHnomatch; // not const-compatible
4857 if (!MODimplicitConv(index->mod, ta->index->mod))
4858 return MATCHnomatch; // not const-compatible
4860 MATCH m = next->constConv(ta->next);
4861 MATCH mi = index->constConv(ta->index);
4862 if (m > MATCHnomatch && mi > MATCHnomatch)
4864 return MODimplicitConv(mod, to->mod) ? MATCHconst : MATCHnomatch;
4867 return Type::implicitConvTo(to);
4870 MATCH TypeAArray::constConv(Type *to)
4872 if (to->ty == Taarray)
4874 TypeAArray *taa = (TypeAArray *)to;
4875 MATCH mindex = index->constConv(taa->index);
4876 MATCH mkey = next->constConv(taa->next);
4877 // Pick the worst match
4878 return mkey < mindex ? mkey : mindex;
4880 return Type::constConv(to);
4883 /***************************** TypePointer *****************************/
4885 TypePointer::TypePointer(Type *t)
4886 : TypeNext(Tpointer, t)
4890 TypePointer *TypePointer::create(Type *t)
4892 return new TypePointer(t);
4895 const char *TypePointer::kind()
4897 return "pointer";
4900 Type *TypePointer::syntaxCopy()
4902 Type *t = next->syntaxCopy();
4903 if (t == next)
4904 t = this;
4905 else
4907 t = new TypePointer(t);
4908 t->mod = mod;
4910 return t;
4913 Type *TypePointer::semantic(Loc loc, Scope *sc)
4915 //printf("TypePointer::semantic() %s\n", toChars());
4916 if (deco)
4917 return this;
4918 Type *n = next->semantic(loc, sc);
4919 switch (n->toBasetype()->ty)
4921 case Ttuple:
4922 error(loc, "can't have pointer to %s", n->toChars());
4923 /* fall through */
4924 case Terror:
4925 return Type::terror;
4926 default:
4927 break;
4929 if (n != next)
4931 deco = NULL;
4933 next = n;
4934 if (next->ty != Tfunction)
4935 { transitive();
4936 return merge();
4938 deco = merge()->deco;
4939 /* Don't return merge(), because arg identifiers and default args
4940 * can be different
4941 * even though the types match
4943 return this;
4947 d_uns64 TypePointer::size(Loc)
4949 return Target::ptrsize;
4952 MATCH TypePointer::implicitConvTo(Type *to)
4954 //printf("TypePointer::implicitConvTo(to = %s) %s\n", to->toChars(), toChars());
4956 if (equals(to))
4957 return MATCHexact;
4958 if (next->ty == Tfunction)
4960 if (to->ty == Tpointer)
4962 TypePointer *tp = (TypePointer *)to;
4963 if (tp->next->ty == Tfunction)
4965 if (next->equals(tp->next))
4966 return MATCHconst;
4968 if (next->covariant(tp->next) == 1)
4970 Type *tret = this->next->nextOf();
4971 Type *toret = tp->next->nextOf();
4972 if (tret->ty == Tclass && toret->ty == Tclass)
4974 /* Bugzilla 10219: Check covariant interface return with offset tweaking.
4975 * interface I {}
4976 * class C : Object, I {}
4977 * I function() dg = function C() {} // should be error
4979 int offset = 0;
4980 if (toret->isBaseOf(tret, &offset) && offset != 0)
4981 return MATCHnomatch;
4983 return MATCHconvert;
4986 else if (tp->next->ty == Tvoid)
4988 // Allow conversions to void*
4989 return MATCHconvert;
4992 return MATCHnomatch;
4994 else if (to->ty == Tpointer)
4996 TypePointer *tp = (TypePointer *)to;
4997 assert(tp->next);
4999 if (!MODimplicitConv(next->mod, tp->next->mod))
5000 return MATCHnomatch; // not const-compatible
5002 /* Alloc conversion to void*
5004 if (next->ty != Tvoid && tp->next->ty == Tvoid)
5006 return MATCHconvert;
5009 MATCH m = next->constConv(tp->next);
5010 if (m > MATCHnomatch)
5012 if (m == MATCHexact && mod != to->mod)
5013 m = MATCHconst;
5014 return m;
5017 return MATCHnomatch;
5020 MATCH TypePointer::constConv(Type *to)
5022 if (next->ty == Tfunction)
5024 if (to->nextOf() && next->equals(((TypeNext *)to)->next))
5025 return Type::constConv(to);
5026 else
5027 return MATCHnomatch;
5029 return TypeNext::constConv(to);
5032 bool TypePointer::isscalar()
5034 return true;
5037 Expression *TypePointer::defaultInit(Loc loc)
5039 return new NullExp(loc, this);
5042 bool TypePointer::isZeroInit(Loc)
5044 return true;
5047 bool TypePointer::hasPointers()
5049 return true;
5053 /***************************** TypeReference *****************************/
5055 TypeReference::TypeReference(Type *t)
5056 : TypeNext(Treference, t)
5058 // BUG: what about references to static arrays?
5061 const char *TypeReference::kind()
5063 return "reference";
5066 Type *TypeReference::syntaxCopy()
5068 Type *t = next->syntaxCopy();
5069 if (t == next)
5070 t = this;
5071 else
5073 t = new TypeReference(t);
5074 t->mod = mod;
5076 return t;
5079 Type *TypeReference::semantic(Loc loc, Scope *sc)
5081 //printf("TypeReference::semantic()\n");
5082 Type *n = next->semantic(loc, sc);
5083 if (n != next)
5084 deco = NULL;
5085 next = n;
5086 transitive();
5087 return merge();
5091 d_uns64 TypeReference::size(Loc)
5093 return Target::ptrsize;
5096 Expression *TypeReference::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
5098 // References just forward things along
5099 return next->dotExp(sc, e, ident, flag);
5102 Expression *TypeReference::defaultInit(Loc loc)
5104 return new NullExp(loc, this);
5107 bool TypeReference::isZeroInit(Loc)
5109 return true;
5113 /***************************** TypeFunction *****************************/
5115 TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc)
5116 : TypeNext(Tfunction, treturn)
5118 //if (!treturn) *(char*)0=0;
5119 // assert(treturn);
5120 assert(0 <= varargs && varargs <= 2);
5121 this->parameters = parameters;
5122 this->varargs = varargs;
5123 this->linkage = linkage;
5124 this->inuse = 0;
5125 this->isnothrow = false;
5126 this->isnogc = false;
5127 this->purity = PUREimpure;
5128 this->isproperty = false;
5129 this->isref = false;
5130 this->isreturn = false;
5131 this->isscope = false;
5132 this->isscopeinferred = false;
5133 this->iswild = 0;
5134 this->fargs = NULL;
5136 if (stc & STCpure)
5137 this->purity = PUREfwdref;
5138 if (stc & STCnothrow)
5139 this->isnothrow = true;
5140 if (stc & STCnogc)
5141 this->isnogc = true;
5142 if (stc & STCproperty)
5143 this->isproperty = true;
5145 if (stc & STCref)
5146 this->isref = true;
5147 if (stc & STCreturn)
5148 this->isreturn = true;
5149 if (stc & STCscope)
5150 this->isscope = true;
5151 if (stc & STCscopeinferred)
5152 this->isscopeinferred = true;
5154 this->trust = TRUSTdefault;
5155 if (stc & STCsafe)
5156 this->trust = TRUSTsafe;
5157 if (stc & STCsystem)
5158 this->trust = TRUSTsystem;
5159 if (stc & STCtrusted)
5160 this->trust = TRUSTtrusted;
5163 TypeFunction *TypeFunction::create(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc)
5165 return new TypeFunction(parameters, treturn, varargs, linkage, stc);
5168 const char *TypeFunction::kind()
5170 return "function";
5173 Type *TypeFunction::syntaxCopy()
5175 Type *treturn = next ? next->syntaxCopy() : NULL;
5176 Parameters *params = Parameter::arraySyntaxCopy(parameters);
5177 TypeFunction *t = new TypeFunction(params, treturn, varargs, linkage);
5178 t->mod = mod;
5179 t->isnothrow = isnothrow;
5180 t->isnogc = isnogc;
5181 t->purity = purity;
5182 t->isproperty = isproperty;
5183 t->isref = isref;
5184 t->isreturn = isreturn;
5185 t->isscope = isscope;
5186 t->isscopeinferred = isscopeinferred;
5187 t->iswild = iswild;
5188 t->trust = trust;
5189 t->fargs = fargs;
5190 return t;
5193 /*******************************
5194 * Covariant means that 'this' can substitute for 't',
5195 * i.e. a pure function is a match for an impure type.
5196 * Params:
5197 * t = type 'this' is covariant with
5198 * pstc = if not null, store STCxxxx which would make it covariant
5199 * fix17349 = enable fix https://issues.dlang.org/show_bug.cgi?id=17349
5200 * Returns:
5201 * 0 types are distinct
5202 * 1 this is covariant with t
5203 * 2 arguments match as far as overloading goes,
5204 * but types are not covariant
5205 * 3 cannot determine covariance because of forward references
5206 * *pstc STCxxxx which would make it covariant
5209 int Type::covariant(Type *t, StorageClass *pstc, bool fix17349)
5211 if (pstc)
5212 *pstc = 0;
5213 StorageClass stc = 0;
5215 bool notcovariant = false;
5217 TypeFunction *t1;
5218 TypeFunction *t2;
5220 if (equals(t))
5221 return 1; // covariant
5223 if (ty != Tfunction || t->ty != Tfunction)
5224 goto Ldistinct;
5226 t1 = (TypeFunction *)this;
5227 t2 = (TypeFunction *)t;
5229 if (t1->varargs != t2->varargs)
5230 goto Ldistinct;
5232 if (t1->parameters && t2->parameters)
5234 size_t dim = Parameter::dim(t1->parameters);
5235 if (dim != Parameter::dim(t2->parameters))
5236 goto Ldistinct;
5238 for (size_t i = 0; i < dim; i++)
5240 Parameter *fparam1 = Parameter::getNth(t1->parameters, i);
5241 Parameter *fparam2 = Parameter::getNth(t2->parameters, i);
5243 if (!fparam1->type->equals(fparam2->type))
5245 if (!fix17349)
5246 goto Ldistinct;
5247 Type *tp1 = fparam1->type;
5248 Type *tp2 = fparam2->type;
5249 if (tp1->ty == tp2->ty)
5251 if (tp1->ty == Tclass)
5253 if (((TypeClass *)tp1)->sym == ((TypeClass *)tp2)->sym && MODimplicitConv(tp2->mod, tp1->mod))
5254 goto Lcov;
5256 else if (tp1->ty == Tstruct)
5258 if (((TypeStruct *)tp1)->sym == ((TypeStruct *)tp2)->sym && MODimplicitConv(tp2->mod, tp1->mod))
5259 goto Lcov;
5261 else if (tp1->ty == Tpointer)
5263 if (tp2->implicitConvTo(tp1))
5264 goto Lcov;
5266 else if (tp1->ty == Tarray)
5268 if (tp2->implicitConvTo(tp1))
5269 goto Lcov;
5271 else if (tp1->ty == Tdelegate)
5273 if (tp1->implicitConvTo(tp2))
5274 goto Lcov;
5277 goto Ldistinct;
5279 Lcov:
5280 notcovariant |= !fparam1->isCovariant(t1->isref, fparam2);
5283 else if (t1->parameters != t2->parameters)
5285 size_t dim1 = !t1->parameters ? 0 : t1->parameters->dim;
5286 size_t dim2 = !t2->parameters ? 0 : t2->parameters->dim;
5287 if (dim1 || dim2)
5288 goto Ldistinct;
5291 // The argument lists match
5292 if (notcovariant)
5293 goto Lnotcovariant;
5294 if (t1->linkage != t2->linkage)
5295 goto Lnotcovariant;
5298 // Return types
5299 Type *t1n = t1->next;
5300 Type *t2n = t2->next;
5302 if (!t1n || !t2n) // happens with return type inference
5303 goto Lnotcovariant;
5305 if (t1n->equals(t2n))
5306 goto Lcovariant;
5307 if (t1n->ty == Tclass && t2n->ty == Tclass)
5309 /* If same class type, but t2n is const, then it's
5310 * covariant. Do this test first because it can work on
5311 * forward references.
5313 if (((TypeClass *)t1n)->sym == ((TypeClass *)t2n)->sym &&
5314 MODimplicitConv(t1n->mod, t2n->mod))
5315 goto Lcovariant;
5317 // If t1n is forward referenced:
5318 ClassDeclaration *cd = ((TypeClass *)t1n)->sym;
5319 if (cd->_scope)
5320 cd->semantic(NULL);
5321 if (!cd->isBaseInfoComplete())
5323 return 3; // forward references
5326 if (t1n->ty == Tstruct && t2n->ty == Tstruct)
5328 if (((TypeStruct *)t1n)->sym == ((TypeStruct *)t2n)->sym &&
5329 MODimplicitConv(t1n->mod, t2n->mod))
5330 goto Lcovariant;
5332 else if (t1n->ty == t2n->ty && t1n->implicitConvTo(t2n))
5333 goto Lcovariant;
5334 else if (t1n->ty == Tnull && t1n->implicitConvTo(t2n) &&
5335 t1n->size() == t2n->size())
5336 goto Lcovariant;
5338 goto Lnotcovariant;
5340 Lcovariant:
5341 if (t1->isref != t2->isref)
5342 goto Lnotcovariant;
5344 if (!t1->isref && (t1->isscope || t2->isscope))
5346 StorageClass stc1 = t1->isscope ? STCscope : 0;
5347 StorageClass stc2 = t2->isscope ? STCscope : 0;
5348 if (t1->isreturn)
5350 stc1 |= STCreturn;
5351 if (!t1->isscope)
5352 stc1 |= STCref;
5354 if (t2->isreturn)
5356 stc2 |= STCreturn;
5357 if (!t2->isscope)
5358 stc2 |= STCref;
5360 if (!Parameter::isCovariantScope(t1->isref, stc1, stc2))
5361 goto Lnotcovariant;
5364 // We can subtract 'return ref' from 'this', but cannot add it
5365 else if (t1->isreturn && !t2->isreturn)
5366 goto Lnotcovariant;
5368 /* Can convert mutable to const
5370 if (!MODimplicitConv(t2->mod, t1->mod))
5372 goto Ldistinct;
5375 /* Can convert pure to impure, nothrow to throw, and nogc to gc
5377 if (!t1->purity && t2->purity)
5378 stc |= STCpure;
5380 if (!t1->isnothrow && t2->isnothrow)
5381 stc |= STCnothrow;
5383 if (!t1->isnogc && t2->isnogc)
5384 stc |= STCnogc;
5386 /* Can convert safe/trusted to system
5388 if (t1->trust <= TRUSTsystem && t2->trust >= TRUSTtrusted)
5390 // Should we infer trusted or safe? Go with safe.
5391 stc |= STCsafe;
5394 if (stc)
5395 { if (pstc)
5396 *pstc = stc;
5397 goto Lnotcovariant;
5400 //printf("\tcovaraint: 1\n");
5401 return 1;
5403 Ldistinct:
5404 //printf("\tcovaraint: 0\n");
5405 return 0;
5407 Lnotcovariant:
5408 //printf("\tcovaraint: 2\n");
5409 return 2;
5412 Type *TypeFunction::semantic(Loc loc, Scope *sc)
5414 if (deco) // if semantic() already run
5416 //printf("already done\n");
5417 return this;
5419 //printf("TypeFunction::semantic() this = %p\n", this);
5420 //printf("TypeFunction::semantic() %s, sc->stc = %llx, fargs = %p\n", toChars(), sc->stc, fargs);
5422 bool errors = false;
5424 /* Copy in order to not mess up original.
5425 * This can produce redundant copies if inferring return type,
5426 * as semantic() will get called again on this.
5428 TypeFunction *tf = (TypeFunction *)copy();
5429 if (parameters)
5431 tf->parameters = parameters->copy();
5432 for (size_t i = 0; i < parameters->dim; i++)
5434 void *pp = mem.xmalloc(sizeof(Parameter));
5435 Parameter *p = (Parameter *)memcpy(pp, (void *)(*parameters)[i], sizeof(Parameter));
5436 (*tf->parameters)[i] = p;
5440 if (sc->stc & STCpure)
5441 tf->purity = PUREfwdref;
5442 if (sc->stc & STCnothrow)
5443 tf->isnothrow = true;
5444 if (sc->stc & STCnogc)
5445 tf->isnogc = true;
5446 if (sc->stc & STCref)
5447 tf->isref = true;
5448 if (sc->stc & STCreturn)
5449 tf->isreturn = true;
5450 if (sc->stc & STCscope)
5451 tf->isscope = true;
5452 if (sc->stc & STCscopeinferred)
5453 tf->isscopeinferred = true;
5455 // if ((sc->stc & (STCreturn | STCref)) == STCreturn)
5456 // tf->isscope = true; // return by itself means 'return scope'
5458 if (tf->trust == TRUSTdefault)
5460 if (sc->stc & STCsafe)
5461 tf->trust = TRUSTsafe;
5462 if (sc->stc & STCsystem)
5463 tf->trust = TRUSTsystem;
5464 if (sc->stc & STCtrusted)
5465 tf->trust = TRUSTtrusted;
5468 if (sc->stc & STCproperty)
5469 tf->isproperty = true;
5471 tf->linkage = sc->linkage;
5472 bool wildreturn = false;
5473 if (tf->next)
5475 sc = sc->push();
5476 sc->stc &= ~(STC_TYPECTOR | STC_FUNCATTR);
5477 tf->next = tf->next->semantic(loc, sc);
5478 sc = sc->pop();
5479 errors |= tf->checkRetType(loc);
5480 if (tf->next->isscope() && !(sc->flags & SCOPEctor))
5482 error(loc, "functions cannot return scope %s", tf->next->toChars());
5483 errors = true;
5485 if (tf->next->hasWild())
5486 wildreturn = true;
5488 if (tf->isreturn && !tf->isref && !tf->next->hasPointers())
5490 error(loc, "function type '%s' has 'return' but does not return any indirections", tf->toChars());
5494 unsigned char wildparams = 0;
5495 if (tf->parameters)
5497 /* Create a scope for evaluating the default arguments for the parameters
5499 Scope *argsc = sc->push();
5500 argsc->stc = 0; // don't inherit storage class
5501 argsc->protection = Prot(PROTpublic);
5502 argsc->func = NULL;
5504 size_t dim = Parameter::dim(tf->parameters);
5505 for (size_t i = 0; i < dim; i++)
5507 Parameter *fparam = Parameter::getNth(tf->parameters, i);
5508 tf->inuse++;
5509 fparam->type = fparam->type->semantic(loc, argsc);
5510 if (tf->inuse == 1) tf->inuse--;
5512 if (fparam->type->ty == Terror)
5514 errors = true;
5515 continue;
5518 fparam->type = fparam->type->addStorageClass(fparam->storageClass);
5520 if (fparam->storageClass & (STCauto | STCalias | STCstatic))
5522 if (!fparam->type)
5523 continue;
5526 Type *t = fparam->type->toBasetype();
5528 if (t->ty == Tfunction)
5530 error(loc, "cannot have parameter of function type %s", fparam->type->toChars());
5531 errors = true;
5533 else if (!(fparam->storageClass & (STCref | STCout)) &&
5534 (t->ty == Tstruct || t->ty == Tsarray || t->ty == Tenum))
5536 Type *tb2 = t->baseElemOf();
5537 if ((tb2->ty == Tstruct && !((TypeStruct *)tb2)->sym->members) ||
5538 (tb2->ty == Tenum && !((TypeEnum *)tb2)->sym->memtype))
5540 error(loc, "cannot have parameter of opaque type %s by value", fparam->type->toChars());
5541 errors = true;
5544 else if (!(fparam->storageClass & STClazy) && t->ty == Tvoid)
5546 error(loc, "cannot have parameter of type %s", fparam->type->toChars());
5547 errors = true;
5550 if ((fparam->storageClass & (STCref | STCwild)) == (STCref | STCwild))
5552 // 'ref inout' implies 'return'
5553 fparam->storageClass |= STCreturn;
5556 if (fparam->storageClass & STCreturn)
5558 if (fparam->storageClass & (STCref | STCout))
5560 // Disabled for the moment awaiting improvement to allow return by ref
5561 // to be transformed into return by scope.
5562 if (0 && !tf->isref)
5564 StorageClass stc = fparam->storageClass & (STCref | STCout);
5565 error(loc, "parameter %s is 'return %s' but function does not return by ref",
5566 fparam->ident ? fparam->ident->toChars() : "",
5567 stcToChars(stc));
5568 errors = true;
5571 else
5573 fparam->storageClass |= STCscope; // 'return' implies 'scope'
5574 if (tf->isref)
5577 else if (!tf->isref && tf->next && !tf->next->hasPointers())
5579 error(loc, "parameter %s is 'return' but function does not return any indirections",
5580 fparam->ident ? fparam->ident->toChars() : "");
5581 errors = true;
5586 if (fparam->storageClass & (STCref | STClazy))
5589 else if (fparam->storageClass & STCout)
5591 if (unsigned char m = fparam->type->mod & (MODimmutable | MODconst | MODwild))
5593 error(loc, "cannot have %s out parameter of type %s", MODtoChars(m), t->toChars());
5594 errors = true;
5596 else
5598 Type *tv = t;
5599 while (tv->ty == Tsarray)
5600 tv = tv->nextOf()->toBasetype();
5601 if (tv->ty == Tstruct && ((TypeStruct *)tv)->sym->noDefaultCtor)
5603 error(loc, "cannot have out parameter of type %s because the default construction is disabled",
5604 fparam->type->toChars());
5605 errors = true;
5610 if (fparam->storageClass & STCscope && !fparam->type->hasPointers() && fparam->type->ty != Ttuple)
5612 fparam->storageClass &= ~STCscope;
5613 if (!(fparam->storageClass & STCref))
5614 fparam->storageClass &= ~STCreturn;
5617 if (t->hasWild())
5619 wildparams |= 1;
5620 //if (tf->next && !wildreturn)
5621 // error(loc, "inout on parameter means inout must be on return type as well (if from D1 code, replace with 'ref')");
5624 if (fparam->defaultArg)
5626 Expression *e = fparam->defaultArg;
5627 if (fparam->storageClass & (STCref | STCout))
5629 e = ::semantic(e, argsc);
5630 e = resolveProperties(argsc, e);
5632 else
5634 e = inferType(e, fparam->type);
5635 Initializer *iz = new ExpInitializer(e->loc, e);
5636 iz = ::semantic(iz, argsc, fparam->type, INITnointerpret);
5637 e = initializerToExpression(iz);
5639 if (e->op == TOKfunction) // see Bugzilla 4820
5641 FuncExp *fe = (FuncExp *)e;
5642 // Replace function literal with a function symbol,
5643 // since default arg expression must be copied when used
5644 // and copying the literal itself is wrong.
5645 e = new VarExp(e->loc, fe->fd, false);
5646 e = new AddrExp(e->loc, e);
5647 e = ::semantic(e, argsc);
5649 e = e->implicitCastTo(argsc, fparam->type);
5651 // default arg must be an lvalue
5652 if (fparam->storageClass & (STCout | STCref))
5653 e = e->toLvalue(argsc, e);
5655 fparam->defaultArg = e;
5656 if (e->op == TOKerror)
5657 errors = true;
5660 /* If fparam after semantic() turns out to be a tuple, the number of parameters may
5661 * change.
5663 if (t->ty == Ttuple)
5665 /* TypeFunction::parameter also is used as the storage of
5666 * Parameter objects for FuncDeclaration. So we should copy
5667 * the elements of TypeTuple::arguments to avoid unintended
5668 * sharing of Parameter object among other functions.
5670 TypeTuple *tt = (TypeTuple *)t;
5671 if (tt->arguments && tt->arguments->dim)
5673 /* Propagate additional storage class from tuple parameters to their
5674 * element-parameters.
5675 * Make a copy, as original may be referenced elsewhere.
5677 size_t tdim = tt->arguments->dim;
5678 Parameters *newparams = new Parameters();
5679 newparams->setDim(tdim);
5680 for (size_t j = 0; j < tdim; j++)
5682 Parameter *narg = (*tt->arguments)[j];
5684 // Bugzilla 12744: If the storage classes of narg
5685 // conflict with the ones in fparam, it's ignored.
5686 StorageClass stc = fparam->storageClass | narg->storageClass;
5687 StorageClass stc1 = fparam->storageClass & (STCref | STCout | STClazy);
5688 StorageClass stc2 = narg->storageClass & (STCref | STCout | STClazy);
5689 if (stc1 && stc2 && stc1 != stc2)
5691 OutBuffer buf1; stcToBuffer(&buf1, stc1 | ((stc1 & STCref) ? (fparam->storageClass & STCauto) : 0));
5692 OutBuffer buf2; stcToBuffer(&buf2, stc2);
5694 error(loc, "incompatible parameter storage classes '%s' and '%s'",
5695 buf1.peekString(), buf2.peekString());
5696 errors = true;
5697 stc = stc1 | (stc & ~(STCref | STCout | STClazy));
5700 (*newparams)[j] = new Parameter(
5701 stc, narg->type, narg->ident, narg->defaultArg);
5703 fparam->type = new TypeTuple(newparams);
5705 fparam->storageClass = 0;
5707 /* Reset number of parameters, and back up one to do this fparam again,
5708 * now that it is a tuple
5710 dim = Parameter::dim(tf->parameters);
5711 i--;
5712 continue;
5715 /* Resolve "auto ref" storage class to be either ref or value,
5716 * based on the argument matching the parameter
5718 if (fparam->storageClass & STCauto)
5720 if (fargs && i < fargs->dim && (fparam->storageClass & STCref))
5722 Expression *farg = (*fargs)[i];
5723 if (farg->isLvalue())
5724 ; // ref parameter
5725 else
5726 fparam->storageClass &= ~STCref; // value parameter
5727 fparam->storageClass &= ~STCauto; // Bugzilla 14656
5728 fparam->storageClass |= STCautoref;
5730 else
5732 error(loc, "'auto' can only be used as part of 'auto ref' for template function parameters");
5733 errors = true;
5737 // Remove redundant storage classes for type, they are already applied
5738 fparam->storageClass &= ~(STC_TYPECTOR | STCin);
5740 argsc->pop();
5742 if (tf->isWild())
5743 wildparams |= 2;
5745 if (wildreturn && !wildparams)
5747 error(loc, "inout on return means inout must be on a parameter as well for %s", toChars());
5748 errors = true;
5750 tf->iswild = wildparams;
5752 if (tf->inuse)
5754 error(loc, "recursive type");
5755 tf->inuse = 0;
5756 errors = true;
5759 if (tf->isproperty && (tf->varargs || Parameter::dim(tf->parameters) > 2))
5761 error(loc, "properties can only have zero, one, or two parameter");
5762 errors = true;
5765 if (tf->varargs == 1 && tf->linkage != LINKd && Parameter::dim(tf->parameters) == 0)
5767 error(loc, "variadic functions with non-D linkage must have at least one parameter");
5768 errors = true;
5771 if (errors)
5772 return terror;
5774 if (tf->next)
5775 tf->deco = tf->merge()->deco;
5777 /* Don't return merge(), because arg identifiers and default args
5778 * can be different
5779 * even though the types match
5781 return tf;
5784 bool TypeFunction::checkRetType(Loc loc)
5786 Type *tb = next->toBasetype();
5787 if (tb->ty == Tfunction)
5789 error(loc, "functions cannot return a function");
5790 next = Type::terror;
5792 if (tb->ty == Ttuple)
5794 error(loc, "functions cannot return a tuple");
5795 next = Type::terror;
5797 if (!isref && (tb->ty == Tstruct || tb->ty == Tsarray))
5799 Type *tb2 = tb->baseElemOf();
5800 if (tb2->ty == Tstruct && !((TypeStruct *)tb2)->sym->members)
5802 error(loc, "functions cannot return opaque type %s by value", tb->toChars());
5803 next = Type::terror;
5806 if (tb->ty == Terror)
5807 return true;
5809 return false;
5812 /* Determine purity level based on mutability of t
5813 * and whether it is a 'ref' type or not.
5815 static PURE purityOfType(bool isref, Type *t)
5817 if (isref)
5819 if (t->mod & MODimmutable)
5820 return PUREstrong;
5821 if (t->mod & (MODconst | MODwild))
5822 return PUREconst;
5823 return PUREweak;
5826 t = t->baseElemOf();
5828 if (!t->hasPointers() || t->mod & MODimmutable)
5829 return PUREstrong;
5831 /* Accept immutable(T)[] and immutable(T)* as being strongly pure
5833 if (t->ty == Tarray || t->ty == Tpointer)
5835 Type *tn = t->nextOf()->toBasetype();
5836 if (tn->mod & MODimmutable)
5837 return PUREstrong;
5838 if (tn->mod & (MODconst | MODwild))
5839 return PUREconst;
5842 /* The rest of this is too strict; fix later.
5843 * For example, the only pointer members of a struct may be immutable,
5844 * which would maintain strong purity.
5845 * (Just like for dynamic arrays and pointers above.)
5847 if (t->mod & (MODconst | MODwild))
5848 return PUREconst;
5850 /* Should catch delegates and function pointers, and fold in their purity
5852 return PUREweak;
5855 /********************************************
5856 * Set 'purity' field of 'this'.
5857 * Do this lazily, as the parameter types might be forward referenced.
5859 void TypeFunction::purityLevel()
5861 TypeFunction *tf = this;
5862 if (tf->purity != PUREfwdref)
5863 return;
5865 purity = PUREstrong; // assume strong until something weakens it
5867 /* Evaluate what kind of purity based on the modifiers for the parameters
5869 const size_t dim = Parameter::dim(tf->parameters);
5870 for (size_t i = 0; i < dim; i++)
5872 Parameter *fparam = Parameter::getNth(tf->parameters, i);
5873 Type *t = fparam->type;
5874 if (!t)
5875 continue;
5877 if (fparam->storageClass & (STClazy | STCout))
5879 purity = PUREweak;
5880 break;
5882 switch (purityOfType((fparam->storageClass & STCref) != 0, t))
5884 case PUREweak:
5885 purity = PUREweak;
5886 break;
5888 case PUREconst:
5889 purity = PUREconst;
5890 continue;
5892 case PUREstrong:
5893 continue;
5895 default:
5896 assert(0);
5898 break; // since PUREweak, no need to check further
5901 if (purity > PUREweak && tf->nextOf())
5903 /* Adjust purity based on mutability of return type.
5904 * https://issues.dlang.org/show_bug.cgi?id=15862
5906 const PURE purity2 = purityOfType(tf->isref, tf->nextOf());
5907 if (purity2 < purity)
5908 purity = purity2;
5910 tf->purity = purity;
5913 /********************************
5914 * 'args' are being matched to function 'this'
5915 * Determine match level.
5916 * Input:
5917 * flag 1 performing a partial ordering match
5918 * Returns:
5919 * MATCHxxxx
5922 MATCH TypeFunction::callMatch(Type *tthis, Expressions *args, int flag)
5924 //printf("TypeFunction::callMatch() %s\n", toChars());
5925 MATCH match = MATCHexact; // assume exact match
5926 unsigned char wildmatch = 0;
5928 if (tthis)
5930 Type *t = tthis;
5931 if (t->toBasetype()->ty == Tpointer)
5932 t = t->toBasetype()->nextOf(); // change struct* to struct
5933 if (t->mod != mod)
5935 if (MODimplicitConv(t->mod, mod))
5936 match = MATCHconst;
5937 else if ((mod & MODwild) && MODimplicitConv(t->mod, (mod & ~MODwild) | MODconst))
5939 match = MATCHconst;
5941 else
5942 return MATCHnomatch;
5944 if (isWild())
5946 if (t->isWild())
5947 wildmatch |= MODwild;
5948 else if (t->isConst())
5949 wildmatch |= MODconst;
5950 else if (t->isImmutable())
5951 wildmatch |= MODimmutable;
5952 else
5953 wildmatch |= MODmutable;
5957 size_t nparams = Parameter::dim(parameters);
5958 size_t nargs = args ? args->dim : 0;
5959 if (nparams == nargs)
5961 else if (nargs > nparams)
5963 if (varargs == 0)
5964 goto Nomatch; // too many args; no match
5965 match = MATCHconvert; // match ... with a "conversion" match level
5968 for (size_t u = 0; u < nargs; u++)
5970 if (u >= nparams)
5971 break;
5972 Parameter *p = Parameter::getNth(parameters, u);
5973 Expression *arg = (*args)[u];
5974 assert(arg);
5975 Type *tprm = p->type;
5976 Type *targ = arg->type;
5978 if (!(p->storageClass & STClazy && tprm->ty == Tvoid && targ->ty != Tvoid))
5980 bool isRef = (p->storageClass & (STCref | STCout)) != 0;
5981 wildmatch |= targ->deduceWild(tprm, isRef);
5984 if (wildmatch)
5986 /* Calculate wild matching modifier
5988 if (wildmatch & MODconst || wildmatch & (wildmatch - 1))
5989 wildmatch = MODconst;
5990 else if (wildmatch & MODimmutable)
5991 wildmatch = MODimmutable;
5992 else if (wildmatch & MODwild)
5993 wildmatch = MODwild;
5994 else
5996 assert(wildmatch & MODmutable);
5997 wildmatch = MODmutable;
6001 for (size_t u = 0; u < nparams; u++)
6003 MATCH m;
6005 Parameter *p = Parameter::getNth(parameters, u);
6006 assert(p);
6007 if (u >= nargs)
6009 if (p->defaultArg)
6010 continue;
6011 goto L1; // try typesafe variadics
6014 Expression *arg = (*args)[u];
6015 assert(arg);
6016 //printf("arg: %s, type: %s\n", arg->toChars(), arg->type->toChars());
6018 Type *targ = arg->type;
6019 Type *tprm = wildmatch ? p->type->substWildTo(wildmatch) : p->type;
6021 if (p->storageClass & STClazy && tprm->ty == Tvoid && targ->ty != Tvoid)
6022 m = MATCHconvert;
6023 else
6025 //printf("%s of type %s implicitConvTo %s\n", arg->toChars(), targ->toChars(), tprm->toChars());
6026 if (flag)
6028 // for partial ordering, value is an irrelevant mockup, just look at the type
6029 m = targ->implicitConvTo(tprm);
6031 else
6032 m = arg->implicitConvTo(tprm);
6033 //printf("match %d\n", m);
6036 // Non-lvalues do not match ref or out parameters
6037 if (p->storageClass & (STCref | STCout))
6039 // Bugzilla 13783: Don't use toBasetype() to handle enum types.
6040 Type *ta = targ;
6041 Type *tp = tprm;
6042 //printf("fparam[%d] ta = %s, tp = %s\n", u, ta->toChars(), tp->toChars());
6044 if (m && !arg->isLvalue())
6046 if (p->storageClass & STCout)
6047 goto Nomatch;
6049 if (arg->op == TOKstring && tp->ty == Tsarray)
6051 if (ta->ty != Tsarray)
6053 Type *tn = tp->nextOf()->castMod(ta->nextOf()->mod);
6054 dinteger_t dim = ((StringExp *)arg)->len;
6055 ta = tn->sarrayOf(dim);
6058 else if (arg->op == TOKslice && tp->ty == Tsarray)
6060 // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
6061 if (ta->ty != Tsarray)
6063 Type *tn = ta->nextOf();
6064 dinteger_t dim = ((TypeSArray *)tp)->dim->toUInteger();
6065 ta = tn->sarrayOf(dim);
6068 else
6069 goto Nomatch;
6072 /* Find most derived alias this type being matched.
6073 * Bugzilla 15674: Allow on both ref and out parameters.
6075 while (1)
6077 Type *tat = ta->toBasetype()->aliasthisOf();
6078 if (!tat || !tat->implicitConvTo(tprm))
6079 break;
6080 ta = tat;
6083 /* A ref variable should work like a head-const reference.
6084 * e.g. disallows:
6085 * ref T <- an lvalue of const(T) argument
6086 * ref T[dim] <- an lvalue of const(T[dim]) argument
6088 if (!ta->constConv(tp))
6089 goto Nomatch;
6093 /* prefer matching the element type rather than the array
6094 * type when more arguments are present with T[]...
6096 if (varargs == 2 && u + 1 == nparams && nargs > nparams)
6097 goto L1;
6099 //printf("\tm = %d\n", m);
6100 if (m == MATCHnomatch) // if no match
6103 if (varargs == 2 && u + 1 == nparams) // if last varargs param
6105 Type *tb = p->type->toBasetype();
6106 TypeSArray *tsa;
6107 dinteger_t sz;
6109 switch (tb->ty)
6111 case Tsarray:
6112 tsa = (TypeSArray *)tb;
6113 sz = tsa->dim->toInteger();
6114 if (sz != nargs - u)
6115 goto Nomatch;
6116 /* fall through */
6117 case Tarray:
6119 TypeArray *ta = (TypeArray *)tb;
6120 for (; u < nargs; u++)
6122 Expression *arg = (*args)[u];
6123 assert(arg);
6125 /* If lazy array of delegates,
6126 * convert arg(s) to delegate(s)
6128 Type *tret = p->isLazyArray();
6129 if (tret)
6131 if (ta->next->equals(arg->type))
6132 m = MATCHexact;
6133 else if (tret->toBasetype()->ty == Tvoid)
6134 m = MATCHconvert;
6135 else
6137 m = arg->implicitConvTo(tret);
6138 if (m == MATCHnomatch)
6139 m = arg->implicitConvTo(ta->next);
6142 else
6143 m = arg->implicitConvTo(ta->next);
6145 if (m == MATCHnomatch)
6146 goto Nomatch;
6147 if (m < match)
6148 match = m;
6150 goto Ldone;
6152 case Tclass:
6153 // Should see if there's a constructor match?
6154 // Or just leave it ambiguous?
6155 goto Ldone;
6157 default:
6158 goto Nomatch;
6161 goto Nomatch;
6163 if (m < match)
6164 match = m; // pick worst match
6167 Ldone:
6168 //printf("match = %d\n", match);
6169 return match;
6171 Nomatch:
6172 //printf("no match\n");
6173 return MATCHnomatch;
6176 /********************************************
6177 * Return true if there are lazy parameters.
6179 bool TypeFunction::hasLazyParameters()
6181 size_t dim = Parameter::dim(parameters);
6182 for (size_t i = 0; i < dim; i++)
6184 Parameter *fparam = Parameter::getNth(parameters, i);
6185 if (fparam->storageClass & STClazy)
6186 return true;
6188 return false;
6191 /***************************
6192 * Examine function signature for parameter p and see if
6193 * the value of p can 'escape' the scope of the function.
6194 * This is useful to minimize the needed annotations for the parameters.
6195 * Params:
6196 * p = parameter to this function
6197 * Returns:
6198 * true if escapes via assignment to global or through a parameter
6201 bool TypeFunction::parameterEscapes(Parameter *p)
6203 /* Scope parameters do not escape.
6204 * Allow 'lazy' to imply 'scope' -
6205 * lazy parameters can be passed along
6206 * as lazy parameters to the next function, but that isn't
6207 * escaping.
6209 if (parameterStorageClass(p) & (STCscope | STClazy))
6210 return false;
6211 return true;
6214 /************************************
6215 * Take the specified storage class for p,
6216 * and use the function signature to infer whether
6217 * STCscope and STCreturn should be OR'd in.
6218 * (This will not affect the name mangling.)
6219 * Params:
6220 * p = one of the parameters to 'this'
6221 * Returns:
6222 * storage class with STCscope or STCreturn OR'd in
6224 StorageClass TypeFunction::parameterStorageClass(Parameter *p)
6226 StorageClass stc = p->storageClass;
6227 if (!global.params.vsafe)
6228 return stc;
6230 if (stc & (STCscope | STCreturn | STClazy) || purity == PUREimpure)
6231 return stc;
6233 /* If haven't inferred the return type yet, can't infer storage classes
6235 if (!nextOf())
6236 return stc;
6238 purityLevel();
6240 // See if p can escape via any of the other parameters
6241 if (purity == PUREweak)
6243 const size_t dim = Parameter::dim(parameters);
6244 for (size_t i = 0; i < dim; i++)
6246 Parameter *fparam = Parameter::getNth(parameters, i);
6247 Type *t = fparam->type;
6248 if (!t)
6249 continue;
6250 t = t->baseElemOf();
6251 if (t->isMutable() && t->hasPointers())
6253 if (fparam->storageClass & (STCref | STCout))
6256 else if (t->ty == Tarray || t->ty == Tpointer)
6258 Type *tn = t->nextOf()->toBasetype();
6259 if (!(tn->isMutable() && tn->hasPointers()))
6260 continue;
6262 return stc;
6267 stc |= STCscope;
6269 /* Inferring STCreturn here has false positives
6270 * for pure functions, producing spurious error messages
6271 * about escaping references.
6272 * Give up on it for now.
6274 return stc;
6277 Expression *TypeFunction::defaultInit(Loc loc)
6279 error(loc, "function does not have a default initializer");
6280 return new ErrorExp();
6283 Type *TypeFunction::addStorageClass(StorageClass stc)
6285 //printf("addStorageClass(%llx) %d\n", stc, (stc & STCscope) != 0);
6286 TypeFunction *t = (TypeFunction *)Type::addStorageClass(stc);
6287 if ((stc & STCpure && !t->purity) ||
6288 (stc & STCnothrow && !t->isnothrow) ||
6289 (stc & STCnogc && !t->isnogc) ||
6290 (stc & STCscope && !t->isscope) ||
6291 (stc & STCsafe && t->trust < TRUSTtrusted))
6293 // Klunky to change these
6294 TypeFunction *tf = new TypeFunction(t->parameters, t->next, t->varargs, t->linkage, 0);
6295 tf->mod = t->mod;
6296 tf->fargs = fargs;
6297 tf->purity = t->purity;
6298 tf->isnothrow = t->isnothrow;
6299 tf->isnogc = t->isnogc;
6300 tf->isproperty = t->isproperty;
6301 tf->isref = t->isref;
6302 tf->isreturn = t->isreturn;
6303 tf->isscope = t->isscope;
6304 tf->isscopeinferred = t->isscopeinferred;
6305 tf->trust = t->trust;
6306 tf->iswild = t->iswild;
6308 if (stc & STCpure)
6309 tf->purity = PUREfwdref;
6310 if (stc & STCnothrow)
6311 tf->isnothrow = true;
6312 if (stc & STCnogc)
6313 tf->isnogc = true;
6314 if (stc & STCsafe)
6315 tf->trust = TRUSTsafe;
6316 if (stc & STCscope)
6318 tf->isscope = true;
6319 if (stc & STCscopeinferred)
6320 tf->isscopeinferred = true;
6323 tf->deco = tf->merge()->deco;
6324 t = tf;
6326 return t;
6329 /** For each active attribute (ref/const/nogc/etc) call fp with a void* for the
6330 work param and a string representation of the attribute. */
6331 int TypeFunction::attributesApply(void *param, int (*fp)(void *, const char *), TRUSTformat trustFormat)
6333 int res = 0;
6335 if (purity) res = fp(param, "pure");
6336 if (res) return res;
6338 if (isnothrow) res = fp(param, "nothrow");
6339 if (res) return res;
6341 if (isnogc) res = fp(param, "@nogc");
6342 if (res) return res;
6344 if (isproperty) res = fp(param, "@property");
6345 if (res) return res;
6347 if (isref) res = fp(param, "ref");
6348 if (res) return res;
6350 if (isreturn) res = fp(param, "return");
6351 if (res) return res;
6353 if (isscope && !isscopeinferred) res = fp(param, "scope");
6354 if (res) return res;
6356 TRUST trustAttrib = trust;
6358 if (trustAttrib == TRUSTdefault)
6360 // Print out "@system" when trust equals TRUSTdefault (if desired).
6361 if (trustFormat == TRUSTformatSystem)
6362 trustAttrib = TRUSTsystem;
6363 else
6364 return res; // avoid calling with an empty string
6367 return fp(param, trustToChars(trustAttrib));
6370 /***************************** TypeDelegate *****************************/
6372 TypeDelegate::TypeDelegate(Type *t)
6373 : TypeNext(Tfunction, t)
6375 ty = Tdelegate;
6378 TypeDelegate *TypeDelegate::create(Type *t)
6380 return new TypeDelegate(t);
6383 const char *TypeDelegate::kind()
6385 return "delegate";
6388 Type *TypeDelegate::syntaxCopy()
6390 Type *t = next->syntaxCopy();
6391 if (t == next)
6392 t = this;
6393 else
6395 t = new TypeDelegate(t);
6396 t->mod = mod;
6398 return t;
6401 Type *TypeDelegate::semantic(Loc loc, Scope *sc)
6403 //printf("TypeDelegate::semantic() %s\n", toChars());
6404 if (deco) // if semantic() already run
6406 //printf("already done\n");
6407 return this;
6409 next = next->semantic(loc,sc);
6410 if (next->ty != Tfunction)
6411 return terror;
6413 /* In order to deal with Bugzilla 4028, perhaps default arguments should
6414 * be removed from next before the merge.
6417 /* Don't return merge(), because arg identifiers and default args
6418 * can be different
6419 * even though the types match
6421 deco = merge()->deco;
6422 return this;
6425 Type *TypeDelegate::addStorageClass(StorageClass stc)
6427 TypeDelegate *t = (TypeDelegate*)Type::addStorageClass(stc);
6428 if (!global.params.vsafe)
6429 return t;
6431 /* The rest is meant to add 'scope' to a delegate declaration if it is of the form:
6432 * alias dg_t = void* delegate();
6433 * scope dg_t dg = ...;
6435 if(stc & STCscope)
6437 Type *n = t->next->addStorageClass(STCscope | STCscopeinferred);
6438 if (n != t->next)
6440 t->next = n;
6441 t->deco = t->merge()->deco; // mangling supposed to not be changed due to STCscopeinferrred
6444 return t;
6447 d_uns64 TypeDelegate::size(Loc)
6449 return Target::ptrsize * 2;
6452 unsigned TypeDelegate::alignsize()
6454 return Target::ptrsize;
6457 MATCH TypeDelegate::implicitConvTo(Type *to)
6459 //printf("TypeDelegate::implicitConvTo(this=%p, to=%p)\n", this, to);
6460 //printf("from: %s\n", toChars());
6461 //printf("to : %s\n", to->toChars());
6462 if (this == to)
6463 return MATCHexact;
6464 #if 1 // not allowing covariant conversions because it interferes with overriding
6465 if (to->ty == Tdelegate && this->nextOf()->covariant(to->nextOf()) == 1)
6467 Type *tret = this->next->nextOf();
6468 Type *toret = ((TypeDelegate *)to)->next->nextOf();
6469 if (tret->ty == Tclass && toret->ty == Tclass)
6471 /* Bugzilla 10219: Check covariant interface return with offset tweaking.
6472 * interface I {}
6473 * class C : Object, I {}
6474 * I delegate() dg = delegate C() {} // should be error
6476 int offset = 0;
6477 if (toret->isBaseOf(tret, &offset) && offset != 0)
6478 return MATCHnomatch;
6480 return MATCHconvert;
6482 #endif
6483 return MATCHnomatch;
6486 Expression *TypeDelegate::defaultInit(Loc loc)
6488 return new NullExp(loc, this);
6491 bool TypeDelegate::isZeroInit(Loc)
6493 return true;
6496 bool TypeDelegate::isBoolean()
6498 return true;
6501 Expression *TypeDelegate::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
6503 if (ident == Id::ptr)
6505 e = new DelegatePtrExp(e->loc, e);
6506 e = ::semantic(e, sc);
6508 else if (ident == Id::funcptr)
6510 if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
6512 e->error("%s.funcptr cannot be used in @safe code", e->toChars());
6513 return new ErrorExp();
6515 e = new DelegateFuncptrExp(e->loc, e);
6516 e = ::semantic(e, sc);
6518 else
6520 e = Type::dotExp(sc, e, ident, flag);
6522 return e;
6525 bool TypeDelegate::hasPointers()
6527 return true;
6532 /***************************** TypeQualified *****************************/
6534 TypeQualified::TypeQualified(TY ty, Loc loc)
6535 : Type(ty)
6537 this->loc = loc;
6540 void TypeQualified::syntaxCopyHelper(TypeQualified *t)
6542 //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars());
6543 idents.setDim(t->idents.dim);
6544 for (size_t i = 0; i < idents.dim; i++)
6546 RootObject *id = t->idents[i];
6547 if (id->dyncast() == DYNCAST_DSYMBOL)
6549 TemplateInstance *ti = (TemplateInstance *)id;
6551 ti = (TemplateInstance *)ti->syntaxCopy(NULL);
6552 id = ti;
6554 else if (id->dyncast() == DYNCAST_EXPRESSION)
6556 Expression *e = (Expression *)id;
6557 e = e->syntaxCopy();
6558 id = e;
6560 else if (id->dyncast() == DYNCAST_TYPE)
6562 Type *tx = (Type *)id;
6563 tx = tx->syntaxCopy();
6564 id = tx;
6566 idents[i] = id;
6570 void TypeQualified::addIdent(Identifier *ident)
6572 idents.push(ident);
6575 void TypeQualified::addInst(TemplateInstance *inst)
6577 idents.push(inst);
6580 void TypeQualified::addIndex(RootObject *e)
6582 idents.push(e);
6585 d_uns64 TypeQualified::size(Loc)
6587 error(this->loc, "size of type %s is not known", toChars());
6588 return SIZE_INVALID;
6591 /*************************************
6592 * Resolve a tuple index.
6594 void TypeQualified::resolveTupleIndex(Loc loc, Scope *sc, Dsymbol *s,
6595 Expression **pe, Type **pt, Dsymbol **ps, RootObject *oindex)
6597 *pt = NULL;
6598 *ps = NULL;
6599 *pe = NULL;
6601 TupleDeclaration *td = s->isTupleDeclaration();
6603 Expression *eindex = isExpression(oindex);
6604 Type *tindex = isType(oindex);
6605 Dsymbol *sindex = isDsymbol(oindex);
6607 if (!td)
6609 // It's really an index expression
6610 if (tindex)
6611 eindex = new TypeExp(loc, tindex);
6612 else if (sindex)
6613 eindex = ::resolve(loc, sc, sindex, false);
6614 Expression *e = new IndexExp(loc, ::resolve(loc, sc, s, false), eindex);
6615 e = ::semantic(e, sc);
6616 resolveExp(e, pt, pe, ps);
6617 return;
6620 // Convert oindex to Expression, then try to resolve to constant.
6621 if (tindex)
6622 tindex->resolve(loc, sc, &eindex, &tindex, &sindex);
6623 if (sindex)
6624 eindex = ::resolve(loc, sc, sindex, false);
6625 if (!eindex)
6627 ::error(loc, "index is %s not an expression", oindex->toChars());
6628 *pt = Type::terror;
6629 return;
6631 sc = sc->startCTFE();
6632 eindex = ::semantic(eindex, sc);
6633 sc = sc->endCTFE();
6635 eindex = eindex->ctfeInterpret();
6636 if (eindex->op == TOKerror)
6638 *pt = Type::terror;
6639 return;
6642 const uinteger_t d = eindex->toUInteger();
6643 if (d >= td->objects->dim)
6645 ::error(loc, "tuple index %llu exceeds length %u", (ulonglong)d, (unsigned)td->objects->dim);
6646 *pt = Type::terror;
6647 return;
6650 RootObject *o = (*td->objects)[(size_t)d];
6651 *pt = isType(o);
6652 *ps = isDsymbol(o);
6653 *pe = isExpression(o);
6655 if (*pt)
6656 *pt = (*pt)->semantic(loc, sc);
6657 if (*pe)
6658 resolveExp(*pe, pt, pe, ps);
6661 /*************************************
6662 * Takes an array of Identifiers and figures out if
6663 * it represents a Type or an Expression.
6664 * Output:
6665 * if expression, *pe is set
6666 * if type, *pt is set
6668 void TypeQualified::resolveHelper(Loc loc, Scope *sc,
6669 Dsymbol *s, Dsymbol *,
6670 Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
6672 *pe = NULL;
6673 *pt = NULL;
6674 *ps = NULL;
6675 if (s)
6677 //printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
6678 Declaration *d = s->isDeclaration();
6679 if (d && (d->storage_class & STCtemplateparameter))
6680 s = s->toAlias();
6681 else
6682 s->checkDeprecated(loc, sc); // check for deprecated aliases
6684 s = s->toAlias();
6685 //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
6686 for (size_t i = 0; i < idents.dim; i++)
6688 RootObject *id = idents[i];
6690 if (id->dyncast() == DYNCAST_EXPRESSION ||
6691 id->dyncast() == DYNCAST_TYPE)
6693 Type *tx;
6694 Expression *ex;
6695 Dsymbol *sx;
6696 resolveTupleIndex(loc, sc, s, &ex, &tx, &sx, id);
6697 if (sx)
6699 s = sx->toAlias();
6700 continue;
6702 if (tx)
6703 ex = new TypeExp(loc, tx);
6704 assert(ex);
6706 ex = typeToExpressionHelper(this, ex, i + 1);
6707 ex = ::semantic(ex, sc);
6708 resolveExp(ex, pt, pe, ps);
6709 return;
6712 Type *t = s->getType(); // type symbol, type alias, or type tuple?
6713 unsigned errorsave = global.errors;
6714 Dsymbol *sm = s->searchX(loc, sc, id);
6715 if (sm && !(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, sm))
6717 ::deprecation(loc, "%s is not visible from module %s", sm->toPrettyChars(), sc->_module->toChars());
6718 // sm = NULL;
6720 if (global.errors != errorsave)
6722 *pt = Type::terror;
6723 return;
6725 //printf("\t3: s = %p %s %s, sm = %p\n", s, s->kind(), s->toChars(), sm);
6726 if (intypeid && !t && sm && sm->needThis())
6727 goto L3;
6728 if (VarDeclaration *v = s->isVarDeclaration())
6730 if (v->storage_class & (STCconst | STCimmutable | STCmanifest) ||
6731 v->type->isConst() || v->type->isImmutable())
6733 // Bugzilla 13087: this.field is not constant always
6734 if (!v->isThisDeclaration())
6735 goto L3;
6738 if (!sm)
6740 if (!t)
6742 if (s->isDeclaration()) // var, func, or tuple declaration?
6744 t = s->isDeclaration()->type;
6745 if (!t && s->isTupleDeclaration()) // expression tuple?
6746 goto L3;
6748 else if (s->isTemplateInstance() ||
6749 s->isImport() || s->isPackage() || s->isModule())
6751 goto L3;
6754 if (t)
6756 sm = t->toDsymbol(sc);
6757 if (sm && id->dyncast() == DYNCAST_IDENTIFIER)
6759 sm = sm->search(loc, (Identifier *)id);
6760 if (sm)
6761 goto L2;
6764 Expression *e;
6765 VarDeclaration *v = s->isVarDeclaration();
6766 FuncDeclaration *f = s->isFuncDeclaration();
6767 if (intypeid || (!v && !f))
6768 e = ::resolve(loc, sc, s, true);
6769 else
6770 e = new VarExp(loc, s->isDeclaration(), true);
6772 e = typeToExpressionHelper(this, e, i);
6773 e = ::semantic(e, sc);
6774 resolveExp(e, pt, pe, ps);
6775 return;
6777 else
6779 if (id->dyncast() == DYNCAST_DSYMBOL)
6781 // searchX already handles errors for template instances
6782 assert(global.errors);
6784 else
6786 assert(id->dyncast() == DYNCAST_IDENTIFIER);
6787 sm = s->search_correct((Identifier *)id);
6788 if (sm)
6789 error(loc, "identifier '%s' of '%s' is not defined, did you mean %s '%s'?",
6790 id->toChars(), toChars(), sm->kind(), sm->toChars());
6791 else
6792 error(loc, "identifier '%s' of '%s' is not defined", id->toChars(), toChars());
6794 *pe = new ErrorExp();
6796 return;
6799 s = sm->toAlias();
6802 if (EnumMember *em = s->isEnumMember())
6804 // It's not a type, it's an expression
6805 *pe = em->getVarExp(loc, sc);
6806 return;
6808 if (VarDeclaration *v = s->isVarDeclaration())
6810 /* This is mostly same with DsymbolExp::semantic(), but we cannot use it
6811 * because some variables used in type context need to prevent lowering
6812 * to a literal or contextful expression. For example:
6814 * enum a = 1; alias b = a;
6815 * template X(alias e){ alias v = e; } alias x = X!(1);
6816 * struct S { int v; alias w = v; }
6817 * // TypeIdentifier 'a', 'e', and 'v' should be TOKvar,
6818 * // because getDsymbol() need to work in AliasDeclaration::semantic().
6820 if (!v->type ||
6821 (!v->type->deco && v->inuse))
6823 if (v->inuse) // Bugzilla 9494
6824 error(loc, "circular reference to %s '%s'", v->kind(), v->toPrettyChars());
6825 else
6826 error(loc, "forward reference to %s '%s'", v->kind(), v->toPrettyChars());
6827 *pt = Type::terror;
6828 return;
6830 if (v->type->ty == Terror)
6831 *pt = Type::terror;
6832 else
6833 *pe = new VarExp(loc, v);
6834 return;
6836 if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
6838 //printf("'%s' is a function literal\n", fld->toChars());
6839 *pe = new FuncExp(loc, fld);
6840 *pe = ::semantic(*pe, sc);
6841 return;
6844 Type *t = s->getType();
6845 if (!t)
6847 // If the symbol is an import, try looking inside the import
6848 if (Import *si = s->isImport())
6850 s = si->search(loc, s->ident);
6851 if (s && s != si)
6852 goto L1;
6853 s = si;
6855 *ps = s;
6856 return;
6858 if (t->ty == Tinstance && t != this && !t->deco)
6860 if (!((TypeInstance *)t)->tempinst->errors)
6861 error(loc, "forward reference to '%s'", t->toChars());
6862 *pt = Type::terror;
6863 return;
6866 if (t->ty == Ttuple)
6867 *pt = t;
6868 else
6869 *pt = t->merge();
6871 if (!s)
6873 /* Look for what user might have intended
6875 const char *p = mutableOf()->unSharedOf()->toChars();
6876 Identifier *id = Identifier::idPool(p, strlen(p));
6877 if (const char *n = importHint(p))
6878 error(loc, "`%s` is not defined, perhaps `import %s;` ?", p, n);
6879 else if (Dsymbol *s2 = sc->search_correct(id))
6880 error(loc, "undefined identifier `%s`, did you mean %s `%s`?", p, s2->kind(), s2->toChars());
6881 else if (const char *q = Scope::search_correct_C(id))
6882 error(loc, "undefined identifier `%s`, did you mean `%s`?", p, q);
6883 else
6884 error(loc, "undefined identifier `%s`", p);
6886 *pt = Type::terror;
6890 /***************************** TypeIdentifier *****************************/
6892 TypeIdentifier::TypeIdentifier(Loc loc, Identifier *ident)
6893 : TypeQualified(Tident, loc)
6895 this->ident = ident;
6898 const char *TypeIdentifier::kind()
6900 return "identifier";
6903 Type *TypeIdentifier::syntaxCopy()
6905 TypeIdentifier *t = new TypeIdentifier(loc, ident);
6906 t->syntaxCopyHelper(this);
6907 t->mod = mod;
6908 return t;
6911 /*************************************
6912 * Takes an array of Identifiers and figures out if
6913 * it represents a Type or an Expression.
6914 * Output:
6915 * if expression, *pe is set
6916 * if type, *pt is set
6919 void TypeIdentifier::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
6921 //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars());
6923 if ((ident->equals(Id::_super) || ident->equals(Id::This)) && !hasThis(sc))
6925 AggregateDeclaration *ad = sc->getStructClassScope();
6926 if (ad)
6928 ClassDeclaration *cd = ad->isClassDeclaration();
6929 if (cd)
6931 if (ident->equals(Id::This))
6932 ident = cd->ident;
6933 else if (cd->baseClass && ident->equals(Id::_super))
6934 ident = cd->baseClass->ident;
6936 else
6938 StructDeclaration *sd = ad->isStructDeclaration();
6939 if (sd && ident->equals(Id::This))
6940 ident = sd->ident;
6944 if (ident == Id::ctfe)
6946 error(loc, "variable __ctfe cannot be read at compile time");
6947 *pe = NULL;
6948 *ps = NULL;
6949 *pt = Type::terror;
6950 return;
6953 Dsymbol *scopesym;
6954 Dsymbol *s = sc->search(loc, ident, &scopesym);
6955 resolveHelper(loc, sc, s, scopesym, pe, pt, ps, intypeid);
6956 if (*pt)
6957 (*pt) = (*pt)->addMod(mod);
6960 /*****************************************
6961 * See if type resolves to a symbol, if so,
6962 * return that symbol.
6965 Dsymbol *TypeIdentifier::toDsymbol(Scope *sc)
6967 //printf("TypeIdentifier::toDsymbol('%s')\n", toChars());
6968 if (!sc)
6969 return NULL;
6971 Type *t;
6972 Expression *e;
6973 Dsymbol *s;
6975 resolve(loc, sc, &e, &t, &s);
6976 if (t && t->ty != Tident)
6977 s = t->toDsymbol(sc);
6978 if (e)
6979 s = getDsymbol(e);
6981 return s;
6984 Type *TypeIdentifier::semantic(Loc loc, Scope *sc)
6986 Type *t;
6987 Expression *e;
6988 Dsymbol *s;
6990 //printf("TypeIdentifier::semantic(%s)\n", toChars());
6991 resolve(loc, sc, &e, &t, &s);
6992 if (t)
6994 //printf("\tit's a type %d, %s, %s\n", t->ty, t->toChars(), t->deco);
6995 t = t->addMod(mod);
6997 else
6999 if (s)
7001 s->error(loc, "is used as a type");
7002 //halt();
7004 else
7005 error(loc, "%s is used as a type", toChars());
7006 t = terror;
7008 //t->print();
7009 return t;
7012 /***************************** TypeInstance *****************************/
7014 TypeInstance::TypeInstance(Loc loc, TemplateInstance *tempinst)
7015 : TypeQualified(Tinstance, loc)
7017 this->tempinst = tempinst;
7020 const char *TypeInstance::kind()
7022 return "instance";
7025 Type *TypeInstance::syntaxCopy()
7027 //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim);
7028 TypeInstance *t = new TypeInstance(loc, (TemplateInstance *)tempinst->syntaxCopy(NULL));
7029 t->syntaxCopyHelper(this);
7030 t->mod = mod;
7031 return t;
7034 void TypeInstance::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
7036 // Note close similarity to TypeIdentifier::resolve()
7037 *pe = NULL;
7038 *pt = NULL;
7039 *ps = NULL;
7040 //printf("TypeInstance::resolve(sc = %p, tempinst = '%s')\n", sc, tempinst->toChars());
7041 tempinst->semantic(sc);
7042 if (!global.gag && tempinst->errors)
7044 *pt = terror;
7045 return;
7048 resolveHelper(loc, sc, tempinst, NULL, pe, pt, ps, intypeid);
7049 if (*pt)
7050 *pt = (*pt)->addMod(mod);
7051 //if (*pt) printf("pt = '%s'\n", (*pt)->toChars());
7054 Type *TypeInstance::semantic(Loc loc, Scope *sc)
7056 Type *t;
7057 Expression *e;
7058 Dsymbol *s;
7060 //printf("TypeInstance::semantic(%p, %s)\n", this, toChars());
7062 unsigned errors = global.errors;
7063 resolve(loc, sc, &e, &t, &s);
7064 // if we had an error evaluating the symbol, suppress further errors
7065 if (!t && errors != global.errors)
7066 return terror;
7069 if (!t)
7071 if (!e && s && s->errors)
7073 // if there was an error evaluating the symbol, it might actually
7074 // be a type. Avoid misleading error messages.
7075 error(loc, "%s had previous errors", toChars());
7077 else
7078 error(loc, "%s is used as a type", toChars());
7079 t = terror;
7081 return t;
7084 Dsymbol *TypeInstance::toDsymbol(Scope *sc)
7086 Type *t;
7087 Expression *e;
7088 Dsymbol *s;
7090 //printf("TypeInstance::semantic(%s)\n", toChars());
7091 resolve(loc, sc, &e, &t, &s);
7092 if (t && t->ty != Tinstance)
7093 s = t->toDsymbol(sc);
7095 return s;
7099 /***************************** TypeTypeof *****************************/
7101 TypeTypeof::TypeTypeof(Loc loc, Expression *exp)
7102 : TypeQualified(Ttypeof, loc)
7104 this->exp = exp;
7105 inuse = 0;
7108 const char *TypeTypeof::kind()
7110 return "typeof";
7113 Type *TypeTypeof::syntaxCopy()
7115 //printf("TypeTypeof::syntaxCopy() %s\n", toChars());
7116 TypeTypeof *t = new TypeTypeof(loc, exp->syntaxCopy());
7117 t->syntaxCopyHelper(this);
7118 t->mod = mod;
7119 return t;
7122 Dsymbol *TypeTypeof::toDsymbol(Scope *sc)
7124 //printf("TypeTypeof::toDsymbol('%s')\n", toChars());
7125 Expression *e;
7126 Type *t;
7127 Dsymbol *s;
7128 resolve(loc, sc, &e, &t, &s);
7130 return s;
7133 void TypeTypeof::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
7135 *pe = NULL;
7136 *pt = NULL;
7137 *ps = NULL;
7139 //printf("TypeTypeof::resolve(sc = %p, idents = '%s')\n", sc, toChars());
7140 //static int nest; if (++nest == 50) *(char*)0=0;
7141 if (inuse)
7143 inuse = 2;
7144 error(loc, "circular typeof definition");
7145 Lerr:
7146 *pt = Type::terror;
7147 inuse--;
7148 return;
7150 inuse++;
7152 Type *t;
7154 /* Currently we cannot evalute 'exp' in speculative context, because
7155 * the type implementation may leak to the final execution. Consider:
7157 * struct S(T) {
7158 * string toString() const { return "x"; }
7160 * void main() {
7161 * alias X = typeof(S!int());
7162 * assert(typeid(X).xtoString(null) == "x");
7165 Scope *sc2 = sc->push();
7166 sc2->intypeof = 1;
7167 Expression *exp2 = ::semantic(exp, sc2);
7168 exp2 = resolvePropertiesOnly(sc2, exp2);
7169 sc2->pop();
7171 if (exp2->op == TOKerror)
7173 if (!global.gag)
7174 exp = exp2;
7175 goto Lerr;
7177 exp = exp2;
7179 if (exp->op == TOKtype ||
7180 exp->op == TOKscope)
7182 if (exp->checkType())
7183 goto Lerr;
7185 /* Today, 'typeof(func)' returns void if func is a
7186 * function template (TemplateExp), or
7187 * template lambda (FuncExp).
7188 * It's actually used in Phobos as an idiom, to branch code for
7189 * template functions.
7192 if (FuncDeclaration *f = exp->op == TOKvar ? (( VarExp *)exp)->var->isFuncDeclaration()
7193 : exp->op == TOKdotvar ? ((DotVarExp *)exp)->var->isFuncDeclaration() : NULL)
7195 if (f->checkForwardRef(loc))
7196 goto Lerr;
7198 if (FuncDeclaration *f = isFuncAddress(exp))
7200 if (f->checkForwardRef(loc))
7201 goto Lerr;
7204 t = exp->type;
7205 if (!t)
7207 error(loc, "expression (%s) has no type", exp->toChars());
7208 goto Lerr;
7210 if (t->ty == Ttypeof)
7212 error(loc, "forward reference to %s", toChars());
7213 goto Lerr;
7216 if (idents.dim == 0)
7217 *pt = t;
7218 else
7220 if (Dsymbol *s = t->toDsymbol(sc))
7221 resolveHelper(loc, sc, s, NULL, pe, pt, ps, intypeid);
7222 else
7224 Expression *e = typeToExpressionHelper(this, new TypeExp(loc, t));
7225 e = ::semantic(e, sc);
7226 resolveExp(e, pt, pe, ps);
7229 if (*pt)
7230 (*pt) = (*pt)->addMod(mod);
7231 inuse--;
7232 return;
7235 Type *TypeTypeof::semantic(Loc loc, Scope *sc)
7237 //printf("TypeTypeof::semantic() %s\n", toChars());
7239 Expression *e;
7240 Type *t;
7241 Dsymbol *s;
7242 resolve(loc, sc, &e, &t, &s);
7243 if (s && (t = s->getType()) != NULL)
7244 t = t->addMod(mod);
7245 if (!t)
7247 error(loc, "%s is used as a type", toChars());
7248 t = Type::terror;
7250 return t;
7253 d_uns64 TypeTypeof::size(Loc loc)
7255 if (exp->type)
7256 return exp->type->size(loc);
7257 else
7258 return TypeQualified::size(loc);
7263 /***************************** TypeReturn *****************************/
7265 TypeReturn::TypeReturn(Loc loc)
7266 : TypeQualified(Treturn, loc)
7270 const char *TypeReturn::kind()
7272 return "return";
7275 Type *TypeReturn::syntaxCopy()
7277 TypeReturn *t = new TypeReturn(loc);
7278 t->syntaxCopyHelper(this);
7279 t->mod = mod;
7280 return t;
7283 Dsymbol *TypeReturn::toDsymbol(Scope *sc)
7285 Expression *e;
7286 Type *t;
7287 Dsymbol *s;
7288 resolve(loc, sc, &e, &t, &s);
7290 return s;
7293 void TypeReturn::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
7295 *pe = NULL;
7296 *pt = NULL;
7297 *ps = NULL;
7299 //printf("TypeReturn::resolve(sc = %p, idents = '%s')\n", sc, toChars());
7300 Type *t;
7302 FuncDeclaration *func = sc->func;
7303 if (!func)
7305 error(loc, "typeof(return) must be inside function");
7306 goto Lerr;
7308 if (func->fes)
7309 func = func->fes->func;
7311 t = func->type->nextOf();
7312 if (!t)
7314 error(loc, "cannot use typeof(return) inside function %s with inferred return type", sc->func->toChars());
7315 goto Lerr;
7318 if (idents.dim == 0)
7319 *pt = t;
7320 else
7322 if (Dsymbol *s = t->toDsymbol(sc))
7323 resolveHelper(loc, sc, s, NULL, pe, pt, ps, intypeid);
7324 else
7326 Expression *e = typeToExpressionHelper(this, new TypeExp(loc, t));
7327 e = ::semantic(e, sc);
7328 resolveExp(e, pt, pe, ps);
7331 if (*pt)
7332 (*pt) = (*pt)->addMod(mod);
7333 return;
7335 Lerr:
7336 *pt = Type::terror;
7337 return;
7340 Type *TypeReturn::semantic(Loc loc, Scope *sc)
7342 //printf("TypeReturn::semantic() %s\n", toChars());
7344 Expression *e;
7345 Type *t;
7346 Dsymbol *s;
7347 resolve(loc, sc, &e, &t, &s);
7348 if (s && (t = s->getType()) != NULL)
7349 t = t->addMod(mod);
7350 if (!t)
7352 error(loc, "%s is used as a type", toChars());
7353 t = Type::terror;
7355 return t;
7358 /***************************** TypeEnum *****************************/
7360 TypeEnum::TypeEnum(EnumDeclaration *sym)
7361 : Type(Tenum)
7363 this->sym = sym;
7366 const char *TypeEnum::kind()
7368 return "enum";
7371 Type *TypeEnum::syntaxCopy()
7373 return this;
7376 Type *TypeEnum::semantic(Loc, Scope *)
7378 //printf("TypeEnum::semantic() %s\n", toChars());
7379 if (deco)
7380 return this;
7381 return merge();
7384 d_uns64 TypeEnum::size(Loc loc)
7386 return sym->getMemtype(loc)->size(loc);
7389 unsigned TypeEnum::alignsize()
7391 Type *t = sym->getMemtype(Loc());
7392 if (t->ty == Terror)
7393 return 4;
7394 return t->alignsize();
7397 Dsymbol *TypeEnum::toDsymbol(Scope *)
7399 return sym;
7402 Type *TypeEnum::toBasetype()
7404 if (!sym->members && !sym->memtype)
7405 return this;
7406 Type *tb = sym->getMemtype(Loc())->toBasetype();
7407 return tb->castMod(mod); // retain modifier bits from 'this'
7410 Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
7412 // Bugzilla 14010
7413 if (ident == Id::_mangleof)
7414 return getProperty(e->loc, ident, flag & 1);
7416 if (sym->_scope)
7417 sym->semantic(sym->_scope);
7418 if (!sym->members)
7420 if (sym->isSpecial())
7422 /* Special enums forward to the base type
7424 e = sym->memtype->dotExp(sc, e, ident, flag);
7426 else if (!(flag & 1))
7428 sym->error("is forward referenced when looking for '%s'", ident->toChars());
7429 e = new ErrorExp();
7431 else
7432 e = NULL;
7433 return e;
7436 Dsymbol *s = sym->search(e->loc, ident);
7437 if (!s)
7439 if (ident == Id::max ||
7440 ident == Id::min ||
7441 ident == Id::_init)
7443 return getProperty(e->loc, ident, flag & 1);
7445 Expression *res = sym->getMemtype(Loc())->dotExp(sc, e, ident, 1);
7446 if (!(flag & 1) && !res)
7448 if (Dsymbol *ns = sym->search_correct(ident))
7449 e->error("no property '%s' for type '%s'. Did you mean '%s.%s' ?",
7450 ident->toChars(), toChars(), toChars(), ns->toChars());
7451 else
7452 e->error("no property '%s' for type '%s'",
7453 ident->toChars(), toChars());
7455 return new ErrorExp();
7457 return res;
7459 EnumMember *m = s->isEnumMember();
7460 return m->getVarExp(e->loc, sc);
7463 Expression *TypeEnum::getProperty(Loc loc, Identifier *ident, int flag)
7465 Expression *e;
7466 if (ident == Id::max || ident == Id::min)
7468 return sym->getMaxMinValue(loc, ident);
7470 else if (ident == Id::_init)
7472 e = defaultInitLiteral(loc);
7474 else if (ident == Id::stringof)
7476 const char *s = toChars();
7477 e = new StringExp(loc, const_cast<char *>(s), strlen(s));
7478 Scope sc;
7479 e = ::semantic(e, &sc);
7481 else if (ident == Id::_mangleof)
7483 e = Type::getProperty(loc, ident, flag);
7485 else
7487 e = toBasetype()->getProperty(loc, ident, flag);
7489 return e;
7492 bool TypeEnum::isintegral()
7494 return sym->getMemtype(Loc())->isintegral();
7497 bool TypeEnum::isfloating()
7499 return sym->getMemtype(Loc())->isfloating();
7502 bool TypeEnum::isreal()
7504 return sym->getMemtype(Loc())->isreal();
7507 bool TypeEnum::isimaginary()
7509 return sym->getMemtype(Loc())->isimaginary();
7512 bool TypeEnum::iscomplex()
7514 return sym->getMemtype(Loc())->iscomplex();
7517 bool TypeEnum::isunsigned()
7519 return sym->getMemtype(Loc())->isunsigned();
7522 bool TypeEnum::isscalar()
7524 return sym->getMemtype(Loc())->isscalar();
7527 bool TypeEnum::isString()
7529 return sym->getMemtype(Loc())->isString();
7532 bool TypeEnum::isAssignable()
7534 return sym->getMemtype(Loc())->isAssignable();
7537 bool TypeEnum::isBoolean()
7539 return sym->getMemtype(Loc())->isBoolean();
7542 bool TypeEnum::needsDestruction()
7544 return sym->getMemtype(Loc())->needsDestruction();
7547 bool TypeEnum::needsNested()
7549 return sym->getMemtype(Loc())->needsNested();
7552 MATCH TypeEnum::implicitConvTo(Type *to)
7554 MATCH m;
7556 //printf("TypeEnum::implicitConvTo()\n");
7557 if (ty == to->ty && sym == ((TypeEnum *)to)->sym)
7558 m = (mod == to->mod) ? MATCHexact : MATCHconst;
7559 else if (sym->getMemtype(Loc())->implicitConvTo(to))
7560 m = MATCHconvert; // match with conversions
7561 else
7562 m = MATCHnomatch; // no match
7563 return m;
7566 MATCH TypeEnum::constConv(Type *to)
7568 if (equals(to))
7569 return MATCHexact;
7570 if (ty == to->ty && sym == ((TypeEnum *)to)->sym &&
7571 MODimplicitConv(mod, to->mod))
7572 return MATCHconst;
7573 return MATCHnomatch;
7577 Expression *TypeEnum::defaultInit(Loc loc)
7579 // Initialize to first member of enum
7580 Expression *e = sym->getDefaultValue(loc);
7581 e = e->copy();
7582 e->loc = loc;
7583 e->type = this; // to deal with const, immutable, etc., variants
7584 return e;
7587 bool TypeEnum::isZeroInit(Loc loc)
7589 return sym->getDefaultValue(loc)->isBool(false);
7592 bool TypeEnum::hasPointers()
7594 return sym->getMemtype(Loc())->hasPointers();
7597 bool TypeEnum::hasVoidInitPointers()
7599 return sym->getMemtype(Loc())->hasVoidInitPointers();
7602 Type *TypeEnum::nextOf()
7604 return sym->getMemtype(Loc())->nextOf();
7607 /***************************** TypeStruct *****************************/
7609 TypeStruct::TypeStruct(StructDeclaration *sym)
7610 : Type(Tstruct)
7612 this->sym = sym;
7613 this->att = RECfwdref;
7614 this->cppmangle = CPPMANGLEdefault;
7617 TypeStruct *TypeStruct::create(StructDeclaration *sym)
7619 return new TypeStruct(sym);
7622 const char *TypeStruct::kind()
7624 return "struct";
7627 Type *TypeStruct::syntaxCopy()
7629 return this;
7632 Type *TypeStruct::semantic(Loc, Scope *sc)
7634 //printf("TypeStruct::semantic('%s')\n", sym->toChars());
7635 if (deco)
7637 if (sc && sc->cppmangle != CPPMANGLEdefault)
7639 if (this->cppmangle == CPPMANGLEdefault)
7640 this->cppmangle = sc->cppmangle;
7641 else
7642 assert(this->cppmangle == sc->cppmangle);
7644 return this;
7647 /* Don't semantic for sym because it should be deferred until
7648 * sizeof needed or its members accessed.
7650 // instead, parent should be set correctly
7651 assert(sym->parent);
7653 if (sym->type->ty == Terror)
7654 return Type::terror;
7655 if (sc)
7656 this->cppmangle = sc->cppmangle;
7657 return merge();
7660 d_uns64 TypeStruct::size(Loc loc)
7662 return sym->size(loc);
7665 unsigned TypeStruct::alignsize()
7667 sym->size(Loc()); // give error for forward references
7668 return sym->alignsize;
7671 Dsymbol *TypeStruct::toDsymbol(Scope *)
7673 return sym;
7676 static Dsymbol *searchSymStruct(Scope *sc, Dsymbol *sym, Expression *e, Identifier *ident)
7678 int flags = sc->flags & SCOPEignoresymbolvisibility ? IgnoreSymbolVisibility : 0;
7679 Dsymbol *sold = NULL;
7680 if (global.params.bug10378 || global.params.check10378)
7682 sold = sym->search(e->loc, ident, flags);
7683 if (!global.params.check10378)
7684 return sold;
7687 Dsymbol *s = sym->search(e->loc, ident, flags | SearchLocalsOnly);
7688 if (global.params.check10378)
7690 Dsymbol *snew = s;
7691 if (sold != snew)
7692 Scope::deprecation10378(e->loc, sold, snew);
7693 if (global.params.bug10378)
7694 s = sold;
7696 return s;
7699 Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
7701 Dsymbol *s;
7703 assert(e->op != TOKdot);
7705 // Bugzilla 14010
7706 if (ident == Id::_mangleof)
7707 return getProperty(e->loc, ident, flag & 1);
7709 /* If e.tupleof
7711 if (ident == Id::_tupleof)
7713 /* Create a TupleExp out of the fields of the struct e:
7714 * (e.field0, e.field1, e.field2, ...)
7716 e = ::semantic(e, sc); // do this before turning on noaccesscheck
7718 sym->size(e->loc); // do semantic of type
7720 Expression *e0 = NULL;
7721 Expression *ev = e->op == TOKtype ? NULL : e;
7722 if (ev)
7723 ev = extractSideEffect(sc, "__tup", &e0, ev);
7725 Expressions *exps = new Expressions;
7726 exps->reserve(sym->fields.dim);
7727 for (size_t i = 0; i < sym->fields.dim; i++)
7729 VarDeclaration *v = sym->fields[i];
7730 Expression *ex;
7731 if (ev)
7732 ex = new DotVarExp(e->loc, ev, v);
7733 else
7735 ex = new VarExp(e->loc, v);
7736 ex->type = ex->type->addMod(e->type->mod);
7738 exps->push(ex);
7741 e = new TupleExp(e->loc, e0, exps);
7742 Scope *sc2 = sc->push();
7743 sc2->flags = sc->flags | SCOPEnoaccesscheck;
7744 e = ::semantic(e, sc2);
7745 sc2->pop();
7746 return e;
7749 s = searchSymStruct(sc, sym, e, ident);
7751 if (!s)
7753 return noMember(sc, e, ident, flag);
7755 if (!(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, s))
7757 ::deprecation(e->loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toPrettyChars());
7758 // return noMember(sc, e, ident, flag);
7760 if (!s->isFuncDeclaration()) // because of overloading
7761 s->checkDeprecated(e->loc, sc);
7762 s = s->toAlias();
7764 EnumMember *em = s->isEnumMember();
7765 if (em)
7767 return em->getVarExp(e->loc, sc);
7770 if (VarDeclaration *v = s->isVarDeclaration())
7772 if (!v->type ||
7773 (!v->type->deco && v->inuse))
7775 if (v->inuse) // Bugzilla 9494
7776 e->error("circular reference to %s '%s'", v->kind(), v->toPrettyChars());
7777 else
7778 e->error("forward reference to %s '%s'", v->kind(), v->toPrettyChars());
7779 return new ErrorExp();
7781 if (v->type->ty == Terror)
7782 return new ErrorExp();
7784 if ((v->storage_class & STCmanifest) && v->_init)
7786 if (v->inuse)
7788 e->error("circular initialization of %s '%s'", v->kind(), v->toPrettyChars());
7789 return new ErrorExp();
7791 checkAccess(e->loc, sc, NULL, v);
7792 Expression *ve = new VarExp(e->loc, v);
7793 ve = ::semantic(ve, sc);
7794 return ve;
7798 if (Type *t = s->getType())
7800 return ::semantic(new TypeExp(e->loc, t), sc);
7803 TemplateMixin *tm = s->isTemplateMixin();
7804 if (tm)
7806 Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, tm));
7807 de->type = e->type;
7808 return de;
7811 TemplateDeclaration *td = s->isTemplateDeclaration();
7812 if (td)
7814 if (e->op == TOKtype)
7815 e = new TemplateExp(e->loc, td);
7816 else
7817 e = new DotTemplateExp(e->loc, e, td);
7818 e = ::semantic(e, sc);
7819 return e;
7822 TemplateInstance *ti = s->isTemplateInstance();
7823 if (ti)
7825 if (!ti->semanticRun)
7827 ti->semantic(sc);
7828 if (!ti->inst || ti->errors) // if template failed to expand
7829 return new ErrorExp();
7831 s = ti->inst->toAlias();
7832 if (!s->isTemplateInstance())
7833 goto L1;
7834 if (e->op == TOKtype)
7835 e = new ScopeExp(e->loc, ti);
7836 else
7837 e = new DotExp(e->loc, e, new ScopeExp(e->loc, ti));
7838 return ::semantic(e, sc);
7841 if (s->isImport() || s->isModule() || s->isPackage())
7843 e = ::resolve(e->loc, sc, s, false);
7844 return e;
7847 OverloadSet *o = s->isOverloadSet();
7848 if (o)
7850 OverExp *oe = new OverExp(e->loc, o);
7851 if (e->op == TOKtype)
7852 return oe;
7853 return new DotExp(e->loc, e, oe);
7856 Declaration *d = s->isDeclaration();
7857 if (!d)
7859 e->error("%s.%s is not a declaration", e->toChars(), ident->toChars());
7860 return new ErrorExp();
7863 if (e->op == TOKtype)
7865 /* It's:
7866 * Struct.d
7868 if (TupleDeclaration *tup = d->isTupleDeclaration())
7870 e = new TupleExp(e->loc, tup);
7871 e = ::semantic(e, sc);
7872 return e;
7874 if (d->needThis() && sc->intypeof != 1)
7876 /* Rewrite as:
7877 * this.d
7879 if (hasThis(sc))
7881 e = new DotVarExp(e->loc, new ThisExp(e->loc), d);
7882 e = ::semantic(e, sc);
7883 return e;
7886 if (d->semanticRun == PASSinit && d->_scope)
7887 d->semantic(d->_scope);
7888 checkAccess(e->loc, sc, e, d);
7889 VarExp *ve = new VarExp(e->loc, d);
7890 if (d->isVarDeclaration() && d->needThis())
7891 ve->type = d->type->addMod(e->type->mod);
7892 return ve;
7895 bool unreal = e->op == TOKvar && ((VarExp *)e)->var->isField();
7896 if (d->isDataseg() || (unreal && d->isField()))
7898 // (e, d)
7899 checkAccess(e->loc, sc, e, d);
7900 Expression *ve = new VarExp(e->loc, d);
7901 e = unreal ? ve : new CommaExp(e->loc, e, ve);
7902 e = ::semantic(e, sc);
7903 return e;
7906 e = new DotVarExp(e->loc, e, d);
7907 e = ::semantic(e, sc);
7908 return e;
7911 structalign_t TypeStruct::alignment()
7913 if (sym->alignment == 0)
7914 sym->size(sym->loc);
7915 return sym->alignment;
7918 Expression *TypeStruct::defaultInit(Loc)
7920 Declaration *d = new SymbolDeclaration(sym->loc, sym);
7921 assert(d);
7922 d->type = this;
7923 d->storage_class |= STCrvalue; // Bugzilla 14398
7924 return new VarExp(sym->loc, d);
7927 /***************************************
7928 * Use when we prefer the default initializer to be a literal,
7929 * rather than a global immutable variable.
7931 Expression *TypeStruct::defaultInitLiteral(Loc loc)
7933 sym->size(loc);
7934 if (sym->sizeok != SIZEOKdone)
7935 return new ErrorExp();
7936 Expressions *structelems = new Expressions();
7937 structelems->setDim(sym->fields.dim - sym->isNested());
7938 unsigned offset = 0;
7939 for (size_t j = 0; j < structelems->dim; j++)
7941 VarDeclaration *vd = sym->fields[j];
7942 Expression *e;
7943 if (vd->inuse)
7945 error(loc, "circular reference to '%s'", vd->toPrettyChars());
7946 return new ErrorExp();
7948 if (vd->offset < offset || vd->type->size() == 0)
7949 e = NULL;
7950 else if (vd->_init)
7952 if (vd->_init->isVoidInitializer())
7953 e = NULL;
7954 else
7955 e = vd->getConstInitializer(false);
7957 else
7958 e = vd->type->defaultInitLiteral(loc);
7959 if (e && e->op == TOKerror)
7960 return e;
7961 if (e)
7962 offset = vd->offset + (unsigned)vd->type->size();
7963 (*structelems)[j] = e;
7965 StructLiteralExp *structinit = new StructLiteralExp(loc, (StructDeclaration *)sym, structelems);
7967 /* Copy from the initializer symbol for larger symbols,
7968 * otherwise the literals expressed as code get excessively large.
7970 if (size(loc) > Target::ptrsize * 4U && !needsNested())
7971 structinit->useStaticInit = true;
7973 structinit->type = this;
7974 return structinit;
7978 bool TypeStruct::isZeroInit(Loc)
7980 return sym->zeroInit != 0;
7983 bool TypeStruct::isBoolean()
7985 return false;
7988 bool TypeStruct::needsDestruction()
7990 return sym->dtor != NULL;
7993 bool TypeStruct::needsNested()
7995 if (sym->isNested())
7996 return true;
7998 for (size_t i = 0; i < sym->fields.dim; i++)
8000 VarDeclaration *v = sym->fields[i];
8001 if (!v->isDataseg() && v->type->needsNested())
8002 return true;
8004 return false;
8007 bool TypeStruct::isAssignable()
8009 bool assignable = true;
8010 unsigned offset = ~0; // dead-store initialize to prevent spurious warning
8012 /* If any of the fields are const or immutable,
8013 * then one cannot assign this struct.
8015 for (size_t i = 0; i < sym->fields.dim; i++)
8017 VarDeclaration *v = sym->fields[i];
8018 //printf("%s [%d] v = (%s) %s, v->offset = %d, v->parent = %s", sym->toChars(), i, v->kind(), v->toChars(), v->offset, v->parent->kind());
8019 if (i == 0)
8021 else if (v->offset == offset)
8023 /* If any fields of anonymous union are assignable,
8024 * then regard union as assignable.
8025 * This is to support unsafe things like Rebindable templates.
8027 if (assignable)
8028 continue;
8030 else
8032 if (!assignable)
8033 return false;
8035 assignable = v->type->isMutable() && v->type->isAssignable();
8036 offset = v->offset;
8037 //printf(" -> assignable = %d\n", assignable);
8040 return assignable;
8043 bool TypeStruct::hasPointers()
8045 // Probably should cache this information in sym rather than recompute
8046 StructDeclaration *s = sym;
8048 sym->size(Loc()); // give error for forward references
8049 for (size_t i = 0; i < s->fields.dim; i++)
8051 Declaration *d = s->fields[i];
8052 if (d->storage_class & STCref || d->hasPointers())
8053 return true;
8055 return false;
8058 bool TypeStruct::hasVoidInitPointers()
8060 // Probably should cache this information in sym rather than recompute
8061 StructDeclaration *s = sym;
8063 sym->size(Loc()); // give error for forward references
8064 for (size_t i = 0; i < s->fields.dim; i++)
8066 VarDeclaration *v = s->fields[i];
8067 if (v->_init && v->_init->isVoidInitializer() && v->type->hasPointers())
8068 return true;
8069 if (!v->_init && v->type->hasVoidInitPointers())
8070 return true;
8072 return false;
8075 MATCH TypeStruct::implicitConvTo(Type *to)
8076 { MATCH m;
8078 //printf("TypeStruct::implicitConvTo(%s => %s)\n", toChars(), to->toChars());
8080 if (ty == to->ty && sym == ((TypeStruct *)to)->sym)
8082 m = MATCHexact; // exact match
8083 if (mod != to->mod)
8085 m = MATCHconst;
8086 if (MODimplicitConv(mod, to->mod))
8088 else
8090 /* Check all the fields. If they can all be converted,
8091 * allow the conversion.
8093 unsigned offset = ~0; // dead-store to prevent spurious warning
8094 for (size_t i = 0; i < sym->fields.dim; i++)
8096 VarDeclaration *v = sym->fields[i];
8097 if (i == 0)
8099 else if (v->offset == offset)
8101 if (m > MATCHnomatch)
8102 continue;
8104 else
8106 if (m <= MATCHnomatch)
8107 return m;
8110 // 'from' type
8111 Type *tvf = v->type->addMod(mod);
8113 // 'to' type
8114 Type *tv = v->type->addMod(to->mod);
8116 // field match
8117 MATCH mf = tvf->implicitConvTo(tv);
8118 //printf("\t%s => %s, match = %d\n", v->type->toChars(), tv->toChars(), mf);
8120 if (mf <= MATCHnomatch)
8121 return mf;
8122 if (mf < m) // if field match is worse
8123 m = mf;
8124 offset = v->offset;
8129 else if (sym->aliasthis && !(att & RECtracing))
8131 att = (AliasThisRec)(att | RECtracing);
8132 m = aliasthisOf()->implicitConvTo(to);
8133 att = (AliasThisRec)(att & ~RECtracing);
8135 else
8136 m = MATCHnomatch; // no match
8137 return m;
8140 MATCH TypeStruct::constConv(Type *to)
8142 if (equals(to))
8143 return MATCHexact;
8144 if (ty == to->ty && sym == ((TypeStruct *)to)->sym &&
8145 MODimplicitConv(mod, to->mod))
8146 return MATCHconst;
8147 return MATCHnomatch;
8150 unsigned char TypeStruct::deduceWild(Type *t, bool isRef)
8152 if (ty == t->ty && sym == ((TypeStruct *)t)->sym)
8153 return Type::deduceWild(t, isRef);
8155 unsigned char wm = 0;
8157 if (t->hasWild() && sym->aliasthis && !(att & RECtracing))
8159 att = (AliasThisRec)(att | RECtracing);
8160 wm = aliasthisOf()->deduceWild(t, isRef);
8161 att = (AliasThisRec)(att & ~RECtracing);
8164 return wm;
8167 Type *TypeStruct::toHeadMutable()
8169 return this;
8173 /***************************** TypeClass *****************************/
8175 TypeClass::TypeClass(ClassDeclaration *sym)
8176 : Type(Tclass)
8178 this->sym = sym;
8179 this->att = RECfwdref;
8180 this->cppmangle = CPPMANGLEdefault;
8183 const char *TypeClass::kind()
8185 return "class";
8188 Type *TypeClass::syntaxCopy()
8190 return this;
8193 Type *TypeClass::semantic(Loc, Scope *sc)
8195 //printf("TypeClass::semantic(%s)\n", sym->toChars());
8196 if (deco)
8198 if (sc && sc->cppmangle != CPPMANGLEdefault)
8200 if (this->cppmangle == CPPMANGLEdefault)
8201 this->cppmangle = sc->cppmangle;
8202 else
8203 assert(this->cppmangle == sc->cppmangle);
8205 return this;
8208 /* Don't semantic for sym because it should be deferred until
8209 * sizeof needed or its members accessed.
8211 // instead, parent should be set correctly
8212 assert(sym->parent);
8214 if (sym->type->ty == Terror)
8215 return Type::terror;
8216 if (sc)
8217 this->cppmangle = sc->cppmangle;
8218 return merge();
8221 d_uns64 TypeClass::size(Loc)
8223 return Target::ptrsize;
8226 Dsymbol *TypeClass::toDsymbol(Scope *)
8228 return sym;
8231 static Dsymbol *searchSymClass(Scope *sc, Dsymbol *sym, Expression *e, Identifier *ident)
8233 int flags = sc->flags & SCOPEignoresymbolvisibility ? IgnoreSymbolVisibility : 0;
8234 Dsymbol *sold = NULL;
8235 if (global.params.bug10378 || global.params.check10378)
8237 sold = sym->search(e->loc, ident, flags | IgnoreSymbolVisibility);
8238 if (!global.params.check10378)
8239 return sold;
8242 Dsymbol *s = sym->search(e->loc, ident, flags | SearchLocalsOnly);
8243 if (!s && !(flags & IgnoreSymbolVisibility))
8245 s = sym->search(e->loc, ident, flags | SearchLocalsOnly | IgnoreSymbolVisibility);
8246 if (s && !(flags & IgnoreErrors))
8247 ::deprecation(e->loc, "%s is not visible from class %s", s->toPrettyChars(), sym->toChars());
8249 if (global.params.check10378)
8251 Dsymbol *snew = s;
8252 if (sold != snew)
8253 Scope::deprecation10378(e->loc, sold, snew);
8254 if (global.params.bug10378)
8255 s = sold;
8257 return s;
8260 Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
8262 Dsymbol *s;
8263 assert(e->op != TOKdot);
8265 // Bugzilla 12543
8266 if (ident == Id::__sizeof || ident == Id::__xalignof || ident == Id::_mangleof)
8268 return Type::getProperty(e->loc, ident, 0);
8271 /* If e.tupleof
8273 if (ident == Id::_tupleof)
8275 /* Create a TupleExp
8277 e = ::semantic(e, sc); // do this before turning on noaccesscheck
8279 sym->size(e->loc); // do semantic of type
8281 Expression *e0 = NULL;
8282 Expression *ev = e->op == TOKtype ? NULL : e;
8283 if (ev)
8284 ev = extractSideEffect(sc, "__tup", &e0, ev);
8286 Expressions *exps = new Expressions;
8287 exps->reserve(sym->fields.dim);
8288 for (size_t i = 0; i < sym->fields.dim; i++)
8290 VarDeclaration *v = sym->fields[i];
8291 // Don't include hidden 'this' pointer
8292 if (v->isThisDeclaration())
8293 continue;
8294 Expression *ex;
8295 if (ev)
8296 ex = new DotVarExp(e->loc, ev, v);
8297 else
8299 ex = new VarExp(e->loc, v);
8300 ex->type = ex->type->addMod(e->type->mod);
8302 exps->push(ex);
8305 e = new TupleExp(e->loc, e0, exps);
8306 Scope *sc2 = sc->push();
8307 sc2->flags = sc->flags | SCOPEnoaccesscheck;
8308 e = ::semantic(e, sc2);
8309 sc2->pop();
8310 return e;
8313 s = searchSymClass(sc, sym, e, ident);
8315 if (!s)
8317 // See if it's 'this' class or a base class
8318 if (sym->ident == ident)
8320 if (e->op == TOKtype)
8321 return Type::getProperty(e->loc, ident, 0);
8322 e = new DotTypeExp(e->loc, e, sym);
8323 e = ::semantic(e, sc);
8324 return e;
8326 if (ClassDeclaration *cbase = sym->searchBase(ident))
8328 if (e->op == TOKtype)
8329 return Type::getProperty(e->loc, ident, 0);
8330 if (InterfaceDeclaration *ifbase = cbase->isInterfaceDeclaration())
8331 e = new CastExp(e->loc, e, ifbase->type);
8332 else
8333 e = new DotTypeExp(e->loc, e, cbase);
8334 e = ::semantic(e, sc);
8335 return e;
8338 if (ident == Id::classinfo)
8340 assert(Type::typeinfoclass);
8341 Type *t = Type::typeinfoclass->type;
8342 if (e->op == TOKtype || e->op == TOKdottype)
8344 /* For type.classinfo, we know the classinfo
8345 * at compile time.
8347 if (!sym->vclassinfo)
8348 sym->vclassinfo = new TypeInfoClassDeclaration(sym->type);
8349 e = new VarExp(e->loc, sym->vclassinfo);
8350 e = e->addressOf();
8351 e->type = t; // do this so we don't get redundant dereference
8353 else
8355 /* For class objects, the classinfo reference is the first
8356 * entry in the vtbl[]
8358 e = new PtrExp(e->loc, e);
8359 e->type = t->pointerTo();
8360 if (sym->isInterfaceDeclaration())
8362 if (sym->isCPPinterface())
8364 /* C++ interface vtbl[]s are different in that the
8365 * first entry is always pointer to the first virtual
8366 * function, not classinfo.
8367 * We can't get a .classinfo for it.
8369 error(e->loc, "no .classinfo for C++ interface objects");
8371 /* For an interface, the first entry in the vtbl[]
8372 * is actually a pointer to an instance of struct Interface.
8373 * The first member of Interface is the .classinfo,
8374 * so add an extra pointer indirection.
8376 e->type = e->type->pointerTo();
8377 e = new PtrExp(e->loc, e);
8378 e->type = t->pointerTo();
8380 e = new PtrExp(e->loc, e, t);
8382 return e;
8385 if (ident == Id::__vptr)
8387 /* The pointer to the vtbl[]
8388 * *cast(immutable(void*)**)e
8390 e = e->castTo(sc, tvoidptr->immutableOf()->pointerTo()->pointerTo());
8391 e = new PtrExp(e->loc, e);
8392 e = ::semantic(e, sc);
8393 return e;
8396 if (ident == Id::__monitor)
8398 /* The handle to the monitor (call it a void*)
8399 * *(cast(void**)e + 1)
8401 e = e->castTo(sc, tvoidptr->pointerTo());
8402 e = new AddExp(e->loc, e, new IntegerExp(1));
8403 e = new PtrExp(e->loc, e);
8404 e = ::semantic(e, sc);
8405 return e;
8408 if (ident == Id::outer && sym->vthis)
8410 if (sym->vthis->_scope)
8411 sym->vthis->semantic(NULL);
8413 if (ClassDeclaration *cdp = sym->toParent2()->isClassDeclaration())
8415 DotVarExp *dve = new DotVarExp(e->loc, e, sym->vthis);
8416 dve->type = cdp->type->addMod(e->type->mod);
8417 return dve;
8420 /* Bugzilla 15839: Find closest parent class through nested functions.
8422 for (Dsymbol *p = sym->toParent2(); p; p = p->toParent2())
8424 FuncDeclaration *fd = p->isFuncDeclaration();
8425 if (!fd)
8426 break;
8427 if (fd->isNested())
8428 continue;
8429 AggregateDeclaration *ad = fd->isThis();
8430 if (!ad)
8431 break;
8432 if (ad->isClassDeclaration())
8434 ThisExp *ve = new ThisExp(e->loc);
8436 ve->var = fd->vthis;
8437 const bool nestedError = fd->vthis->checkNestedReference(sc, e->loc);
8438 assert(!nestedError);
8440 ve->type = fd->vthis->type->addMod(e->type->mod);
8441 return ve;
8443 break;
8446 // Continue to show enclosing function's frame (stack or closure).
8447 DotVarExp *dve = new DotVarExp(e->loc, e, sym->vthis);
8448 dve->type = sym->vthis->type->addMod(e->type->mod);
8449 return dve;
8452 return noMember(sc, e, ident, flag & 1);
8454 if (!(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, s))
8456 ::deprecation(e->loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toPrettyChars());
8457 // return noMember(sc, e, ident, flag);
8459 if (!s->isFuncDeclaration()) // because of overloading
8460 s->checkDeprecated(e->loc, sc);
8461 s = s->toAlias();
8463 EnumMember *em = s->isEnumMember();
8464 if (em)
8466 return em->getVarExp(e->loc, sc);
8469 if (VarDeclaration *v = s->isVarDeclaration())
8471 if (!v->type ||
8472 (!v->type->deco && v->inuse))
8474 if (v->inuse) // Bugzilla 9494
8475 e->error("circular reference to %s '%s'", v->kind(), v->toPrettyChars());
8476 else
8477 e->error("forward reference to %s '%s'", v->kind(), v->toPrettyChars());
8478 return new ErrorExp();
8480 if (v->type->ty == Terror)
8481 return new ErrorExp();
8483 if ((v->storage_class & STCmanifest) && v->_init)
8485 if (v->inuse)
8487 e->error("circular initialization of %s '%s'", v->kind(), v->toPrettyChars());
8488 return new ErrorExp();
8490 checkAccess(e->loc, sc, NULL, v);
8491 Expression *ve = new VarExp(e->loc, v);
8492 ve = ::semantic(ve, sc);
8493 return ve;
8497 if (Type *t = s->getType())
8499 return ::semantic(new TypeExp(e->loc, t), sc);
8502 TemplateMixin *tm = s->isTemplateMixin();
8503 if (tm)
8505 Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, tm));
8506 de->type = e->type;
8507 return de;
8510 TemplateDeclaration *td = s->isTemplateDeclaration();
8511 if (td)
8513 if (e->op == TOKtype)
8514 e = new TemplateExp(e->loc, td);
8515 else
8516 e = new DotTemplateExp(e->loc, e, td);
8517 e = ::semantic(e, sc);
8518 return e;
8521 TemplateInstance *ti = s->isTemplateInstance();
8522 if (ti)
8524 if (!ti->semanticRun)
8526 ti->semantic(sc);
8527 if (!ti->inst || ti->errors) // if template failed to expand
8528 return new ErrorExp();
8530 s = ti->inst->toAlias();
8531 if (!s->isTemplateInstance())
8532 goto L1;
8533 if (e->op == TOKtype)
8534 e = new ScopeExp(e->loc, ti);
8535 else
8536 e = new DotExp(e->loc, e, new ScopeExp(e->loc, ti));
8537 return ::semantic(e, sc);
8540 if (s->isImport() || s->isModule() || s->isPackage())
8542 e = ::resolve(e->loc, sc, s, false);
8543 return e;
8546 OverloadSet *o = s->isOverloadSet();
8547 if (o)
8549 OverExp *oe = new OverExp(e->loc, o);
8550 if (e->op == TOKtype)
8551 return oe;
8552 return new DotExp(e->loc, e, oe);
8555 Declaration *d = s->isDeclaration();
8556 if (!d)
8558 e->error("%s.%s is not a declaration", e->toChars(), ident->toChars());
8559 return new ErrorExp();
8562 if (e->op == TOKtype)
8564 /* It's:
8565 * Class.d
8567 if (TupleDeclaration *tup = d->isTupleDeclaration())
8569 e = new TupleExp(e->loc, tup);
8570 e = ::semantic(e, sc);
8571 return e;
8573 if (d->needThis() && sc->intypeof != 1)
8575 /* Rewrite as:
8576 * this.d
8578 if (hasThis(sc))
8580 // This is almost same as getRightThis() in expression.c
8581 Expression *e1 = new ThisExp(e->loc);
8582 e1 = ::semantic(e1, sc);
8584 Type *t = e1->type->toBasetype();
8585 ClassDeclaration *cd = e->type->isClassHandle();
8586 ClassDeclaration *tcd = t->isClassHandle();
8587 if (cd && tcd && (tcd == cd || cd->isBaseOf(tcd, NULL)))
8589 e = new DotTypeExp(e1->loc, e1, cd);
8590 e = new DotVarExp(e->loc, e, d);
8591 e = ::semantic(e, sc);
8592 return e;
8594 if (tcd && tcd->isNested())
8595 { /* e1 is the 'this' pointer for an inner class: tcd.
8596 * Rewrite it as the 'this' pointer for the outer class.
8599 e1 = new DotVarExp(e->loc, e1, tcd->vthis);
8600 e1->type = tcd->vthis->type;
8601 e1->type = e1->type->addMod(t->mod);
8602 // Do not call checkNestedRef()
8603 //e1 = ::semantic(e1, sc);
8605 // Skip up over nested functions, and get the enclosing
8606 // class type.
8607 int n = 0;
8608 for (s = tcd->toParent();
8609 s && s->isFuncDeclaration();
8610 s = s->toParent())
8611 { FuncDeclaration *f = s->isFuncDeclaration();
8612 if (f->vthis)
8614 //printf("rewriting e1 to %s's this\n", f->toChars());
8615 n++;
8616 e1 = new VarExp(e->loc, f->vthis);
8618 else
8620 e = new VarExp(e->loc, d);
8621 return e;
8624 if (s && s->isClassDeclaration())
8625 { e1->type = s->isClassDeclaration()->type;
8626 e1->type = e1->type->addMod(t->mod);
8627 if (n > 1)
8628 e1 = ::semantic(e1, sc);
8630 else
8631 e1 = ::semantic(e1, sc);
8632 goto L2;
8636 //printf("e = %s, d = %s\n", e->toChars(), d->toChars());
8637 if (d->semanticRun == PASSinit && d->_scope)
8638 d->semantic(d->_scope);
8639 checkAccess(e->loc, sc, e, d);
8640 VarExp *ve = new VarExp(e->loc, d);
8641 if (d->isVarDeclaration() && d->needThis())
8642 ve->type = d->type->addMod(e->type->mod);
8643 return ve;
8646 bool unreal = e->op == TOKvar && ((VarExp *)e)->var->isField();
8647 if (d->isDataseg() || (unreal && d->isField()))
8649 // (e, d)
8650 checkAccess(e->loc, sc, e, d);
8651 Expression *ve = new VarExp(e->loc, d);
8652 e = unreal ? ve : new CommaExp(e->loc, e, ve);
8653 e = ::semantic(e, sc);
8654 return e;
8657 e = new DotVarExp(e->loc, e, d);
8658 e = ::semantic(e, sc);
8659 return e;
8662 ClassDeclaration *TypeClass::isClassHandle()
8664 return sym;
8667 bool TypeClass::isscope()
8669 return sym->isscope;
8672 bool TypeClass::isBaseOf(Type *t, int *poffset)
8674 if (t && t->ty == Tclass)
8676 ClassDeclaration *cd = ((TypeClass *)t)->sym;
8677 if (sym->isBaseOf(cd, poffset))
8678 return true;
8680 return false;
8683 MATCH TypeClass::implicitConvTo(Type *to)
8685 //printf("TypeClass::implicitConvTo(to = '%s') %s\n", to->toChars(), toChars());
8686 MATCH m = constConv(to);
8687 if (m > MATCHnomatch)
8688 return m;
8690 ClassDeclaration *cdto = to->isClassHandle();
8691 if (cdto)
8693 //printf("TypeClass::implicitConvTo(to = '%s') %s, isbase = %d %d\n", to->toChars(), toChars(), cdto->isBaseInfoComplete(), sym->isBaseInfoComplete());
8694 if (cdto->_scope && !cdto->isBaseInfoComplete())
8695 cdto->semantic(NULL);
8696 if (sym->_scope && !sym->isBaseInfoComplete())
8697 sym->semantic(NULL);
8698 if (cdto->isBaseOf(sym, NULL) && MODimplicitConv(mod, to->mod))
8700 //printf("'to' is base\n");
8701 return MATCHconvert;
8705 m = MATCHnomatch;
8706 if (sym->aliasthis && !(att & RECtracing))
8708 att = (AliasThisRec)(att | RECtracing);
8709 m = aliasthisOf()->implicitConvTo(to);
8710 att = (AliasThisRec)(att & ~RECtracing);
8713 return m;
8716 MATCH TypeClass::constConv(Type *to)
8718 if (equals(to))
8719 return MATCHexact;
8720 if (ty == to->ty && sym == ((TypeClass *)to)->sym &&
8721 MODimplicitConv(mod, to->mod))
8722 return MATCHconst;
8724 /* Conversion derived to const(base)
8726 int offset = 0;
8727 if (to->isBaseOf(this, &offset) && offset == 0 &&
8728 MODimplicitConv(mod, to->mod))
8730 // Disallow:
8731 // derived to base
8732 // inout(derived) to inout(base)
8733 if (!to->isMutable() && !to->isWild())
8734 return MATCHconvert;
8737 return MATCHnomatch;
8740 unsigned char TypeClass::deduceWild(Type *t, bool isRef)
8742 ClassDeclaration *cd = t->isClassHandle();
8743 if (cd && (sym == cd || cd->isBaseOf(sym, NULL)))
8744 return Type::deduceWild(t, isRef);
8746 unsigned char wm = 0;
8748 if (t->hasWild() && sym->aliasthis && !(att & RECtracing))
8750 att = (AliasThisRec)(att | RECtracing);
8751 wm = aliasthisOf()->deduceWild(t, isRef);
8752 att = (AliasThisRec)(att & ~RECtracing);
8755 return wm;
8758 Type *TypeClass::toHeadMutable()
8760 return this;
8763 Expression *TypeClass::defaultInit(Loc loc)
8765 return new NullExp(loc, this);
8768 bool TypeClass::isZeroInit(Loc)
8770 return true;
8773 bool TypeClass::isBoolean()
8775 return true;
8778 bool TypeClass::hasPointers()
8780 return true;
8783 /***************************** TypeTuple *****************************/
8785 TypeTuple::TypeTuple(Parameters *arguments)
8786 : Type(Ttuple)
8788 //printf("TypeTuple(this = %p)\n", this);
8789 this->arguments = arguments;
8790 //printf("TypeTuple() %p, %s\n", this, toChars());
8793 /****************
8794 * Form TypeTuple from the types of the expressions.
8795 * Assume exps[] is already tuple expanded.
8798 TypeTuple::TypeTuple(Expressions *exps)
8799 : Type(Ttuple)
8801 Parameters *arguments = new Parameters;
8802 if (exps)
8804 arguments->setDim(exps->dim);
8805 for (size_t i = 0; i < exps->dim; i++)
8806 { Expression *e = (*exps)[i];
8807 if (e->type->ty == Ttuple)
8808 e->error("cannot form tuple of tuples");
8809 Parameter *arg = new Parameter(STCundefined, e->type, NULL, NULL);
8810 (*arguments)[i] = arg;
8813 this->arguments = arguments;
8814 //printf("TypeTuple() %p, %s\n", this, toChars());
8817 TypeTuple *TypeTuple::create(Parameters *arguments)
8819 return new TypeTuple(arguments);
8822 /*******************************************
8823 * Type tuple with 0, 1 or 2 types in it.
8825 TypeTuple::TypeTuple()
8826 : Type(Ttuple)
8828 arguments = new Parameters();
8831 TypeTuple::TypeTuple(Type *t1)
8832 : Type(Ttuple)
8834 arguments = new Parameters();
8835 arguments->push(new Parameter(0, t1, NULL, NULL));
8838 TypeTuple::TypeTuple(Type *t1, Type *t2)
8839 : Type(Ttuple)
8841 arguments = new Parameters();
8842 arguments->push(new Parameter(0, t1, NULL, NULL));
8843 arguments->push(new Parameter(0, t2, NULL, NULL));
8846 const char *TypeTuple::kind()
8848 return "tuple";
8851 Type *TypeTuple::syntaxCopy()
8853 Parameters *args = Parameter::arraySyntaxCopy(arguments);
8854 Type *t = new TypeTuple(args);
8855 t->mod = mod;
8856 return t;
8859 Type *TypeTuple::semantic(Loc, Scope *)
8861 //printf("TypeTuple::semantic(this = %p)\n", this);
8862 //printf("TypeTuple::semantic() %p, %s\n", this, toChars());
8863 if (!deco)
8864 deco = merge()->deco;
8866 /* Don't return merge(), because a tuple with one type has the
8867 * same deco as that type.
8869 return this;
8872 bool TypeTuple::equals(RootObject *o)
8874 Type *t = (Type *)o;
8875 //printf("TypeTuple::equals(%s, %s)\n", toChars(), t->toChars());
8876 if (this == t)
8877 return true;
8878 if (t->ty == Ttuple)
8880 TypeTuple *tt = (TypeTuple *)t;
8881 if (arguments->dim == tt->arguments->dim)
8883 for (size_t i = 0; i < tt->arguments->dim; i++)
8885 Parameter *arg1 = (*arguments)[i];
8886 Parameter *arg2 = (*tt->arguments)[i];
8887 if (!arg1->type->equals(arg2->type))
8888 return false;
8890 return true;
8893 return false;
8896 Expression *TypeTuple::getProperty(Loc loc, Identifier *ident, int flag)
8898 Expression *e;
8900 if (ident == Id::length)
8902 e = new IntegerExp(loc, arguments->dim, Type::tsize_t);
8904 else if (ident == Id::_init)
8906 e = defaultInitLiteral(loc);
8908 else if (flag)
8910 e = NULL;
8912 else
8914 error(loc, "no property '%s' for tuple '%s'", ident->toChars(), toChars());
8915 e = new ErrorExp();
8917 return e;
8920 Expression *TypeTuple::defaultInit(Loc loc)
8922 Expressions *exps = new Expressions();
8923 exps->setDim(arguments->dim);
8924 for (size_t i = 0; i < arguments->dim; i++)
8926 Parameter *p = (*arguments)[i];
8927 assert(p->type);
8928 Expression *e = p->type->defaultInitLiteral(loc);
8929 if (e->op == TOKerror)
8930 return e;
8931 (*exps)[i] = e;
8933 return new TupleExp(loc, exps);
8936 /***************************** TypeSlice *****************************/
8938 /* This is so we can slice a TypeTuple */
8940 TypeSlice::TypeSlice(Type *next, Expression *lwr, Expression *upr)
8941 : TypeNext(Tslice, next)
8943 //printf("TypeSlice[%s .. %s]\n", lwr->toChars(), upr->toChars());
8944 this->lwr = lwr;
8945 this->upr = upr;
8948 const char *TypeSlice::kind()
8950 return "slice";
8953 Type *TypeSlice::syntaxCopy()
8955 Type *t = new TypeSlice(next->syntaxCopy(), lwr->syntaxCopy(), upr->syntaxCopy());
8956 t->mod = mod;
8957 return t;
8960 Type *TypeSlice::semantic(Loc loc, Scope *sc)
8962 //printf("TypeSlice::semantic() %s\n", toChars());
8963 Type *tn = next->semantic(loc, sc);
8964 //printf("next: %s\n", tn->toChars());
8966 Type *tbn = tn->toBasetype();
8967 if (tbn->ty != Ttuple)
8969 error(loc, "can only slice tuple types, not %s", tbn->toChars());
8970 return Type::terror;
8972 TypeTuple *tt = (TypeTuple *)tbn;
8974 lwr = semanticLength(sc, tbn, lwr);
8975 lwr = lwr->ctfeInterpret();
8976 uinteger_t i1 = lwr->toUInteger();
8978 upr = semanticLength(sc, tbn, upr);
8979 upr = upr->ctfeInterpret();
8980 uinteger_t i2 = upr->toUInteger();
8982 if (!(i1 <= i2 && i2 <= tt->arguments->dim))
8984 error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, tt->arguments->dim);
8985 return Type::terror;
8988 next = tn;
8989 transitive();
8991 Parameters *args = new Parameters;
8992 args->reserve((size_t)(i2 - i1));
8993 for (size_t i = (size_t)i1; i < (size_t)i2; i++)
8995 Parameter *arg = (*tt->arguments)[i];
8996 args->push(arg);
8998 Type *t = new TypeTuple(args);
8999 return t->semantic(loc, sc);
9002 void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
9004 next->resolve(loc, sc, pe, pt, ps, intypeid);
9005 if (*pe)
9007 // It's really a slice expression
9008 if (Dsymbol *s = getDsymbol(*pe))
9009 *pe = new DsymbolExp(loc, s);
9010 *pe = new ArrayExp(loc, *pe, new IntervalExp(loc, lwr, upr));
9012 else if (*ps)
9014 Dsymbol *s = *ps;
9015 TupleDeclaration *td = s->isTupleDeclaration();
9016 if (td)
9018 /* It's a slice of a TupleDeclaration
9020 ScopeDsymbol *sym = new ArrayScopeSymbol(sc, td);
9021 sym->parent = sc->scopesym;
9022 sc = sc->push(sym);
9023 sc = sc->startCTFE();
9024 lwr = ::semantic(lwr, sc);
9025 upr = ::semantic(upr, sc);
9026 sc = sc->endCTFE();
9027 sc = sc->pop();
9029 lwr = lwr->ctfeInterpret();
9030 upr = upr->ctfeInterpret();
9031 uinteger_t i1 = lwr->toUInteger();
9032 uinteger_t i2 = upr->toUInteger();
9034 if (!(i1 <= i2 && i2 <= td->objects->dim))
9036 error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, td->objects->dim);
9037 *ps = NULL;
9038 *pt = Type::terror;
9039 return;
9042 if (i1 == 0 && i2 == td->objects->dim)
9044 *ps = td;
9045 return;
9048 /* Create a new TupleDeclaration which
9049 * is a slice [i1..i2] out of the old one.
9051 Objects *objects = new Objects;
9052 objects->setDim((size_t)(i2 - i1));
9053 for (size_t i = 0; i < objects->dim; i++)
9055 (*objects)[i] = (*td->objects)[(size_t)i1 + i];
9058 TupleDeclaration *tds = new TupleDeclaration(loc, td->ident, objects);
9059 *ps = tds;
9061 else
9062 goto Ldefault;
9064 else
9066 if ((*pt)->ty != Terror)
9067 next = *pt; // prevent re-running semantic() on 'next'
9068 Ldefault:
9069 Type::resolve(loc, sc, pe, pt, ps, intypeid);
9073 /***************************** TypeNull *****************************/
9075 TypeNull::TypeNull()
9076 : Type(Tnull)
9080 const char *TypeNull::kind()
9082 return "null";
9085 Type *TypeNull::syntaxCopy()
9087 // No semantic analysis done, no need to copy
9088 return this;
9091 MATCH TypeNull::implicitConvTo(Type *to)
9093 //printf("TypeNull::implicitConvTo(this=%p, to=%p)\n", this, to);
9094 //printf("from: %s\n", toChars());
9095 //printf("to : %s\n", to->toChars());
9096 MATCH m = Type::implicitConvTo(to);
9097 if (m != MATCHnomatch)
9098 return m;
9100 // NULL implicitly converts to any pointer type or dynamic array
9101 //if (type->ty == Tpointer && type->nextOf()->ty == Tvoid)
9103 Type *tb = to->toBasetype();
9104 if (tb->ty == Tnull ||
9105 tb->ty == Tpointer || tb->ty == Tarray ||
9106 tb->ty == Taarray || tb->ty == Tclass ||
9107 tb->ty == Tdelegate)
9108 return MATCHconst;
9111 return MATCHnomatch;
9114 bool TypeNull::isBoolean()
9116 return true;
9119 d_uns64 TypeNull::size(Loc loc)
9121 return tvoidptr->size(loc);
9124 Expression *TypeNull::defaultInit(Loc)
9126 return new NullExp(Loc(), Type::tnull);
9129 /***************************** Parameter *****************************/
9131 Parameter::Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg)
9133 this->type = type;
9134 this->ident = ident;
9135 this->storageClass = storageClass;
9136 this->defaultArg = defaultArg;
9139 Parameter *Parameter::create(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg)
9141 return new Parameter(storageClass, type, ident, defaultArg);
9144 Parameter *Parameter::syntaxCopy()
9146 return new Parameter(storageClass,
9147 type ? type->syntaxCopy() : NULL,
9148 ident,
9149 defaultArg ? defaultArg->syntaxCopy() : NULL);
9152 Parameters *Parameter::arraySyntaxCopy(Parameters *parameters)
9154 Parameters *params = NULL;
9155 if (parameters)
9157 params = new Parameters();
9158 params->setDim(parameters->dim);
9159 for (size_t i = 0; i < params->dim; i++)
9160 (*params)[i] = (*parameters)[i]->syntaxCopy();
9162 return params;
9165 /****************************************************
9166 * Determine if parameter is a lazy array of delegates.
9167 * If so, return the return type of those delegates.
9168 * If not, return NULL.
9170 * Returns T if the type is one of the following forms:
9171 * T delegate()[]
9172 * T delegate()[dim]
9175 Type *Parameter::isLazyArray()
9177 Type *tb = type->toBasetype();
9178 if (tb->ty == Tsarray || tb->ty == Tarray)
9180 Type *tel = ((TypeArray *)tb)->next->toBasetype();
9181 if (tel->ty == Tdelegate)
9183 TypeDelegate *td = (TypeDelegate *)tel;
9184 TypeFunction *tf = (TypeFunction *)td->next;
9186 if (!tf->varargs && Parameter::dim(tf->parameters) == 0)
9188 return tf->next; // return type of delegate
9192 return NULL;
9195 /***************************************
9196 * Determine number of arguments, folding in tuples.
9199 static int dimDg(void *ctx, size_t, Parameter *)
9201 ++*(size_t *)ctx;
9202 return 0;
9205 size_t Parameter::dim(Parameters *parameters)
9207 size_t n = 0;
9208 Parameter_foreach(parameters, &dimDg, &n);
9209 return n;
9212 /***************************************
9213 * Get nth Parameter, folding in tuples.
9214 * Returns:
9215 * Parameter* nth Parameter
9216 * NULL not found, *pn gets incremented by the number
9217 * of Parameters
9220 struct GetNthParamCtx
9222 size_t nth;
9223 Parameter *param;
9226 static int getNthParamDg(void *ctx, size_t n, Parameter *p)
9228 GetNthParamCtx *c = (GetNthParamCtx *)ctx;
9229 if (n == c->nth)
9231 c->param = p;
9232 return 1;
9234 return 0;
9237 Parameter *Parameter::getNth(Parameters *parameters, size_t nth, size_t *)
9239 GetNthParamCtx ctx = { nth, NULL };
9240 int res = Parameter_foreach(parameters, &getNthParamDg, &ctx);
9241 return res ? ctx.param : NULL;
9244 /***************************************
9245 * Expands tuples in args in depth first order. Calls
9246 * dg(void *ctx, size_t argidx, Parameter *arg) for each Parameter.
9247 * If dg returns !=0, stops and returns that value else returns 0.
9248 * Use this function to avoid the O(N + N^2/2) complexity of
9249 * calculating dim and calling N times getNth.
9252 int Parameter_foreach(Parameters *parameters, ForeachDg dg, void *ctx, size_t *pn)
9254 assert(dg);
9255 if (!parameters)
9256 return 0;
9258 size_t n = pn ? *pn : 0; // take over index
9259 int result = 0;
9260 for (size_t i = 0; i < parameters->dim; i++)
9262 Parameter *p = (*parameters)[i];
9263 Type *t = p->type->toBasetype();
9265 if (t->ty == Ttuple)
9267 TypeTuple *tu = (TypeTuple *)t;
9268 result = Parameter_foreach(tu->arguments, dg, ctx, &n);
9270 else
9271 result = dg(ctx, n++, p);
9273 if (result)
9274 break;
9277 if (pn)
9278 *pn = n; // update index
9279 return result;
9283 const char *Parameter::toChars()
9285 return ident ? ident->toChars() : "__anonymous_param";
9288 /*********************************
9289 * Compute covariance of parameters `this` and `p`
9290 * as determined by the storage classes of both.
9291 * Params:
9292 * p = Parameter to compare with
9293 * Returns:
9294 * true = `this` can be used in place of `p`
9295 * false = nope
9297 bool Parameter::isCovariant(bool returnByRef, const Parameter *p) const
9299 const StorageClass stc = STCref | STCin | STCout | STClazy;
9300 if ((this->storageClass & stc) != (p->storageClass & stc))
9301 return false;
9303 return isCovariantScope(returnByRef, this->storageClass, p->storageClass);
9306 bool Parameter::isCovariantScope(bool returnByRef, StorageClass from, StorageClass to)
9308 if (from == to)
9309 return true;
9311 struct SR
9313 /* Classification of 'scope-return-ref' possibilities
9315 enum
9317 SRNone,
9318 SRScope,
9319 SRReturnScope,
9320 SRRef,
9321 SRReturnRef,
9322 SRRefScope,
9323 SRReturnRef_Scope,
9324 SRRef_ReturnScope,
9325 SRMAX,
9328 /* Shrinking the representation is necessary because StorageClass is so wide
9329 * Params:
9330 * returnByRef = true if the function returns by ref
9331 * stc = storage class of parameter
9333 static unsigned buildSR(bool returnByRef, StorageClass stc)
9335 unsigned result;
9336 StorageClass stc2 = stc & (STCref | STCscope | STCreturn);
9337 if (stc2 == 0)
9338 result = SRNone;
9339 else if (stc2 == STCref)
9340 result = SRRef;
9341 else if (stc2 == STCscope)
9342 result = SRScope;
9343 else if (stc2 == (STCscope | STCreturn))
9344 result = SRReturnScope;
9345 else if (stc2 == (STCref | STCreturn))
9346 result = SRReturnRef;
9347 else if (stc2 == (STCscope | STCref))
9348 result = SRRefScope;
9349 else if (stc2 == (STCscope | STCref | STCreturn))
9350 result = returnByRef ? SRReturnRef_Scope : SRRef_ReturnScope;
9351 else
9352 assert(0);
9353 return result;
9356 static void covariantInit(bool covariant[SRMAX][SRMAX])
9358 /* Initialize covariant[][] with this:
9360 From\To n rs s
9361 None X
9362 ReturnScope X X
9363 Scope X X X
9365 From\To r rr rs rr-s r-rs
9366 Ref X X
9367 ReturnRef X
9368 RefScope X X X X X
9369 ReturnRef-Scope X X
9370 Ref-ReturnScope X X X
9372 for (int i = 0; i < SRMAX; i++)
9374 covariant[i][i] = true;
9375 covariant[SRRefScope][i] = true;
9377 covariant[SRReturnScope][SRNone] = true;
9378 covariant[SRScope ][SRNone] = true;
9379 covariant[SRScope ][SRReturnScope] = true;
9381 covariant[SRRef ][SRReturnRef] = true;
9382 covariant[SRReturnRef_Scope][SRReturnRef] = true;
9383 covariant[SRRef_ReturnScope][SRRef ] = true;
9384 covariant[SRRef_ReturnScope][SRReturnRef] = true;
9388 /* result is true if the 'from' can be used as a 'to'
9391 if ((from ^ to) & STCref) // differing in 'ref' means no covariance
9392 return false;
9394 static bool covariant[SR::SRMAX][SR::SRMAX];
9395 static bool init = false;
9396 if (!init)
9398 SR::covariantInit(covariant);
9399 init = true;
9402 return covariant[SR::buildSR(returnByRef, from)][SR::buildSR(returnByRef, to)];