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