]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/dmd/mtype.c
PR d/90660
[thirdparty/gcc.git] / gcc / d / dmd / mtype.c
1
2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/mtype.c
9 */
10
11 #include "root/dsystem.h"
12 #include "root/checkedint.h"
13 #include "root/rmem.h"
14
15 #include "mars.h"
16 #include "mangle.h"
17 #include "dsymbol.h"
18 #include "mtype.h"
19 #include "scope.h"
20 #include "init.h"
21 #include "expression.h"
22 #include "statement.h"
23 #include "attrib.h"
24 #include "declaration.h"
25 #include "template.h"
26 #include "id.h"
27 #include "enum.h"
28 #include "module.h"
29 #include "import.h"
30 #include "aggregate.h"
31 #include "hdrgen.h"
32 #include "target.h"
33
34 bool symbolIsVisible(Scope *sc, Dsymbol *s);
35 typedef int (*ForeachDg)(void *ctx, size_t paramidx, Parameter *param);
36 int Parameter_foreach(Parameters *parameters, ForeachDg dg, void *ctx, size_t *pn = NULL);
37 FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL);
38 Expression *extractSideEffect(Scope *sc, const char *name, Expression **e0, Expression *e, bool alwaysCopy = false);
39 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads);
40 Expression *semantic(Expression *e, Scope *sc);
41 Expression *semanticY(DotIdExp *exp, Scope *sc, int flag);
42 Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag);
43 Expression *typeToExpression(Type *t);
44 Expression *typeToExpressionHelper(TypeQualified *t, Expression *e, size_t i = 0);
45 Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret);
46
47 int Tsize_t = Tuns32;
48 int Tptrdiff_t = Tint32;
49
50 /***************************** Type *****************************/
51
52 ClassDeclaration *Type::dtypeinfo;
53 ClassDeclaration *Type::typeinfoclass;
54 ClassDeclaration *Type::typeinfointerface;
55 ClassDeclaration *Type::typeinfostruct;
56 ClassDeclaration *Type::typeinfopointer;
57 ClassDeclaration *Type::typeinfoarray;
58 ClassDeclaration *Type::typeinfostaticarray;
59 ClassDeclaration *Type::typeinfoassociativearray;
60 ClassDeclaration *Type::typeinfovector;
61 ClassDeclaration *Type::typeinfoenum;
62 ClassDeclaration *Type::typeinfofunction;
63 ClassDeclaration *Type::typeinfodelegate;
64 ClassDeclaration *Type::typeinfotypelist;
65 ClassDeclaration *Type::typeinfoconst;
66 ClassDeclaration *Type::typeinfoinvariant;
67 ClassDeclaration *Type::typeinfoshared;
68 ClassDeclaration *Type::typeinfowild;
69
70 TemplateDeclaration *Type::rtinfo;
71
72 Type *Type::tvoid;
73 Type *Type::tint8;
74 Type *Type::tuns8;
75 Type *Type::tint16;
76 Type *Type::tuns16;
77 Type *Type::tint32;
78 Type *Type::tuns32;
79 Type *Type::tint64;
80 Type *Type::tuns64;
81 Type *Type::tint128;
82 Type *Type::tuns128;
83 Type *Type::tfloat32;
84 Type *Type::tfloat64;
85 Type *Type::tfloat80;
86
87 Type *Type::timaginary32;
88 Type *Type::timaginary64;
89 Type *Type::timaginary80;
90
91 Type *Type::tcomplex32;
92 Type *Type::tcomplex64;
93 Type *Type::tcomplex80;
94
95 Type *Type::tbool;
96 Type *Type::tchar;
97 Type *Type::twchar;
98 Type *Type::tdchar;
99
100 Type *Type::tshiftcnt;
101 Type *Type::terror;
102 Type *Type::tnull;
103
104 Type *Type::tsize_t;
105 Type *Type::tptrdiff_t;
106 Type *Type::thash_t;
107
108 Type *Type::tvoidptr;
109 Type *Type::tstring;
110 Type *Type::twstring;
111 Type *Type::tdstring;
112 Type *Type::tvalist;
113 Type *Type::basic[TMAX];
114 unsigned char Type::sizeTy[TMAX];
115 StringTable Type::stringtable;
116
117 void initTypeMangle();
118
119 Type::Type(TY ty)
120 {
121 this->ty = ty;
122 this->mod = 0;
123 this->deco = NULL;
124 this->cto = NULL;
125 this->ito = NULL;
126 this->sto = NULL;
127 this->scto = NULL;
128 this->wto = NULL;
129 this->wcto = NULL;
130 this->swto = NULL;
131 this->swcto = NULL;
132 this->pto = NULL;
133 this->rto = NULL;
134 this->arrayof = NULL;
135 this->vtinfo = NULL;
136 this->ctype = NULL;
137 }
138
139 const char *Type::kind()
140 {
141 assert(false); // should be overridden
142 return NULL;
143 }
144
145 Type *Type::copy()
146 {
147 void *pt = mem.xmalloc(sizeTy[ty]);
148 Type *t = (Type *)memcpy(pt, (void *)this, sizeTy[ty]);
149 return t;
150 }
151
152 Type *Type::syntaxCopy()
153 {
154 print();
155 fprintf(stderr, "ty = %d\n", ty);
156 assert(0);
157 return this;
158 }
159
160 bool Type::equals(RootObject *o)
161 {
162 Type *t = (Type *)o;
163 //printf("Type::equals(%s, %s)\n", toChars(), t->toChars());
164 // deco strings are unique
165 // and semantic() has been run
166 if (this == o || ((t && deco == t->deco) && deco != NULL))
167 {
168 //printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
169 return true;
170 }
171 //if (deco && t && t->deco) printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
172 return false;
173 }
174
175 bool Type::equivalent(Type *t)
176 {
177 return immutableOf()->equals(t->immutableOf());
178 }
179
180 void Type::_init()
181 {
182 stringtable._init(14000);
183
184 for (size_t i = 0; i < TMAX; i++)
185 sizeTy[i] = sizeof(TypeBasic);
186 sizeTy[Tsarray] = sizeof(TypeSArray);
187 sizeTy[Tarray] = sizeof(TypeDArray);
188 sizeTy[Taarray] = sizeof(TypeAArray);
189 sizeTy[Tpointer] = sizeof(TypePointer);
190 sizeTy[Treference] = sizeof(TypeReference);
191 sizeTy[Tfunction] = sizeof(TypeFunction);
192 sizeTy[Tdelegate] = sizeof(TypeDelegate);
193 sizeTy[Tident] = sizeof(TypeIdentifier);
194 sizeTy[Tinstance] = sizeof(TypeInstance);
195 sizeTy[Ttypeof] = sizeof(TypeTypeof);
196 sizeTy[Tenum] = sizeof(TypeEnum);
197 sizeTy[Tstruct] = sizeof(TypeStruct);
198 sizeTy[Tclass] = sizeof(TypeClass);
199 sizeTy[Ttuple] = sizeof(TypeTuple);
200 sizeTy[Tslice] = sizeof(TypeSlice);
201 sizeTy[Treturn] = sizeof(TypeReturn);
202 sizeTy[Terror] = sizeof(TypeError);
203 sizeTy[Tnull] = sizeof(TypeNull);
204 sizeTy[Tvector] = sizeof(TypeVector);
205
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
282 d_uns64 Type::size()
283 {
284 return size(Loc());
285 }
286
287 d_uns64 Type::size(Loc loc)
288 {
289 error(loc, "no size for type %s", toChars());
290 return SIZE_INVALID;
291 }
292
293 unsigned Type::alignsize()
294 {
295 return (unsigned)size(Loc());
296 }
297
298 Type *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
309 Type *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
327 Type *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
355 Type *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
376 Type *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
397 Type *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
444 Type *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
461 Type *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
492 Type *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
535 Type *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
552 Type *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
569 Type *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
586 Type *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
608 void 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
697 void 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
829 Type *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
839 Type *Type::makeImmutable()
840 {
841 if (ito) return ito;
842 Type *t = this->nullAttributes();
843 t->mod = MODimmutable;
844 return t;
845 }
846
847 Type *Type::makeShared()
848 {
849 if (sto) return sto;
850 Type *t = this->nullAttributes();
851 t->mod = MODshared;
852 return t;
853 }
854
855 Type *Type::makeSharedConst()
856 {
857 if (scto) return scto;
858 Type *t = this->nullAttributes();
859 t->mod = MODshared | MODconst;
860 return t;
861 }
862
863 Type *Type::makeWild()
864 {
865 if (wto) return wto;
866 Type *t = this->nullAttributes();
867 t->mod = MODwild;
868 return t;
869 }
870
871 Type *Type::makeWildConst()
872 {
873 if (wcto) return wcto;
874 Type *t = this->nullAttributes();
875 t->mod = MODwildconst;
876 return t;
877 }
878
879 Type *Type::makeSharedWild()
880 {
881 if (swto) return swto;
882 Type *t = this->nullAttributes();
883 t->mod = MODshared | MODwild;
884 return t;
885 }
886
887 Type *Type::makeSharedWildConst()
888 {
889 if (swcto) return swcto;
890 Type *t = this->nullAttributes();
891 t->mod = MODshared | MODwildconst;
892 return t;
893 }
894
895 Type *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
907 Type *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
977 StorageClass 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
991 Type *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
1044 Type *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
1148 Type *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
1168 Type *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
1186 Type *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
1198 Type *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
1211 Type *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
1223 Type *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
1286 bool 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
1307 Dsymbol *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
1317 Type *Type::toBasetype()
1318 {
1319 return this;
1320 }
1321
1322 /***************************
1323 * Return !=0 if modfrom can be implicitly converted to modto
1324 */
1325 bool 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 */
1353 MATCH 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 */
1382 MOD 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 */
1416 void 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 */
1466 char *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
1478 const 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
1489 char *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 */
1503 void 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 */
1515 char *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
1524 void* for the work param and a string representation of the attribute. */
1525 int 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
1546 Type *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());
1616 Lnot:
1617 return t;
1618 }
1619
1620 /************************************
1621 */
1622
1623 Type *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 */
1665 Type *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
1683 bool Type::isintegral()
1684 {
1685 return false;
1686 }
1687
1688 bool Type::isfloating()
1689 {
1690 return false;
1691 }
1692
1693 bool Type::isreal()
1694 {
1695 return false;
1696 }
1697
1698 bool Type::isimaginary()
1699 {
1700 return false;
1701 }
1702
1703 bool Type::iscomplex()
1704 {
1705 return false;
1706 }
1707
1708 bool Type::isscalar()
1709 {
1710 return false;
1711 }
1712
1713 bool Type::isunsigned()
1714 {
1715 return false;
1716 }
1717
1718 ClassDeclaration *Type::isClassHandle()
1719 {
1720 return NULL;
1721 }
1722
1723 bool Type::isscope()
1724 {
1725 return false;
1726 }
1727
1728 bool 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 */
1741 bool Type::isAssignable()
1742 {
1743 return true;
1744 }
1745
1746 /**************************
1747 * Returns true if T can be converted to boolean value.
1748 */
1749 bool 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 */
1758 bool Type::needsDestruction()
1759 {
1760 return false;
1761 }
1762
1763 /*********************************
1764 *
1765 */
1766
1767 bool Type::needsNested()
1768 {
1769 return false;
1770 }
1771
1772 /*********************************
1773 * Check type to see if it is based on a deprecated symbol.
1774 */
1775
1776 void Type::checkDeprecated(Loc loc, Scope *sc)
1777 {
1778 Dsymbol *s = toDsymbol(sc);
1779
1780 if (s)
1781 s->checkDeprecated(loc, sc);
1782 }
1783
1784
1785 Expression *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 */
1794 Expression *Type::defaultInitLiteral(Loc loc)
1795 {
1796 return defaultInit(loc);
1797 }
1798
1799 bool Type::isZeroInit(Loc)
1800 {
1801 return false; // assume not
1802 }
1803
1804 bool 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
1816 MATCH 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
1835 MATCH 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
1849 unsigned 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
1876 Type *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
1907 Type *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
1950 L1:
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
1989 Type *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 */
2037 Type *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 */
2049 Expression *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 */
2123 Expression *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
2177 Lreturn:
2178 if (e)
2179 e = ::semantic(e, sc);
2180 return e;
2181 }
2182
2183 /************************************
2184 * Return alignment to use for this type.
2185 */
2186
2187 structalign_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 */
2198 Expression *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
2296 void 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
2304 void 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
2312 Identifier *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;
2325 char *name = namelen <= sizeof(namebuf) ? namebuf : (char *)mem.xmalloc(namelen);
2326
2327 int length = sprintf(name, "_D%lluTypeInfo_%s6__initZ", (unsigned long long) 9 + len, buf.data);
2328 //printf("%p, deco = %s, name = %s\n", this, deco, name);
2329 assert(0 < length && (size_t)length < namelen); // don't overflow the buffer
2330
2331 Identifier *id = Identifier::idPool(name, length);
2332
2333 if (name != namebuf)
2334 free(name);
2335 return id;
2336 }
2337
2338 TypeBasic *Type::isTypeBasic()
2339 {
2340 return NULL;
2341 }
2342
2343 TypeFunction *Type::toTypeFunction()
2344 {
2345 if (ty != Tfunction)
2346 assert(0);
2347 return (TypeFunction *)this;
2348 }
2349
2350 /***************************************
2351 * Resolve 'this' type to either type, symbol, or expression.
2352 * If errors happened, resolved to Type.terror.
2353 */
2354 void 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 */
2366 void 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
2431 int 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 */
2440 bool 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 */
2453 bool Type::hasVoidInitPointers()
2454 {
2455 return false;
2456 }
2457
2458 /*************************************
2459 * If this is a type of something, return that something.
2460 */
2461
2462 Type *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
2471 Type *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
2484 void 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 */
2524 uinteger_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
2549 TypeError::TypeError()
2550 : Type(Terror)
2551 {
2552 }
2553
2554 Type *TypeError::syntaxCopy()
2555 {
2556 // No semantic analysis done, no need to copy
2557 return this;
2558 }
2559
2560 d_uns64 TypeError::size(Loc) { return SIZE_INVALID; }
2561 Expression *TypeError::getProperty(Loc, Identifier *, int) { return new ErrorExp(); }
2562 Expression *TypeError::dotExp(Scope *, Expression *, Identifier *, int) { return new ErrorExp(); }
2563 Expression *TypeError::defaultInit(Loc) { return new ErrorExp(); }
2564 Expression *TypeError::defaultInitLiteral(Loc) { return new ErrorExp(); }
2565
2566 /* ============================= TypeNext =========================== */
2567
2568 TypeNext::TypeNext(TY ty, Type *next)
2569 : Type(ty)
2570 {
2571 this->next = next;
2572 }
2573
2574 void 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
2581 int 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
2597 Type *TypeNext::nextOf()
2598 {
2599 return next;
2600 }
2601
2602 Type *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
2633 Type *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
2650 Type *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
2681 Type *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
2702 Type *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
2733 Type *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
2754 Type *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
2775 Type *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
2793 Type *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
2805 MATCH 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
2832 unsigned 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
2857 void 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
2873 TypeBasic::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
2983 const char *TypeBasic::kind()
2984 {
2985 return dstring;
2986 }
2987
2988 Type *TypeBasic::syntaxCopy()
2989 {
2990 // No semantic analysis done on basic types, no need to copy
2991 return this;
2992 }
2993
2994 d_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
3044 unsigned TypeBasic::alignsize()
3045 {
3046 return Target::alignsize(this);
3047 }
3048
3049
3050 Expression *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
3373 Livalue:
3374 e = new IntegerExp(loc, ivalue, this);
3375 return e;
3376
3377 Lfvalue:
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
3390 Lint:
3391 e = new IntegerExp(loc, ivalue, Type::tint32);
3392 return e;
3393 }
3394
3395 Expression *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
3468 Expression *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
3506 bool 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
3528 bool TypeBasic::isintegral()
3529 {
3530 //printf("TypeBasic::isintegral('%s') x%x\n", toChars(), flags);
3531 return (flags & TFLAGSintegral) != 0;
3532 }
3533
3534 bool TypeBasic::isfloating()
3535 {
3536 return (flags & TFLAGSfloating) != 0;
3537 }
3538
3539 bool TypeBasic::isreal()
3540 {
3541 return (flags & TFLAGSreal) != 0;
3542 }
3543
3544 bool TypeBasic::isimaginary()
3545 {
3546 return (flags & TFLAGSimaginary) != 0;
3547 }
3548
3549 bool TypeBasic::iscomplex()
3550 {
3551 return (flags & TFLAGScomplex) != 0;
3552 }
3553
3554 bool TypeBasic::isunsigned()
3555 {
3556 return (flags & TFLAGSunsigned) != 0;
3557 }
3558
3559 bool TypeBasic::isscalar()
3560 {
3561 return (flags & (TFLAGSintegral | TFLAGSfloating)) != 0;
3562 }
3563
3564 MATCH 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
3658 TypeBasic *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 */
3670 TypeVector::TypeVector(Type *basetype)
3671 : Type(Tvector)
3672 {
3673 this->basetype = basetype;
3674 }
3675
3676 TypeVector *TypeVector::create(Loc, Type *basetype)
3677 {
3678 return new TypeVector(basetype);
3679 }
3680
3681 const char *TypeVector::kind()
3682 {
3683 return "vector";
3684 }
3685
3686 Type *TypeVector::syntaxCopy()
3687 {
3688 return new TypeVector(basetype->syntaxCopy());
3689 }
3690
3691 Type *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
3724 TypeBasic *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
3733 bool TypeVector::isBoolean()
3734 {
3735 return false;
3736 }
3737
3738 d_uns64 TypeVector::size(Loc)
3739 {
3740 return basetype->size();
3741 }
3742
3743 unsigned TypeVector::alignsize()
3744 {
3745 return (unsigned)basetype->size();
3746 }
3747
3748 Expression *TypeVector::getProperty(Loc loc, Identifier *ident, int flag)
3749 {
3750 return Type::getProperty(loc, ident, flag);
3751 }
3752
3753 Expression *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
3769 e = new VectorArrayExp(e->loc, e);
3770 e = ::semantic(e, sc);
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
3783 Expression *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
3794 Expression *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
3805 bool TypeVector::isZeroInit(Loc loc)
3806 {
3807 return basetype->isZeroInit(loc);
3808 }
3809
3810 bool TypeVector::isintegral()
3811 {
3812 //printf("TypeVector::isintegral('%s') x%x\n", toChars(), flags);
3813 return basetype->nextOf()->isintegral();
3814 }
3815
3816 bool TypeVector::isfloating()
3817 {
3818 return basetype->nextOf()->isfloating();
3819 }
3820
3821 bool TypeVector::isunsigned()
3822 {
3823 return basetype->nextOf()->isunsigned();
3824 }
3825
3826 bool TypeVector::isscalar()
3827 {
3828 return basetype->nextOf()->isscalar();
3829 }
3830
3831 MATCH TypeVector::implicitConvTo(Type *to)
3832 {
3833 //printf("TypeVector::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
3834 if (this == to)
3835 return MATCHexact;
3836 #ifdef IN_GCC
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 }
3853 #else
3854 if (ty == to->ty)
3855 return MATCHconvert;
3856 #endif
3857 return MATCHnomatch;
3858 }
3859
3860 /***************************** TypeArray *****************************/
3861
3862 TypeArray::TypeArray(TY ty, Type *next)
3863 : TypeNext(ty, next)
3864 {
3865 }
3866
3867 Expression *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
3879 TypeSArray::TypeSArray(Type *t, Expression *dim)
3880 : TypeArray(Tsarray, t)
3881 {
3882 //printf("TypeSArray(%s)\n", dim->toChars());
3883 this->dim = dim;
3884 }
3885
3886 const char *TypeSArray::kind()
3887 {
3888 return "sarray";
3889 }
3890
3891 Type *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
3900 d_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
3919 Loverflow:
3920 error(loc, "static array %s size overflowed to %lld", toChars(), (long long)sz);
3921 return SIZE_INVALID;
3922 }
3923
3924 unsigned 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 */
3933 Expression *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
3957 Expression *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
3971 void 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
4059 Type *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 }
4137 else if (tbn->isintegral() ||
4138 tbn->isfloating() ||
4139 tbn->ty == Tpointer ||
4140 tbn->ty == Tarray ||
4141 tbn->ty == Tsarray ||
4142 tbn->ty == Taarray ||
4143 (tbn->ty == Tstruct && (((TypeStruct *)tbn)->sym->sizeok == SIZEOKdone)) ||
4144 tbn->ty == Tclass)
4145 {
4146 /* Only do this for types that don't need to have semantic()
4147 * run on them for the size, since they may be forward referenced.
4148 */
4149 bool overflow = false;
4150 if (mulu(tbn->size(loc), d2, overflow) >= Target::maxStaticDataSize || overflow)
4151 goto Loverflow;
4152 }
4153 }
4154 switch (tbn->ty)
4155 {
4156 case Ttuple:
4157 { // Index the tuple to get the type
4158 assert(dim);
4159 TypeTuple *tt = (TypeTuple *)tbn;
4160 uinteger_t d = dim->toUInteger();
4161
4162 if (d >= tt->arguments->dim)
4163 { error(loc, "tuple index %llu exceeds %u", d, tt->arguments->dim);
4164 goto Lerror;
4165 }
4166 Type *telem = (*tt->arguments)[(size_t)d]->type;
4167 return telem->addMod(this->mod);
4168 }
4169 case Tfunction:
4170 case Tnone:
4171 error(loc, "can't have array of %s", tbn->toChars());
4172 goto Lerror;
4173 default:
4174 break;
4175 }
4176 if (tbn->isscope())
4177 { error(loc, "cannot have array of scope %s", tbn->toChars());
4178 goto Lerror;
4179 }
4180
4181 /* Ensure things like const(immutable(T)[3]) become immutable(T[3])
4182 * and const(T)[3] become const(T[3])
4183 */
4184 next = tn;
4185 transitive();
4186 t = addMod(tn->mod);
4187
4188 return t->merge();
4189
4190 Lerror:
4191 return Type::terror;
4192 }
4193
4194 Expression *TypeSArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
4195 {
4196 if (ident == Id::length)
4197 {
4198 Loc oldLoc = e->loc;
4199 e = dim->copy();
4200 e->loc = oldLoc;
4201 }
4202 else if (ident == Id::ptr)
4203 {
4204 if (e->op == TOKtype)
4205 {
4206 e->error("%s is not an expression", e->toChars());
4207 return new ErrorExp();
4208 }
4209 else if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
4210 {
4211 e->deprecation("%s.ptr cannot be used in @safe code, use &%s[0] instead", e->toChars(), e->toChars());
4212 // return new ErrorExp();
4213 }
4214 e = e->castTo(sc, e->type->nextOf()->pointerTo());
4215 }
4216 else
4217 {
4218 e = TypeArray::dotExp(sc, e, ident, flag);
4219 }
4220 if (!(flag & 1) || e)
4221 e = ::semantic(e, sc);
4222 return e;
4223 }
4224
4225 structalign_t TypeSArray::alignment()
4226 {
4227 return next->alignment();
4228 }
4229
4230 bool TypeSArray::isString()
4231 {
4232 TY nty = next->toBasetype()->ty;
4233 return nty == Tchar || nty == Twchar || nty == Tdchar;
4234 }
4235
4236 MATCH TypeSArray::constConv(Type *to)
4237 {
4238 if (to->ty == Tsarray)
4239 {
4240 TypeSArray *tsa = (TypeSArray *)to;
4241 if (!dim->equals(tsa->dim))
4242 return MATCHnomatch;
4243 }
4244 return TypeNext::constConv(to);
4245 }
4246
4247 MATCH TypeSArray::implicitConvTo(Type *to)
4248 {
4249 //printf("TypeSArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4250
4251 if (to->ty == Tarray)
4252 {
4253 TypeDArray *ta = (TypeDArray *)to;
4254
4255 if (!MODimplicitConv(next->mod, ta->next->mod))
4256 return MATCHnomatch;
4257
4258 /* Allow conversion to void[]
4259 */
4260 if (ta->next->ty == Tvoid)
4261 {
4262 return MATCHconvert;
4263 }
4264
4265 MATCH m = next->constConv(ta->next);
4266 if (m > MATCHnomatch)
4267 {
4268 return MATCHconvert;
4269 }
4270 return MATCHnomatch;
4271 }
4272
4273 if (to->ty == Tsarray)
4274 {
4275 if (this == to)
4276 return MATCHexact;
4277
4278 TypeSArray *tsa = (TypeSArray *)to;
4279
4280 if (dim->equals(tsa->dim))
4281 {
4282 /* Since static arrays are value types, allow
4283 * conversions from const elements to non-const
4284 * ones, just like we allow conversion from const int
4285 * to int.
4286 */
4287 MATCH m = next->implicitConvTo(tsa->next);
4288 if (m >= MATCHconst)
4289 {
4290 if (mod != to->mod)
4291 m = MATCHconst;
4292 return m;
4293 }
4294 }
4295 }
4296 return MATCHnomatch;
4297 }
4298
4299 Expression *TypeSArray::defaultInit(Loc loc)
4300 {
4301 if (next->ty == Tvoid)
4302 return tuns8->defaultInit(loc);
4303 else
4304 return next->defaultInit(loc);
4305 }
4306
4307 bool TypeSArray::isZeroInit(Loc loc)
4308 {
4309 return next->isZeroInit(loc);
4310 }
4311
4312 bool TypeSArray::needsDestruction()
4313 {
4314 return next->needsDestruction();
4315 }
4316
4317 /*********************************
4318 *
4319 */
4320
4321 bool TypeSArray::needsNested()
4322 {
4323 return next->needsNested();
4324 }
4325
4326 Expression *TypeSArray::defaultInitLiteral(Loc loc)
4327 {
4328 size_t d = (size_t)dim->toInteger();
4329 Expression *elementinit;
4330 if (next->ty == Tvoid)
4331 elementinit = tuns8->defaultInitLiteral(loc);
4332 else
4333 elementinit = next->defaultInitLiteral(loc);
4334 Expressions *elements = new Expressions();
4335 elements->setDim(d);
4336 for (size_t i = 0; i < d; i++)
4337 (*elements)[i] = NULL;
4338 ArrayLiteralExp *ae = new ArrayLiteralExp(Loc(), this, elementinit, elements);
4339 return ae;
4340 }
4341
4342 bool TypeSArray::hasPointers()
4343 {
4344 /* Don't want to do this, because:
4345 * struct S { T* array[0]; }
4346 * may be a variable length struct.
4347 */
4348 //if (dim->toInteger() == 0)
4349 // return false;
4350
4351 if (next->ty == Tvoid)
4352 {
4353 // Arrays of void contain arbitrary data, which may include pointers
4354 return true;
4355 }
4356 else
4357 return next->hasPointers();
4358 }
4359
4360 /***************************** TypeDArray *****************************/
4361
4362 TypeDArray::TypeDArray(Type *t)
4363 : TypeArray(Tarray, t)
4364 {
4365 //printf("TypeDArray(t = %p)\n", t);
4366 }
4367
4368 const char *TypeDArray::kind()
4369 {
4370 return "darray";
4371 }
4372
4373 Type *TypeDArray::syntaxCopy()
4374 {
4375 Type *t = next->syntaxCopy();
4376 if (t == next)
4377 t = this;
4378 else
4379 {
4380 t = new TypeDArray(t);
4381 t->mod = mod;
4382 }
4383 return t;
4384 }
4385
4386 d_uns64 TypeDArray::size(Loc)
4387 {
4388 //printf("TypeDArray::size()\n");
4389 return Target::ptrsize * 2;
4390 }
4391
4392 unsigned TypeDArray::alignsize()
4393 {
4394 // A DArray consists of two ptr-sized values, so align it on pointer size
4395 // boundary
4396 return Target::ptrsize;
4397 }
4398
4399 Type *TypeDArray::semantic(Loc loc, Scope *sc)
4400 {
4401 Type *tn = next->semantic(loc,sc);
4402 Type *tbn = tn->toBasetype();
4403 switch (tbn->ty)
4404 {
4405 case Ttuple:
4406 return tbn;
4407 case Tfunction:
4408 case Tnone:
4409 error(loc, "can't have array of %s", tbn->toChars());
4410 return Type::terror;
4411 case Terror:
4412 return Type::terror;
4413 default:
4414 break;
4415 }
4416 if (tn->isscope())
4417 { error(loc, "cannot have array of scope %s", tn->toChars());
4418 return Type::terror;
4419 }
4420 next = tn;
4421 transitive();
4422 return merge();
4423 }
4424
4425 void TypeDArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
4426 {
4427 //printf("TypeDArray::resolve() %s\n", toChars());
4428 next->resolve(loc, sc, pe, pt, ps, intypeid);
4429 //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
4430 if (*pe)
4431 {
4432 // It's really a slice expression
4433 if (Dsymbol *s = getDsymbol(*pe))
4434 *pe = new DsymbolExp(loc, s);
4435 *pe = new ArrayExp(loc, *pe);
4436 }
4437 else if (*ps)
4438 {
4439 TupleDeclaration *td = (*ps)->isTupleDeclaration();
4440 if (td)
4441 ; // keep *ps
4442 else
4443 goto Ldefault;
4444 }
4445 else
4446 {
4447 if ((*pt)->ty != Terror)
4448 next = *pt; // prevent re-running semantic() on 'next'
4449 Ldefault:
4450 Type::resolve(loc, sc, pe, pt, ps, intypeid);
4451 }
4452 }
4453
4454 Expression *TypeDArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
4455 {
4456 if (e->op == TOKtype &&
4457 (ident == Id::length || ident == Id::ptr))
4458 {
4459 e->error("%s is not an expression", e->toChars());
4460 return new ErrorExp();
4461 }
4462 if (ident == Id::length)
4463 {
4464 if (e->op == TOKstring)
4465 {
4466 StringExp *se = (StringExp *)e;
4467 return new IntegerExp(se->loc, se->len, Type::tsize_t);
4468 }
4469 if (e->op == TOKnull)
4470 return new IntegerExp(e->loc, 0, Type::tsize_t);
4471 e = new ArrayLengthExp(e->loc, e);
4472 e->type = Type::tsize_t;
4473 return e;
4474 }
4475 else if (ident == Id::ptr)
4476 {
4477 if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
4478 {
4479 e->deprecation("%s.ptr cannot be used in @safe code, use &%s[0] instead", e->toChars(), e->toChars());
4480 // return new ErrorExp();
4481 }
4482 e = e->castTo(sc, next->pointerTo());
4483 return e;
4484 }
4485 else
4486 {
4487 e = TypeArray::dotExp(sc, e, ident, flag);
4488 }
4489 return e;
4490 }
4491
4492 bool TypeDArray::isString()
4493 {
4494 TY nty = next->toBasetype()->ty;
4495 return nty == Tchar || nty == Twchar || nty == Tdchar;
4496 }
4497
4498 MATCH TypeDArray::implicitConvTo(Type *to)
4499 {
4500 //printf("TypeDArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4501 if (equals(to))
4502 return MATCHexact;
4503
4504 if (to->ty == Tarray)
4505 {
4506 TypeDArray *ta = (TypeDArray *)to;
4507
4508 if (!MODimplicitConv(next->mod, ta->next->mod))
4509 return MATCHnomatch; // not const-compatible
4510
4511 /* Allow conversion to void[]
4512 */
4513 if (next->ty != Tvoid && ta->next->ty == Tvoid)
4514 {
4515 return MATCHconvert;
4516 }
4517
4518 MATCH m = next->constConv(ta->next);
4519 if (m > MATCHnomatch)
4520 {
4521 if (m == MATCHexact && mod != to->mod)
4522 m = MATCHconst;
4523 return m;
4524 }
4525 }
4526 return Type::implicitConvTo(to);
4527 }
4528
4529 Expression *TypeDArray::defaultInit(Loc loc)
4530 {
4531 return new NullExp(loc, this);
4532 }
4533
4534 bool TypeDArray::isZeroInit(Loc)
4535 {
4536 return true;
4537 }
4538
4539 bool TypeDArray::isBoolean()
4540 {
4541 return true;
4542 }
4543
4544 bool TypeDArray::hasPointers()
4545 {
4546 return true;
4547 }
4548
4549
4550 /***************************** TypeAArray *****************************/
4551
4552 TypeAArray::TypeAArray(Type *t, Type *index)
4553 : TypeArray(Taarray, t)
4554 {
4555 this->index = index;
4556 this->loc = Loc();
4557 this->sc = NULL;
4558 }
4559
4560 TypeAArray *TypeAArray::create(Type *t, Type *index)
4561 {
4562 return new TypeAArray(t, index);
4563 }
4564
4565 const char *TypeAArray::kind()
4566 {
4567 return "aarray";
4568 }
4569
4570 Type *TypeAArray::syntaxCopy()
4571 {
4572 Type *t = next->syntaxCopy();
4573 Type *ti = index->syntaxCopy();
4574 if (t == next && ti == index)
4575 t = this;
4576 else
4577 {
4578 t = new TypeAArray(t, ti);
4579 t->mod = mod;
4580 }
4581 return t;
4582 }
4583
4584 d_uns64 TypeAArray::size(Loc)
4585 {
4586 return Target::ptrsize;
4587 }
4588
4589 Type *TypeAArray::semantic(Loc loc, Scope *sc)
4590 {
4591 //printf("TypeAArray::semantic() %s index->ty = %d\n", toChars(), index->ty);
4592 if (deco)
4593 return this;
4594
4595 this->loc = loc;
4596 this->sc = sc;
4597 if (sc)
4598 sc->setNoFree();
4599
4600 // Deal with the case where we thought the index was a type, but
4601 // in reality it was an expression.
4602 if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray ||
4603 index->ty == Ttypeof || index->ty == Treturn)
4604 {
4605 Expression *e;
4606 Type *t;
4607 Dsymbol *s;
4608
4609 index->resolve(loc, sc, &e, &t, &s);
4610 if (e)
4611 {
4612 // It was an expression -
4613 // Rewrite as a static array
4614 TypeSArray *tsa = new TypeSArray(next, e);
4615 return tsa->semantic(loc, sc);
4616 }
4617 else if (t)
4618 index = t->semantic(loc, sc);
4619 else
4620 {
4621 index->error(loc, "index is not a type or an expression");
4622 return Type::terror;
4623 }
4624 }
4625 else
4626 index = index->semantic(loc,sc);
4627 index = index->merge2();
4628
4629 if (index->nextOf() && !index->nextOf()->isImmutable())
4630 {
4631 index = index->constOf()->mutableOf();
4632 }
4633
4634 switch (index->toBasetype()->ty)
4635 {
4636 case Tfunction:
4637 case Tvoid:
4638 case Tnone:
4639 case Ttuple:
4640 error(loc, "can't have associative array key of %s", index->toBasetype()->toChars());
4641 /* fall through */
4642 case Terror:
4643 return Type::terror;
4644 default:
4645 break;
4646 }
4647 Type *tbase = index->baseElemOf();
4648 while (tbase->ty == Tarray)
4649 tbase = tbase->nextOf()->baseElemOf();
4650 if (tbase->ty == Tstruct)
4651 {
4652 /* AA's need typeid(index).equals() and getHash(). Issue error if not correctly set up.
4653 */
4654 StructDeclaration *sd = ((TypeStruct *)tbase)->sym;
4655 if (sd->_scope)
4656 sd->semantic(NULL);
4657
4658 // duplicate a part of StructDeclaration::semanticTypeInfoMembers
4659 //printf("AA = %s, key: xeq = %p, xerreq = %p xhash = %p\n", toChars(), sd->xeq, sd->xerreq, sd->xhash);
4660 if (sd->xeq &&
4661 sd->xeq->_scope &&
4662 sd->xeq->semanticRun < PASSsemantic3done)
4663 {
4664 unsigned errors = global.startGagging();
4665 sd->xeq->semantic3(sd->xeq->_scope);
4666 if (global.endGagging(errors))
4667 sd->xeq = sd->xerreq;
4668 }
4669
4670 const char *s = (index->toBasetype()->ty != Tstruct) ? "bottom of " : "";
4671 if (!sd->xeq)
4672 {
4673 // If sd->xhash != NULL:
4674 // sd or its fields have user-defined toHash.
4675 // AA assumes that its result is consistent with bitwise equality.
4676 // else:
4677 // bitwise equality & hashing
4678 }
4679 else if (sd->xeq == sd->xerreq)
4680 {
4681 if (search_function(sd, Id::eq))
4682 {
4683 error(loc, "%sAA key type %s does not have 'bool opEquals(ref const %s) const'",
4684 s, sd->toChars(), sd->toChars());
4685 }
4686 else
4687 {
4688 error(loc, "%sAA key type %s does not support const equality",
4689 s, sd->toChars());
4690 }
4691 return Type::terror;
4692 }
4693 else if (!sd->xhash)
4694 {
4695 if (search_function(sd, Id::eq))
4696 {
4697 error(loc, "%sAA key type %s should have 'size_t toHash() const nothrow @safe' if opEquals defined",
4698 s, sd->toChars());
4699 }
4700 else
4701 {
4702 error(loc, "%sAA key type %s supports const equality but doesn't support const hashing",
4703 s, sd->toChars());
4704 }
4705 return Type::terror;
4706 }
4707 else
4708 {
4709 // defined equality & hashing
4710 assert(sd->xeq && sd->xhash);
4711
4712 /* xeq and xhash may be implicitly defined by compiler. For example:
4713 * struct S { int[] arr; }
4714 * With 'arr' field equality and hashing, compiler will implicitly
4715 * generate functions for xopEquals and xtoHash in TypeInfo_Struct.
4716 */
4717 }
4718 }
4719 else if (tbase->ty == Tclass && !((TypeClass *)tbase)->sym->isInterfaceDeclaration())
4720 {
4721 ClassDeclaration *cd = ((TypeClass *)tbase)->sym;
4722 if (cd->_scope)
4723 cd->semantic(NULL);
4724
4725 if (!ClassDeclaration::object)
4726 {
4727 error(Loc(), "missing or corrupt object.d");
4728 fatal();
4729 }
4730
4731 static FuncDeclaration *feq = NULL;
4732 static FuncDeclaration *fcmp = NULL;
4733 static FuncDeclaration *fhash = NULL;
4734 if (!feq) feq = search_function(ClassDeclaration::object, Id::eq)->isFuncDeclaration();
4735 if (!fcmp) fcmp = search_function(ClassDeclaration::object, Id::cmp)->isFuncDeclaration();
4736 if (!fhash) fhash = search_function(ClassDeclaration::object, Id::tohash)->isFuncDeclaration();
4737 assert(fcmp && feq && fhash);
4738
4739 if (feq->vtblIndex < (int)cd->vtbl.dim && cd->vtbl[feq ->vtblIndex] == feq)
4740 {
4741 if (fcmp->vtblIndex < (int)cd->vtbl.dim && cd->vtbl[fcmp->vtblIndex] != fcmp)
4742 {
4743 const char *s = (index->toBasetype()->ty != Tclass) ? "bottom of " : "";
4744 error(loc, "%sAA key type %s now requires equality rather than comparison",
4745 s, cd->toChars());
4746 errorSupplemental(loc, "Please override Object.opEquals and toHash.");
4747 }
4748 }
4749 }
4750 next = next->semantic(loc,sc)->merge2();
4751 transitive();
4752
4753 switch (next->toBasetype()->ty)
4754 {
4755 case Tfunction:
4756 case Tvoid:
4757 case Tnone:
4758 case Ttuple:
4759 error(loc, "can't have associative array of %s", next->toChars());
4760 /* fall through */
4761 case Terror:
4762 return Type::terror;
4763 }
4764 if (next->isscope())
4765 { error(loc, "cannot have array of scope %s", next->toChars());
4766 return Type::terror;
4767 }
4768 return merge();
4769 }
4770
4771 void TypeAArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
4772 {
4773 //printf("TypeAArray::resolve() %s\n", toChars());
4774
4775 // Deal with the case where we thought the index was a type, but
4776 // in reality it was an expression.
4777 if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray)
4778 {
4779 Expression *e;
4780 Type *t;
4781 Dsymbol *s;
4782
4783 index->resolve(loc, sc, &e, &t, &s, intypeid);
4784 if (e)
4785 {
4786 // It was an expression -
4787 // Rewrite as a static array
4788 TypeSArray *tsa = new TypeSArray(next, e);
4789 tsa->mod = this->mod; // just copy mod field so tsa's semantic is not yet done
4790 return tsa->resolve(loc, sc, pe, pt, ps, intypeid);
4791 }
4792 else if (t)
4793 index = t;
4794 else
4795 index->error(loc, "index is not a type or an expression");
4796 }
4797 Type::resolve(loc, sc, pe, pt, ps, intypeid);
4798 }
4799
4800
4801 Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
4802 {
4803 if (ident == Id::length)
4804 {
4805 static FuncDeclaration *fd_aaLen = NULL;
4806 if (fd_aaLen == NULL)
4807 {
4808 Parameters *fparams = new Parameters();
4809 fparams->push(new Parameter(STCin, this, NULL, NULL));
4810 fd_aaLen = FuncDeclaration::genCfunc(fparams, Type::tsize_t, Id::aaLen);
4811 TypeFunction *tf = fd_aaLen->type->toTypeFunction();
4812 tf->purity = PUREconst;
4813 tf->isnothrow = true;
4814 tf->isnogc = false;
4815 }
4816 Expression *ev = new VarExp(e->loc, fd_aaLen, false);
4817 e = new CallExp(e->loc, ev, e);
4818 e->type = fd_aaLen->type->toTypeFunction()->next;
4819 }
4820 else
4821 e = Type::dotExp(sc, e, ident, flag);
4822 return e;
4823 }
4824
4825 Expression *TypeAArray::defaultInit(Loc loc)
4826 {
4827 return new NullExp(loc, this);
4828 }
4829
4830 bool TypeAArray::isZeroInit(Loc)
4831 {
4832 return true;
4833 }
4834
4835 bool TypeAArray::isBoolean()
4836 {
4837 return true;
4838 }
4839
4840 bool TypeAArray::hasPointers()
4841 {
4842 return true;
4843 }
4844
4845 MATCH TypeAArray::implicitConvTo(Type *to)
4846 {
4847 //printf("TypeAArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4848 if (equals(to))
4849 return MATCHexact;
4850
4851 if (to->ty == Taarray)
4852 { TypeAArray *ta = (TypeAArray *)to;
4853
4854 if (!MODimplicitConv(next->mod, ta->next->mod))
4855 return MATCHnomatch; // not const-compatible
4856
4857 if (!MODimplicitConv(index->mod, ta->index->mod))
4858 return MATCHnomatch; // not const-compatible
4859
4860 MATCH m = next->constConv(ta->next);
4861 MATCH mi = index->constConv(ta->index);
4862 if (m > MATCHnomatch && mi > MATCHnomatch)
4863 {
4864 return MODimplicitConv(mod, to->mod) ? MATCHconst : MATCHnomatch;
4865 }
4866 }
4867 return Type::implicitConvTo(to);
4868 }
4869
4870 MATCH TypeAArray::constConv(Type *to)
4871 {
4872 if (to->ty == Taarray)
4873 {
4874 TypeAArray *taa = (TypeAArray *)to;
4875 MATCH mindex = index->constConv(taa->index);
4876 MATCH mkey = next->constConv(taa->next);
4877 // Pick the worst match
4878 return mkey < mindex ? mkey : mindex;
4879 }
4880 return Type::constConv(to);
4881 }
4882
4883 /***************************** TypePointer *****************************/
4884
4885 TypePointer::TypePointer(Type *t)
4886 : TypeNext(Tpointer, t)
4887 {
4888 }
4889
4890 TypePointer *TypePointer::create(Type *t)
4891 {
4892 return new TypePointer(t);
4893 }
4894
4895 const char *TypePointer::kind()
4896 {
4897 return "pointer";
4898 }
4899
4900 Type *TypePointer::syntaxCopy()
4901 {
4902 Type *t = next->syntaxCopy();
4903 if (t == next)
4904 t = this;
4905 else
4906 {
4907 t = new TypePointer(t);
4908 t->mod = mod;
4909 }
4910 return t;
4911 }
4912
4913 Type *TypePointer::semantic(Loc loc, Scope *sc)
4914 {
4915 //printf("TypePointer::semantic() %s\n", toChars());
4916 if (deco)
4917 return this;
4918 Type *n = next->semantic(loc, sc);
4919 switch (n->toBasetype()->ty)
4920 {
4921 case Ttuple:
4922 error(loc, "can't have pointer to %s", n->toChars());
4923 /* fall through */
4924 case Terror:
4925 return Type::terror;
4926 default:
4927 break;
4928 }
4929 if (n != next)
4930 {
4931 deco = NULL;
4932 }
4933 next = n;
4934 if (next->ty != Tfunction)
4935 { transitive();
4936 return merge();
4937 }
4938 deco = merge()->deco;
4939 /* Don't return merge(), because arg identifiers and default args
4940 * can be different
4941 * even though the types match
4942 */
4943 return this;
4944 }
4945
4946
4947 d_uns64 TypePointer::size(Loc)
4948 {
4949 return Target::ptrsize;
4950 }
4951
4952 MATCH TypePointer::implicitConvTo(Type *to)
4953 {
4954 //printf("TypePointer::implicitConvTo(to = %s) %s\n", to->toChars(), toChars());
4955
4956 if (equals(to))
4957 return MATCHexact;
4958 if (next->ty == Tfunction)
4959 {
4960 if (to->ty == Tpointer)
4961 {
4962 TypePointer *tp = (TypePointer *)to;
4963 if (tp->next->ty == Tfunction)
4964 {
4965 if (next->equals(tp->next))
4966 return MATCHconst;
4967
4968 if (next->covariant(tp->next) == 1)
4969 {
4970 Type *tret = this->next->nextOf();
4971 Type *toret = tp->next->nextOf();
4972 if (tret->ty == Tclass && toret->ty == Tclass)
4973 {
4974 /* Bugzilla 10219: Check covariant interface return with offset tweaking.
4975 * interface I {}
4976 * class C : Object, I {}
4977 * I function() dg = function C() {} // should be error
4978 */
4979 int offset = 0;
4980 if (toret->isBaseOf(tret, &offset) && offset != 0)
4981 return MATCHnomatch;
4982 }
4983 return MATCHconvert;
4984 }
4985 }
4986 else if (tp->next->ty == Tvoid)
4987 {
4988 // Allow conversions to void*
4989 return MATCHconvert;
4990 }
4991 }
4992 return MATCHnomatch;
4993 }
4994 else if (to->ty == Tpointer)
4995 {
4996 TypePointer *tp = (TypePointer *)to;
4997 assert(tp->next);
4998
4999 if (!MODimplicitConv(next->mod, tp->next->mod))
5000 return MATCHnomatch; // not const-compatible
5001
5002 /* Alloc conversion to void*
5003 */
5004 if (next->ty != Tvoid && tp->next->ty == Tvoid)
5005 {
5006 return MATCHconvert;
5007 }
5008
5009 MATCH m = next->constConv(tp->next);
5010 if (m > MATCHnomatch)
5011 {
5012 if (m == MATCHexact && mod != to->mod)
5013 m = MATCHconst;
5014 return m;
5015 }
5016 }
5017 return MATCHnomatch;
5018 }
5019
5020 MATCH TypePointer::constConv(Type *to)
5021 {
5022 if (next->ty == Tfunction)
5023 {
5024 if (to->nextOf() && next->equals(((TypeNext *)to)->next))
5025 return Type::constConv(to);
5026 else
5027 return MATCHnomatch;
5028 }
5029 return TypeNext::constConv(to);
5030 }
5031
5032 bool TypePointer::isscalar()
5033 {
5034 return true;
5035 }
5036
5037 Expression *TypePointer::defaultInit(Loc loc)
5038 {
5039 return new NullExp(loc, this);
5040 }
5041
5042 bool TypePointer::isZeroInit(Loc)
5043 {
5044 return true;
5045 }
5046
5047 bool TypePointer::hasPointers()
5048 {
5049 return true;
5050 }
5051
5052
5053 /***************************** TypeReference *****************************/
5054
5055 TypeReference::TypeReference(Type *t)
5056 : TypeNext(Treference, t)
5057 {
5058 // BUG: what about references to static arrays?
5059 }
5060
5061 const char *TypeReference::kind()
5062 {
5063 return "reference";
5064 }
5065
5066 Type *TypeReference::syntaxCopy()
5067 {
5068 Type *t = next->syntaxCopy();
5069 if (t == next)
5070 t = this;
5071 else
5072 {
5073 t = new TypeReference(t);
5074 t->mod = mod;
5075 }
5076 return t;
5077 }
5078
5079 Type *TypeReference::semantic(Loc loc, Scope *sc)
5080 {
5081 //printf("TypeReference::semantic()\n");
5082 Type *n = next->semantic(loc, sc);
5083 if (n != next)
5084 deco = NULL;
5085 next = n;
5086 transitive();
5087 return merge();
5088 }
5089
5090
5091 d_uns64 TypeReference::size(Loc)
5092 {
5093 return Target::ptrsize;
5094 }
5095
5096 Expression *TypeReference::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
5097 {
5098 // References just forward things along
5099 return next->dotExp(sc, e, ident, flag);
5100 }
5101
5102 Expression *TypeReference::defaultInit(Loc loc)
5103 {
5104 return new NullExp(loc, this);
5105 }
5106
5107 bool TypeReference::isZeroInit(Loc)
5108 {
5109 return true;
5110 }
5111
5112
5113 /***************************** TypeFunction *****************************/
5114
5115 TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc)
5116 : TypeNext(Tfunction, treturn)
5117 {
5118 //if (!treturn) *(char*)0=0;
5119 // assert(treturn);
5120 assert(0 <= varargs && varargs <= 2);
5121 this->parameters = parameters;
5122 this->varargs = varargs;
5123 this->linkage = linkage;
5124 this->inuse = 0;
5125 this->isnothrow = false;
5126 this->isnogc = false;
5127 this->purity = PUREimpure;
5128 this->isproperty = false;
5129 this->isref = false;
5130 this->isreturn = false;
5131 this->isscope = false;
5132 this->isscopeinferred = false;
5133 this->iswild = 0;
5134 this->fargs = NULL;
5135
5136 if (stc & STCpure)
5137 this->purity = PUREfwdref;
5138 if (stc & STCnothrow)
5139 this->isnothrow = true;
5140 if (stc & STCnogc)
5141 this->isnogc = true;
5142 if (stc & STCproperty)
5143 this->isproperty = true;
5144
5145 if (stc & STCref)
5146 this->isref = true;
5147 if (stc & STCreturn)
5148 this->isreturn = true;
5149 if (stc & STCscope)
5150 this->isscope = true;
5151 if (stc & STCscopeinferred)
5152 this->isscopeinferred = true;
5153
5154 this->trust = TRUSTdefault;
5155 if (stc & STCsafe)
5156 this->trust = TRUSTsafe;
5157 if (stc & STCsystem)
5158 this->trust = TRUSTsystem;
5159 if (stc & STCtrusted)
5160 this->trust = TRUSTtrusted;
5161 }
5162
5163 TypeFunction *TypeFunction::create(Parameters *parameters, Type *treturn, int varargs, LINK linkage, StorageClass stc)
5164 {
5165 return new TypeFunction(parameters, treturn, varargs, linkage, stc);
5166 }
5167
5168 const char *TypeFunction::kind()
5169 {
5170 return "function";
5171 }
5172
5173 Type *TypeFunction::syntaxCopy()
5174 {
5175 Type *treturn = next ? next->syntaxCopy() : NULL;
5176 Parameters *params = Parameter::arraySyntaxCopy(parameters);
5177 TypeFunction *t = new TypeFunction(params, treturn, varargs, linkage);
5178 t->mod = mod;
5179 t->isnothrow = isnothrow;
5180 t->isnogc = isnogc;
5181 t->purity = purity;
5182 t->isproperty = isproperty;
5183 t->isref = isref;
5184 t->isreturn = isreturn;
5185 t->isscope = isscope;
5186 t->isscopeinferred = isscopeinferred;
5187 t->iswild = iswild;
5188 t->trust = trust;
5189 t->fargs = fargs;
5190 return t;
5191 }
5192
5193 /*******************************
5194 * Covariant means that 'this' can substitute for 't',
5195 * i.e. a pure function is a match for an impure type.
5196 * Params:
5197 * t = type 'this' is covariant with
5198 * pstc = if not null, store STCxxxx which would make it covariant
5199 * fix17349 = enable fix https://issues.dlang.org/show_bug.cgi?id=17349
5200 * Returns:
5201 * 0 types are distinct
5202 * 1 this is covariant with t
5203 * 2 arguments match as far as overloading goes,
5204 * but types are not covariant
5205 * 3 cannot determine covariance because of forward references
5206 * *pstc STCxxxx which would make it covariant
5207 */
5208
5209 int Type::covariant(Type *t, StorageClass *pstc, bool fix17349)
5210 {
5211 if (pstc)
5212 *pstc = 0;
5213 StorageClass stc = 0;
5214
5215 bool notcovariant = false;
5216
5217 TypeFunction *t1;
5218 TypeFunction *t2;
5219
5220 if (equals(t))
5221 return 1; // covariant
5222
5223 if (ty != Tfunction || t->ty != Tfunction)
5224 goto Ldistinct;
5225
5226 t1 = (TypeFunction *)this;
5227 t2 = (TypeFunction *)t;
5228
5229 if (t1->varargs != t2->varargs)
5230 goto Ldistinct;
5231
5232 if (t1->parameters && t2->parameters)
5233 {
5234 size_t dim = Parameter::dim(t1->parameters);
5235 if (dim != Parameter::dim(t2->parameters))
5236 goto Ldistinct;
5237
5238 for (size_t i = 0; i < dim; i++)
5239 {
5240 Parameter *fparam1 = Parameter::getNth(t1->parameters, i);
5241 Parameter *fparam2 = Parameter::getNth(t2->parameters, i);
5242
5243 if (!fparam1->type->equals(fparam2->type))
5244 {
5245 if (!fix17349)
5246 goto Ldistinct;
5247 Type *tp1 = fparam1->type;
5248 Type *tp2 = fparam2->type;
5249 if (tp1->ty == tp2->ty)
5250 {
5251 if (tp1->ty == Tclass)
5252 {
5253 if (((TypeClass *)tp1)->sym == ((TypeClass *)tp2)->sym && MODimplicitConv(tp2->mod, tp1->mod))
5254 goto Lcov;
5255 }
5256 else if (tp1->ty == Tstruct)
5257 {
5258 if (((TypeStruct *)tp1)->sym == ((TypeStruct *)tp2)->sym && MODimplicitConv(tp2->mod, tp1->mod))
5259 goto Lcov;
5260 }
5261 else if (tp1->ty == Tpointer)
5262 {
5263 if (tp2->implicitConvTo(tp1))
5264 goto Lcov;
5265 }
5266 else if (tp1->ty == Tarray)
5267 {
5268 if (tp2->implicitConvTo(tp1))
5269 goto Lcov;
5270 }
5271 else if (tp1->ty == Tdelegate)
5272 {
5273 if (tp1->implicitConvTo(tp2))
5274 goto Lcov;
5275 }
5276 }
5277 goto Ldistinct;
5278 }
5279 Lcov:
5280 notcovariant |= !fparam1->isCovariant(t1->isref, fparam2);
5281 }
5282 }
5283 else if (t1->parameters != t2->parameters)
5284 {
5285 size_t dim1 = !t1->parameters ? 0 : t1->parameters->dim;
5286 size_t dim2 = !t2->parameters ? 0 : t2->parameters->dim;
5287 if (dim1 || dim2)
5288 goto Ldistinct;
5289 }
5290
5291 // The argument lists match
5292 if (notcovariant)
5293 goto Lnotcovariant;
5294 if (t1->linkage != t2->linkage)
5295 goto Lnotcovariant;
5296
5297 {
5298 // Return types
5299 Type *t1n = t1->next;
5300 Type *t2n = t2->next;
5301
5302 if (!t1n || !t2n) // happens with return type inference
5303 goto Lnotcovariant;
5304
5305 if (t1n->equals(t2n))
5306 goto Lcovariant;
5307 if (t1n->ty == Tclass && t2n->ty == Tclass)
5308 {
5309 /* If same class type, but t2n is const, then it's
5310 * covariant. Do this test first because it can work on
5311 * forward references.
5312 */
5313 if (((TypeClass *)t1n)->sym == ((TypeClass *)t2n)->sym &&
5314 MODimplicitConv(t1n->mod, t2n->mod))
5315 goto Lcovariant;
5316
5317 // If t1n is forward referenced:
5318 ClassDeclaration *cd = ((TypeClass *)t1n)->sym;
5319 if (cd->_scope)
5320 cd->semantic(NULL);
5321 if (!cd->isBaseInfoComplete())
5322 {
5323 return 3; // forward references
5324 }
5325 }
5326 if (t1n->ty == Tstruct && t2n->ty == Tstruct)
5327 {
5328 if (((TypeStruct *)t1n)->sym == ((TypeStruct *)t2n)->sym &&
5329 MODimplicitConv(t1n->mod, t2n->mod))
5330 goto Lcovariant;
5331 }
5332 else if (t1n->ty == t2n->ty && t1n->implicitConvTo(t2n))
5333 goto Lcovariant;
5334 else if (t1n->ty == Tnull)
5335 {
5336 // NULL is covariant with any pointer type, but not with any
5337 // dynamic arrays, associative arrays or delegates.
5338 // https://issues.dlang.org/show_bug.cgi?id=8589
5339 // https://issues.dlang.org/show_bug.cgi?id=19618
5340 Type *t2bn = t2n->toBasetype();
5341 if (t2bn->ty == Tnull || t2bn->ty == Tpointer || t2bn->ty == Tclass)
5342 goto Lcovariant;
5343 }
5344 }
5345 goto Lnotcovariant;
5346
5347 Lcovariant:
5348 if (t1->isref != t2->isref)
5349 goto Lnotcovariant;
5350
5351 if (!t1->isref && (t1->isscope || t2->isscope))
5352 {
5353 StorageClass stc1 = t1->isscope ? STCscope : 0;
5354 StorageClass stc2 = t2->isscope ? STCscope : 0;
5355 if (t1->isreturn)
5356 {
5357 stc1 |= STCreturn;
5358 if (!t1->isscope)
5359 stc1 |= STCref;
5360 }
5361 if (t2->isreturn)
5362 {
5363 stc2 |= STCreturn;
5364 if (!t2->isscope)
5365 stc2 |= STCref;
5366 }
5367 if (!Parameter::isCovariantScope(t1->isref, stc1, stc2))
5368 goto Lnotcovariant;
5369 }
5370
5371 // We can subtract 'return ref' from 'this', but cannot add it
5372 else if (t1->isreturn && !t2->isreturn)
5373 goto Lnotcovariant;
5374
5375 /* Can convert mutable to const
5376 */
5377 if (!MODimplicitConv(t2->mod, t1->mod))
5378 {
5379 goto Ldistinct;
5380 }
5381
5382 /* Can convert pure to impure, nothrow to throw, and nogc to gc
5383 */
5384 if (!t1->purity && t2->purity)
5385 stc |= STCpure;
5386
5387 if (!t1->isnothrow && t2->isnothrow)
5388 stc |= STCnothrow;
5389
5390 if (!t1->isnogc && t2->isnogc)
5391 stc |= STCnogc;
5392
5393 /* Can convert safe/trusted to system
5394 */
5395 if (t1->trust <= TRUSTsystem && t2->trust >= TRUSTtrusted)
5396 {
5397 // Should we infer trusted or safe? Go with safe.
5398 stc |= STCsafe;
5399 }
5400
5401 if (stc)
5402 { if (pstc)
5403 *pstc = stc;
5404 goto Lnotcovariant;
5405 }
5406
5407 //printf("\tcovaraint: 1\n");
5408 return 1;
5409
5410 Ldistinct:
5411 //printf("\tcovaraint: 0\n");
5412 return 0;
5413
5414 Lnotcovariant:
5415 //printf("\tcovaraint: 2\n");
5416 return 2;
5417 }
5418
5419 Type *TypeFunction::semantic(Loc loc, Scope *sc)
5420 {
5421 if (deco) // if semantic() already run
5422 {
5423 //printf("already done\n");
5424 return this;
5425 }
5426 //printf("TypeFunction::semantic() this = %p\n", this);
5427 //printf("TypeFunction::semantic() %s, sc->stc = %llx, fargs = %p\n", toChars(), sc->stc, fargs);
5428
5429 bool errors = false;
5430
5431 /* Copy in order to not mess up original.
5432 * This can produce redundant copies if inferring return type,
5433 * as semantic() will get called again on this.
5434 */
5435 TypeFunction *tf = copy()->toTypeFunction();
5436 if (parameters)
5437 {
5438 tf->parameters = parameters->copy();
5439 for (size_t i = 0; i < parameters->dim; i++)
5440 {
5441 void *pp = mem.xmalloc(sizeof(Parameter));
5442 Parameter *p = (Parameter *)memcpy(pp, (void *)(*parameters)[i], sizeof(Parameter));
5443 (*tf->parameters)[i] = p;
5444 }
5445 }
5446
5447 if (sc->stc & STCpure)
5448 tf->purity = PUREfwdref;
5449 if (sc->stc & STCnothrow)
5450 tf->isnothrow = true;
5451 if (sc->stc & STCnogc)
5452 tf->isnogc = true;
5453 if (sc->stc & STCref)
5454 tf->isref = true;
5455 if (sc->stc & STCreturn)
5456 tf->isreturn = true;
5457 if (sc->stc & STCscope)
5458 tf->isscope = true;
5459 if (sc->stc & STCscopeinferred)
5460 tf->isscopeinferred = true;
5461
5462 // if ((sc->stc & (STCreturn | STCref)) == STCreturn)
5463 // tf->isscope = true; // return by itself means 'return scope'
5464
5465 if (tf->trust == TRUSTdefault)
5466 {
5467 if (sc->stc & STCsafe)
5468 tf->trust = TRUSTsafe;
5469 if (sc->stc & STCsystem)
5470 tf->trust = TRUSTsystem;
5471 if (sc->stc & STCtrusted)
5472 tf->trust = TRUSTtrusted;
5473 }
5474
5475 if (sc->stc & STCproperty)
5476 tf->isproperty = true;
5477
5478 tf->linkage = sc->linkage;
5479 bool wildreturn = false;
5480 if (tf->next)
5481 {
5482 sc = sc->push();
5483 sc->stc &= ~(STC_TYPECTOR | STC_FUNCATTR);
5484 tf->next = tf->next->semantic(loc, sc);
5485 sc = sc->pop();
5486 errors |= tf->checkRetType(loc);
5487 if (tf->next->isscope() && !(sc->flags & SCOPEctor))
5488 {
5489 error(loc, "functions cannot return scope %s", tf->next->toChars());
5490 errors = true;
5491 }
5492 if (tf->next->hasWild())
5493 wildreturn = true;
5494
5495 if (tf->isreturn && !tf->isref && !tf->next->hasPointers())
5496 {
5497 error(loc, "function type '%s' has 'return' but does not return any indirections", tf->toChars());
5498 }
5499 }
5500
5501 unsigned char wildparams = 0;
5502 if (tf->parameters)
5503 {
5504 /* Create a scope for evaluating the default arguments for the parameters
5505 */
5506 Scope *argsc = sc->push();
5507 argsc->stc = 0; // don't inherit storage class
5508 argsc->protection = Prot(PROTpublic);
5509 argsc->func = NULL;
5510
5511 size_t dim = Parameter::dim(tf->parameters);
5512 for (size_t i = 0; i < dim; i++)
5513 {
5514 Parameter *fparam = Parameter::getNth(tf->parameters, i);
5515 tf->inuse++;
5516 fparam->type = fparam->type->semantic(loc, argsc);
5517 if (tf->inuse == 1) tf->inuse--;
5518
5519 if (fparam->type->ty == Terror)
5520 {
5521 errors = true;
5522 continue;
5523 }
5524
5525 fparam->type = fparam->type->addStorageClass(fparam->storageClass);
5526
5527 if (fparam->storageClass & (STCauto | STCalias | STCstatic))
5528 {
5529 if (!fparam->type)
5530 continue;
5531 }
5532
5533 Type *t = fparam->type->toBasetype();
5534
5535 if (t->ty == Tfunction)
5536 {
5537 error(loc, "cannot have parameter of function type %s", fparam->type->toChars());
5538 errors = true;
5539 }
5540 else if (!(fparam->storageClass & (STCref | STCout)) &&
5541 (t->ty == Tstruct || t->ty == Tsarray || t->ty == Tenum))
5542 {
5543 Type *tb2 = t->baseElemOf();
5544 if ((tb2->ty == Tstruct && !((TypeStruct *)tb2)->sym->members) ||
5545 (tb2->ty == Tenum && !((TypeEnum *)tb2)->sym->memtype))
5546 {
5547 error(loc, "cannot have parameter of opaque type %s by value", fparam->type->toChars());
5548 errors = true;
5549 }
5550 }
5551 else if (!(fparam->storageClass & STClazy) && t->ty == Tvoid)
5552 {
5553 error(loc, "cannot have parameter of type %s", fparam->type->toChars());
5554 errors = true;
5555 }
5556
5557 if ((fparam->storageClass & (STCref | STCwild)) == (STCref | STCwild))
5558 {
5559 // 'ref inout' implies 'return'
5560 fparam->storageClass |= STCreturn;
5561 }
5562
5563 if (fparam->storageClass & STCreturn)
5564 {
5565 if (fparam->storageClass & (STCref | STCout))
5566 {
5567 // Disabled for the moment awaiting improvement to allow return by ref
5568 // to be transformed into return by scope.
5569 if (0 && !tf->isref)
5570 {
5571 StorageClass stc = fparam->storageClass & (STCref | STCout);
5572 error(loc, "parameter %s is 'return %s' but function does not return by ref",
5573 fparam->ident ? fparam->ident->toChars() : "",
5574 stcToChars(stc));
5575 errors = true;
5576 }
5577 }
5578 else
5579 {
5580 fparam->storageClass |= STCscope; // 'return' implies 'scope'
5581 if (tf->isref)
5582 {
5583 }
5584 else if (!tf->isref && tf->next && !tf->next->hasPointers())
5585 {
5586 error(loc, "parameter %s is 'return' but function does not return any indirections",
5587 fparam->ident ? fparam->ident->toChars() : "");
5588 errors = true;
5589 }
5590 }
5591 }
5592
5593 if (fparam->storageClass & (STCref | STClazy))
5594 {
5595 }
5596 else if (fparam->storageClass & STCout)
5597 {
5598 if (unsigned char m = fparam->type->mod & (MODimmutable | MODconst | MODwild))
5599 {
5600 error(loc, "cannot have %s out parameter of type %s", MODtoChars(m), t->toChars());
5601 errors = true;
5602 }
5603 else
5604 {
5605 Type *tv = t;
5606 while (tv->ty == Tsarray)
5607 tv = tv->nextOf()->toBasetype();
5608 if (tv->ty == Tstruct && ((TypeStruct *)tv)->sym->noDefaultCtor)
5609 {
5610 error(loc, "cannot have out parameter of type %s because the default construction is disabled",
5611 fparam->type->toChars());
5612 errors = true;
5613 }
5614 }
5615 }
5616
5617 if (fparam->storageClass & STCscope && !fparam->type->hasPointers() && fparam->type->ty != Ttuple)
5618 {
5619 fparam->storageClass &= ~STCscope;
5620 if (!(fparam->storageClass & STCref))
5621 fparam->storageClass &= ~STCreturn;
5622 }
5623
5624 if (t->hasWild())
5625 {
5626 wildparams |= 1;
5627 //if (tf->next && !wildreturn)
5628 // error(loc, "inout on parameter means inout must be on return type as well (if from D1 code, replace with 'ref')");
5629 }
5630
5631 if (fparam->defaultArg)
5632 {
5633 Expression *e = fparam->defaultArg;
5634 if (fparam->storageClass & (STCref | STCout))
5635 {
5636 e = ::semantic(e, argsc);
5637 e = resolveProperties(argsc, e);
5638 }
5639 else
5640 {
5641 e = inferType(e, fparam->type);
5642 Initializer *iz = new ExpInitializer(e->loc, e);
5643 iz = ::semantic(iz, argsc, fparam->type, INITnointerpret);
5644 e = initializerToExpression(iz);
5645 }
5646 if (e->op == TOKfunction) // see Bugzilla 4820
5647 {
5648 FuncExp *fe = (FuncExp *)e;
5649 // Replace function literal with a function symbol,
5650 // since default arg expression must be copied when used
5651 // and copying the literal itself is wrong.
5652 e = new VarExp(e->loc, fe->fd, false);
5653 e = new AddrExp(e->loc, e);
5654 e = ::semantic(e, argsc);
5655 }
5656 e = e->implicitCastTo(argsc, fparam->type);
5657
5658 // default arg must be an lvalue
5659 if (fparam->storageClass & (STCout | STCref))
5660 e = e->toLvalue(argsc, e);
5661
5662 fparam->defaultArg = e;
5663 if (e->op == TOKerror)
5664 errors = true;
5665 }
5666
5667 /* If fparam after semantic() turns out to be a tuple, the number of parameters may
5668 * change.
5669 */
5670 if (t->ty == Ttuple)
5671 {
5672 /* TypeFunction::parameter also is used as the storage of
5673 * Parameter objects for FuncDeclaration. So we should copy
5674 * the elements of TypeTuple::arguments to avoid unintended
5675 * sharing of Parameter object among other functions.
5676 */
5677 TypeTuple *tt = (TypeTuple *)t;
5678 if (tt->arguments && tt->arguments->dim)
5679 {
5680 /* Propagate additional storage class from tuple parameters to their
5681 * element-parameters.
5682 * Make a copy, as original may be referenced elsewhere.
5683 */
5684 size_t tdim = tt->arguments->dim;
5685 Parameters *newparams = new Parameters();
5686 newparams->setDim(tdim);
5687 for (size_t j = 0; j < tdim; j++)
5688 {
5689 Parameter *narg = (*tt->arguments)[j];
5690
5691 // Bugzilla 12744: If the storage classes of narg
5692 // conflict with the ones in fparam, it's ignored.
5693 StorageClass stc = fparam->storageClass | narg->storageClass;
5694 StorageClass stc1 = fparam->storageClass & (STCref | STCout | STClazy);
5695 StorageClass stc2 = narg->storageClass & (STCref | STCout | STClazy);
5696 if (stc1 && stc2 && stc1 != stc2)
5697 {
5698 OutBuffer buf1; stcToBuffer(&buf1, stc1 | ((stc1 & STCref) ? (fparam->storageClass & STCauto) : 0));
5699 OutBuffer buf2; stcToBuffer(&buf2, stc2);
5700
5701 error(loc, "incompatible parameter storage classes '%s' and '%s'",
5702 buf1.peekString(), buf2.peekString());
5703 errors = true;
5704 stc = stc1 | (stc & ~(STCref | STCout | STClazy));
5705 }
5706
5707 (*newparams)[j] = new Parameter(
5708 stc, narg->type, narg->ident, narg->defaultArg);
5709 }
5710 fparam->type = new TypeTuple(newparams);
5711 }
5712 fparam->storageClass = 0;
5713
5714 /* Reset number of parameters, and back up one to do this fparam again,
5715 * now that it is a tuple
5716 */
5717 dim = Parameter::dim(tf->parameters);
5718 i--;
5719 continue;
5720 }
5721
5722 /* Resolve "auto ref" storage class to be either ref or value,
5723 * based on the argument matching the parameter
5724 */
5725 if (fparam->storageClass & STCauto)
5726 {
5727 if (fargs && i < fargs->dim && (fparam->storageClass & STCref))
5728 {
5729 Expression *farg = (*fargs)[i];
5730 if (farg->isLvalue())
5731 ; // ref parameter
5732 else
5733 fparam->storageClass &= ~STCref; // value parameter
5734 fparam->storageClass &= ~STCauto; // Bugzilla 14656
5735 fparam->storageClass |= STCautoref;
5736 }
5737 else
5738 {
5739 error(loc, "'auto' can only be used as part of 'auto ref' for template function parameters");
5740 errors = true;
5741 }
5742 }
5743
5744 // Remove redundant storage classes for type, they are already applied
5745 fparam->storageClass &= ~(STC_TYPECTOR | STCin);
5746 }
5747 argsc->pop();
5748 }
5749 if (tf->isWild())
5750 wildparams |= 2;
5751
5752 if (wildreturn && !wildparams)
5753 {
5754 error(loc, "inout on return means inout must be on a parameter as well for %s", toChars());
5755 errors = true;
5756 }
5757 tf->iswild = wildparams;
5758
5759 if (tf->inuse)
5760 {
5761 error(loc, "recursive type");
5762 tf->inuse = 0;
5763 errors = true;
5764 }
5765
5766 if (tf->isproperty && (tf->varargs || Parameter::dim(tf->parameters) > 2))
5767 {
5768 error(loc, "properties can only have zero, one, or two parameter");
5769 errors = true;
5770 }
5771
5772 if (tf->varargs == 1 && tf->linkage != LINKd && Parameter::dim(tf->parameters) == 0)
5773 {
5774 error(loc, "variadic functions with non-D linkage must have at least one parameter");
5775 errors = true;
5776 }
5777
5778 if (errors)
5779 return terror;
5780
5781 if (tf->next)
5782 tf->deco = tf->merge()->deco;
5783
5784 /* Don't return merge(), because arg identifiers and default args
5785 * can be different
5786 * even though the types match
5787 */
5788 return tf;
5789 }
5790
5791 bool TypeFunction::checkRetType(Loc loc)
5792 {
5793 Type *tb = next->toBasetype();
5794 if (tb->ty == Tfunction)
5795 {
5796 error(loc, "functions cannot return a function");
5797 next = Type::terror;
5798 }
5799 if (tb->ty == Ttuple)
5800 {
5801 error(loc, "functions cannot return a tuple");
5802 next = Type::terror;
5803 }
5804 if (!isref && (tb->ty == Tstruct || tb->ty == Tsarray))
5805 {
5806 Type *tb2 = tb->baseElemOf();
5807 if (tb2->ty == Tstruct && !((TypeStruct *)tb2)->sym->members)
5808 {
5809 error(loc, "functions cannot return opaque type %s by value", tb->toChars());
5810 next = Type::terror;
5811 }
5812 }
5813 if (tb->ty == Terror)
5814 return true;
5815
5816 return false;
5817 }
5818
5819 /* Determine purity level based on mutability of t
5820 * and whether it is a 'ref' type or not.
5821 */
5822 static PURE purityOfType(bool isref, Type *t)
5823 {
5824 if (isref)
5825 {
5826 if (t->mod & MODimmutable)
5827 return PUREstrong;
5828 if (t->mod & (MODconst | MODwild))
5829 return PUREconst;
5830 return PUREweak;
5831 }
5832
5833 t = t->baseElemOf();
5834
5835 if (!t->hasPointers() || t->mod & MODimmutable)
5836 return PUREstrong;
5837
5838 /* Accept immutable(T)[] and immutable(T)* as being strongly pure
5839 */
5840 if (t->ty == Tarray || t->ty == Tpointer)
5841 {
5842 Type *tn = t->nextOf()->toBasetype();
5843 if (tn->mod & MODimmutable)
5844 return PUREstrong;
5845 if (tn->mod & (MODconst | MODwild))
5846 return PUREconst;
5847 }
5848
5849 /* The rest of this is too strict; fix later.
5850 * For example, the only pointer members of a struct may be immutable,
5851 * which would maintain strong purity.
5852 * (Just like for dynamic arrays and pointers above.)
5853 */
5854 if (t->mod & (MODconst | MODwild))
5855 return PUREconst;
5856
5857 /* Should catch delegates and function pointers, and fold in their purity
5858 */
5859 return PUREweak;
5860 }
5861
5862 /********************************************
5863 * Set 'purity' field of 'this'.
5864 * Do this lazily, as the parameter types might be forward referenced.
5865 */
5866 void TypeFunction::purityLevel()
5867 {
5868 TypeFunction *tf = this;
5869 if (tf->purity != PUREfwdref)
5870 return;
5871
5872 purity = PUREstrong; // assume strong until something weakens it
5873
5874 /* Evaluate what kind of purity based on the modifiers for the parameters
5875 */
5876 const size_t dim = Parameter::dim(tf->parameters);
5877 for (size_t i = 0; i < dim; i++)
5878 {
5879 Parameter *fparam = Parameter::getNth(tf->parameters, i);
5880 Type *t = fparam->type;
5881 if (!t)
5882 continue;
5883
5884 if (fparam->storageClass & (STClazy | STCout))
5885 {
5886 purity = PUREweak;
5887 break;
5888 }
5889 switch (purityOfType((fparam->storageClass & STCref) != 0, t))
5890 {
5891 case PUREweak:
5892 purity = PUREweak;
5893 break;
5894
5895 case PUREconst:
5896 purity = PUREconst;
5897 continue;
5898
5899 case PUREstrong:
5900 continue;
5901
5902 default:
5903 assert(0);
5904 }
5905 break; // since PUREweak, no need to check further
5906 }
5907
5908 if (purity > PUREweak && tf->nextOf())
5909 {
5910 /* Adjust purity based on mutability of return type.
5911 * https://issues.dlang.org/show_bug.cgi?id=15862
5912 */
5913 const PURE purity2 = purityOfType(tf->isref, tf->nextOf());
5914 if (purity2 < purity)
5915 purity = purity2;
5916 }
5917 tf->purity = purity;
5918 }
5919
5920 /********************************
5921 * 'args' are being matched to function 'this'
5922 * Determine match level.
5923 * Input:
5924 * flag 1 performing a partial ordering match
5925 * Returns:
5926 * MATCHxxxx
5927 */
5928
5929 MATCH TypeFunction::callMatch(Type *tthis, Expressions *args, int flag)
5930 {
5931 //printf("TypeFunction::callMatch() %s\n", toChars());
5932 MATCH match = MATCHexact; // assume exact match
5933 unsigned char wildmatch = 0;
5934
5935 if (tthis)
5936 {
5937 Type *t = tthis;
5938 if (t->toBasetype()->ty == Tpointer)
5939 t = t->toBasetype()->nextOf(); // change struct* to struct
5940 if (t->mod != mod)
5941 {
5942 if (MODimplicitConv(t->mod, mod))
5943 match = MATCHconst;
5944 else if ((mod & MODwild) && MODimplicitConv(t->mod, (mod & ~MODwild) | MODconst))
5945 {
5946 match = MATCHconst;
5947 }
5948 else
5949 return MATCHnomatch;
5950 }
5951 if (isWild())
5952 {
5953 if (t->isWild())
5954 wildmatch |= MODwild;
5955 else if (t->isConst())
5956 wildmatch |= MODconst;
5957 else if (t->isImmutable())
5958 wildmatch |= MODimmutable;
5959 else
5960 wildmatch |= MODmutable;
5961 }
5962 }
5963
5964 size_t nparams = Parameter::dim(parameters);
5965 size_t nargs = args ? args->dim : 0;
5966 if (nparams == nargs)
5967 ;
5968 else if (nargs > nparams)
5969 {
5970 if (varargs == 0)
5971 goto Nomatch; // too many args; no match
5972 match = MATCHconvert; // match ... with a "conversion" match level
5973 }
5974
5975 for (size_t u = 0; u < nargs; u++)
5976 {
5977 if (u >= nparams)
5978 break;
5979 Parameter *p = Parameter::getNth(parameters, u);
5980 Expression *arg = (*args)[u];
5981 assert(arg);
5982 Type *tprm = p->type;
5983 Type *targ = arg->type;
5984
5985 if (!(p->storageClass & STClazy && tprm->ty == Tvoid && targ->ty != Tvoid))
5986 {
5987 bool isRef = (p->storageClass & (STCref | STCout)) != 0;
5988 wildmatch |= targ->deduceWild(tprm, isRef);
5989 }
5990 }
5991 if (wildmatch)
5992 {
5993 /* Calculate wild matching modifier
5994 */
5995 if (wildmatch & MODconst || wildmatch & (wildmatch - 1))
5996 wildmatch = MODconst;
5997 else if (wildmatch & MODimmutable)
5998 wildmatch = MODimmutable;
5999 else if (wildmatch & MODwild)
6000 wildmatch = MODwild;
6001 else
6002 {
6003 assert(wildmatch & MODmutable);
6004 wildmatch = MODmutable;
6005 }
6006 }
6007
6008 for (size_t u = 0; u < nparams; u++)
6009 {
6010 MATCH m;
6011
6012 Parameter *p = Parameter::getNth(parameters, u);
6013 assert(p);
6014 if (u >= nargs)
6015 {
6016 if (p->defaultArg)
6017 continue;
6018 goto L1; // try typesafe variadics
6019 }
6020 {
6021 Expression *arg = (*args)[u];
6022 assert(arg);
6023 //printf("arg: %s, type: %s\n", arg->toChars(), arg->type->toChars());
6024
6025 Type *targ = arg->type;
6026 Type *tprm = wildmatch ? p->type->substWildTo(wildmatch) : p->type;
6027
6028 if (p->storageClass & STClazy && tprm->ty == Tvoid && targ->ty != Tvoid)
6029 m = MATCHconvert;
6030 else
6031 {
6032 //printf("%s of type %s implicitConvTo %s\n", arg->toChars(), targ->toChars(), tprm->toChars());
6033 if (flag)
6034 {
6035 // for partial ordering, value is an irrelevant mockup, just look at the type
6036 m = targ->implicitConvTo(tprm);
6037 }
6038 else
6039 m = arg->implicitConvTo(tprm);
6040 //printf("match %d\n", m);
6041 }
6042
6043 // Non-lvalues do not match ref or out parameters
6044 if (p->storageClass & (STCref | STCout))
6045 {
6046 // Bugzilla 13783: Don't use toBasetype() to handle enum types.
6047 Type *ta = targ;
6048 Type *tp = tprm;
6049 //printf("fparam[%d] ta = %s, tp = %s\n", u, ta->toChars(), tp->toChars());
6050
6051 if (m && !arg->isLvalue())
6052 {
6053 if (p->storageClass & STCout)
6054 goto Nomatch;
6055
6056 if (arg->op == TOKstring && tp->ty == Tsarray)
6057 {
6058 if (ta->ty != Tsarray)
6059 {
6060 Type *tn = tp->nextOf()->castMod(ta->nextOf()->mod);
6061 dinteger_t dim = ((StringExp *)arg)->len;
6062 ta = tn->sarrayOf(dim);
6063 }
6064 }
6065 else if (arg->op == TOKslice && tp->ty == Tsarray)
6066 {
6067 // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
6068 if (ta->ty != Tsarray)
6069 {
6070 Type *tn = ta->nextOf();
6071 dinteger_t dim = ((TypeSArray *)tp)->dim->toUInteger();
6072 ta = tn->sarrayOf(dim);
6073 }
6074 }
6075 else
6076 goto Nomatch;
6077 }
6078
6079 /* Find most derived alias this type being matched.
6080 * Bugzilla 15674: Allow on both ref and out parameters.
6081 */
6082 while (1)
6083 {
6084 Type *tat = ta->toBasetype()->aliasthisOf();
6085 if (!tat || !tat->implicitConvTo(tprm))
6086 break;
6087 ta = tat;
6088 }
6089
6090 /* A ref variable should work like a head-const reference.
6091 * e.g. disallows:
6092 * ref T <- an lvalue of const(T) argument
6093 * ref T[dim] <- an lvalue of const(T[dim]) argument
6094 */
6095 if (!ta->constConv(tp))
6096 goto Nomatch;
6097 }
6098 }
6099
6100 /* prefer matching the element type rather than the array
6101 * type when more arguments are present with T[]...
6102 */
6103 if (varargs == 2 && u + 1 == nparams && nargs > nparams)
6104 goto L1;
6105
6106 //printf("\tm = %d\n", m);
6107 if (m == MATCHnomatch) // if no match
6108 {
6109 L1:
6110 if (varargs == 2 && u + 1 == nparams) // if last varargs param
6111 {
6112 Type *tb = p->type->toBasetype();
6113 TypeSArray *tsa;
6114 dinteger_t sz;
6115
6116 switch (tb->ty)
6117 {
6118 case Tsarray:
6119 tsa = (TypeSArray *)tb;
6120 sz = tsa->dim->toInteger();
6121 if (sz != nargs - u)
6122 goto Nomatch;
6123 /* fall through */
6124 case Tarray:
6125 {
6126 TypeArray *ta = (TypeArray *)tb;
6127 for (; u < nargs; u++)
6128 {
6129 Expression *arg = (*args)[u];
6130 assert(arg);
6131
6132 /* If lazy array of delegates,
6133 * convert arg(s) to delegate(s)
6134 */
6135 Type *tret = p->isLazyArray();
6136 if (tret)
6137 {
6138 if (ta->next->equals(arg->type))
6139 m = MATCHexact;
6140 else if (tret->toBasetype()->ty == Tvoid)
6141 m = MATCHconvert;
6142 else
6143 {
6144 m = arg->implicitConvTo(tret);
6145 if (m == MATCHnomatch)
6146 m = arg->implicitConvTo(ta->next);
6147 }
6148 }
6149 else
6150 m = arg->implicitConvTo(ta->next);
6151
6152 if (m == MATCHnomatch)
6153 goto Nomatch;
6154 if (m < match)
6155 match = m;
6156 }
6157 goto Ldone;
6158 }
6159 case Tclass:
6160 // Should see if there's a constructor match?
6161 // Or just leave it ambiguous?
6162 goto Ldone;
6163
6164 default:
6165 goto Nomatch;
6166 }
6167 }
6168 goto Nomatch;
6169 }
6170 if (m < match)
6171 match = m; // pick worst match
6172 }
6173
6174 Ldone:
6175 //printf("match = %d\n", match);
6176 return match;
6177
6178 Nomatch:
6179 //printf("no match\n");
6180 return MATCHnomatch;
6181 }
6182
6183 /********************************************
6184 * Return true if there are lazy parameters.
6185 */
6186 bool TypeFunction::hasLazyParameters()
6187 {
6188 size_t dim = Parameter::dim(parameters);
6189 for (size_t i = 0; i < dim; i++)
6190 {
6191 Parameter *fparam = Parameter::getNth(parameters, i);
6192 if (fparam->storageClass & STClazy)
6193 return true;
6194 }
6195 return false;
6196 }
6197
6198 /***************************
6199 * Examine function signature for parameter p and see if
6200 * the value of p can 'escape' the scope of the function.
6201 * This is useful to minimize the needed annotations for the parameters.
6202 * Params:
6203 * p = parameter to this function
6204 * Returns:
6205 * true if escapes via assignment to global or through a parameter
6206 */
6207
6208 bool TypeFunction::parameterEscapes(Parameter *p)
6209 {
6210 /* Scope parameters do not escape.
6211 * Allow 'lazy' to imply 'scope' -
6212 * lazy parameters can be passed along
6213 * as lazy parameters to the next function, but that isn't
6214 * escaping.
6215 */
6216 if (parameterStorageClass(p) & (STCscope | STClazy))
6217 return false;
6218 return true;
6219 }
6220
6221 /************************************
6222 * Take the specified storage class for p,
6223 * and use the function signature to infer whether
6224 * STCscope and STCreturn should be OR'd in.
6225 * (This will not affect the name mangling.)
6226 * Params:
6227 * p = one of the parameters to 'this'
6228 * Returns:
6229 * storage class with STCscope or STCreturn OR'd in
6230 */
6231 StorageClass TypeFunction::parameterStorageClass(Parameter *p)
6232 {
6233 StorageClass stc = p->storageClass;
6234 if (!global.params.vsafe)
6235 return stc;
6236
6237 if (stc & (STCscope | STCreturn | STClazy) || purity == PUREimpure)
6238 return stc;
6239
6240 /* If haven't inferred the return type yet, can't infer storage classes
6241 */
6242 if (!nextOf())
6243 return stc;
6244
6245 purityLevel();
6246
6247 // See if p can escape via any of the other parameters
6248 if (purity == PUREweak)
6249 {
6250 const size_t dim = Parameter::dim(parameters);
6251 for (size_t i = 0; i < dim; i++)
6252 {
6253 Parameter *fparam = Parameter::getNth(parameters, i);
6254 Type *t = fparam->type;
6255 if (!t)
6256 continue;
6257 t = t->baseElemOf();
6258 if (t->isMutable() && t->hasPointers())
6259 {
6260 if (fparam->storageClass & (STCref | STCout))
6261 {
6262 }
6263 else if (t->ty == Tarray || t->ty == Tpointer)
6264 {
6265 Type *tn = t->nextOf()->toBasetype();
6266 if (!(tn->isMutable() && tn->hasPointers()))
6267 continue;
6268 }
6269 return stc;
6270 }
6271 }
6272 }
6273
6274 stc |= STCscope;
6275
6276 /* Inferring STCreturn here has false positives
6277 * for pure functions, producing spurious error messages
6278 * about escaping references.
6279 * Give up on it for now.
6280 */
6281 return stc;
6282 }
6283
6284 Expression *TypeFunction::defaultInit(Loc loc)
6285 {
6286 error(loc, "function does not have a default initializer");
6287 return new ErrorExp();
6288 }
6289
6290 Type *TypeFunction::addStorageClass(StorageClass stc)
6291 {
6292 //printf("addStorageClass(%llx) %d\n", stc, (stc & STCscope) != 0);
6293 TypeFunction *t = Type::addStorageClass(stc)->toTypeFunction();
6294 if ((stc & STCpure && !t->purity) ||
6295 (stc & STCnothrow && !t->isnothrow) ||
6296 (stc & STCnogc && !t->isnogc) ||
6297 (stc & STCscope && !t->isscope) ||
6298 (stc & STCsafe && t->trust < TRUSTtrusted))
6299 {
6300 // Klunky to change these
6301 TypeFunction *tf = new TypeFunction(t->parameters, t->next, t->varargs, t->linkage, 0);
6302 tf->mod = t->mod;
6303 tf->fargs = fargs;
6304 tf->purity = t->purity;
6305 tf->isnothrow = t->isnothrow;
6306 tf->isnogc = t->isnogc;
6307 tf->isproperty = t->isproperty;
6308 tf->isref = t->isref;
6309 tf->isreturn = t->isreturn;
6310 tf->isscope = t->isscope;
6311 tf->isscopeinferred = t->isscopeinferred;
6312 tf->trust = t->trust;
6313 tf->iswild = t->iswild;
6314
6315 if (stc & STCpure)
6316 tf->purity = PUREfwdref;
6317 if (stc & STCnothrow)
6318 tf->isnothrow = true;
6319 if (stc & STCnogc)
6320 tf->isnogc = true;
6321 if (stc & STCsafe)
6322 tf->trust = TRUSTsafe;
6323 if (stc & STCscope)
6324 {
6325 tf->isscope = true;
6326 if (stc & STCscopeinferred)
6327 tf->isscopeinferred = true;
6328 }
6329
6330 tf->deco = tf->merge()->deco;
6331 t = tf;
6332 }
6333 return t;
6334 }
6335
6336 /** For each active attribute (ref/const/nogc/etc) call fp with a void* for the
6337 work param and a string representation of the attribute. */
6338 int TypeFunction::attributesApply(void *param, int (*fp)(void *, const char *), TRUSTformat trustFormat)
6339 {
6340 int res = 0;
6341
6342 if (purity) res = fp(param, "pure");
6343 if (res) return res;
6344
6345 if (isnothrow) res = fp(param, "nothrow");
6346 if (res) return res;
6347
6348 if (isnogc) res = fp(param, "@nogc");
6349 if (res) return res;
6350
6351 if (isproperty) res = fp(param, "@property");
6352 if (res) return res;
6353
6354 if (isref) res = fp(param, "ref");
6355 if (res) return res;
6356
6357 if (isreturn) res = fp(param, "return");
6358 if (res) return res;
6359
6360 if (isscope && !isscopeinferred) res = fp(param, "scope");
6361 if (res) return res;
6362
6363 TRUST trustAttrib = trust;
6364
6365 if (trustAttrib == TRUSTdefault)
6366 {
6367 // Print out "@system" when trust equals TRUSTdefault (if desired).
6368 if (trustFormat == TRUSTformatSystem)
6369 trustAttrib = TRUSTsystem;
6370 else
6371 return res; // avoid calling with an empty string
6372 }
6373
6374 return fp(param, trustToChars(trustAttrib));
6375 }
6376
6377 /***************************** TypeDelegate *****************************/
6378
6379 TypeDelegate::TypeDelegate(Type *t)
6380 : TypeNext(Tfunction, t)
6381 {
6382 ty = Tdelegate;
6383 }
6384
6385 TypeDelegate *TypeDelegate::create(Type *t)
6386 {
6387 return new TypeDelegate(t);
6388 }
6389
6390 const char *TypeDelegate::kind()
6391 {
6392 return "delegate";
6393 }
6394
6395 Type *TypeDelegate::syntaxCopy()
6396 {
6397 Type *t = next->syntaxCopy();
6398 if (t == next)
6399 t = this;
6400 else
6401 {
6402 t = new TypeDelegate(t);
6403 t->mod = mod;
6404 }
6405 return t;
6406 }
6407
6408 Type *TypeDelegate::semantic(Loc loc, Scope *sc)
6409 {
6410 //printf("TypeDelegate::semantic() %s\n", toChars());
6411 if (deco) // if semantic() already run
6412 {
6413 //printf("already done\n");
6414 return this;
6415 }
6416 next = next->semantic(loc,sc);
6417 if (next->ty != Tfunction)
6418 return terror;
6419
6420 /* In order to deal with Bugzilla 4028, perhaps default arguments should
6421 * be removed from next before the merge.
6422 */
6423
6424 /* Don't return merge(), because arg identifiers and default args
6425 * can be different
6426 * even though the types match
6427 */
6428 deco = merge()->deco;
6429 return this;
6430 }
6431
6432 Type *TypeDelegate::addStorageClass(StorageClass stc)
6433 {
6434 TypeDelegate *t = (TypeDelegate*)Type::addStorageClass(stc);
6435 if (!global.params.vsafe)
6436 return t;
6437
6438 /* The rest is meant to add 'scope' to a delegate declaration if it is of the form:
6439 * alias dg_t = void* delegate();
6440 * scope dg_t dg = ...;
6441 */
6442 if(stc & STCscope)
6443 {
6444 Type *n = t->next->addStorageClass(STCscope | STCscopeinferred);
6445 if (n != t->next)
6446 {
6447 t->next = n;
6448 t->deco = t->merge()->deco; // mangling supposed to not be changed due to STCscopeinferrred
6449 }
6450 }
6451 return t;
6452 }
6453
6454 d_uns64 TypeDelegate::size(Loc)
6455 {
6456 return Target::ptrsize * 2;
6457 }
6458
6459 unsigned TypeDelegate::alignsize()
6460 {
6461 return Target::ptrsize;
6462 }
6463
6464 MATCH TypeDelegate::implicitConvTo(Type *to)
6465 {
6466 //printf("TypeDelegate::implicitConvTo(this=%p, to=%p)\n", this, to);
6467 //printf("from: %s\n", toChars());
6468 //printf("to : %s\n", to->toChars());
6469 if (this == to)
6470 return MATCHexact;
6471 #if 1 // not allowing covariant conversions because it interferes with overriding
6472 if (to->ty == Tdelegate && this->nextOf()->covariant(to->nextOf()) == 1)
6473 {
6474 Type *tret = this->next->nextOf();
6475 Type *toret = ((TypeDelegate *)to)->next->nextOf();
6476 if (tret->ty == Tclass && toret->ty == Tclass)
6477 {
6478 /* Bugzilla 10219: Check covariant interface return with offset tweaking.
6479 * interface I {}
6480 * class C : Object, I {}
6481 * I delegate() dg = delegate C() {} // should be error
6482 */
6483 int offset = 0;
6484 if (toret->isBaseOf(tret, &offset) && offset != 0)
6485 return MATCHnomatch;
6486 }
6487 return MATCHconvert;
6488 }
6489 #endif
6490 return MATCHnomatch;
6491 }
6492
6493 Expression *TypeDelegate::defaultInit(Loc loc)
6494 {
6495 return new NullExp(loc, this);
6496 }
6497
6498 bool TypeDelegate::isZeroInit(Loc)
6499 {
6500 return true;
6501 }
6502
6503 bool TypeDelegate::isBoolean()
6504 {
6505 return true;
6506 }
6507
6508 Expression *TypeDelegate::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
6509 {
6510 if (ident == Id::ptr)
6511 {
6512 e = new DelegatePtrExp(e->loc, e);
6513 e = ::semantic(e, sc);
6514 }
6515 else if (ident == Id::funcptr)
6516 {
6517 if (!(flag & 2) && sc->func && !sc->intypeof && sc->func->setUnsafe())
6518 {
6519 e->error("%s.funcptr cannot be used in @safe code", e->toChars());
6520 return new ErrorExp();
6521 }
6522 e = new DelegateFuncptrExp(e->loc, e);
6523 e = ::semantic(e, sc);
6524 }
6525 else
6526 {
6527 e = Type::dotExp(sc, e, ident, flag);
6528 }
6529 return e;
6530 }
6531
6532 bool TypeDelegate::hasPointers()
6533 {
6534 return true;
6535 }
6536
6537
6538
6539 /***************************** TypeQualified *****************************/
6540
6541 TypeQualified::TypeQualified(TY ty, Loc loc)
6542 : Type(ty)
6543 {
6544 this->loc = loc;
6545 }
6546
6547 void TypeQualified::syntaxCopyHelper(TypeQualified *t)
6548 {
6549 //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars());
6550 idents.setDim(t->idents.dim);
6551 for (size_t i = 0; i < idents.dim; i++)
6552 {
6553 RootObject *id = t->idents[i];
6554 if (id->dyncast() == DYNCAST_DSYMBOL)
6555 {
6556 TemplateInstance *ti = (TemplateInstance *)id;
6557
6558 ti = (TemplateInstance *)ti->syntaxCopy(NULL);
6559 id = ti;
6560 }
6561 else if (id->dyncast() == DYNCAST_EXPRESSION)
6562 {
6563 Expression *e = (Expression *)id;
6564 e = e->syntaxCopy();
6565 id = e;
6566 }
6567 else if (id->dyncast() == DYNCAST_TYPE)
6568 {
6569 Type *tx = (Type *)id;
6570 tx = tx->syntaxCopy();
6571 id = tx;
6572 }
6573 idents[i] = id;
6574 }
6575 }
6576
6577 void TypeQualified::addIdent(Identifier *ident)
6578 {
6579 idents.push(ident);
6580 }
6581
6582 void TypeQualified::addInst(TemplateInstance *inst)
6583 {
6584 idents.push(inst);
6585 }
6586
6587 void TypeQualified::addIndex(RootObject *e)
6588 {
6589 idents.push(e);
6590 }
6591
6592 d_uns64 TypeQualified::size(Loc)
6593 {
6594 error(this->loc, "size of type %s is not known", toChars());
6595 return SIZE_INVALID;
6596 }
6597
6598 /*************************************
6599 * Resolve a tuple index.
6600 */
6601 void TypeQualified::resolveTupleIndex(Loc loc, Scope *sc, Dsymbol *s,
6602 Expression **pe, Type **pt, Dsymbol **ps, RootObject *oindex)
6603 {
6604 *pt = NULL;
6605 *ps = NULL;
6606 *pe = NULL;
6607
6608 TupleDeclaration *td = s->isTupleDeclaration();
6609
6610 Expression *eindex = isExpression(oindex);
6611 Type *tindex = isType(oindex);
6612 Dsymbol *sindex = isDsymbol(oindex);
6613
6614 if (!td)
6615 {
6616 // It's really an index expression
6617 if (tindex)
6618 eindex = new TypeExp(loc, tindex);
6619 else if (sindex)
6620 eindex = ::resolve(loc, sc, sindex, false);
6621 Expression *e = new IndexExp(loc, ::resolve(loc, sc, s, false), eindex);
6622 e = ::semantic(e, sc);
6623 resolveExp(e, pt, pe, ps);
6624 return;
6625 }
6626
6627 // Convert oindex to Expression, then try to resolve to constant.
6628 if (tindex)
6629 tindex->resolve(loc, sc, &eindex, &tindex, &sindex);
6630 if (sindex)
6631 eindex = ::resolve(loc, sc, sindex, false);
6632 if (!eindex)
6633 {
6634 ::error(loc, "index is %s not an expression", oindex->toChars());
6635 *pt = Type::terror;
6636 return;
6637 }
6638 sc = sc->startCTFE();
6639 eindex = ::semantic(eindex, sc);
6640 sc = sc->endCTFE();
6641
6642 eindex = eindex->ctfeInterpret();
6643 if (eindex->op == TOKerror)
6644 {
6645 *pt = Type::terror;
6646 return;
6647 }
6648
6649 const uinteger_t d = eindex->toUInteger();
6650 if (d >= td->objects->dim)
6651 {
6652 ::error(loc, "tuple index %llu exceeds length %u", (ulonglong)d, (unsigned)td->objects->dim);
6653 *pt = Type::terror;
6654 return;
6655 }
6656
6657 RootObject *o = (*td->objects)[(size_t)d];
6658 *pt = isType(o);
6659 *ps = isDsymbol(o);
6660 *pe = isExpression(o);
6661
6662 if (*pt)
6663 *pt = (*pt)->semantic(loc, sc);
6664 if (*pe)
6665 resolveExp(*pe, pt, pe, ps);
6666 }
6667
6668 /*************************************
6669 * Takes an array of Identifiers and figures out if
6670 * it represents a Type or an Expression.
6671 * Output:
6672 * if expression, *pe is set
6673 * if type, *pt is set
6674 */
6675 void TypeQualified::resolveHelper(Loc loc, Scope *sc,
6676 Dsymbol *s, Dsymbol *,
6677 Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
6678 {
6679 *pe = NULL;
6680 *pt = NULL;
6681 *ps = NULL;
6682 if (s)
6683 {
6684 //printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
6685 Declaration *d = s->isDeclaration();
6686 if (d && (d->storage_class & STCtemplateparameter))
6687 s = s->toAlias();
6688 else
6689 s->checkDeprecated(loc, sc); // check for deprecated aliases
6690
6691 s = s->toAlias();
6692 //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
6693 for (size_t i = 0; i < idents.dim; i++)
6694 {
6695 RootObject *id = idents[i];
6696
6697 if (id->dyncast() == DYNCAST_EXPRESSION ||
6698 id->dyncast() == DYNCAST_TYPE)
6699 {
6700 Type *tx;
6701 Expression *ex;
6702 Dsymbol *sx;
6703 resolveTupleIndex(loc, sc, s, &ex, &tx, &sx, id);
6704 if (sx)
6705 {
6706 s = sx->toAlias();
6707 continue;
6708 }
6709 if (tx)
6710 ex = new TypeExp(loc, tx);
6711 assert(ex);
6712
6713 ex = typeToExpressionHelper(this, ex, i + 1);
6714 ex = ::semantic(ex, sc);
6715 resolveExp(ex, pt, pe, ps);
6716 return;
6717 }
6718
6719 Type *t = s->getType(); // type symbol, type alias, or type tuple?
6720 unsigned errorsave = global.errors;
6721 Dsymbol *sm = s->searchX(loc, sc, id);
6722 if (sm && !(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, sm))
6723 {
6724 ::deprecation(loc, "%s is not visible from module %s", sm->toPrettyChars(), sc->_module->toChars());
6725 // sm = NULL;
6726 }
6727 if (global.errors != errorsave)
6728 {
6729 *pt = Type::terror;
6730 return;
6731 }
6732 //printf("\t3: s = %p %s %s, sm = %p\n", s, s->kind(), s->toChars(), sm);
6733 if (intypeid && !t && sm && sm->needThis())
6734 goto L3;
6735 if (VarDeclaration *v = s->isVarDeclaration())
6736 {
6737 // https://issues.dlang.org/show_bug.cgi?id=19913
6738 // v->type would be null if it is a forward referenced member.
6739 if (v->type == NULL)
6740 v->semantic(sc);
6741 if (v->storage_class & (STCconst | STCimmutable | STCmanifest) ||
6742 v->type->isConst() || v->type->isImmutable())
6743 {
6744 // Bugzilla 13087: this.field is not constant always
6745 if (!v->isThisDeclaration())
6746 goto L3;
6747 }
6748 }
6749 if (!sm)
6750 {
6751 if (!t)
6752 {
6753 if (s->isDeclaration()) // var, func, or tuple declaration?
6754 {
6755 t = s->isDeclaration()->type;
6756 if (!t && s->isTupleDeclaration()) // expression tuple?
6757 goto L3;
6758 }
6759 else if (s->isTemplateInstance() ||
6760 s->isImport() || s->isPackage() || s->isModule())
6761 {
6762 goto L3;
6763 }
6764 }
6765 if (t)
6766 {
6767 sm = t->toDsymbol(sc);
6768 if (sm && id->dyncast() == DYNCAST_IDENTIFIER)
6769 {
6770 sm = sm->search(loc, (Identifier *)id);
6771 if (sm)
6772 goto L2;
6773 }
6774 L3:
6775 Expression *e;
6776 VarDeclaration *v = s->isVarDeclaration();
6777 FuncDeclaration *f = s->isFuncDeclaration();
6778 if (intypeid || (!v && !f))
6779 e = ::resolve(loc, sc, s, true);
6780 else
6781 e = new VarExp(loc, s->isDeclaration(), true);
6782
6783 e = typeToExpressionHelper(this, e, i);
6784 e = ::semantic(e, sc);
6785 resolveExp(e, pt, pe, ps);
6786 return;
6787 }
6788 else
6789 {
6790 if (id->dyncast() == DYNCAST_DSYMBOL)
6791 {
6792 // searchX already handles errors for template instances
6793 assert(global.errors);
6794 }
6795 else
6796 {
6797 assert(id->dyncast() == DYNCAST_IDENTIFIER);
6798 sm = s->search_correct((Identifier *)id);
6799 if (sm)
6800 error(loc, "identifier '%s' of '%s' is not defined, did you mean %s '%s'?",
6801 id->toChars(), toChars(), sm->kind(), sm->toChars());
6802 else
6803 error(loc, "identifier '%s' of '%s' is not defined", id->toChars(), toChars());
6804 }
6805 *pe = new ErrorExp();
6806 }
6807 return;
6808 }
6809 L2:
6810 s = sm->toAlias();
6811 }
6812
6813 if (EnumMember *em = s->isEnumMember())
6814 {
6815 // It's not a type, it's an expression
6816 *pe = em->getVarExp(loc, sc);
6817 return;
6818 }
6819 if (VarDeclaration *v = s->isVarDeclaration())
6820 {
6821 /* This is mostly same with DsymbolExp::semantic(), but we cannot use it
6822 * because some variables used in type context need to prevent lowering
6823 * to a literal or contextful expression. For example:
6824 *
6825 * enum a = 1; alias b = a;
6826 * template X(alias e){ alias v = e; } alias x = X!(1);
6827 * struct S { int v; alias w = v; }
6828 * // TypeIdentifier 'a', 'e', and 'v' should be TOKvar,
6829 * // because getDsymbol() need to work in AliasDeclaration::semantic().
6830 */
6831 if (!v->type ||
6832 (!v->type->deco && v->inuse))
6833 {
6834 if (v->inuse) // Bugzilla 9494
6835 error(loc, "circular reference to %s '%s'", v->kind(), v->toPrettyChars());
6836 else
6837 error(loc, "forward reference to %s '%s'", v->kind(), v->toPrettyChars());
6838 *pt = Type::terror;
6839 return;
6840 }
6841 if (v->type->ty == Terror)
6842 *pt = Type::terror;
6843 else
6844 *pe = new VarExp(loc, v);
6845 return;
6846 }
6847 if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
6848 {
6849 //printf("'%s' is a function literal\n", fld->toChars());
6850 *pe = new FuncExp(loc, fld);
6851 *pe = ::semantic(*pe, sc);
6852 return;
6853 }
6854 L1:
6855 Type *t = s->getType();
6856 if (!t)
6857 {
6858 // If the symbol is an import, try looking inside the import
6859 if (Import *si = s->isImport())
6860 {
6861 s = si->search(loc, s->ident);
6862 if (s && s != si)
6863 goto L1;
6864 s = si;
6865 }
6866 *ps = s;
6867 return;
6868 }
6869 if (t->ty == Tinstance && t != this && !t->deco)
6870 {
6871 if (!((TypeInstance *)t)->tempinst->errors)
6872 error(loc, "forward reference to '%s'", t->toChars());
6873 *pt = Type::terror;
6874 return;
6875 }
6876
6877 if (t->ty == Ttuple)
6878 *pt = t;
6879 else
6880 *pt = t->merge();
6881 }
6882 if (!s)
6883 {
6884 /* Look for what user might have intended
6885 */
6886 const char *p = mutableOf()->unSharedOf()->toChars();
6887 Identifier *id = Identifier::idPool(p, strlen(p));
6888 if (const char *n = importHint(p))
6889 error(loc, "`%s` is not defined, perhaps `import %s;` ?", p, n);
6890 else if (Dsymbol *s2 = sc->search_correct(id))
6891 error(loc, "undefined identifier `%s`, did you mean %s `%s`?", p, s2->kind(), s2->toChars());
6892 else if (const char *q = Scope::search_correct_C(id))
6893 error(loc, "undefined identifier `%s`, did you mean `%s`?", p, q);
6894 else
6895 error(loc, "undefined identifier `%s`", p);
6896
6897 *pt = Type::terror;
6898 }
6899 }
6900
6901 /***************************** TypeIdentifier *****************************/
6902
6903 TypeIdentifier::TypeIdentifier(Loc loc, Identifier *ident)
6904 : TypeQualified(Tident, loc)
6905 {
6906 this->ident = ident;
6907 }
6908
6909 const char *TypeIdentifier::kind()
6910 {
6911 return "identifier";
6912 }
6913
6914 Type *TypeIdentifier::syntaxCopy()
6915 {
6916 TypeIdentifier *t = new TypeIdentifier(loc, ident);
6917 t->syntaxCopyHelper(this);
6918 t->mod = mod;
6919 return t;
6920 }
6921
6922 /*************************************
6923 * Takes an array of Identifiers and figures out if
6924 * it represents a Type or an Expression.
6925 * Output:
6926 * if expression, *pe is set
6927 * if type, *pt is set
6928 */
6929
6930 void TypeIdentifier::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
6931 {
6932 //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars());
6933
6934 if ((ident->equals(Id::_super) || ident->equals(Id::This)) && !hasThis(sc))
6935 {
6936 AggregateDeclaration *ad = sc->getStructClassScope();
6937 if (ad)
6938 {
6939 ClassDeclaration *cd = ad->isClassDeclaration();
6940 if (cd)
6941 {
6942 if (ident->equals(Id::This))
6943 ident = cd->ident;
6944 else if (cd->baseClass && ident->equals(Id::_super))
6945 ident = cd->baseClass->ident;
6946 }
6947 else
6948 {
6949 StructDeclaration *sd = ad->isStructDeclaration();
6950 if (sd && ident->equals(Id::This))
6951 ident = sd->ident;
6952 }
6953 }
6954 }
6955 if (ident == Id::ctfe)
6956 {
6957 error(loc, "variable __ctfe cannot be read at compile time");
6958 *pe = NULL;
6959 *ps = NULL;
6960 *pt = Type::terror;
6961 return;
6962 }
6963
6964 Dsymbol *scopesym;
6965 Dsymbol *s = sc->search(loc, ident, &scopesym);
6966 resolveHelper(loc, sc, s, scopesym, pe, pt, ps, intypeid);
6967 if (*pt)
6968 (*pt) = (*pt)->addMod(mod);
6969 }
6970
6971 /*****************************************
6972 * See if type resolves to a symbol, if so,
6973 * return that symbol.
6974 */
6975
6976 Dsymbol *TypeIdentifier::toDsymbol(Scope *sc)
6977 {
6978 //printf("TypeIdentifier::toDsymbol('%s')\n", toChars());
6979 if (!sc)
6980 return NULL;
6981
6982 Type *t;
6983 Expression *e;
6984 Dsymbol *s;
6985
6986 resolve(loc, sc, &e, &t, &s);
6987 if (t && t->ty != Tident)
6988 s = t->toDsymbol(sc);
6989 if (e)
6990 s = getDsymbol(e);
6991
6992 return s;
6993 }
6994
6995 Type *TypeIdentifier::semantic(Loc loc, Scope *sc)
6996 {
6997 Type *t;
6998 Expression *e;
6999 Dsymbol *s;
7000
7001 //printf("TypeIdentifier::semantic(%s)\n", toChars());
7002 resolve(loc, sc, &e, &t, &s);
7003 if (t)
7004 {
7005 //printf("\tit's a type %d, %s, %s\n", t->ty, t->toChars(), t->deco);
7006 t = t->addMod(mod);
7007 }
7008 else
7009 {
7010 if (s)
7011 {
7012 s->error(loc, "is used as a type");
7013 //halt();
7014 }
7015 else
7016 error(loc, "%s is used as a type", toChars());
7017 t = terror;
7018 }
7019 //t->print();
7020 return t;
7021 }
7022
7023 /***************************** TypeInstance *****************************/
7024
7025 TypeInstance::TypeInstance(Loc loc, TemplateInstance *tempinst)
7026 : TypeQualified(Tinstance, loc)
7027 {
7028 this->tempinst = tempinst;
7029 }
7030
7031 const char *TypeInstance::kind()
7032 {
7033 return "instance";
7034 }
7035
7036 Type *TypeInstance::syntaxCopy()
7037 {
7038 //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim);
7039 TypeInstance *t = new TypeInstance(loc, (TemplateInstance *)tempinst->syntaxCopy(NULL));
7040 t->syntaxCopyHelper(this);
7041 t->mod = mod;
7042 return t;
7043 }
7044
7045 void TypeInstance::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
7046 {
7047 // Note close similarity to TypeIdentifier::resolve()
7048 *pe = NULL;
7049 *pt = NULL;
7050 *ps = NULL;
7051 //printf("TypeInstance::resolve(sc = %p, tempinst = '%s')\n", sc, tempinst->toChars());
7052 tempinst->semantic(sc);
7053 if (!global.gag && tempinst->errors)
7054 {
7055 *pt = terror;
7056 return;
7057 }
7058
7059 resolveHelper(loc, sc, tempinst, NULL, pe, pt, ps, intypeid);
7060 if (*pt)
7061 *pt = (*pt)->addMod(mod);
7062 //if (*pt) printf("pt = '%s'\n", (*pt)->toChars());
7063 }
7064
7065 Type *TypeInstance::semantic(Loc loc, Scope *sc)
7066 {
7067 Type *t;
7068 Expression *e;
7069 Dsymbol *s;
7070
7071 //printf("TypeInstance::semantic(%p, %s)\n", this, toChars());
7072 {
7073 unsigned errors = global.errors;
7074 resolve(loc, sc, &e, &t, &s);
7075 // if we had an error evaluating the symbol, suppress further errors
7076 if (!t && errors != global.errors)
7077 return terror;
7078 }
7079
7080 if (!t)
7081 {
7082 if (!e && s && s->errors)
7083 {
7084 // if there was an error evaluating the symbol, it might actually
7085 // be a type. Avoid misleading error messages.
7086 error(loc, "%s had previous errors", toChars());
7087 }
7088 else
7089 error(loc, "%s is used as a type", toChars());
7090 t = terror;
7091 }
7092 return t;
7093 }
7094
7095 Dsymbol *TypeInstance::toDsymbol(Scope *sc)
7096 {
7097 Type *t;
7098 Expression *e;
7099 Dsymbol *s;
7100
7101 //printf("TypeInstance::semantic(%s)\n", toChars());
7102 resolve(loc, sc, &e, &t, &s);
7103 if (t && t->ty != Tinstance)
7104 s = t->toDsymbol(sc);
7105
7106 return s;
7107 }
7108
7109
7110 /***************************** TypeTypeof *****************************/
7111
7112 TypeTypeof::TypeTypeof(Loc loc, Expression *exp)
7113 : TypeQualified(Ttypeof, loc)
7114 {
7115 this->exp = exp;
7116 inuse = 0;
7117 }
7118
7119 const char *TypeTypeof::kind()
7120 {
7121 return "typeof";
7122 }
7123
7124 Type *TypeTypeof::syntaxCopy()
7125 {
7126 //printf("TypeTypeof::syntaxCopy() %s\n", toChars());
7127 TypeTypeof *t = new TypeTypeof(loc, exp->syntaxCopy());
7128 t->syntaxCopyHelper(this);
7129 t->mod = mod;
7130 return t;
7131 }
7132
7133 Dsymbol *TypeTypeof::toDsymbol(Scope *sc)
7134 {
7135 //printf("TypeTypeof::toDsymbol('%s')\n", toChars());
7136 Expression *e;
7137 Type *t;
7138 Dsymbol *s;
7139 resolve(loc, sc, &e, &t, &s);
7140
7141 return s;
7142 }
7143
7144 void TypeTypeof::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
7145 {
7146 *pe = NULL;
7147 *pt = NULL;
7148 *ps = NULL;
7149
7150 //printf("TypeTypeof::resolve(sc = %p, idents = '%s')\n", sc, toChars());
7151 //static int nest; if (++nest == 50) *(char*)0=0;
7152 if (inuse)
7153 {
7154 inuse = 2;
7155 error(loc, "circular typeof definition");
7156 Lerr:
7157 *pt = Type::terror;
7158 inuse--;
7159 return;
7160 }
7161 inuse++;
7162
7163 Type *t;
7164 {
7165 /* Currently we cannot evalute 'exp' in speculative context, because
7166 * the type implementation may leak to the final execution. Consider:
7167 *
7168 * struct S(T) {
7169 * string toString() const { return "x"; }
7170 * }
7171 * void main() {
7172 * alias X = typeof(S!int());
7173 * assert(typeid(X).xtoString(null) == "x");
7174 * }
7175 */
7176 Scope *sc2 = sc->push();
7177 sc2->intypeof = 1;
7178 Expression *exp2 = ::semantic(exp, sc2);
7179 exp2 = resolvePropertiesOnly(sc2, exp2);
7180 sc2->pop();
7181
7182 if (exp2->op == TOKerror)
7183 {
7184 if (!global.gag)
7185 exp = exp2;
7186 goto Lerr;
7187 }
7188 exp = exp2;
7189
7190 if (exp->op == TOKtype ||
7191 exp->op == TOKscope)
7192 {
7193 if (exp->checkType())
7194 goto Lerr;
7195
7196 /* Today, 'typeof(func)' returns void if func is a
7197 * function template (TemplateExp), or
7198 * template lambda (FuncExp).
7199 * It's actually used in Phobos as an idiom, to branch code for
7200 * template functions.
7201 */
7202 }
7203 if (FuncDeclaration *f = exp->op == TOKvar ? (( VarExp *)exp)->var->isFuncDeclaration()
7204 : exp->op == TOKdotvar ? ((DotVarExp *)exp)->var->isFuncDeclaration() : NULL)
7205 {
7206 if (f->checkForwardRef(loc))
7207 goto Lerr;
7208 }
7209 if (FuncDeclaration *f = isFuncAddress(exp))
7210 {
7211 if (f->checkForwardRef(loc))
7212 goto Lerr;
7213 }
7214
7215 t = exp->type;
7216 if (!t)
7217 {
7218 error(loc, "expression (%s) has no type", exp->toChars());
7219 goto Lerr;
7220 }
7221 if (t->ty == Ttypeof)
7222 {
7223 error(loc, "forward reference to %s", toChars());
7224 goto Lerr;
7225 }
7226 }
7227 if (idents.dim == 0)
7228 *pt = t;
7229 else
7230 {
7231 if (Dsymbol *s = t->toDsymbol(sc))
7232 resolveHelper(loc, sc, s, NULL, pe, pt, ps, intypeid);
7233 else
7234 {
7235 Expression *e = typeToExpressionHelper(this, new TypeExp(loc, t));
7236 e = ::semantic(e, sc);
7237 resolveExp(e, pt, pe, ps);
7238 }
7239 }
7240 if (*pt)
7241 (*pt) = (*pt)->addMod(mod);
7242 inuse--;
7243 return;
7244 }
7245
7246 Type *TypeTypeof::semantic(Loc loc, Scope *sc)
7247 {
7248 //printf("TypeTypeof::semantic() %s\n", toChars());
7249
7250 Expression *e;
7251 Type *t;
7252 Dsymbol *s;
7253 resolve(loc, sc, &e, &t, &s);
7254 if (s && (t = s->getType()) != NULL)
7255 t = t->addMod(mod);
7256 if (!t)
7257 {
7258 error(loc, "%s is used as a type", toChars());
7259 t = Type::terror;
7260 }
7261 return t;
7262 }
7263
7264 d_uns64 TypeTypeof::size(Loc loc)
7265 {
7266 if (exp->type)
7267 return exp->type->size(loc);
7268 else
7269 return TypeQualified::size(loc);
7270 }
7271
7272
7273
7274 /***************************** TypeReturn *****************************/
7275
7276 TypeReturn::TypeReturn(Loc loc)
7277 : TypeQualified(Treturn, loc)
7278 {
7279 }
7280
7281 const char *TypeReturn::kind()
7282 {
7283 return "return";
7284 }
7285
7286 Type *TypeReturn::syntaxCopy()
7287 {
7288 TypeReturn *t = new TypeReturn(loc);
7289 t->syntaxCopyHelper(this);
7290 t->mod = mod;
7291 return t;
7292 }
7293
7294 Dsymbol *TypeReturn::toDsymbol(Scope *sc)
7295 {
7296 Expression *e;
7297 Type *t;
7298 Dsymbol *s;
7299 resolve(loc, sc, &e, &t, &s);
7300
7301 return s;
7302 }
7303
7304 void TypeReturn::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
7305 {
7306 *pe = NULL;
7307 *pt = NULL;
7308 *ps = NULL;
7309
7310 //printf("TypeReturn::resolve(sc = %p, idents = '%s')\n", sc, toChars());
7311 Type *t;
7312 {
7313 FuncDeclaration *func = sc->func;
7314 if (!func)
7315 {
7316 error(loc, "typeof(return) must be inside function");
7317 goto Lerr;
7318 }
7319 if (func->fes)
7320 func = func->fes->func;
7321
7322 t = func->type->nextOf();
7323 if (!t)
7324 {
7325 error(loc, "cannot use typeof(return) inside function %s with inferred return type", sc->func->toChars());
7326 goto Lerr;
7327 }
7328 }
7329 if (idents.dim == 0)
7330 *pt = t;
7331 else
7332 {
7333 if (Dsymbol *s = t->toDsymbol(sc))
7334 resolveHelper(loc, sc, s, NULL, pe, pt, ps, intypeid);
7335 else
7336 {
7337 Expression *e = typeToExpressionHelper(this, new TypeExp(loc, t));
7338 e = ::semantic(e, sc);
7339 resolveExp(e, pt, pe, ps);
7340 }
7341 }
7342 if (*pt)
7343 (*pt) = (*pt)->addMod(mod);
7344 return;
7345
7346 Lerr:
7347 *pt = Type::terror;
7348 return;
7349 }
7350
7351 Type *TypeReturn::semantic(Loc loc, Scope *sc)
7352 {
7353 //printf("TypeReturn::semantic() %s\n", toChars());
7354
7355 Expression *e;
7356 Type *t;
7357 Dsymbol *s;
7358 resolve(loc, sc, &e, &t, &s);
7359 if (s && (t = s->getType()) != NULL)
7360 t = t->addMod(mod);
7361 if (!t)
7362 {
7363 error(loc, "%s is used as a type", toChars());
7364 t = Type::terror;
7365 }
7366 return t;
7367 }
7368
7369 /***************************** TypeEnum *****************************/
7370
7371 TypeEnum::TypeEnum(EnumDeclaration *sym)
7372 : Type(Tenum)
7373 {
7374 this->sym = sym;
7375 }
7376
7377 const char *TypeEnum::kind()
7378 {
7379 return "enum";
7380 }
7381
7382 Type *TypeEnum::syntaxCopy()
7383 {
7384 return this;
7385 }
7386
7387 Type *TypeEnum::semantic(Loc, Scope *)
7388 {
7389 //printf("TypeEnum::semantic() %s\n", toChars());
7390 if (deco)
7391 return this;
7392 return merge();
7393 }
7394
7395 d_uns64 TypeEnum::size(Loc loc)
7396 {
7397 return sym->getMemtype(loc)->size(loc);
7398 }
7399
7400 unsigned TypeEnum::alignsize()
7401 {
7402 Type *t = sym->getMemtype(Loc());
7403 if (t->ty == Terror)
7404 return 4;
7405 return t->alignsize();
7406 }
7407
7408 Dsymbol *TypeEnum::toDsymbol(Scope *)
7409 {
7410 return sym;
7411 }
7412
7413 Type *TypeEnum::toBasetype()
7414 {
7415 if (!sym->members && !sym->memtype)
7416 return this;
7417 Type *tb = sym->getMemtype(Loc())->toBasetype();
7418 return tb->castMod(mod); // retain modifier bits from 'this'
7419 }
7420
7421 Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
7422 {
7423 // Bugzilla 14010
7424 if (ident == Id::_mangleof)
7425 return getProperty(e->loc, ident, flag & 1);
7426
7427 if (sym->_scope)
7428 sym->semantic(sym->_scope);
7429 if (!sym->members)
7430 {
7431 if (sym->isSpecial())
7432 {
7433 /* Special enums forward to the base type
7434 */
7435 e = sym->memtype->dotExp(sc, e, ident, flag);
7436 }
7437 else if (!(flag & 1))
7438 {
7439 sym->error("is forward referenced when looking for '%s'", ident->toChars());
7440 e = new ErrorExp();
7441 }
7442 else
7443 e = NULL;
7444 return e;
7445 }
7446
7447 Dsymbol *s = sym->search(e->loc, ident);
7448 if (!s)
7449 {
7450 if (ident == Id::max ||
7451 ident == Id::min ||
7452 ident == Id::_init)
7453 {
7454 return getProperty(e->loc, ident, flag & 1);
7455 }
7456 Expression *res = sym->getMemtype(Loc())->dotExp(sc, e, ident, 1);
7457 if (!(flag & 1) && !res)
7458 {
7459 if (Dsymbol *ns = sym->search_correct(ident))
7460 e->error("no property '%s' for type '%s'. Did you mean '%s.%s' ?",
7461 ident->toChars(), toChars(), toChars(), ns->toChars());
7462 else
7463 e->error("no property '%s' for type '%s'",
7464 ident->toChars(), toChars());
7465
7466 return new ErrorExp();
7467 }
7468 return res;
7469 }
7470 EnumMember *m = s->isEnumMember();
7471 return m->getVarExp(e->loc, sc);
7472 }
7473
7474 Expression *TypeEnum::getProperty(Loc loc, Identifier *ident, int flag)
7475 {
7476 Expression *e;
7477 if (ident == Id::max || ident == Id::min)
7478 {
7479 return sym->getMaxMinValue(loc, ident);
7480 }
7481 else if (ident == Id::_init)
7482 {
7483 e = defaultInitLiteral(loc);
7484 }
7485 else if (ident == Id::stringof)
7486 {
7487 const char *s = toChars();
7488 e = new StringExp(loc, const_cast<char *>(s), strlen(s));
7489 Scope sc;
7490 e = ::semantic(e, &sc);
7491 }
7492 else if (ident == Id::_mangleof)
7493 {
7494 e = Type::getProperty(loc, ident, flag);
7495 }
7496 else
7497 {
7498 e = toBasetype()->getProperty(loc, ident, flag);
7499 }
7500 return e;
7501 }
7502
7503 bool TypeEnum::isintegral()
7504 {
7505 return sym->getMemtype(Loc())->isintegral();
7506 }
7507
7508 bool TypeEnum::isfloating()
7509 {
7510 return sym->getMemtype(Loc())->isfloating();
7511 }
7512
7513 bool TypeEnum::isreal()
7514 {
7515 return sym->getMemtype(Loc())->isreal();
7516 }
7517
7518 bool TypeEnum::isimaginary()
7519 {
7520 return sym->getMemtype(Loc())->isimaginary();
7521 }
7522
7523 bool TypeEnum::iscomplex()
7524 {
7525 return sym->getMemtype(Loc())->iscomplex();
7526 }
7527
7528 bool TypeEnum::isunsigned()
7529 {
7530 return sym->getMemtype(Loc())->isunsigned();
7531 }
7532
7533 bool TypeEnum::isscalar()
7534 {
7535 return sym->getMemtype(Loc())->isscalar();
7536 }
7537
7538 bool TypeEnum::isString()
7539 {
7540 return sym->getMemtype(Loc())->isString();
7541 }
7542
7543 bool TypeEnum::isAssignable()
7544 {
7545 return sym->getMemtype(Loc())->isAssignable();
7546 }
7547
7548 bool TypeEnum::isBoolean()
7549 {
7550 return sym->getMemtype(Loc())->isBoolean();
7551 }
7552
7553 bool TypeEnum::needsDestruction()
7554 {
7555 return sym->getMemtype(Loc())->needsDestruction();
7556 }
7557
7558 bool TypeEnum::needsNested()
7559 {
7560 return sym->getMemtype(Loc())->needsNested();
7561 }
7562
7563 MATCH TypeEnum::implicitConvTo(Type *to)
7564 {
7565 MATCH m;
7566
7567 //printf("TypeEnum::implicitConvTo()\n");
7568 if (ty == to->ty && sym == ((TypeEnum *)to)->sym)
7569 m = (mod == to->mod) ? MATCHexact : MATCHconst;
7570 else if (sym->getMemtype(Loc())->implicitConvTo(to))
7571 m = MATCHconvert; // match with conversions
7572 else
7573 m = MATCHnomatch; // no match
7574 return m;
7575 }
7576
7577 MATCH TypeEnum::constConv(Type *to)
7578 {
7579 if (equals(to))
7580 return MATCHexact;
7581 if (ty == to->ty && sym == ((TypeEnum *)to)->sym &&
7582 MODimplicitConv(mod, to->mod))
7583 return MATCHconst;
7584 return MATCHnomatch;
7585 }
7586
7587
7588 Expression *TypeEnum::defaultInit(Loc loc)
7589 {
7590 // Initialize to first member of enum
7591 Expression *e = sym->getDefaultValue(loc);
7592 e = e->copy();
7593 e->loc = loc;
7594 e->type = this; // to deal with const, immutable, etc., variants
7595 return e;
7596 }
7597
7598 bool TypeEnum::isZeroInit(Loc loc)
7599 {
7600 return sym->getDefaultValue(loc)->isBool(false);
7601 }
7602
7603 bool TypeEnum::hasPointers()
7604 {
7605 return sym->getMemtype(Loc())->hasPointers();
7606 }
7607
7608 bool TypeEnum::hasVoidInitPointers()
7609 {
7610 return sym->getMemtype(Loc())->hasVoidInitPointers();
7611 }
7612
7613 Type *TypeEnum::nextOf()
7614 {
7615 return sym->getMemtype(Loc())->nextOf();
7616 }
7617
7618 /***************************** TypeStruct *****************************/
7619
7620 TypeStruct::TypeStruct(StructDeclaration *sym)
7621 : Type(Tstruct)
7622 {
7623 this->sym = sym;
7624 this->att = RECfwdref;
7625 this->cppmangle = CPPMANGLEdefault;
7626 }
7627
7628 TypeStruct *TypeStruct::create(StructDeclaration *sym)
7629 {
7630 return new TypeStruct(sym);
7631 }
7632
7633 const char *TypeStruct::kind()
7634 {
7635 return "struct";
7636 }
7637
7638 Type *TypeStruct::syntaxCopy()
7639 {
7640 return this;
7641 }
7642
7643 Type *TypeStruct::semantic(Loc, Scope *sc)
7644 {
7645 //printf("TypeStruct::semantic('%s')\n", sym->toChars());
7646 if (deco)
7647 {
7648 if (sc && sc->cppmangle != CPPMANGLEdefault)
7649 {
7650 if (this->cppmangle == CPPMANGLEdefault)
7651 this->cppmangle = sc->cppmangle;
7652 else
7653 assert(this->cppmangle == sc->cppmangle);
7654 }
7655 return this;
7656 }
7657
7658 /* Don't semantic for sym because it should be deferred until
7659 * sizeof needed or its members accessed.
7660 */
7661 // instead, parent should be set correctly
7662 assert(sym->parent);
7663
7664 if (sym->type->ty == Terror)
7665 return Type::terror;
7666 if (sc)
7667 this->cppmangle = sc->cppmangle;
7668 return merge();
7669 }
7670
7671 d_uns64 TypeStruct::size(Loc loc)
7672 {
7673 return sym->size(loc);
7674 }
7675
7676 unsigned TypeStruct::alignsize()
7677 {
7678 sym->size(Loc()); // give error for forward references
7679 return sym->alignsize;
7680 }
7681
7682 Dsymbol *TypeStruct::toDsymbol(Scope *)
7683 {
7684 return sym;
7685 }
7686
7687 static Dsymbol *searchSymStruct(Scope *sc, Dsymbol *sym, Expression *e, Identifier *ident)
7688 {
7689 int flags = sc->flags & SCOPEignoresymbolvisibility ? IgnoreSymbolVisibility : 0;
7690 Dsymbol *sold = NULL;
7691 if (global.params.bug10378 || global.params.check10378)
7692 {
7693 sold = sym->search(e->loc, ident, flags);
7694 if (!global.params.check10378)
7695 return sold;
7696 }
7697
7698 Dsymbol *s = sym->search(e->loc, ident, flags | SearchLocalsOnly);
7699 if (global.params.check10378)
7700 {
7701 Dsymbol *snew = s;
7702 if (sold != snew)
7703 Scope::deprecation10378(e->loc, sold, snew);
7704 if (global.params.bug10378)
7705 s = sold;
7706 }
7707 return s;
7708 }
7709
7710 Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
7711 {
7712 Dsymbol *s;
7713
7714 assert(e->op != TOKdot);
7715
7716 // Bugzilla 14010
7717 if (ident == Id::_mangleof)
7718 return getProperty(e->loc, ident, flag & 1);
7719
7720 /* If e.tupleof
7721 */
7722 if (ident == Id::_tupleof)
7723 {
7724 /* Create a TupleExp out of the fields of the struct e:
7725 * (e.field0, e.field1, e.field2, ...)
7726 */
7727 e = ::semantic(e, sc); // do this before turning on noaccesscheck
7728
7729 sym->size(e->loc); // do semantic of type
7730
7731 Expression *e0 = NULL;
7732 Expression *ev = e->op == TOKtype ? NULL : e;
7733 if (ev)
7734 ev = extractSideEffect(sc, "__tup", &e0, ev);
7735
7736 Expressions *exps = new Expressions;
7737 exps->reserve(sym->fields.dim);
7738 for (size_t i = 0; i < sym->fields.dim; i++)
7739 {
7740 VarDeclaration *v = sym->fields[i];
7741 Expression *ex;
7742 if (ev)
7743 ex = new DotVarExp(e->loc, ev, v);
7744 else
7745 {
7746 ex = new VarExp(e->loc, v);
7747 ex->type = ex->type->addMod(e->type->mod);
7748 }
7749 exps->push(ex);
7750 }
7751
7752 e = new TupleExp(e->loc, e0, exps);
7753 Scope *sc2 = sc->push();
7754 sc2->flags = sc->flags | SCOPEnoaccesscheck;
7755 e = ::semantic(e, sc2);
7756 sc2->pop();
7757 return e;
7758 }
7759
7760 s = searchSymStruct(sc, sym, e, ident);
7761 L1:
7762 if (!s)
7763 {
7764 return noMember(sc, e, ident, flag);
7765 }
7766 if (!(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, s))
7767 {
7768 ::deprecation(e->loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toPrettyChars());
7769 // return noMember(sc, e, ident, flag);
7770 }
7771 if (!s->isFuncDeclaration()) // because of overloading
7772 s->checkDeprecated(e->loc, sc);
7773 s = s->toAlias();
7774
7775 EnumMember *em = s->isEnumMember();
7776 if (em)
7777 {
7778 return em->getVarExp(e->loc, sc);
7779 }
7780
7781 if (VarDeclaration *v = s->isVarDeclaration())
7782 {
7783 if (!v->type ||
7784 (!v->type->deco && v->inuse))
7785 {
7786 if (v->inuse) // Bugzilla 9494
7787 e->error("circular reference to %s '%s'", v->kind(), v->toPrettyChars());
7788 else
7789 e->error("forward reference to %s '%s'", v->kind(), v->toPrettyChars());
7790 return new ErrorExp();
7791 }
7792 if (v->type->ty == Terror)
7793 return new ErrorExp();
7794
7795 if ((v->storage_class & STCmanifest) && v->_init)
7796 {
7797 if (v->inuse)
7798 {
7799 e->error("circular initialization of %s '%s'", v->kind(), v->toPrettyChars());
7800 return new ErrorExp();
7801 }
7802 checkAccess(e->loc, sc, NULL, v);
7803 Expression *ve = new VarExp(e->loc, v);
7804 ve = ::semantic(ve, sc);
7805 return ve;
7806 }
7807 }
7808
7809 if (Type *t = s->getType())
7810 {
7811 return ::semantic(new TypeExp(e->loc, t), sc);
7812 }
7813
7814 TemplateMixin *tm = s->isTemplateMixin();
7815 if (tm)
7816 {
7817 Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, tm));
7818 de->type = e->type;
7819 return de;
7820 }
7821
7822 TemplateDeclaration *td = s->isTemplateDeclaration();
7823 if (td)
7824 {
7825 if (e->op == TOKtype)
7826 e = new TemplateExp(e->loc, td);
7827 else
7828 e = new DotTemplateExp(e->loc, e, td);
7829 e = ::semantic(e, sc);
7830 return e;
7831 }
7832
7833 TemplateInstance *ti = s->isTemplateInstance();
7834 if (ti)
7835 {
7836 if (!ti->semanticRun)
7837 {
7838 ti->semantic(sc);
7839 if (!ti->inst || ti->errors) // if template failed to expand
7840 return new ErrorExp();
7841 }
7842 s = ti->inst->toAlias();
7843 if (!s->isTemplateInstance())
7844 goto L1;
7845 if (e->op == TOKtype)
7846 e = new ScopeExp(e->loc, ti);
7847 else
7848 e = new DotExp(e->loc, e, new ScopeExp(e->loc, ti));
7849 return ::semantic(e, sc);
7850 }
7851
7852 if (s->isImport() || s->isModule() || s->isPackage())
7853 {
7854 e = ::resolve(e->loc, sc, s, false);
7855 return e;
7856 }
7857
7858 OverloadSet *o = s->isOverloadSet();
7859 if (o)
7860 {
7861 OverExp *oe = new OverExp(e->loc, o);
7862 if (e->op == TOKtype)
7863 return oe;
7864 return new DotExp(e->loc, e, oe);
7865 }
7866
7867 Declaration *d = s->isDeclaration();
7868 if (!d)
7869 {
7870 e->error("%s.%s is not a declaration", e->toChars(), ident->toChars());
7871 return new ErrorExp();
7872 }
7873
7874 if (e->op == TOKtype)
7875 {
7876 /* It's:
7877 * Struct.d
7878 */
7879 if (TupleDeclaration *tup = d->isTupleDeclaration())
7880 {
7881 e = new TupleExp(e->loc, tup);
7882 e = ::semantic(e, sc);
7883 return e;
7884 }
7885 if (d->needThis() && sc->intypeof != 1)
7886 {
7887 /* Rewrite as:
7888 * this.d
7889 */
7890 if (hasThis(sc))
7891 {
7892 e = new DotVarExp(e->loc, new ThisExp(e->loc), d);
7893 e = ::semantic(e, sc);
7894 return e;
7895 }
7896 }
7897 if (d->semanticRun == PASSinit && d->_scope)
7898 d->semantic(d->_scope);
7899 checkAccess(e->loc, sc, e, d);
7900 VarExp *ve = new VarExp(e->loc, d);
7901 if (d->isVarDeclaration() && d->needThis())
7902 ve->type = d->type->addMod(e->type->mod);
7903 return ve;
7904 }
7905
7906 bool unreal = e->op == TOKvar && ((VarExp *)e)->var->isField();
7907 if (d->isDataseg() || (unreal && d->isField()))
7908 {
7909 // (e, d)
7910 checkAccess(e->loc, sc, e, d);
7911 Expression *ve = new VarExp(e->loc, d);
7912 e = unreal ? ve : new CommaExp(e->loc, e, ve);
7913 e = ::semantic(e, sc);
7914 return e;
7915 }
7916
7917 e = new DotVarExp(e->loc, e, d);
7918 e = ::semantic(e, sc);
7919 return e;
7920 }
7921
7922 structalign_t TypeStruct::alignment()
7923 {
7924 if (sym->alignment == 0)
7925 sym->size(sym->loc);
7926 return sym->alignment;
7927 }
7928
7929 Expression *TypeStruct::defaultInit(Loc)
7930 {
7931 Declaration *d = new SymbolDeclaration(sym->loc, sym);
7932 assert(d);
7933 d->type = this;
7934 d->storage_class |= STCrvalue; // Bugzilla 14398
7935 return new VarExp(sym->loc, d);
7936 }
7937
7938 /***************************************
7939 * Use when we prefer the default initializer to be a literal,
7940 * rather than a global immutable variable.
7941 */
7942 Expression *TypeStruct::defaultInitLiteral(Loc loc)
7943 {
7944 sym->size(loc);
7945 if (sym->sizeok != SIZEOKdone)
7946 return new ErrorExp();
7947 Expressions *structelems = new Expressions();
7948 structelems->setDim(sym->fields.dim - sym->isNested());
7949 unsigned offset = 0;
7950 for (size_t j = 0; j < structelems->dim; j++)
7951 {
7952 VarDeclaration *vd = sym->fields[j];
7953 Expression *e;
7954 if (vd->inuse)
7955 {
7956 error(loc, "circular reference to '%s'", vd->toPrettyChars());
7957 return new ErrorExp();
7958 }
7959 if (vd->offset < offset || vd->type->size() == 0)
7960 e = NULL;
7961 else if (vd->_init)
7962 {
7963 if (vd->_init->isVoidInitializer())
7964 e = NULL;
7965 else
7966 e = vd->getConstInitializer(false);
7967 }
7968 else
7969 e = vd->type->defaultInitLiteral(loc);
7970 if (e && e->op == TOKerror)
7971 return e;
7972 if (e)
7973 offset = vd->offset + (unsigned)vd->type->size();
7974 (*structelems)[j] = e;
7975 }
7976 StructLiteralExp *structinit = new StructLiteralExp(loc, (StructDeclaration *)sym, structelems);
7977
7978 /* Copy from the initializer symbol for larger symbols,
7979 * otherwise the literals expressed as code get excessively large.
7980 */
7981 if (size(loc) > Target::ptrsize * 4U && !needsNested())
7982 structinit->useStaticInit = true;
7983
7984 structinit->type = this;
7985 return structinit;
7986 }
7987
7988
7989 bool TypeStruct::isZeroInit(Loc)
7990 {
7991 return sym->zeroInit != 0;
7992 }
7993
7994 bool TypeStruct::isBoolean()
7995 {
7996 return false;
7997 }
7998
7999 bool TypeStruct::needsDestruction()
8000 {
8001 return sym->dtor != NULL;
8002 }
8003
8004 bool TypeStruct::needsNested()
8005 {
8006 if (sym->isNested())
8007 return true;
8008
8009 for (size_t i = 0; i < sym->fields.dim; i++)
8010 {
8011 VarDeclaration *v = sym->fields[i];
8012 if (!v->isDataseg() && v->type->needsNested())
8013 return true;
8014 }
8015 return false;
8016 }
8017
8018 bool TypeStruct::isAssignable()
8019 {
8020 bool assignable = true;
8021 unsigned offset = ~0; // dead-store initialize to prevent spurious warning
8022
8023 /* If any of the fields are const or immutable,
8024 * then one cannot assign this struct.
8025 */
8026 for (size_t i = 0; i < sym->fields.dim; i++)
8027 {
8028 VarDeclaration *v = sym->fields[i];
8029 //printf("%s [%d] v = (%s) %s, v->offset = %d, v->parent = %s", sym->toChars(), i, v->kind(), v->toChars(), v->offset, v->parent->kind());
8030 if (i == 0)
8031 ;
8032 else if (v->offset == offset)
8033 {
8034 /* If any fields of anonymous union are assignable,
8035 * then regard union as assignable.
8036 * This is to support unsafe things like Rebindable templates.
8037 */
8038 if (assignable)
8039 continue;
8040 }
8041 else
8042 {
8043 if (!assignable)
8044 return false;
8045 }
8046 assignable = v->type->isMutable() && v->type->isAssignable();
8047 offset = v->offset;
8048 //printf(" -> assignable = %d\n", assignable);
8049 }
8050
8051 return assignable;
8052 }
8053
8054 bool TypeStruct::hasPointers()
8055 {
8056 // Probably should cache this information in sym rather than recompute
8057 StructDeclaration *s = sym;
8058
8059 sym->size(Loc()); // give error for forward references
8060 for (size_t i = 0; i < s->fields.dim; i++)
8061 {
8062 Declaration *d = s->fields[i];
8063 if (d->storage_class & STCref || d->hasPointers())
8064 return true;
8065 }
8066 return false;
8067 }
8068
8069 bool TypeStruct::hasVoidInitPointers()
8070 {
8071 // Probably should cache this information in sym rather than recompute
8072 StructDeclaration *s = sym;
8073
8074 sym->size(Loc()); // give error for forward references
8075 for (size_t i = 0; i < s->fields.dim; i++)
8076 {
8077 VarDeclaration *v = s->fields[i];
8078 if (v->_init && v->_init->isVoidInitializer() && v->type->hasPointers())
8079 return true;
8080 if (!v->_init && v->type->hasVoidInitPointers())
8081 return true;
8082 }
8083 return false;
8084 }
8085
8086 MATCH TypeStruct::implicitConvTo(Type *to)
8087 { MATCH m;
8088
8089 //printf("TypeStruct::implicitConvTo(%s => %s)\n", toChars(), to->toChars());
8090
8091 if (ty == to->ty && sym == ((TypeStruct *)to)->sym)
8092 {
8093 m = MATCHexact; // exact match
8094 if (mod != to->mod)
8095 {
8096 m = MATCHconst;
8097 if (MODimplicitConv(mod, to->mod))
8098 ;
8099 else
8100 {
8101 /* Check all the fields. If they can all be converted,
8102 * allow the conversion.
8103 */
8104 unsigned offset = ~0; // dead-store to prevent spurious warning
8105 for (size_t i = 0; i < sym->fields.dim; i++)
8106 {
8107 VarDeclaration *v = sym->fields[i];
8108 if (i == 0)
8109 ;
8110 else if (v->offset == offset)
8111 {
8112 if (m > MATCHnomatch)
8113 continue;
8114 }
8115 else
8116 {
8117 if (m <= MATCHnomatch)
8118 return m;
8119 }
8120
8121 // 'from' type
8122 Type *tvf = v->type->addMod(mod);
8123
8124 // 'to' type
8125 Type *tv = v->type->addMod(to->mod);
8126
8127 // field match
8128 MATCH mf = tvf->implicitConvTo(tv);
8129 //printf("\t%s => %s, match = %d\n", v->type->toChars(), tv->toChars(), mf);
8130
8131 if (mf <= MATCHnomatch)
8132 return mf;
8133 if (mf < m) // if field match is worse
8134 m = mf;
8135 offset = v->offset;
8136 }
8137 }
8138 }
8139 }
8140 else if (sym->aliasthis && !(att & RECtracing))
8141 {
8142 att = (AliasThisRec)(att | RECtracing);
8143 m = aliasthisOf()->implicitConvTo(to);
8144 att = (AliasThisRec)(att & ~RECtracing);
8145 }
8146 else
8147 m = MATCHnomatch; // no match
8148 return m;
8149 }
8150
8151 MATCH TypeStruct::constConv(Type *to)
8152 {
8153 if (equals(to))
8154 return MATCHexact;
8155 if (ty == to->ty && sym == ((TypeStruct *)to)->sym &&
8156 MODimplicitConv(mod, to->mod))
8157 return MATCHconst;
8158 return MATCHnomatch;
8159 }
8160
8161 unsigned char TypeStruct::deduceWild(Type *t, bool isRef)
8162 {
8163 if (ty == t->ty && sym == ((TypeStruct *)t)->sym)
8164 return Type::deduceWild(t, isRef);
8165
8166 unsigned char wm = 0;
8167
8168 if (t->hasWild() && sym->aliasthis && !(att & RECtracing))
8169 {
8170 att = (AliasThisRec)(att | RECtracing);
8171 wm = aliasthisOf()->deduceWild(t, isRef);
8172 att = (AliasThisRec)(att & ~RECtracing);
8173 }
8174
8175 return wm;
8176 }
8177
8178 Type *TypeStruct::toHeadMutable()
8179 {
8180 return this;
8181 }
8182
8183
8184 /***************************** TypeClass *****************************/
8185
8186 TypeClass::TypeClass(ClassDeclaration *sym)
8187 : Type(Tclass)
8188 {
8189 this->sym = sym;
8190 this->att = RECfwdref;
8191 this->cppmangle = CPPMANGLEdefault;
8192 }
8193
8194 const char *TypeClass::kind()
8195 {
8196 return "class";
8197 }
8198
8199 Type *TypeClass::syntaxCopy()
8200 {
8201 return this;
8202 }
8203
8204 Type *TypeClass::semantic(Loc, Scope *sc)
8205 {
8206 //printf("TypeClass::semantic(%s)\n", sym->toChars());
8207 if (deco)
8208 {
8209 if (sc && sc->cppmangle != CPPMANGLEdefault)
8210 {
8211 if (this->cppmangle == CPPMANGLEdefault)
8212 this->cppmangle = sc->cppmangle;
8213 else
8214 assert(this->cppmangle == sc->cppmangle);
8215 }
8216 return this;
8217 }
8218
8219 /* Don't semantic for sym because it should be deferred until
8220 * sizeof needed or its members accessed.
8221 */
8222 // instead, parent should be set correctly
8223 assert(sym->parent);
8224
8225 if (sym->type->ty == Terror)
8226 return Type::terror;
8227 if (sc)
8228 this->cppmangle = sc->cppmangle;
8229 return merge();
8230 }
8231
8232 d_uns64 TypeClass::size(Loc)
8233 {
8234 return Target::ptrsize;
8235 }
8236
8237 Dsymbol *TypeClass::toDsymbol(Scope *)
8238 {
8239 return sym;
8240 }
8241
8242 static Dsymbol *searchSymClass(Scope *sc, Dsymbol *sym, Expression *e, Identifier *ident)
8243 {
8244 int flags = sc->flags & SCOPEignoresymbolvisibility ? IgnoreSymbolVisibility : 0;
8245 Dsymbol *sold = NULL;
8246 if (global.params.bug10378 || global.params.check10378)
8247 {
8248 sold = sym->search(e->loc, ident, flags | IgnoreSymbolVisibility);
8249 if (!global.params.check10378)
8250 return sold;
8251 }
8252
8253 Dsymbol *s = sym->search(e->loc, ident, flags | SearchLocalsOnly);
8254 if (!s && !(flags & IgnoreSymbolVisibility))
8255 {
8256 s = sym->search(e->loc, ident, flags | SearchLocalsOnly | IgnoreSymbolVisibility);
8257 if (s && !(flags & IgnoreErrors))
8258 ::deprecation(e->loc, "%s is not visible from class %s", s->toPrettyChars(), sym->toChars());
8259 }
8260 if (global.params.check10378)
8261 {
8262 Dsymbol *snew = s;
8263 if (sold != snew)
8264 Scope::deprecation10378(e->loc, sold, snew);
8265 if (global.params.bug10378)
8266 s = sold;
8267 }
8268 return s;
8269 }
8270
8271 Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident, int flag)
8272 {
8273 Dsymbol *s;
8274 assert(e->op != TOKdot);
8275
8276 // Bugzilla 12543
8277 if (ident == Id::__sizeof || ident == Id::__xalignof || ident == Id::_mangleof)
8278 {
8279 return Type::getProperty(e->loc, ident, 0);
8280 }
8281
8282 /* If e.tupleof
8283 */
8284 if (ident == Id::_tupleof)
8285 {
8286 /* Create a TupleExp
8287 */
8288 e = ::semantic(e, sc); // do this before turning on noaccesscheck
8289
8290 sym->size(e->loc); // do semantic of type
8291
8292 Expression *e0 = NULL;
8293 Expression *ev = e->op == TOKtype ? NULL : e;
8294 if (ev)
8295 ev = extractSideEffect(sc, "__tup", &e0, ev);
8296
8297 Expressions *exps = new Expressions;
8298 exps->reserve(sym->fields.dim);
8299 for (size_t i = 0; i < sym->fields.dim; i++)
8300 {
8301 VarDeclaration *v = sym->fields[i];
8302 // Don't include hidden 'this' pointer
8303 if (v->isThisDeclaration())
8304 continue;
8305 Expression *ex;
8306 if (ev)
8307 ex = new DotVarExp(e->loc, ev, v);
8308 else
8309 {
8310 ex = new VarExp(e->loc, v);
8311 ex->type = ex->type->addMod(e->type->mod);
8312 }
8313 exps->push(ex);
8314 }
8315
8316 e = new TupleExp(e->loc, e0, exps);
8317 Scope *sc2 = sc->push();
8318 sc2->flags = sc->flags | SCOPEnoaccesscheck;
8319 e = ::semantic(e, sc2);
8320 sc2->pop();
8321 return e;
8322 }
8323
8324 s = searchSymClass(sc, sym, e, ident);
8325 L1:
8326 if (!s)
8327 {
8328 // See if it's 'this' class or a base class
8329 if (sym->ident == ident)
8330 {
8331 if (e->op == TOKtype)
8332 return Type::getProperty(e->loc, ident, 0);
8333 e = new DotTypeExp(e->loc, e, sym);
8334 e = ::semantic(e, sc);
8335 return e;
8336 }
8337 if (ClassDeclaration *cbase = sym->searchBase(ident))
8338 {
8339 if (e->op == TOKtype)
8340 return Type::getProperty(e->loc, ident, 0);
8341 if (InterfaceDeclaration *ifbase = cbase->isInterfaceDeclaration())
8342 e = new CastExp(e->loc, e, ifbase->type);
8343 else
8344 e = new DotTypeExp(e->loc, e, cbase);
8345 e = ::semantic(e, sc);
8346 return e;
8347 }
8348
8349 if (ident == Id::classinfo)
8350 {
8351 assert(Type::typeinfoclass);
8352 Type *t = Type::typeinfoclass->type;
8353 if (e->op == TOKtype || e->op == TOKdottype)
8354 {
8355 /* For type.classinfo, we know the classinfo
8356 * at compile time.
8357 */
8358 if (!sym->vclassinfo)
8359 sym->vclassinfo = new TypeInfoClassDeclaration(sym->type);
8360 e = new VarExp(e->loc, sym->vclassinfo);
8361 e = e->addressOf();
8362 e->type = t; // do this so we don't get redundant dereference
8363 }
8364 else
8365 {
8366 /* For class objects, the classinfo reference is the first
8367 * entry in the vtbl[]
8368 */
8369 e = new PtrExp(e->loc, e);
8370 e->type = t->pointerTo();
8371 if (sym->isInterfaceDeclaration())
8372 {
8373 if (sym->isCPPinterface())
8374 {
8375 /* C++ interface vtbl[]s are different in that the
8376 * first entry is always pointer to the first virtual
8377 * function, not classinfo.
8378 * We can't get a .classinfo for it.
8379 */
8380 error(e->loc, "no .classinfo for C++ interface objects");
8381 }
8382 /* For an interface, the first entry in the vtbl[]
8383 * is actually a pointer to an instance of struct Interface.
8384 * The first member of Interface is the .classinfo,
8385 * so add an extra pointer indirection.
8386 */
8387 e->type = e->type->pointerTo();
8388 e = new PtrExp(e->loc, e);
8389 e->type = t->pointerTo();
8390 }
8391 e = new PtrExp(e->loc, e, t);
8392 }
8393 return e;
8394 }
8395
8396 if (ident == Id::__vptr)
8397 {
8398 /* The pointer to the vtbl[]
8399 * *cast(immutable(void*)**)e
8400 */
8401 e = e->castTo(sc, tvoidptr->immutableOf()->pointerTo()->pointerTo());
8402 e = new PtrExp(e->loc, e);
8403 e = ::semantic(e, sc);
8404 return e;
8405 }
8406
8407 if (ident == Id::__monitor)
8408 {
8409 /* The handle to the monitor (call it a void*)
8410 * *(cast(void**)e + 1)
8411 */
8412 e = e->castTo(sc, tvoidptr->pointerTo());
8413 e = new AddExp(e->loc, e, new IntegerExp(1));
8414 e = new PtrExp(e->loc, e);
8415 e = ::semantic(e, sc);
8416 return e;
8417 }
8418
8419 if (ident == Id::outer && sym->vthis)
8420 {
8421 if (sym->vthis->_scope)
8422 sym->vthis->semantic(NULL);
8423
8424 if (ClassDeclaration *cdp = sym->toParent2()->isClassDeclaration())
8425 {
8426 DotVarExp *dve = new DotVarExp(e->loc, e, sym->vthis);
8427 dve->type = cdp->type->addMod(e->type->mod);
8428 return dve;
8429 }
8430
8431 /* Bugzilla 15839: Find closest parent class through nested functions.
8432 */
8433 for (Dsymbol *p = sym->toParent2(); p; p = p->toParent2())
8434 {
8435 FuncDeclaration *fd = p->isFuncDeclaration();
8436 if (!fd)
8437 break;
8438 if (fd->isNested())
8439 continue;
8440 AggregateDeclaration *ad = fd->isThis();
8441 if (!ad)
8442 break;
8443 if (ad->isClassDeclaration())
8444 {
8445 ThisExp *ve = new ThisExp(e->loc);
8446
8447 ve->var = fd->vthis;
8448 const bool nestedError = fd->vthis->checkNestedReference(sc, e->loc);
8449 assert(!nestedError);
8450
8451 ve->type = fd->vthis->type->addMod(e->type->mod);
8452 return ve;
8453 }
8454 break;
8455 }
8456
8457 // Continue to show enclosing function's frame (stack or closure).
8458 DotVarExp *dve = new DotVarExp(e->loc, e, sym->vthis);
8459 dve->type = sym->vthis->type->addMod(e->type->mod);
8460 return dve;
8461 }
8462
8463 return noMember(sc, e, ident, flag & 1);
8464 }
8465 if (!(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc, s))
8466 {
8467 ::deprecation(e->loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toPrettyChars());
8468 // return noMember(sc, e, ident, flag);
8469 }
8470 if (!s->isFuncDeclaration()) // because of overloading
8471 s->checkDeprecated(e->loc, sc);
8472 s = s->toAlias();
8473
8474 EnumMember *em = s->isEnumMember();
8475 if (em)
8476 {
8477 return em->getVarExp(e->loc, sc);
8478 }
8479
8480 if (VarDeclaration *v = s->isVarDeclaration())
8481 {
8482 if (!v->type ||
8483 (!v->type->deco && v->inuse))
8484 {
8485 if (v->inuse) // Bugzilla 9494
8486 e->error("circular reference to %s '%s'", v->kind(), v->toPrettyChars());
8487 else
8488 e->error("forward reference to %s '%s'", v->kind(), v->toPrettyChars());
8489 return new ErrorExp();
8490 }
8491 if (v->type->ty == Terror)
8492 return new ErrorExp();
8493
8494 if ((v->storage_class & STCmanifest) && v->_init)
8495 {
8496 if (v->inuse)
8497 {
8498 e->error("circular initialization of %s '%s'", v->kind(), v->toPrettyChars());
8499 return new ErrorExp();
8500 }
8501 checkAccess(e->loc, sc, NULL, v);
8502 Expression *ve = new VarExp(e->loc, v);
8503 ve = ::semantic(ve, sc);
8504 return ve;
8505 }
8506 }
8507
8508 if (Type *t = s->getType())
8509 {
8510 return ::semantic(new TypeExp(e->loc, t), sc);
8511 }
8512
8513 TemplateMixin *tm = s->isTemplateMixin();
8514 if (tm)
8515 {
8516 Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, tm));
8517 de->type = e->type;
8518 return de;
8519 }
8520
8521 TemplateDeclaration *td = s->isTemplateDeclaration();
8522 if (td)
8523 {
8524 if (e->op == TOKtype)
8525 e = new TemplateExp(e->loc, td);
8526 else
8527 e = new DotTemplateExp(e->loc, e, td);
8528 e = ::semantic(e, sc);
8529 return e;
8530 }
8531
8532 TemplateInstance *ti = s->isTemplateInstance();
8533 if (ti)
8534 {
8535 if (!ti->semanticRun)
8536 {
8537 ti->semantic(sc);
8538 if (!ti->inst || ti->errors) // if template failed to expand
8539 return new ErrorExp();
8540 }
8541 s = ti->inst->toAlias();
8542 if (!s->isTemplateInstance())
8543 goto L1;
8544 if (e->op == TOKtype)
8545 e = new ScopeExp(e->loc, ti);
8546 else
8547 e = new DotExp(e->loc, e, new ScopeExp(e->loc, ti));
8548 return ::semantic(e, sc);
8549 }
8550
8551 if (s->isImport() || s->isModule() || s->isPackage())
8552 {
8553 e = ::resolve(e->loc, sc, s, false);
8554 return e;
8555 }
8556
8557 OverloadSet *o = s->isOverloadSet();
8558 if (o)
8559 {
8560 OverExp *oe = new OverExp(e->loc, o);
8561 if (e->op == TOKtype)
8562 return oe;
8563 return new DotExp(e->loc, e, oe);
8564 }
8565
8566 Declaration *d = s->isDeclaration();
8567 if (!d)
8568 {
8569 e->error("%s.%s is not a declaration", e->toChars(), ident->toChars());
8570 return new ErrorExp();
8571 }
8572
8573 if (e->op == TOKtype)
8574 {
8575 /* It's:
8576 * Class.d
8577 */
8578 if (TupleDeclaration *tup = d->isTupleDeclaration())
8579 {
8580 e = new TupleExp(e->loc, tup);
8581 e = ::semantic(e, sc);
8582 return e;
8583 }
8584 if (d->needThis() && sc->intypeof != 1)
8585 {
8586 /* Rewrite as:
8587 * this.d
8588 */
8589 if (hasThis(sc))
8590 {
8591 // This is almost same as getRightThis() in expression.c
8592 Expression *e1 = new ThisExp(e->loc);
8593 e1 = ::semantic(e1, sc);
8594 L2:
8595 Type *t = e1->type->toBasetype();
8596 ClassDeclaration *cd = e->type->isClassHandle();
8597 ClassDeclaration *tcd = t->isClassHandle();
8598 if (cd && tcd && (tcd == cd || cd->isBaseOf(tcd, NULL)))
8599 {
8600 e = new DotTypeExp(e1->loc, e1, cd);
8601 e = new DotVarExp(e->loc, e, d);
8602 e = ::semantic(e, sc);
8603 return e;
8604 }
8605 if (tcd && tcd->isNested())
8606 { /* e1 is the 'this' pointer for an inner class: tcd.
8607 * Rewrite it as the 'this' pointer for the outer class.
8608 */
8609
8610 e1 = new DotVarExp(e->loc, e1, tcd->vthis);
8611 e1->type = tcd->vthis->type;
8612 e1->type = e1->type->addMod(t->mod);
8613 // Do not call checkNestedRef()
8614 //e1 = ::semantic(e1, sc);
8615
8616 // Skip up over nested functions, and get the enclosing
8617 // class type.
8618 int n = 0;
8619 for (s = tcd->toParent();
8620 s && s->isFuncDeclaration();
8621 s = s->toParent())
8622 { FuncDeclaration *f = s->isFuncDeclaration();
8623 if (f->vthis)
8624 {
8625 //printf("rewriting e1 to %s's this\n", f->toChars());
8626 n++;
8627 e1 = new VarExp(e->loc, f->vthis);
8628 }
8629 else
8630 {
8631 e = new VarExp(e->loc, d);
8632 return e;
8633 }
8634 }
8635 if (s && s->isClassDeclaration())
8636 { e1->type = s->isClassDeclaration()->type;
8637 e1->type = e1->type->addMod(t->mod);
8638 if (n > 1)
8639 e1 = ::semantic(e1, sc);
8640 }
8641 else
8642 e1 = ::semantic(e1, sc);
8643 goto L2;
8644 }
8645 }
8646 }
8647 //printf("e = %s, d = %s\n", e->toChars(), d->toChars());
8648 if (d->semanticRun == PASSinit && d->_scope)
8649 d->semantic(d->_scope);
8650 checkAccess(e->loc, sc, e, d);
8651 VarExp *ve = new VarExp(e->loc, d);
8652 if (d->isVarDeclaration() && d->needThis())
8653 ve->type = d->type->addMod(e->type->mod);
8654 return ve;
8655 }
8656
8657 bool unreal = e->op == TOKvar && ((VarExp *)e)->var->isField();
8658 if (d->isDataseg() || (unreal && d->isField()))
8659 {
8660 // (e, d)
8661 checkAccess(e->loc, sc, e, d);
8662 Expression *ve = new VarExp(e->loc, d);
8663 e = unreal ? ve : new CommaExp(e->loc, e, ve);
8664 e = ::semantic(e, sc);
8665 return e;
8666 }
8667
8668 e = new DotVarExp(e->loc, e, d);
8669 e = ::semantic(e, sc);
8670 return e;
8671 }
8672
8673 ClassDeclaration *TypeClass::isClassHandle()
8674 {
8675 return sym;
8676 }
8677
8678 bool TypeClass::isscope()
8679 {
8680 return sym->isscope;
8681 }
8682
8683 bool TypeClass::isBaseOf(Type *t, int *poffset)
8684 {
8685 if (t && t->ty == Tclass)
8686 {
8687 ClassDeclaration *cd = ((TypeClass *)t)->sym;
8688 if (sym->isBaseOf(cd, poffset))
8689 return true;
8690 }
8691 return false;
8692 }
8693
8694 MATCH TypeClass::implicitConvTo(Type *to)
8695 {
8696 //printf("TypeClass::implicitConvTo(to = '%s') %s\n", to->toChars(), toChars());
8697 MATCH m = constConv(to);
8698 if (m > MATCHnomatch)
8699 return m;
8700
8701 ClassDeclaration *cdto = to->isClassHandle();
8702 if (cdto)
8703 {
8704 //printf("TypeClass::implicitConvTo(to = '%s') %s, isbase = %d %d\n", to->toChars(), toChars(), cdto->isBaseInfoComplete(), sym->isBaseInfoComplete());
8705 if (cdto->_scope && !cdto->isBaseInfoComplete())
8706 cdto->semantic(NULL);
8707 if (sym->_scope && !sym->isBaseInfoComplete())
8708 sym->semantic(NULL);
8709 if (cdto->isBaseOf(sym, NULL) && MODimplicitConv(mod, to->mod))
8710 {
8711 //printf("'to' is base\n");
8712 return MATCHconvert;
8713 }
8714 }
8715
8716 m = MATCHnomatch;
8717 if (sym->aliasthis && !(att & RECtracing))
8718 {
8719 att = (AliasThisRec)(att | RECtracing);
8720 m = aliasthisOf()->implicitConvTo(to);
8721 att = (AliasThisRec)(att & ~RECtracing);
8722 }
8723
8724 return m;
8725 }
8726
8727 MATCH TypeClass::constConv(Type *to)
8728 {
8729 if (equals(to))
8730 return MATCHexact;
8731 if (ty == to->ty && sym == ((TypeClass *)to)->sym &&
8732 MODimplicitConv(mod, to->mod))
8733 return MATCHconst;
8734
8735 /* Conversion derived to const(base)
8736 */
8737 int offset = 0;
8738 if (to->isBaseOf(this, &offset) && offset == 0 &&
8739 MODimplicitConv(mod, to->mod))
8740 {
8741 // Disallow:
8742 // derived to base
8743 // inout(derived) to inout(base)
8744 if (!to->isMutable() && !to->isWild())
8745 return MATCHconvert;
8746 }
8747
8748 return MATCHnomatch;
8749 }
8750
8751 unsigned char TypeClass::deduceWild(Type *t, bool isRef)
8752 {
8753 ClassDeclaration *cd = t->isClassHandle();
8754 if (cd && (sym == cd || cd->isBaseOf(sym, NULL)))
8755 return Type::deduceWild(t, isRef);
8756
8757 unsigned char wm = 0;
8758
8759 if (t->hasWild() && sym->aliasthis && !(att & RECtracing))
8760 {
8761 att = (AliasThisRec)(att | RECtracing);
8762 wm = aliasthisOf()->deduceWild(t, isRef);
8763 att = (AliasThisRec)(att & ~RECtracing);
8764 }
8765
8766 return wm;
8767 }
8768
8769 Type *TypeClass::toHeadMutable()
8770 {
8771 return this;
8772 }
8773
8774 Expression *TypeClass::defaultInit(Loc loc)
8775 {
8776 return new NullExp(loc, this);
8777 }
8778
8779 bool TypeClass::isZeroInit(Loc)
8780 {
8781 return true;
8782 }
8783
8784 bool TypeClass::isBoolean()
8785 {
8786 return true;
8787 }
8788
8789 bool TypeClass::hasPointers()
8790 {
8791 return true;
8792 }
8793
8794 /***************************** TypeTuple *****************************/
8795
8796 TypeTuple::TypeTuple(Parameters *arguments)
8797 : Type(Ttuple)
8798 {
8799 //printf("TypeTuple(this = %p)\n", this);
8800 this->arguments = arguments;
8801 //printf("TypeTuple() %p, %s\n", this, toChars());
8802 }
8803
8804 /****************
8805 * Form TypeTuple from the types of the expressions.
8806 * Assume exps[] is already tuple expanded.
8807 */
8808
8809 TypeTuple::TypeTuple(Expressions *exps)
8810 : Type(Ttuple)
8811 {
8812 Parameters *arguments = new Parameters;
8813 if (exps)
8814 {
8815 arguments->setDim(exps->dim);
8816 for (size_t i = 0; i < exps->dim; i++)
8817 { Expression *e = (*exps)[i];
8818 if (e->type->ty == Ttuple)
8819 e->error("cannot form tuple of tuples");
8820 Parameter *arg = new Parameter(STCundefined, e->type, NULL, NULL);
8821 (*arguments)[i] = arg;
8822 }
8823 }
8824 this->arguments = arguments;
8825 //printf("TypeTuple() %p, %s\n", this, toChars());
8826 }
8827
8828 TypeTuple *TypeTuple::create(Parameters *arguments)
8829 {
8830 return new TypeTuple(arguments);
8831 }
8832
8833 /*******************************************
8834 * Type tuple with 0, 1 or 2 types in it.
8835 */
8836 TypeTuple::TypeTuple()
8837 : Type(Ttuple)
8838 {
8839 arguments = new Parameters();
8840 }
8841
8842 TypeTuple::TypeTuple(Type *t1)
8843 : Type(Ttuple)
8844 {
8845 arguments = new Parameters();
8846 arguments->push(new Parameter(0, t1, NULL, NULL));
8847 }
8848
8849 TypeTuple::TypeTuple(Type *t1, Type *t2)
8850 : Type(Ttuple)
8851 {
8852 arguments = new Parameters();
8853 arguments->push(new Parameter(0, t1, NULL, NULL));
8854 arguments->push(new Parameter(0, t2, NULL, NULL));
8855 }
8856
8857 const char *TypeTuple::kind()
8858 {
8859 return "tuple";
8860 }
8861
8862 Type *TypeTuple::syntaxCopy()
8863 {
8864 Parameters *args = Parameter::arraySyntaxCopy(arguments);
8865 Type *t = new TypeTuple(args);
8866 t->mod = mod;
8867 return t;
8868 }
8869
8870 Type *TypeTuple::semantic(Loc, Scope *)
8871 {
8872 //printf("TypeTuple::semantic(this = %p)\n", this);
8873 //printf("TypeTuple::semantic() %p, %s\n", this, toChars());
8874 if (!deco)
8875 deco = merge()->deco;
8876
8877 /* Don't return merge(), because a tuple with one type has the
8878 * same deco as that type.
8879 */
8880 return this;
8881 }
8882
8883 bool TypeTuple::equals(RootObject *o)
8884 {
8885 Type *t = (Type *)o;
8886 //printf("TypeTuple::equals(%s, %s)\n", toChars(), t->toChars());
8887 if (this == t)
8888 return true;
8889 if (t->ty == Ttuple)
8890 {
8891 TypeTuple *tt = (TypeTuple *)t;
8892 if (arguments->dim == tt->arguments->dim)
8893 {
8894 for (size_t i = 0; i < tt->arguments->dim; i++)
8895 {
8896 Parameter *arg1 = (*arguments)[i];
8897 Parameter *arg2 = (*tt->arguments)[i];
8898 if (!arg1->type->equals(arg2->type))
8899 return false;
8900 }
8901 return true;
8902 }
8903 }
8904 return false;
8905 }
8906
8907 Expression *TypeTuple::getProperty(Loc loc, Identifier *ident, int flag)
8908 {
8909 Expression *e;
8910
8911 if (ident == Id::length)
8912 {
8913 e = new IntegerExp(loc, arguments->dim, Type::tsize_t);
8914 }
8915 else if (ident == Id::_init)
8916 {
8917 e = defaultInitLiteral(loc);
8918 }
8919 else if (flag)
8920 {
8921 e = NULL;
8922 }
8923 else
8924 {
8925 error(loc, "no property '%s' for tuple '%s'", ident->toChars(), toChars());
8926 e = new ErrorExp();
8927 }
8928 return e;
8929 }
8930
8931 Expression *TypeTuple::defaultInit(Loc loc)
8932 {
8933 Expressions *exps = new Expressions();
8934 exps->setDim(arguments->dim);
8935 for (size_t i = 0; i < arguments->dim; i++)
8936 {
8937 Parameter *p = (*arguments)[i];
8938 assert(p->type);
8939 Expression *e = p->type->defaultInitLiteral(loc);
8940 if (e->op == TOKerror)
8941 return e;
8942 (*exps)[i] = e;
8943 }
8944 return new TupleExp(loc, exps);
8945 }
8946
8947 /***************************** TypeSlice *****************************/
8948
8949 /* This is so we can slice a TypeTuple */
8950
8951 TypeSlice::TypeSlice(Type *next, Expression *lwr, Expression *upr)
8952 : TypeNext(Tslice, next)
8953 {
8954 //printf("TypeSlice[%s .. %s]\n", lwr->toChars(), upr->toChars());
8955 this->lwr = lwr;
8956 this->upr = upr;
8957 }
8958
8959 const char *TypeSlice::kind()
8960 {
8961 return "slice";
8962 }
8963
8964 Type *TypeSlice::syntaxCopy()
8965 {
8966 Type *t = new TypeSlice(next->syntaxCopy(), lwr->syntaxCopy(), upr->syntaxCopy());
8967 t->mod = mod;
8968 return t;
8969 }
8970
8971 Type *TypeSlice::semantic(Loc loc, Scope *sc)
8972 {
8973 //printf("TypeSlice::semantic() %s\n", toChars());
8974 Type *tn = next->semantic(loc, sc);
8975 //printf("next: %s\n", tn->toChars());
8976
8977 Type *tbn = tn->toBasetype();
8978 if (tbn->ty != Ttuple)
8979 {
8980 error(loc, "can only slice tuple types, not %s", tbn->toChars());
8981 return Type::terror;
8982 }
8983 TypeTuple *tt = (TypeTuple *)tbn;
8984
8985 lwr = semanticLength(sc, tbn, lwr);
8986 lwr = lwr->ctfeInterpret();
8987 uinteger_t i1 = lwr->toUInteger();
8988
8989 upr = semanticLength(sc, tbn, upr);
8990 upr = upr->ctfeInterpret();
8991 uinteger_t i2 = upr->toUInteger();
8992
8993 if (!(i1 <= i2 && i2 <= tt->arguments->dim))
8994 {
8995 error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, tt->arguments->dim);
8996 return Type::terror;
8997 }
8998
8999 next = tn;
9000 transitive();
9001
9002 Parameters *args = new Parameters;
9003 args->reserve((size_t)(i2 - i1));
9004 for (size_t i = (size_t)i1; i < (size_t)i2; i++)
9005 {
9006 Parameter *arg = (*tt->arguments)[i];
9007 args->push(arg);
9008 }
9009 Type *t = new TypeTuple(args);
9010 return t->semantic(loc, sc);
9011 }
9012
9013 void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid)
9014 {
9015 next->resolve(loc, sc, pe, pt, ps, intypeid);
9016 if (*pe)
9017 {
9018 // It's really a slice expression
9019 if (Dsymbol *s = getDsymbol(*pe))
9020 *pe = new DsymbolExp(loc, s);
9021 *pe = new ArrayExp(loc, *pe, new IntervalExp(loc, lwr, upr));
9022 }
9023 else if (*ps)
9024 {
9025 Dsymbol *s = *ps;
9026 TupleDeclaration *td = s->isTupleDeclaration();
9027 if (td)
9028 {
9029 /* It's a slice of a TupleDeclaration
9030 */
9031 ScopeDsymbol *sym = new ArrayScopeSymbol(sc, td);
9032 sym->parent = sc->scopesym;
9033 sc = sc->push(sym);
9034 sc = sc->startCTFE();
9035 lwr = ::semantic(lwr, sc);
9036 upr = ::semantic(upr, sc);
9037 sc = sc->endCTFE();
9038 sc = sc->pop();
9039
9040 lwr = lwr->ctfeInterpret();
9041 upr = upr->ctfeInterpret();
9042 uinteger_t i1 = lwr->toUInteger();
9043 uinteger_t i2 = upr->toUInteger();
9044
9045 if (!(i1 <= i2 && i2 <= td->objects->dim))
9046 {
9047 error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, td->objects->dim);
9048 *ps = NULL;
9049 *pt = Type::terror;
9050 return;
9051 }
9052
9053 if (i1 == 0 && i2 == td->objects->dim)
9054 {
9055 *ps = td;
9056 return;
9057 }
9058
9059 /* Create a new TupleDeclaration which
9060 * is a slice [i1..i2] out of the old one.
9061 */
9062 Objects *objects = new Objects;
9063 objects->setDim((size_t)(i2 - i1));
9064 for (size_t i = 0; i < objects->dim; i++)
9065 {
9066 (*objects)[i] = (*td->objects)[(size_t)i1 + i];
9067 }
9068
9069 TupleDeclaration *tds = new TupleDeclaration(loc, td->ident, objects);
9070 *ps = tds;
9071 }
9072 else
9073 goto Ldefault;
9074 }
9075 else
9076 {
9077 if ((*pt)->ty != Terror)
9078 next = *pt; // prevent re-running semantic() on 'next'
9079 Ldefault:
9080 Type::resolve(loc, sc, pe, pt, ps, intypeid);
9081 }
9082 }
9083
9084 /***************************** TypeNull *****************************/
9085
9086 TypeNull::TypeNull()
9087 : Type(Tnull)
9088 {
9089 }
9090
9091 const char *TypeNull::kind()
9092 {
9093 return "null";
9094 }
9095
9096 Type *TypeNull::syntaxCopy()
9097 {
9098 // No semantic analysis done, no need to copy
9099 return this;
9100 }
9101
9102 MATCH TypeNull::implicitConvTo(Type *to)
9103 {
9104 //printf("TypeNull::implicitConvTo(this=%p, to=%p)\n", this, to);
9105 //printf("from: %s\n", toChars());
9106 //printf("to : %s\n", to->toChars());
9107 MATCH m = Type::implicitConvTo(to);
9108 if (m != MATCHnomatch)
9109 return m;
9110
9111 // NULL implicitly converts to any pointer type or dynamic array
9112 //if (type->ty == Tpointer && type->nextOf()->ty == Tvoid)
9113 {
9114 Type *tb = to->toBasetype();
9115 if (tb->ty == Tnull ||
9116 tb->ty == Tpointer || tb->ty == Tarray ||
9117 tb->ty == Taarray || tb->ty == Tclass ||
9118 tb->ty == Tdelegate)
9119 return MATCHconst;
9120 }
9121
9122 return MATCHnomatch;
9123 }
9124
9125 bool TypeNull::isBoolean()
9126 {
9127 return true;
9128 }
9129
9130 d_uns64 TypeNull::size(Loc loc)
9131 {
9132 return tvoidptr->size(loc);
9133 }
9134
9135 Expression *TypeNull::defaultInit(Loc)
9136 {
9137 return new NullExp(Loc(), Type::tnull);
9138 }
9139
9140 /***************************** Parameter *****************************/
9141
9142 Parameter::Parameter(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg)
9143 {
9144 this->type = type;
9145 this->ident = ident;
9146 this->storageClass = storageClass;
9147 this->defaultArg = defaultArg;
9148 }
9149
9150 Parameter *Parameter::create(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg)
9151 {
9152 return new Parameter(storageClass, type, ident, defaultArg);
9153 }
9154
9155 Parameter *Parameter::syntaxCopy()
9156 {
9157 return new Parameter(storageClass,
9158 type ? type->syntaxCopy() : NULL,
9159 ident,
9160 defaultArg ? defaultArg->syntaxCopy() : NULL);
9161 }
9162
9163 Parameters *Parameter::arraySyntaxCopy(Parameters *parameters)
9164 {
9165 Parameters *params = NULL;
9166 if (parameters)
9167 {
9168 params = new Parameters();
9169 params->setDim(parameters->dim);
9170 for (size_t i = 0; i < params->dim; i++)
9171 (*params)[i] = (*parameters)[i]->syntaxCopy();
9172 }
9173 return params;
9174 }
9175
9176 /****************************************************
9177 * Determine if parameter is a lazy array of delegates.
9178 * If so, return the return type of those delegates.
9179 * If not, return NULL.
9180 *
9181 * Returns T if the type is one of the following forms:
9182 * T delegate()[]
9183 * T delegate()[dim]
9184 */
9185
9186 Type *Parameter::isLazyArray()
9187 {
9188 Type *tb = type->toBasetype();
9189 if (tb->ty == Tsarray || tb->ty == Tarray)
9190 {
9191 Type *tel = ((TypeArray *)tb)->next->toBasetype();
9192 if (tel->ty == Tdelegate)
9193 {
9194 TypeDelegate *td = (TypeDelegate *)tel;
9195 TypeFunction *tf = td->next->toTypeFunction();
9196
9197 if (!tf->varargs && Parameter::dim(tf->parameters) == 0)
9198 {
9199 return tf->next; // return type of delegate
9200 }
9201 }
9202 }
9203 return NULL;
9204 }
9205
9206 /***************************************
9207 * Determine number of arguments, folding in tuples.
9208 */
9209
9210 static int dimDg(void *ctx, size_t, Parameter *)
9211 {
9212 ++*(size_t *)ctx;
9213 return 0;
9214 }
9215
9216 size_t Parameter::dim(Parameters *parameters)
9217 {
9218 size_t n = 0;
9219 Parameter_foreach(parameters, &dimDg, &n);
9220 return n;
9221 }
9222
9223 /***************************************
9224 * Get nth Parameter, folding in tuples.
9225 * Returns:
9226 * Parameter* nth Parameter
9227 * NULL not found, *pn gets incremented by the number
9228 * of Parameters
9229 */
9230
9231 struct GetNthParamCtx
9232 {
9233 size_t nth;
9234 Parameter *param;
9235 };
9236
9237 static int getNthParamDg(void *ctx, size_t n, Parameter *p)
9238 {
9239 GetNthParamCtx *c = (GetNthParamCtx *)ctx;
9240 if (n == c->nth)
9241 {
9242 c->param = p;
9243 return 1;
9244 }
9245 return 0;
9246 }
9247
9248 Parameter *Parameter::getNth(Parameters *parameters, size_t nth, size_t *)
9249 {
9250 GetNthParamCtx ctx = { nth, NULL };
9251 int res = Parameter_foreach(parameters, &getNthParamDg, &ctx);
9252 return res ? ctx.param : NULL;
9253 }
9254
9255 /***************************************
9256 * Expands tuples in args in depth first order. Calls
9257 * dg(void *ctx, size_t argidx, Parameter *arg) for each Parameter.
9258 * If dg returns !=0, stops and returns that value else returns 0.
9259 * Use this function to avoid the O(N + N^2/2) complexity of
9260 * calculating dim and calling N times getNth.
9261 */
9262
9263 int Parameter_foreach(Parameters *parameters, ForeachDg dg, void *ctx, size_t *pn)
9264 {
9265 assert(dg);
9266 if (!parameters)
9267 return 0;
9268
9269 size_t n = pn ? *pn : 0; // take over index
9270 int result = 0;
9271 for (size_t i = 0; i < parameters->dim; i++)
9272 {
9273 Parameter *p = (*parameters)[i];
9274 Type *t = p->type->toBasetype();
9275
9276 if (t->ty == Ttuple)
9277 {
9278 TypeTuple *tu = (TypeTuple *)t;
9279 result = Parameter_foreach(tu->arguments, dg, ctx, &n);
9280 }
9281 else
9282 result = dg(ctx, n++, p);
9283
9284 if (result)
9285 break;
9286 }
9287
9288 if (pn)
9289 *pn = n; // update index
9290 return result;
9291 }
9292
9293
9294 const char *Parameter::toChars()
9295 {
9296 return ident ? ident->toChars() : "__anonymous_param";
9297 }
9298
9299 /*********************************
9300 * Compute covariance of parameters `this` and `p`
9301 * as determined by the storage classes of both.
9302 * Params:
9303 * p = Parameter to compare with
9304 * Returns:
9305 * true = `this` can be used in place of `p`
9306 * false = nope
9307 */
9308 bool Parameter::isCovariant(bool returnByRef, const Parameter *p) const
9309 {
9310 const StorageClass stc = STCref | STCin | STCout | STClazy;
9311 if ((this->storageClass & stc) != (p->storageClass & stc))
9312 return false;
9313
9314 return isCovariantScope(returnByRef, this->storageClass, p->storageClass);
9315 }
9316
9317 bool Parameter::isCovariantScope(bool returnByRef, StorageClass from, StorageClass to)
9318 {
9319 if (from == to)
9320 return true;
9321
9322 struct SR
9323 {
9324 /* Classification of 'scope-return-ref' possibilities
9325 */
9326 enum
9327 {
9328 SRNone,
9329 SRScope,
9330 SRReturnScope,
9331 SRRef,
9332 SRReturnRef,
9333 SRRefScope,
9334 SRReturnRef_Scope,
9335 SRRef_ReturnScope,
9336 SRMAX,
9337 };
9338
9339 /* Shrinking the representation is necessary because StorageClass is so wide
9340 * Params:
9341 * returnByRef = true if the function returns by ref
9342 * stc = storage class of parameter
9343 */
9344 static unsigned buildSR(bool returnByRef, StorageClass stc)
9345 {
9346 unsigned result;
9347 StorageClass stc2 = stc & (STCref | STCscope | STCreturn);
9348 if (stc2 == 0)
9349 result = SRNone;
9350 else if (stc2 == STCref)
9351 result = SRRef;
9352 else if (stc2 == STCscope)
9353 result = SRScope;
9354 else if (stc2 == (STCscope | STCreturn))
9355 result = SRReturnScope;
9356 else if (stc2 == (STCref | STCreturn))
9357 result = SRReturnRef;
9358 else if (stc2 == (STCscope | STCref))
9359 result = SRRefScope;
9360 else if (stc2 == (STCscope | STCref | STCreturn))
9361 result = returnByRef ? SRReturnRef_Scope : SRRef_ReturnScope;
9362 else
9363 assert(0);
9364 return result;
9365 }
9366
9367 static void covariantInit(bool covariant[SRMAX][SRMAX])
9368 {
9369 /* Initialize covariant[][] with this:
9370
9371 From\To n rs s
9372 None X
9373 ReturnScope X X
9374 Scope X X X
9375
9376 From\To r rr rs rr-s r-rs
9377 Ref X X
9378 ReturnRef X
9379 RefScope X X X X X
9380 ReturnRef-Scope X X
9381 Ref-ReturnScope X X X
9382 */
9383 for (int i = 0; i < SRMAX; i++)
9384 {
9385 covariant[i][i] = true;
9386 covariant[SRRefScope][i] = true;
9387 }
9388 covariant[SRReturnScope][SRNone] = true;
9389 covariant[SRScope ][SRNone] = true;
9390 covariant[SRScope ][SRReturnScope] = true;
9391
9392 covariant[SRRef ][SRReturnRef] = true;
9393 covariant[SRReturnRef_Scope][SRReturnRef] = true;
9394 covariant[SRRef_ReturnScope][SRRef ] = true;
9395 covariant[SRRef_ReturnScope][SRReturnRef] = true;
9396 }
9397 };
9398
9399 /* result is true if the 'from' can be used as a 'to'
9400 */
9401
9402 if ((from ^ to) & STCref) // differing in 'ref' means no covariance
9403 return false;
9404
9405 static bool covariant[SR::SRMAX][SR::SRMAX];
9406 static bool init = false;
9407 if (!init)
9408 {
9409 SR::covariantInit(covariant);
9410 init = true;
9411 }
9412
9413 return covariant[SR::buildSR(returnByRef, from)][SR::buildSR(returnByRef, to)];
9414 }