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