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