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