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