2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/mtype.c
11 #include "root/dsystem.h"
12 #include "root/checkedint.h"
13 #include "root/rmem.h"
21 #include "expression.h"
22 #include "statement.h"
24 #include "declaration.h"
30 #include "aggregate.h"
34 bool symbolIsVisible(Scope
*sc
, Dsymbol
*s
);
35 typedef int (*ForeachDg
)(void *ctx
, size_t paramidx
, Parameter
*param
);
36 int Parameter_foreach(Parameters
*parameters
, ForeachDg dg
, void *ctx
, size_t *pn
= NULL
);
37 FuncDeclaration
*isFuncAddress(Expression
*e
, bool *hasOverloads
= NULL
);
38 Expression
*extractSideEffect(Scope
*sc
, const char *name
, Expression
**e0
, Expression
*e
, bool alwaysCopy
= false);
39 Expression
*resolve(Loc loc
, Scope
*sc
, Dsymbol
*s
, bool hasOverloads
);
40 Expression
*semantic(Expression
*e
, Scope
*sc
);
41 Expression
*semanticY(DotIdExp
*exp
, Scope
*sc
, int flag
);
42 Expression
*semanticY(DotTemplateInstanceExp
*exp
, Scope
*sc
, int flag
);
43 Expression
*typeToExpression(Type
*t
);
44 Expression
*typeToExpressionHelper(TypeQualified
*t
, Expression
*e
, size_t i
= 0);
45 Initializer
*semantic(Initializer
*init
, Scope
*sc
, Type
*t
, NeedInterpret needInterpret
);
48 int Tptrdiff_t
= Tint32
;
50 /***************************** Type *****************************/
52 ClassDeclaration
*Type::dtypeinfo
;
53 ClassDeclaration
*Type::typeinfoclass
;
54 ClassDeclaration
*Type::typeinfointerface
;
55 ClassDeclaration
*Type::typeinfostruct
;
56 ClassDeclaration
*Type::typeinfopointer
;
57 ClassDeclaration
*Type::typeinfoarray
;
58 ClassDeclaration
*Type::typeinfostaticarray
;
59 ClassDeclaration
*Type::typeinfoassociativearray
;
60 ClassDeclaration
*Type::typeinfovector
;
61 ClassDeclaration
*Type::typeinfoenum
;
62 ClassDeclaration
*Type::typeinfofunction
;
63 ClassDeclaration
*Type::typeinfodelegate
;
64 ClassDeclaration
*Type::typeinfotypelist
;
65 ClassDeclaration
*Type::typeinfoconst
;
66 ClassDeclaration
*Type::typeinfoinvariant
;
67 ClassDeclaration
*Type::typeinfoshared
;
68 ClassDeclaration
*Type::typeinfowild
;
70 TemplateDeclaration
*Type::rtinfo
;
87 Type
*Type::timaginary32
;
88 Type
*Type::timaginary64
;
89 Type
*Type::timaginary80
;
91 Type
*Type::tcomplex32
;
92 Type
*Type::tcomplex64
;
93 Type
*Type::tcomplex80
;
100 Type
*Type::tshiftcnt
;
105 Type
*Type::tptrdiff_t
;
108 Type
*Type::tvoidptr
;
110 Type
*Type::twstring
;
111 Type
*Type::tdstring
;
113 Type
*Type::basic
[TMAX
];
114 unsigned char Type::sizeTy
[TMAX
];
115 StringTable
Type::stringtable
;
117 void initTypeMangle();
134 this->arrayof
= NULL
;
139 const char *Type::kind()
141 assert(false); // should be overridden
147 void *pt
= mem
.xmalloc(sizeTy
[ty
]);
148 Type
*t
= (Type
*)memcpy(pt
, (void *)this, sizeTy
[ty
]);
152 Type
*Type::syntaxCopy()
155 fprintf(stderr
, "ty = %d\n", ty
);
160 bool Type::equals(RootObject
*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
))
168 //printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
171 //if (deco && t && t->deco) printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
175 bool Type::equivalent(Type
*t
)
177 return immutableOf()->equals(t
->immutableOf());
182 stringtable
._init(14000);
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
);
209 static TY basetab
[] =
210 { Tvoid
, Tint8
, Tuns8
, Tint16
, Tuns16
, Tint32
, Tuns32
, Tint64
, Tuns64
,
212 Tfloat32
, Tfloat64
, Tfloat80
,
213 Timaginary32
, Timaginary64
, Timaginary80
,
214 Tcomplex32
, Tcomplex64
, Tcomplex80
,
216 Tchar
, Twchar
, Tdchar
, Terror
};
218 for (size_t i
= 0; basetab
[i
] != Terror
; i
++)
220 Type
*t
= new TypeBasic(basetab
[i
]);
222 basic
[basetab
[i
]] = t
;
224 basic
[Terror
] = new TypeError();
226 tvoid
= basic
[Tvoid
];
227 tint8
= basic
[Tint8
];
228 tuns8
= basic
[Tuns8
];
229 tint16
= basic
[Tint16
];
230 tuns16
= basic
[Tuns16
];
231 tint32
= basic
[Tint32
];
232 tuns32
= basic
[Tuns32
];
233 tint64
= basic
[Tint64
];
234 tuns64
= basic
[Tuns64
];
235 tint128
= basic
[Tint128
];
236 tuns128
= basic
[Tuns128
];
237 tfloat32
= basic
[Tfloat32
];
238 tfloat64
= basic
[Tfloat64
];
239 tfloat80
= basic
[Tfloat80
];
241 timaginary32
= basic
[Timaginary32
];
242 timaginary64
= basic
[Timaginary64
];
243 timaginary80
= basic
[Timaginary80
];
245 tcomplex32
= basic
[Tcomplex32
];
246 tcomplex64
= basic
[Tcomplex64
];
247 tcomplex80
= basic
[Tcomplex80
];
249 tbool
= basic
[Tbool
];
250 tchar
= basic
[Tchar
];
251 twchar
= basic
[Twchar
];
252 tdchar
= basic
[Tdchar
];
255 terror
= basic
[Terror
];
256 tnull
= basic
[Tnull
];
257 tnull
= new TypeNull();
258 tnull
->deco
= tnull
->merge()->deco
;
260 tvoidptr
= tvoid
->pointerTo();
261 tstring
= tchar
->immutableOf()->arrayOf();
262 twstring
= twchar
->immutableOf()->arrayOf();
263 tdstring
= tdchar
->immutableOf()->arrayOf();
264 tvalist
= Target::va_listType();
266 if (global
.params
.isLP64
)
277 tsize_t
= basic
[Tsize_t
];
278 tptrdiff_t
= basic
[Tptrdiff_t
];
287 d_uns64
Type::size(Loc loc
)
289 error(loc
, "no size for type %s", toChars());
293 unsigned Type::alignsize()
295 return (unsigned)size(Loc());
298 Type
*Type::semantic(Loc loc
, Scope
*)
300 if (ty
== Tint128
|| ty
== Tuns128
)
302 error(loc
, "cent and ucent types not implemented");
309 Type
*Type::trySemantic(Loc loc
, Scope
*sc
)
311 //printf("+trySemantic(%s) %d\n", toChars(), global.errors);
312 unsigned errors
= global
.startGagging();
313 Type
*t
= semantic(loc
, sc
);
314 if (global
.endGagging(errors
) || t
->ty
== Terror
) // if any errors happened
318 //printf("-trySemantic(%s) %d\n", toChars(), global.errors);
322 /********************************
323 * Return a copy of this type with all attributes null-initialized.
324 * Useful for creating a type with different modifiers.
327 Type
*Type::nullAttributes()
329 unsigned sz
= sizeTy
[ty
];
330 void *pt
= mem
.xmalloc(sz
);
331 Type
*t
= (Type
*)memcpy(pt
, (void *)this, sz
);
346 if (t
->ty
== Tstruct
) ((TypeStruct
*)t
)->att
= RECfwdref
;
347 if (t
->ty
== Tclass
) ((TypeClass
*)t
)->att
= RECfwdref
;
351 /********************************
352 * Convert to 'const'.
355 Type
*Type::constOf()
357 //printf("Type::constOf() %p %s\n", this, toChars());
362 assert(cto
->mod
== MODconst
);
365 Type
*t
= makeConst();
368 //printf("-Type::constOf() %p %s\n", t, t->toChars());
372 /********************************
373 * Convert to 'immutable'.
376 Type
*Type::immutableOf()
378 //printf("Type::immutableOf() %p %s\n", this, toChars());
383 assert(ito
->isImmutable());
386 Type
*t
= makeImmutable();
389 //printf("\t%p\n", t);
393 /********************************
397 Type
*Type::mutableOf()
399 //printf("Type::mutableOf() %p, %s\n", this, toChars());
403 t
= ito
; // immutable => naked
404 assert(!t
|| (t
->isMutable() && !t
->isShared()));
411 t
= swcto
; // shared wild const -> shared
413 t
= sto
; // shared const => shared
418 t
= wcto
; // wild const -> naked
420 t
= cto
; // const => naked
422 assert(!t
|| t
->isMutable());
427 t
= sto
; // shared wild => shared
429 t
= wto
; // wild => naked
430 assert(!t
|| t
->isMutable());
440 assert(t
->isMutable());
444 Type
*Type::sharedOf()
446 //printf("Type::sharedOf() %p, %s\n", this, toChars());
447 if (mod
== MODshared
)
451 assert(sto
->mod
== MODshared
);
454 Type
*t
= makeShared();
457 //printf("\t%p\n", t);
461 Type
*Type::sharedConstOf()
463 //printf("Type::sharedConstOf() %p, %s\n", this, toChars());
464 if (mod
== (MODshared
| MODconst
))
468 assert(scto
->mod
== (MODshared
| MODconst
));
471 Type
*t
= makeSharedConst();
474 //printf("\t%p\n", t);
479 /********************************
480 * Make type unshared.
483 * immutable => immutable
485 * shared const => const
487 * wild const => wild const
488 * shared wild => wild
489 * shared wild const => wild const
492 Type
*Type::unSharedOf()
494 //printf("Type::unSharedOf() %p, %s\n", this, toChars());
502 t
= wcto
; // shared wild const => wild const
504 t
= wto
; // shared wild => wild
509 t
= cto
; // shared const => const
511 t
= sto
; // shared => naked
513 assert(!t
|| !t
->isShared());
518 t
= this->nullAttributes();
519 t
->mod
= mod
& ~MODshared
;
527 assert(!t
->isShared());
531 /********************************
537 //printf("Type::wildOf() %p %s\n", this, toChars());
542 assert(wto
->mod
== MODwild
);
545 Type
*t
= makeWild();
548 //printf("\t%p %s\n", t, t->toChars());
552 Type
*Type::wildConstOf()
554 //printf("Type::wildConstOf() %p %s\n", this, toChars());
555 if (mod
== MODwildconst
)
559 assert(wcto
->mod
== MODwildconst
);
562 Type
*t
= makeWildConst();
565 //printf("\t%p %s\n", t, t->toChars());
569 Type
*Type::sharedWildOf()
571 //printf("Type::sharedWildOf() %p, %s\n", this, toChars());
572 if (mod
== (MODshared
| MODwild
))
576 assert(swto
->mod
== (MODshared
| MODwild
));
579 Type
*t
= makeSharedWild();
582 //printf("\t%p %s\n", t, t->toChars());
586 Type
*Type::sharedWildConstOf()
588 //printf("Type::sharedWildConstOf() %p, %s\n", this, toChars());
589 if (mod
== (MODshared
| MODwildconst
))
593 assert(swcto
->mod
== (MODshared
| MODwildconst
));
596 Type
*t
= makeSharedWildConst();
599 //printf("\t%p %s\n", t, t->toChars());
603 /**********************************
604 * For our new type 'this', which is type-constructed from t,
605 * fill in the cto, ito, sto, scto, wto shortcuts.
608 void Type::fixTo(Type
*t
)
610 // If fixing this: immutable(T*) by t: immutable(T)*,
611 // cache t to this->xto won't break transitivity.
614 if (!tn
|| (ty
!= Tsarray
&& tn
->mod
== t
->nextOf()->mod
))
618 case 0: mto
= t
; break;
619 case MODconst
: cto
= t
; break;
620 case MODwild
: wto
= t
; break;
621 case MODwildconst
: wcto
= t
; break;
622 case MODshared
: sto
= t
; break;
623 case MODshared
| MODconst
: scto
= t
; break;
624 case MODshared
| MODwild
: swto
= t
; break;
625 case MODshared
| MODwildconst
: swcto
= t
; break;
626 case MODimmutable
: ito
= t
; break;
630 assert(mod
!= t
->mod
);
631 #define X(m, n) (((m) << 4) | (n))
657 case MODshared
| MODconst
:
662 case MODshared
| MODwild
:
667 case MODshared
| MODwildconst
:
674 if (t
-> cto
) t
-> cto
->ito
= this;
675 if (t
-> sto
) t
-> sto
->ito
= this;
676 if (t
-> scto
) t
-> scto
->ito
= this;
677 if (t
-> wto
) t
-> wto
->ito
= this;
678 if (t
-> wcto
) t
-> wcto
->ito
= this;
679 if (t
-> swto
) t
-> swto
->ito
= this;
680 if (t
->swcto
) t
->swcto
->ito
= this;
690 //printf("fixTo: %s, %s\n", toChars(), t->toChars());
693 /***************************
694 * Look for bugs in constructing types.
702 if (cto
) assert(cto
->mod
== MODconst
);
703 if (ito
) assert(ito
->mod
== MODimmutable
);
704 if (sto
) assert(sto
->mod
== MODshared
);
705 if (scto
) assert(scto
->mod
== (MODshared
| MODconst
));
706 if (wto
) assert(wto
->mod
== MODwild
);
707 if (wcto
) assert(wcto
->mod
== MODwildconst
);
708 if (swto
) assert(swto
->mod
== (MODshared
| MODwild
));
709 if (swcto
) assert(swcto
->mod
== (MODshared
| MODwildconst
));
713 if (cto
) assert(cto
->mod
== 0);
714 if (ito
) assert(ito
->mod
== MODimmutable
);
715 if (sto
) assert(sto
->mod
== MODshared
);
716 if (scto
) assert(scto
->mod
== (MODshared
| MODconst
));
717 if (wto
) assert(wto
->mod
== MODwild
);
718 if (wcto
) assert(wcto
->mod
== MODwildconst
);
719 if (swto
) assert(swto
->mod
== (MODshared
| MODwild
));
720 if (swcto
) assert(swcto
->mod
== (MODshared
| MODwildconst
));
724 if (cto
) assert(cto
->mod
== MODconst
);
725 if (ito
) assert(ito
->mod
== MODimmutable
);
726 if (sto
) assert(sto
->mod
== MODshared
);
727 if (scto
) assert(scto
->mod
== (MODshared
| MODconst
));
728 if (wto
) assert(wto
->mod
== 0);
729 if (wcto
) assert(wcto
->mod
== MODwildconst
);
730 if (swto
) assert(swto
->mod
== (MODshared
| MODwild
));
731 if (swcto
) assert(swcto
->mod
== (MODshared
| MODwildconst
));
735 assert(! cto
|| cto
->mod
== MODconst
);
736 assert(! ito
|| ito
->mod
== MODimmutable
);
737 assert(! sto
|| sto
->mod
== MODshared
);
738 assert(! scto
|| scto
->mod
== (MODshared
| MODconst
));
739 assert(! wto
|| wto
->mod
== MODwild
);
740 assert(! wcto
|| wcto
->mod
== 0);
741 assert(! swto
|| swto
->mod
== (MODshared
| MODwild
));
742 assert(!swcto
|| swcto
->mod
== (MODshared
| MODwildconst
));
746 if (cto
) assert(cto
->mod
== MODconst
);
747 if (ito
) assert(ito
->mod
== MODimmutable
);
748 if (sto
) assert(sto
->mod
== 0);
749 if (scto
) assert(scto
->mod
== (MODshared
| MODconst
));
750 if (wto
) assert(wto
->mod
== MODwild
);
751 if (wcto
) assert(wcto
->mod
== MODwildconst
);
752 if (swto
) assert(swto
->mod
== (MODshared
| MODwild
));
753 if (swcto
) assert(swcto
->mod
== (MODshared
| MODwildconst
));
756 case MODshared
| MODconst
:
757 if (cto
) assert(cto
->mod
== MODconst
);
758 if (ito
) assert(ito
->mod
== MODimmutable
);
759 if (sto
) assert(sto
->mod
== MODshared
);
760 if (scto
) assert(scto
->mod
== 0);
761 if (wto
) assert(wto
->mod
== MODwild
);
762 if (wcto
) assert(wcto
->mod
== MODwildconst
);
763 if (swto
) assert(swto
->mod
== (MODshared
| MODwild
));
764 if (swcto
) assert(swcto
->mod
== (MODshared
| MODwildconst
));
767 case MODshared
| MODwild
:
768 if (cto
) assert(cto
->mod
== MODconst
);
769 if (ito
) assert(ito
->mod
== MODimmutable
);
770 if (sto
) assert(sto
->mod
== MODshared
);
771 if (scto
) assert(scto
->mod
== (MODshared
| MODconst
));
772 if (wto
) assert(wto
->mod
== MODwild
);
773 if (wcto
) assert(wcto
->mod
== MODwildconst
);
774 if (swto
) assert(swto
->mod
== 0);
775 if (swcto
) assert(swcto
->mod
== (MODshared
| MODwildconst
));
778 case MODshared
| MODwildconst
:
779 assert(! cto
|| cto
->mod
== MODconst
);
780 assert(! ito
|| ito
->mod
== MODimmutable
);
781 assert(! sto
|| sto
->mod
== MODshared
);
782 assert(! scto
|| scto
->mod
== (MODshared
| MODconst
));
783 assert(! wto
|| wto
->mod
== MODwild
);
784 assert(! wcto
|| wcto
->mod
== MODwildconst
);
785 assert(! swto
|| swto
->mod
== (MODshared
| MODwild
));
786 assert(!swcto
|| swcto
->mod
== 0);
790 if (cto
) assert(cto
->mod
== MODconst
);
791 if (ito
) assert(ito
->mod
== 0);
792 if (sto
) assert(sto
->mod
== MODshared
);
793 if (scto
) assert(scto
->mod
== (MODshared
| MODconst
));
794 if (wto
) assert(wto
->mod
== MODwild
);
795 if (wcto
) assert(wcto
->mod
== MODwildconst
);
796 if (swto
) assert(swto
->mod
== (MODshared
| MODwild
));
797 if (swcto
) assert(swcto
->mod
== (MODshared
| MODwildconst
));
805 if (tn
&& ty
!= Tfunction
&& tn
->ty
!= Tfunction
&& ty
!= Tenum
)
807 // Verify transitivity
815 case MODshared
| MODconst
:
816 case MODshared
| MODwild
:
817 case MODshared
| MODwildconst
:
819 assert(tn
->mod
== MODimmutable
|| (tn
->mod
& mod
) == mod
);
829 Type
*Type::makeConst()
831 //printf("Type::makeConst() %p, %s\n", this, toChars());
833 Type
*t
= this->nullAttributes();
835 //printf("-Type::makeConst() %p, %s\n", t, toChars());
839 Type
*Type::makeImmutable()
842 Type
*t
= this->nullAttributes();
843 t
->mod
= MODimmutable
;
847 Type
*Type::makeShared()
850 Type
*t
= this->nullAttributes();
855 Type
*Type::makeSharedConst()
857 if (scto
) return scto
;
858 Type
*t
= this->nullAttributes();
859 t
->mod
= MODshared
| MODconst
;
863 Type
*Type::makeWild()
866 Type
*t
= this->nullAttributes();
871 Type
*Type::makeWildConst()
873 if (wcto
) return wcto
;
874 Type
*t
= this->nullAttributes();
875 t
->mod
= MODwildconst
;
879 Type
*Type::makeSharedWild()
881 if (swto
) return swto
;
882 Type
*t
= this->nullAttributes();
883 t
->mod
= MODshared
| MODwild
;
887 Type
*Type::makeSharedWildConst()
889 if (swcto
) return swcto
;
890 Type
*t
= this->nullAttributes();
891 t
->mod
= MODshared
| MODwildconst
;
895 Type
*Type::makeMutable()
897 Type
*t
= this->nullAttributes();
898 t
->mod
= mod
& MODshared
;
902 /*************************************
903 * Apply STCxxxx bits to existing type.
904 * Use *before* semantic analysis is run.
907 Type
*Type::addSTC(StorageClass stc
)
910 if (t
->isImmutable())
912 else if (stc
& STCimmutable
)
914 t
= t
->makeImmutable();
918 if ((stc
& STCshared
) && !t
->isShared())
923 t
= t
->makeSharedWildConst();
925 t
= t
->makeSharedWild();
930 t
= t
->makeSharedConst();
935 if ((stc
& STCconst
) && !t
->isConst())
940 t
= t
->makeSharedWildConst();
942 t
= t
->makeSharedConst();
947 t
= t
->makeWildConst();
952 if ((stc
& STCwild
) && !t
->isWild())
957 t
= t
->makeSharedWildConst();
959 t
= t
->makeSharedWild();
964 t
= t
->makeWildConst();
973 /************************************
974 * Convert MODxxxx to STCxxx
977 StorageClass
ModToStc(unsigned mod
)
979 StorageClass stc
= 0;
980 if (mod
& MODimmutable
) stc
|= STCimmutable
;
981 if (mod
& MODconst
) stc
|= STCconst
;
982 if (mod
& MODwild
) stc
|= STCwild
;
983 if (mod
& MODshared
) stc
|= STCshared
;
987 /************************************
988 * Apply MODxxxx bits to existing type.
991 Type
*Type::castMod(MOD mod
)
997 t
= unSharedOf()->mutableOf();
1001 t
= unSharedOf()->constOf();
1005 t
= unSharedOf()->wildOf();
1009 t
= unSharedOf()->wildConstOf();
1013 t
= mutableOf()->sharedOf();
1016 case MODshared
| MODconst
:
1017 t
= sharedConstOf();
1020 case MODshared
| MODwild
:
1024 case MODshared
| MODwildconst
:
1025 t
= sharedWildConstOf();
1038 /************************************
1039 * Add MODxxxx bits to existing type.
1040 * We're adding, not replacing, so adding const to
1041 * a shared type => "shared const"
1044 Type
*Type::addMod(MOD mod
)
1046 /* Add anything to immutable, and it remains immutable
1049 if (!t
->isImmutable())
1051 //printf("addMod(%x) %s\n", mod, toChars());
1061 t
= sharedWildConstOf();
1063 t
= sharedConstOf();
1078 t
= sharedWildConstOf();
1093 t
= sharedWildConstOf();
1102 t
= sharedWildConstOf();
1109 t
= sharedConstOf();
1115 case MODshared
| MODconst
:
1117 t
= sharedWildConstOf();
1119 t
= sharedConstOf();
1122 case MODshared
| MODwild
:
1124 t
= sharedWildConstOf();
1129 case MODshared
| MODwildconst
:
1130 t
= sharedWildConstOf();
1144 /************************************
1145 * Add storage class modifiers to type.
1148 Type
*Type::addStorageClass(StorageClass stc
)
1150 /* Just translate to MOD bits and let addMod() do the work
1154 if (stc
& STCimmutable
)
1158 if (stc
& (STCconst
| STCin
))
1162 if (stc
& STCshared
)
1168 Type
*Type::pointerTo()
1174 Type
*t
= new TypePointer(this);
1175 if (ty
== Tfunction
)
1177 t
->deco
= t
->merge()->deco
;
1186 Type
*Type::referenceTo()
1192 Type
*t
= new TypeReference(this);
1198 Type
*Type::arrayOf()
1204 Type
*t
= new TypeDArray(this);
1205 arrayof
= t
->merge();
1210 // Make corresponding static array type without semantic
1211 Type
*Type::sarrayOf(dinteger_t dim
)
1214 Type
*t
= new TypeSArray(this, new IntegerExp(Loc(), dim
, Type::tsize_t
));
1216 // according to TypeSArray::semantic()
1223 Type
*Type::aliasthisOf()
1225 AggregateDeclaration
*ad
= isAggregate(this);
1226 if (ad
&& ad
->aliasthis
)
1228 Dsymbol
*s
= ad
->aliasthis
;
1229 if (s
->isAliasDeclaration())
1231 Declaration
*d
= s
->isDeclaration();
1232 if (d
&& !d
->isTupleDeclaration())
1236 if (d
->isVarDeclaration() && d
->needThis())
1238 t
= t
->addMod(this->mod
);
1240 else if (d
->isFuncDeclaration())
1242 FuncDeclaration
*fd
= resolveFuncCall(Loc(), NULL
, d
, NULL
, this, NULL
, 1);
1243 if (fd
&& fd
->errors
)
1244 return Type::terror
;
1245 if (fd
&& !fd
->type
->nextOf() && !fd
->functionSemantic())
1249 t
= fd
->type
->nextOf();
1250 if (!t
) // issue 14185
1251 return Type::terror
;
1252 t
= t
->substWildTo(mod
== 0 ? MODmutable
: (MODFlags
)mod
);
1255 return Type::terror
;
1259 EnumDeclaration
*ed
= s
->isEnumDeclaration();
1265 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
1269 FuncDeclaration
*fd
= resolveFuncCall(Loc(), NULL
, td
, NULL
, this, NULL
, 1);
1270 if (fd
&& fd
->errors
)
1271 return Type::terror
;
1272 if (fd
&& fd
->functionSemantic())
1274 Type
*t
= fd
->type
->nextOf();
1275 t
= t
->substWildTo(mod
== 0 ? MODmutable
: (MODFlags
)mod
);
1279 return Type::terror
;
1281 //printf("%s\n", s->kind());
1286 bool Type::checkAliasThisRec()
1288 Type
*tb
= toBasetype();
1289 AliasThisRec
* pflag
;
1290 if (tb
->ty
== Tstruct
)
1291 pflag
= &((TypeStruct
*)tb
)->att
;
1292 else if (tb
->ty
== Tclass
)
1293 pflag
= &((TypeClass
*)tb
)->att
;
1297 AliasThisRec flag
= (AliasThisRec
)(*pflag
& RECtypeMask
);
1298 if (flag
== RECfwdref
)
1300 Type
*att
= aliasthisOf();
1301 flag
= att
&& att
->implicitConvTo(this) ? RECyes
: RECno
;
1303 *pflag
= (AliasThisRec
)(flag
| (*pflag
& ~RECtypeMask
));
1304 return flag
== RECyes
;
1307 Dsymbol
*Type::toDsymbol(Scope
*)
1312 /*******************************
1313 * If this is a shell around another type,
1314 * get that other type.
1317 Type
*Type::toBasetype()
1322 /***************************
1323 * Return !=0 if modfrom can be implicitly converted to modto
1325 bool MODimplicitConv(MOD modfrom
, MOD modto
)
1327 if (modfrom
== modto
)
1330 //printf("MODimplicitConv(from = %x, to = %x)\n", modfrom, modto);
1331 #define X(m, n) (((m) << 4) | (n))
1332 switch (X(modfrom
& ~MODshared
, modto
& ~MODshared
))
1334 case X(0, MODconst
):
1335 case X(MODwild
, MODconst
):
1336 case X(MODwild
, MODwildconst
):
1337 case X(MODwildconst
, MODconst
):
1338 return (modfrom
& MODshared
) == (modto
& MODshared
);
1340 case X(MODimmutable
, MODconst
):
1341 case X(MODimmutable
, MODwildconst
):
1350 /***************************
1351 * Return MATCHexact or MATCHconst if a method of type '() modfrom' can call a method of type '() modto'.
1353 MATCH
MODmethodConv(MOD modfrom
, MOD modto
)
1355 if (modfrom
== modto
)
1357 if (MODimplicitConv(modfrom
, modto
))
1360 #define X(m, n) (((m) << 4) | (n))
1361 switch (X(modfrom
, modto
))
1364 case X(MODimmutable
, MODwild
):
1365 case X(MODconst
, MODwild
):
1366 case X(MODwildconst
, MODwild
):
1367 case X(MODshared
, MODshared
|MODwild
):
1368 case X(MODshared
|MODimmutable
, MODshared
|MODwild
):
1369 case X(MODshared
|MODconst
, MODshared
|MODwild
):
1370 case X(MODshared
|MODwildconst
, MODshared
|MODwild
):
1374 return MATCHnomatch
;
1379 /***************************
1380 * Merge mod bits to form common mod.
1382 MOD
MODmerge(MOD mod1
, MOD mod2
)
1387 //printf("MODmerge(1 = %x, 2 = %x)\n", mod1, mod2);
1389 if ((mod1
| mod2
) & MODshared
)
1391 // If either type is shared, the result will be shared
1392 result
|= MODshared
;
1396 if (mod1
== 0 || mod1
== MODmutable
|| mod1
== MODconst
||
1397 mod2
== 0 || mod2
== MODmutable
|| mod2
== MODconst
)
1399 // If either type is mutable or const, the result will be const.
1404 // MODimmutable vs MODwild
1405 // MODimmutable vs MODwildconst
1406 // MODwild vs MODwildconst
1407 assert(mod1
& MODwild
|| mod2
& MODwild
);
1408 result
|= MODwildconst
;
1413 /*********************************
1414 * Store modifier name into buf.
1416 void MODtoBuffer(OutBuffer
*buf
, MOD mod
)
1424 buf
->writestring(Token::tochars
[TOKimmutable
]);
1428 buf
->writestring(Token::tochars
[TOKshared
]);
1431 case MODshared
| MODconst
:
1432 buf
->writestring(Token::tochars
[TOKshared
]);
1433 buf
->writeByte(' ');
1436 buf
->writestring(Token::tochars
[TOKconst
]);
1439 case MODshared
| MODwild
:
1440 buf
->writestring(Token::tochars
[TOKshared
]);
1441 buf
->writeByte(' ');
1444 buf
->writestring(Token::tochars
[TOKwild
]);
1447 case MODshared
| MODwildconst
:
1448 buf
->writestring(Token::tochars
[TOKshared
]);
1449 buf
->writeByte(' ');
1452 buf
->writestring(Token::tochars
[TOKwild
]);
1453 buf
->writeByte(' ');
1454 buf
->writestring(Token::tochars
[TOKconst
]);
1463 /*********************************
1464 * Return modifier name.
1466 char *MODtoChars(MOD mod
)
1470 MODtoBuffer(&buf
, mod
);
1471 return buf
.extractString();
1474 /********************************
1475 * For pretty-printing a type.
1478 const char *Type::toChars()
1483 hgs
.fullQual
= (ty
== Tclass
&& !mod
);
1485 ::toCBuffer(this, &buf
, NULL
, &hgs
);
1486 return buf
.extractString();
1489 char *Type::toPrettyChars(bool QualifyTypes
)
1494 hgs
.fullQual
= QualifyTypes
;
1496 ::toCBuffer(this, &buf
, NULL
, &hgs
);
1497 return buf
.extractString();
1500 /*********************************
1501 * Store this type's modifier name into buf.
1503 void Type::modToBuffer(OutBuffer
*buf
)
1507 buf
->writeByte(' ');
1508 MODtoBuffer(buf
, mod
);
1512 /*********************************
1513 * Return this type's modifier name.
1515 char *Type::modToChars()
1520 return buf
.extractString();
1523 /** For each active modifier (MODconst, MODimmutable, etc) call fp with a
1524 void* for the work param and a string representation of the attribute. */
1525 int Type::modifiersApply(void *param
, int (*fp
)(void *, const char *))
1527 static unsigned char modsArr
[] = { MODconst
, MODimmutable
, MODwild
, MODshared
};
1529 for (size_t idx
= 0; idx
< 4; ++idx
)
1531 if (mod
& modsArr
[idx
])
1533 if (int res
= fp(param
, MODtoChars(modsArr
[idx
])))
1540 /************************************
1541 * Strip all parameter's idenfiers and their default arguments for merging types.
1542 * If some of parameter types or return type are function pointer, delegate, or
1543 * the types which contains either, then strip also from them.
1546 Type
*stripDefaultArgs(Type
*t
)
1550 static Parameters
*stripParams(Parameters
*parameters
)
1552 Parameters
*params
= parameters
;
1553 if (params
&& params
->dim
> 0)
1555 for (size_t i
= 0; i
< params
->dim
; i
++)
1557 Parameter
*p
= (*params
)[i
];
1558 Type
*ta
= stripDefaultArgs(p
->type
);
1559 if (ta
!= p
->type
|| p
->defaultArg
|| p
->ident
)
1561 if (params
== parameters
)
1563 params
= new Parameters();
1564 params
->setDim(parameters
->dim
);
1565 for (size_t j
= 0; j
< params
->dim
; j
++)
1566 (*params
)[j
] = (*parameters
)[j
];
1568 (*params
)[i
] = new Parameter(p
->storageClass
, ta
, NULL
, NULL
);
1579 if (t
->ty
== Tfunction
)
1581 TypeFunction
*tf
= (TypeFunction
*)t
;
1582 Type
*tret
= stripDefaultArgs(tf
->next
);
1583 Parameters
*params
= N::stripParams(tf
->parameters
);
1584 if (tret
== tf
->next
&& params
== tf
->parameters
)
1586 tf
= (TypeFunction
*)tf
->copy();
1587 tf
->parameters
= params
;
1589 //printf("strip %s\n <- %s\n", tf->toChars(), t->toChars());
1592 else if (t
->ty
== Ttuple
)
1594 TypeTuple
*tt
= (TypeTuple
*)t
;
1595 Parameters
*args
= N::stripParams(tt
->arguments
);
1596 if (args
== tt
->arguments
)
1599 ((TypeTuple
*)t
)->arguments
= args
;
1601 else if (t
->ty
== Tenum
)
1603 // TypeEnum::nextOf() may be != NULL, but it's not necessary here.
1608 Type
*tn
= t
->nextOf();
1609 Type
*n
= stripDefaultArgs(tn
);
1613 ((TypeNext
*)t
)->next
= n
;
1615 //printf("strip %s\n", t->toChars());
1620 /************************************
1625 if (ty
== Terror
) return this;
1626 if (ty
== Ttypeof
) return this;
1627 if (ty
== Tident
) return this;
1628 if (ty
== Tinstance
) return this;
1629 if (ty
== Taarray
&& !((TypeAArray
*)this)->index
->merge()->deco
)
1631 if (ty
!= Tenum
&& nextOf() && !nextOf()->deco
)
1634 //printf("merge(%s)\n", toChars());
1642 mangleToBuffer(this, &buf
);
1644 StringValue
*sv
= stringtable
.update((char *)buf
.data
, buf
.offset
);
1647 t
= (Type
*) sv
->ptrvalue
;
1649 //printf("old value, deco = '%s' %p\n", t->deco, t->deco);
1653 sv
->ptrvalue
= (char *)(t
= stripDefaultArgs(t
));
1654 deco
= t
->deco
= const_cast<char *>(sv
->toDchars());
1655 //printf("new value, deco = '%s' %p\n", t->deco, t->deco);
1661 /*************************************
1662 * This version does a merge even if the deco is already computed.
1663 * Necessary for types that have a deco, but are not merged.
1665 Type
*Type::merge2()
1667 //printf("merge2(%s)\n", toChars());
1673 StringValue
*sv
= stringtable
.lookup((char *)t
->deco
, strlen(t
->deco
));
1674 if (sv
&& sv
->ptrvalue
)
1675 { t
= (Type
*) sv
->ptrvalue
;
1683 bool Type::isintegral()
1688 bool Type::isfloating()
1698 bool Type::isimaginary()
1703 bool Type::iscomplex()
1708 bool Type::isscalar()
1713 bool Type::isunsigned()
1718 ClassDeclaration
*Type::isClassHandle()
1723 bool Type::isscope()
1728 bool Type::isString()
1733 /**************************
1734 * When T is mutable,
1737 * Can we bitwise assign:
1741 bool Type::isAssignable()
1746 /**************************
1747 * Returns true if T can be converted to boolean value.
1749 bool Type::isBoolean()
1754 /********************************
1755 * true if when type goes out of scope, it needs a destructor applied.
1756 * Only applies to value types, not ref types.
1758 bool Type::needsDestruction()
1763 /*********************************
1767 bool Type::needsNested()
1772 /*********************************
1773 * Check type to see if it is based on a deprecated symbol.
1776 void Type::checkDeprecated(Loc loc
, Scope
*sc
)
1778 Dsymbol
*s
= toDsymbol(sc
);
1781 s
->checkDeprecated(loc
, sc
);
1785 Expression
*Type::defaultInit(Loc
)
1790 /***************************************
1791 * Use when we prefer the default initializer to be a literal,
1792 * rather than a global immutable variable.
1794 Expression
*Type::defaultInitLiteral(Loc loc
)
1796 return defaultInit(loc
);
1799 bool Type::isZeroInit(Loc
)
1801 return false; // assume not
1804 bool Type::isBaseOf(Type
*, int *)
1806 return 0; // assume not
1809 /********************************
1810 * Determine if 'this' can be implicitly converted
1813 * MATCHnomatch, MATCHconvert, MATCHconst, MATCHexact
1816 MATCH
Type::implicitConvTo(Type
*to
)
1818 //printf("Type::implicitConvTo(this=%p, to=%p)\n", this, to);
1819 //printf("from: %s\n", toChars());
1820 //printf("to : %s\n", to->toChars());
1821 if (this->equals(to
))
1823 return MATCHnomatch
;
1826 /*******************************
1827 * Determine if converting 'this' to 'to' is an identity operation,
1828 * a conversion to const operation, or the types aren't the same.
1830 * MATCHexact 'this' == 'to'
1831 * MATCHconst 'to' is const
1832 * MATCHnomatch conversion to mutable or invariant
1835 MATCH
Type::constConv(Type
*to
)
1837 //printf("Type::constConv(this = %s, to = %s)\n", toChars(), to->toChars());
1840 if (ty
== to
->ty
&& MODimplicitConv(mod
, to
->mod
))
1842 return MATCHnomatch
;
1845 /***************************************
1846 * Return MOD bits matching this type to wild parameter type (tprm).
1849 unsigned char Type::deduceWild(Type
*t
, bool)
1851 //printf("Type::deduceWild this = '%s', tprm = '%s'\n", toChars(), tprm->toChars());
1856 return MODimmutable
;
1857 else if (isWildConst())
1859 if (t
->isWildConst())
1862 return MODwildconst
;
1868 else if (isMutable())
1876 Type
*Type::unqualify(unsigned m
)
1878 Type
*t
= mutableOf()->unSharedOf();
1880 Type
*tn
= ty
== Tenum
? NULL
: nextOf();
1881 if (tn
&& tn
->ty
!= Tfunction
)
1883 Type
*utn
= tn
->unqualify(m
);
1887 t
= utn
->pointerTo();
1888 else if (ty
== Tarray
)
1890 else if (ty
== Tsarray
)
1891 t
= new TypeSArray(utn
, ((TypeSArray
*)this)->dim
);
1892 else if (ty
== Taarray
)
1894 t
= new TypeAArray(utn
, ((TypeAArray
*)this)->index
);
1895 ((TypeAArray
*)t
)->sc
= ((TypeAArray
*)this)->sc
; // duplicate scope
1903 t
= t
->addMod(mod
& ~m
);
1907 Type
*Type::substWildTo(unsigned mod
)
1909 //printf("+Type::substWildTo this = %s, mod = x%x\n", toChars(), mod);
1912 if (Type
*tn
= nextOf())
1914 // substitution has no effect on function pointer type.
1915 if (ty
== Tpointer
&& tn
->ty
== Tfunction
)
1921 t
= tn
->substWildTo(mod
);
1928 else if (ty
== Tarray
)
1930 else if (ty
== Tsarray
)
1931 t
= new TypeSArray(t
, ((TypeSArray
*)this)->dim
->syntaxCopy());
1932 else if (ty
== Taarray
)
1934 t
= new TypeAArray(t
, ((TypeAArray
*)this)->index
->syntaxCopy());
1935 ((TypeAArray
*)t
)->sc
= ((TypeAArray
*)this)->sc
; // duplicate scope
1937 else if (ty
== Tdelegate
)
1939 t
= new TypeDelegate(t
);
1953 if (mod
== MODimmutable
)
1955 t
= t
->immutableOf();
1957 else if (mod
== MODwildconst
)
1959 t
= t
->wildConstOf();
1961 else if (mod
== MODwild
)
1964 t
= t
->wildConstOf();
1968 else if (mod
== MODconst
)
1981 t
= t
->addMod(MODconst
);
1983 t
= t
->addMod(MODshared
);
1985 //printf("-Type::substWildTo t = %s\n", t->toChars());
1989 Type
*TypeFunction::substWildTo(unsigned)
1991 if (!iswild
&& !(mod
& MODwild
))
1994 // Substitude inout qualifier of function type to mutable or immutable
1995 // would break type system. Instead substitude inout to the most weak
1996 // qualifer - const.
1997 unsigned m
= MODconst
;
2000 Type
*tret
= next
->substWildTo(m
);
2001 Parameters
*params
= parameters
;
2003 params
= parameters
->copy();
2004 for (size_t i
= 0; i
< params
->dim
; i
++)
2006 Parameter
*p
= (*params
)[i
];
2007 Type
*t
= p
->type
->substWildTo(m
);
2010 if (params
== parameters
)
2011 params
= parameters
->copy();
2012 (*params
)[i
] = new Parameter(p
->storageClass
, t
, NULL
, NULL
);
2014 if (next
== tret
&& params
== parameters
)
2017 // Similar to TypeFunction::syntaxCopy;
2018 TypeFunction
*t
= new TypeFunction(params
, tret
, varargs
, linkage
);
2019 t
->mod
= ((mod
& MODwild
) ? (mod
& ~MODwild
) | MODconst
: mod
);
2020 t
->isnothrow
= isnothrow
;
2023 t
->isproperty
= isproperty
;
2025 t
->isreturn
= isreturn
;
2026 t
->isscope
= isscope
;
2027 t
->isscopeinferred
= isscopeinferred
;
2034 /**************************
2035 * Return type with the top level of it being mutable.
2037 Type
*Type::toHeadMutable()
2044 /***************************************
2045 * Calculate built-in properties which just the type is necessary.
2047 * If flag & 1, don't report "not a property" error and just return NULL.
2049 Expression
*Type::getProperty(Loc loc
, Identifier
*ident
, int flag
)
2053 if (ident
== Id::__sizeof
)
2055 d_uns64 sz
= size(loc
);
2056 if (sz
== SIZE_INVALID
)
2057 return new ErrorExp();
2058 e
= new IntegerExp(loc
, sz
, Type::tsize_t
);
2060 else if (ident
== Id::__xalignof
)
2062 e
= new IntegerExp(loc
, alignsize(), Type::tsize_t
);
2064 else if (ident
== Id::_init
)
2066 Type
*tb
= toBasetype();
2067 e
= defaultInitLiteral(loc
);
2068 if (tb
->ty
== Tstruct
&& tb
->needsNested())
2070 StructLiteralExp
*se
= (StructLiteralExp
*)e
;
2071 se
->useStaticInit
= true;
2074 else if (ident
== Id::_mangleof
)
2078 error(loc
, "forward reference of type %s.mangleof", toChars());
2083 e
= new StringExp(loc
, (char *)deco
, strlen(deco
));
2085 e
= ::semantic(e
, &sc
);
2088 else if (ident
== Id::stringof
)
2090 const char *s
= toChars();
2091 e
= new StringExp(loc
, const_cast<char *>(s
), strlen(s
));
2093 e
= ::semantic(e
, &sc
);
2095 else if (flag
&& this != Type::terror
)
2102 if (ty
== Tstruct
|| ty
== Tclass
|| ty
== Tenum
)
2103 s
= toDsymbol(NULL
);
2105 s
= s
->search_correct(ident
);
2106 if (this != Type::terror
)
2109 error(loc
, "no property '%s' for type '%s', did you mean '%s'?", ident
->toChars(), toChars(), s
->toChars());
2111 error(loc
, "no property '%s' for type '%s'", ident
->toChars(), toChars());
2118 /***************************************
2119 * Access the members of the object e. This type is same as e->type.
2121 * If flag & 1, don't report "not a property" error and just return NULL.
2123 Expression
*Type::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
, int flag
)
2125 VarDeclaration
*v
= NULL
;
2128 while (ex
->op
== TOKcomma
)
2129 ex
= ((CommaExp
*)ex
)->e2
;
2130 if (ex
->op
== TOKdotvar
)
2132 DotVarExp
*dv
= (DotVarExp
*)ex
;
2133 v
= dv
->var
->isVarDeclaration();
2135 else if (ex
->op
== TOKvar
)
2137 VarExp
*ve
= (VarExp
*)ex
;
2138 v
= ve
->var
->isVarDeclaration();
2142 if (ident
== Id::offsetof
)
2146 AggregateDeclaration
*ad
= v
->toParent()->isAggregateDeclaration();
2148 if (ad
->sizeok
!= SIZEOKdone
)
2149 return new ErrorExp();
2150 e
= new IntegerExp(e
->loc
, v
->offset
, Type::tsize_t
);
2154 else if (ident
== Id::_init
)
2156 Type
*tb
= toBasetype();
2157 e
= defaultInitLiteral(e
->loc
);
2158 if (tb
->ty
== Tstruct
&& tb
->needsNested())
2160 StructLiteralExp
*se
= (StructLiteralExp
*)e
;
2161 se
->useStaticInit
= true;
2166 if (ident
== Id::stringof
)
2168 /* Bugzilla 3796: this should demangle e->type->deco rather than
2169 * pretty-printing the type.
2171 const char *s
= e
->toChars();
2172 e
= new StringExp(e
->loc
, const_cast<char *>(s
), strlen(s
));
2175 e
= getProperty(e
->loc
, ident
, flag
& 1);
2179 e
= ::semantic(e
, sc
);
2183 /************************************
2184 * Return alignment to use for this type.
2187 structalign_t
Type::alignment()
2189 return STRUCTALIGN_DEFAULT
;
2192 /***************************************
2193 * Figures out what to do with an undefined member reference
2194 * for classes and structs.
2196 * If flag & 1, don't report "not a property" error and just return NULL.
2198 Expression
*Type::noMember(Scope
*sc
, Expression
*e
, Identifier
*ident
, int flag
)
2200 //printf("Type::noMember(e: %s ident: %s flag: %d)\n", e->toChars(), ident->toChars(), flag);
2202 static int nest
; // https://issues.dlang.org/show_bug.cgi?id=17380
2206 ::error(e
->loc
, "cannot resolve identifier `%s`", ident
->toChars());
2208 return (flag
& 1) ? NULL
: new ErrorExp();
2211 assert(ty
== Tstruct
|| ty
== Tclass
);
2212 AggregateDeclaration
*sym
= toDsymbol(sc
)->isAggregateDeclaration();
2215 if (ident
!= Id::__sizeof
&&
2216 ident
!= Id::__xalignof
&&
2217 ident
!= Id::_init
&&
2218 ident
!= Id::_mangleof
&&
2219 ident
!= Id::stringof
&&
2220 ident
!= Id::offsetof
&&
2221 // Bugzilla 15045: Don't forward special built-in member functions.
2222 ident
!= Id::ctor
&&
2223 ident
!= Id::dtor
&&
2224 ident
!= Id::__xdtor
&&
2225 ident
!= Id::postblit
&&
2226 ident
!= Id::__xpostblit
)
2228 /* Look for overloaded opDot() to see if we should forward request
2231 if (Dsymbol
*fd
= search_function(sym
, Id::opDot
))
2233 /* Rewrite e.ident as:
2236 e
= build_overload(e
->loc
, sc
, e
, NULL
, fd
);
2237 e
= new DotIdExp(e
->loc
, e
, ident
);
2238 e
= ::semantic(e
, sc
);
2243 /* Look for overloaded opDispatch to see if we should forward request
2246 if (Dsymbol
*fd
= search_function(sym
, Id::opDispatch
))
2248 /* Rewrite e.ident as:
2249 * e.opDispatch!("ident")
2251 TemplateDeclaration
*td
= fd
->isTemplateDeclaration();
2254 fd
->error("must be a template opDispatch(string s), not a %s", fd
->kind());
2256 return new ErrorExp();
2258 StringExp
*se
= new StringExp(e
->loc
, const_cast<char *>(ident
->toChars()));
2259 Objects
*tiargs
= new Objects();
2261 DotTemplateInstanceExp
*dti
= new DotTemplateInstanceExp(e
->loc
, e
, Id::opDispatch
, tiargs
);
2262 dti
->ti
->tempdecl
= td
;
2264 /* opDispatch, which doesn't need IFTI, may occur instantiate error.
2265 * It should be gagged if flag & 1.
2267 * template opDispatch(name) if (isValid!name) { ... }
2269 unsigned errors
= flag
& 1 ? global
.startGagging() : 0;
2270 e
= semanticY(dti
, sc
, 0);
2271 if (flag
& 1 && global
.endGagging(errors
))
2277 /* See if we should forward to the alias this.
2280 { /* Rewrite e.ident as:
2283 e
= resolveAliasThis(sc
, e
);
2284 DotIdExp
*die
= new DotIdExp(e
->loc
, e
, ident
);
2285 e
= semanticY(die
, sc
, flag
& 1);
2291 e
= Type::dotExp(sc
, e
, ident
, flag
);
2296 void Type::error(Loc loc
, const char *format
, ...)
2299 va_start(ap
, format
);
2300 ::verror(loc
, format
, ap
);
2304 void Type::warning(Loc loc
, const char *format
, ...)
2307 va_start(ap
, format
);
2308 ::vwarning(loc
, format
, ap
);
2312 Identifier
*Type::getTypeInfoIdent()
2314 // _init_10TypeInfo_%s
2317 mangleToBuffer(this, &buf
);
2319 size_t len
= buf
.offset
;
2322 // Allocate buffer on stack, fail over to using malloc()
2324 size_t namelen
= 19 + sizeof(len
) * 3 + len
+ 1;
2325 char *name
= namelen
<= sizeof(namebuf
) ? namebuf
: (char *)mem
.xmalloc(namelen
);
2327 int length
= sprintf(name
, "_D%lluTypeInfo_%s6__initZ", (unsigned long long) 9 + len
, buf
.data
);
2328 //printf("%p, deco = %s, name = %s\n", this, deco, name);
2329 assert(0 < length
&& (size_t)length
< namelen
); // don't overflow the buffer
2331 Identifier
*id
= Identifier::idPool(name
, length
);
2333 if (name
!= namebuf
)
2338 TypeBasic
*Type::isTypeBasic()
2343 TypeFunction
*Type::toTypeFunction()
2345 if (ty
!= Tfunction
)
2347 return (TypeFunction
*)this;
2350 /***************************************
2351 * Resolve 'this' type to either type, symbol, or expression.
2352 * If errors happened, resolved to Type.terror.
2354 void Type::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
, bool)
2356 //printf("Type::resolve() %s, %d\n", toChars(), ty);
2357 Type
*t
= semantic(loc
, sc
);
2363 /***************************************
2364 * Normalize `e` as the result of Type::resolve() process.
2366 void Type::resolveExp(Expression
*e
, Type
**pt
, Expression
**pe
, Dsymbol
**ps
)
2384 s
= ((VarExp
*)e
)->var
;
2385 if (s
->isVarDeclaration())
2387 //if (s->isOverDeclaration())
2392 // TemplateDeclaration
2393 s
= ((TemplateExp
*)e
)->td
;
2397 s
= ((ScopeExp
*)e
)->sds
;
2398 // TemplateDeclaration, TemplateInstance, Import, Package, Module
2410 //case TOKoverloadset:
2427 /***************************************
2428 * Return !=0 if the type or any of its subtypes is wild.
2431 int Type::hasWild() const
2433 return mod
& MODwild
;
2436 /***************************************
2437 * Return !=0 if type has pointers that need to
2438 * be scanned by the GC during a collection cycle.
2440 bool Type::hasPointers()
2442 //printf("Type::hasPointers() %s, %d\n", toChars(), ty);
2446 /*************************************
2447 * Detect if type has pointer fields that are initialized to void.
2448 * Local stack variables with such void fields can remain uninitialized,
2449 * leading to pointer bugs.
2453 bool Type::hasVoidInitPointers()
2458 /*************************************
2459 * If this is a type of something, return that something.
2462 Type
*Type::nextOf()
2467 /*************************************
2468 * If this is a type of static array, return its base element type.
2471 Type
*Type::baseElemOf()
2473 Type
*t
= toBasetype();
2474 while (t
->ty
== Tsarray
)
2475 t
= ((TypeSArray
*)t
)->next
->toBasetype();
2479 /*************************************
2480 * Bugzilla 14488: Check if the inner most base type is complex or imaginary.
2481 * Should only give alerts when set to emit transitional messages.
2484 void Type::checkComplexTransition(Loc loc
)
2486 Type
*t
= baseElemOf();
2487 while (t
->ty
== Tpointer
|| t
->ty
== Tarray
)
2488 t
= t
->nextOf()->baseElemOf();
2490 if (t
->isimaginary() || t
->iscomplex())
2497 rt
= Type::tfloat32
; break;
2500 rt
= Type::tfloat64
; break;
2503 rt
= Type::tfloat80
; break;
2509 message(loc
, "use of complex type `%s` is scheduled for deprecation, "
2510 "use `std.complex.Complex!(%s)` instead", toChars(), rt
->toChars());
2514 message(loc
, "use of imaginary type `%s` is scheduled for deprecation, "
2515 "use `%s` instead\n", toChars(), rt
->toChars());
2520 /****************************************
2521 * Return the mask that an integral type will
2524 uinteger_t
Type::sizemask()
2527 switch (toBasetype()->ty
)
2529 case Tbool
: m
= 1; break;
2532 case Tuns8
: m
= 0xFF; break;
2535 case Tuns16
: m
= 0xFFFFUL
; break;
2538 case Tuns32
: m
= 0xFFFFFFFFUL
; break;
2540 case Tuns64
: m
= 0xFFFFFFFFFFFFFFFFULL
; break;
2547 /* ============================= TypeError =========================== */
2549 TypeError::TypeError()
2554 Type
*TypeError::syntaxCopy()
2556 // No semantic analysis done, no need to copy
2560 d_uns64
TypeError::size(Loc
) { return SIZE_INVALID
; }
2561 Expression
*TypeError::getProperty(Loc
, Identifier
*, int) { return new ErrorExp(); }
2562 Expression
*TypeError::dotExp(Scope
*, Expression
*, Identifier
*, int) { return new ErrorExp(); }
2563 Expression
*TypeError::defaultInit(Loc
) { return new ErrorExp(); }
2564 Expression
*TypeError::defaultInitLiteral(Loc
) { return new ErrorExp(); }
2566 /* ============================= TypeNext =========================== */
2568 TypeNext::TypeNext(TY ty
, Type
*next
)
2574 void TypeNext::checkDeprecated(Loc loc
, Scope
*sc
)
2576 Type::checkDeprecated(loc
, sc
);
2577 if (next
) // next can be NULL if TypeFunction and auto return type
2578 next
->checkDeprecated(loc
, sc
);
2581 int TypeNext::hasWild() const
2583 if (ty
== Tfunction
)
2585 if (ty
== Tdelegate
)
2586 return Type::hasWild();
2587 return mod
& MODwild
|| (next
&& next
->hasWild());
2591 /*******************************
2592 * For TypeFunction, nextOf() can return NULL if the function return
2593 * type is meant to be inferred, and semantic() hasn't yet ben run
2594 * on the function. After semantic(), it must no longer be NULL.
2597 Type
*TypeNext::nextOf()
2602 Type
*TypeNext::makeConst()
2604 //printf("TypeNext::makeConst() %p, %s\n", this, toChars());
2607 assert(cto
->mod
== MODconst
);
2610 TypeNext
*t
= (TypeNext
*)Type::makeConst();
2611 if (ty
!= Tfunction
&& next
->ty
!= Tfunction
&&
2612 !next
->isImmutable())
2614 if (next
->isShared())
2617 t
->next
= next
->sharedWildConstOf();
2619 t
->next
= next
->sharedConstOf();
2624 t
->next
= next
->wildConstOf();
2626 t
->next
= next
->constOf();
2629 //printf("TypeNext::makeConst() returns %p, %s\n", t, t->toChars());
2633 Type
*TypeNext::makeImmutable()
2635 //printf("TypeNext::makeImmutable() %s\n", toChars());
2638 assert(ito
->isImmutable());
2641 TypeNext
*t
= (TypeNext
*)Type::makeImmutable();
2642 if (ty
!= Tfunction
&& next
->ty
!= Tfunction
&&
2643 !next
->isImmutable())
2645 t
->next
= next
->immutableOf();
2650 Type
*TypeNext::makeShared()
2652 //printf("TypeNext::makeShared() %s\n", toChars());
2655 assert(sto
->mod
== MODshared
);
2658 TypeNext
*t
= (TypeNext
*)Type::makeShared();
2659 if (ty
!= Tfunction
&& next
->ty
!= Tfunction
&&
2660 !next
->isImmutable())
2664 if (next
->isConst())
2665 t
->next
= next
->sharedWildConstOf();
2667 t
->next
= next
->sharedWildOf();
2671 if (next
->isConst())
2672 t
->next
= next
->sharedConstOf();
2674 t
->next
= next
->sharedOf();
2677 //printf("TypeNext::makeShared() returns %p, %s\n", t, t->toChars());
2681 Type
*TypeNext::makeSharedConst()
2683 //printf("TypeNext::makeSharedConst() %s\n", toChars());
2686 assert(scto
->mod
== (MODshared
| MODconst
));
2689 TypeNext
*t
= (TypeNext
*)Type::makeSharedConst();
2690 if (ty
!= Tfunction
&& next
->ty
!= Tfunction
&&
2691 !next
->isImmutable())
2694 t
->next
= next
->sharedWildConstOf();
2696 t
->next
= next
->sharedConstOf();
2698 //printf("TypeNext::makeSharedConst() returns %p, %s\n", t, t->toChars());
2702 Type
*TypeNext::makeWild()
2704 //printf("TypeNext::makeWild() %s\n", toChars());
2707 assert(wto
->mod
== MODwild
);
2710 TypeNext
*t
= (TypeNext
*)Type::makeWild();
2711 if (ty
!= Tfunction
&& next
->ty
!= Tfunction
&&
2712 !next
->isImmutable())
2714 if (next
->isShared())
2716 if (next
->isConst())
2717 t
->next
= next
->sharedWildConstOf();
2719 t
->next
= next
->sharedWildOf();
2723 if (next
->isConst())
2724 t
->next
= next
->wildConstOf();
2726 t
->next
= next
->wildOf();
2729 //printf("TypeNext::makeWild() returns %p, %s\n", t, t->toChars());
2733 Type
*TypeNext::makeWildConst()
2735 //printf("TypeNext::makeWildConst() %s\n", toChars());
2738 assert(wcto
->mod
== MODwildconst
);
2741 TypeNext
*t
= (TypeNext
*)Type::makeWildConst();
2742 if (ty
!= Tfunction
&& next
->ty
!= Tfunction
&&
2743 !next
->isImmutable())
2745 if (next
->isShared())
2746 t
->next
= next
->sharedWildConstOf();
2748 t
->next
= next
->wildConstOf();
2750 //printf("TypeNext::makeWildConst() returns %p, %s\n", t, t->toChars());
2754 Type
*TypeNext::makeSharedWild()
2756 //printf("TypeNext::makeSharedWild() %s\n", toChars());
2759 assert(swto
->isSharedWild());
2762 TypeNext
*t
= (TypeNext
*)Type::makeSharedWild();
2763 if (ty
!= Tfunction
&& next
->ty
!= Tfunction
&&
2764 !next
->isImmutable())
2766 if (next
->isConst())
2767 t
->next
= next
->sharedWildConstOf();
2769 t
->next
= next
->sharedWildOf();
2771 //printf("TypeNext::makeSharedWild() returns %p, %s\n", t, t->toChars());
2775 Type
*TypeNext::makeSharedWildConst()
2777 //printf("TypeNext::makeSharedWildConst() %s\n", toChars());
2780 assert(swcto
->mod
== (MODshared
| MODwildconst
));
2783 TypeNext
*t
= (TypeNext
*)Type::makeSharedWildConst();
2784 if (ty
!= Tfunction
&& next
->ty
!= Tfunction
&&
2785 !next
->isImmutable())
2787 t
->next
= next
->sharedWildConstOf();
2789 //printf("TypeNext::makeSharedWildConst() returns %p, %s\n", t, t->toChars());
2793 Type
*TypeNext::makeMutable()
2795 //printf("TypeNext::makeMutable() %p, %s\n", this, toChars());
2796 TypeNext
*t
= (TypeNext
*)Type::makeMutable();
2799 t
->next
= next
->mutableOf();
2801 //printf("TypeNext::makeMutable() returns %p, %s\n", t, t->toChars());
2805 MATCH
TypeNext::constConv(Type
*to
)
2807 //printf("TypeNext::constConv from = %s, to = %s\n", toChars(), to->toChars());
2811 if (!(ty
== to
->ty
&& MODimplicitConv(mod
, to
->mod
)))
2812 return MATCHnomatch
;
2814 Type
*tn
= to
->nextOf();
2815 if (!(tn
&& next
->ty
== tn
->ty
))
2816 return MATCHnomatch
;
2819 if (to
->isConst()) // whole tail const conversion
2820 { // Recursive shared level check
2821 m
= next
->constConv(tn
);
2822 if (m
== MATCHexact
)
2826 { //printf("\tnext => %s, to->next => %s\n", next->toChars(), tn->toChars());
2827 m
= next
->equals(tn
) ? MATCHconst
: MATCHnomatch
;
2832 unsigned char TypeNext::deduceWild(Type
*t
, bool isRef
)
2834 if (ty
== Tfunction
)
2839 Type
*tn
= t
->nextOf();
2840 if (!isRef
&& (ty
== Tarray
|| ty
== Tpointer
) && tn
)
2842 wm
= next
->deduceWild(tn
, true);
2844 wm
= Type::deduceWild(t
, true);
2848 wm
= Type::deduceWild(t
, isRef
);
2850 wm
= next
->deduceWild(tn
, true);
2857 void TypeNext::transitive()
2859 /* Invoke transitivity of type attributes
2861 next
= next
->addMod(mod
);
2864 /* ============================= TypeBasic =========================== */
2866 #define TFLAGSintegral 1
2867 #define TFLAGSfloating 2
2868 #define TFLAGSunsigned 4
2869 #define TFLAGSreal 8
2870 #define TFLAGSimaginary 0x10
2871 #define TFLAGScomplex 0x20
2873 TypeBasic::TypeBasic(TY ty
)
2881 case Tvoid
: d
= Token::toChars(TOKvoid
);
2884 case Tint8
: d
= Token::toChars(TOKint8
);
2885 flags
|= TFLAGSintegral
;
2888 case Tuns8
: d
= Token::toChars(TOKuns8
);
2889 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
2892 case Tint16
: d
= Token::toChars(TOKint16
);
2893 flags
|= TFLAGSintegral
;
2896 case Tuns16
: d
= Token::toChars(TOKuns16
);
2897 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
2900 case Tint32
: d
= Token::toChars(TOKint32
);
2901 flags
|= TFLAGSintegral
;
2904 case Tuns32
: d
= Token::toChars(TOKuns32
);
2905 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
2908 case Tfloat32
: d
= Token::toChars(TOKfloat32
);
2909 flags
|= TFLAGSfloating
| TFLAGSreal
;
2912 case Tint64
: d
= Token::toChars(TOKint64
);
2913 flags
|= TFLAGSintegral
;
2916 case Tuns64
: d
= Token::toChars(TOKuns64
);
2917 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
2920 case Tint128
: d
= Token::toChars(TOKint128
);
2921 flags
|= TFLAGSintegral
;
2924 case Tuns128
: d
= Token::toChars(TOKuns128
);
2925 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
2928 case Tfloat64
: d
= Token::toChars(TOKfloat64
);
2929 flags
|= TFLAGSfloating
| TFLAGSreal
;
2932 case Tfloat80
: d
= Token::toChars(TOKfloat80
);
2933 flags
|= TFLAGSfloating
| TFLAGSreal
;
2936 case Timaginary32
: d
= Token::toChars(TOKimaginary32
);
2937 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
2940 case Timaginary64
: d
= Token::toChars(TOKimaginary64
);
2941 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
2944 case Timaginary80
: d
= Token::toChars(TOKimaginary80
);
2945 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
2948 case Tcomplex32
: d
= Token::toChars(TOKcomplex32
);
2949 flags
|= TFLAGSfloating
| TFLAGScomplex
;
2952 case Tcomplex64
: d
= Token::toChars(TOKcomplex64
);
2953 flags
|= TFLAGSfloating
| TFLAGScomplex
;
2956 case Tcomplex80
: d
= Token::toChars(TOKcomplex80
);
2957 flags
|= TFLAGSfloating
| TFLAGScomplex
;
2960 case Tbool
: d
= "bool";
2961 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
2964 case Tchar
: d
= Token::toChars(TOKchar
);
2965 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
2968 case Twchar
: d
= Token::toChars(TOKwchar
);
2969 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
2972 case Tdchar
: d
= Token::toChars(TOKdchar
);
2973 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
2979 this->flags
= flags
;
2983 const char *TypeBasic::kind()
2988 Type
*TypeBasic::syntaxCopy()
2990 // No semantic analysis done on basic types, no need to copy
2994 d_uns64
TypeBasic::size(Loc
)
2997 //printf("TypeBasic::size()\n");
3001 case Tuns8
: size
= 1; break;
3003 case Tuns16
: size
= 2; break;
3016 size
= Target::realsize
; break;
3024 size
= Target::realsize
* 2; break;
3027 //size = Type::size(); // error message
3031 case Tbool
: size
= 1; break;
3032 case Tchar
: size
= 1; break;
3033 case Twchar
: size
= 2; break;
3034 case Tdchar
: size
= 4; break;
3040 //printf("TypeBasic::size() = %d\n", size);
3044 unsigned TypeBasic::alignsize()
3046 return Target::alignsize(this);
3050 Expression
*TypeBasic::getProperty(Loc loc
, Identifier
*ident
, int flag
)
3056 //printf("TypeBasic::getProperty('%s')\n", ident->toChars());
3057 if (ident
== Id::max
)
3074 ivalue
= 0x7FFFFFFFUL
;
3077 ivalue
= 0xFFFFFFFFUL
;
3080 ivalue
= 0x7FFFFFFFFFFFFFFFLL
;
3083 ivalue
= 0xFFFFFFFFFFFFFFFFULL
;
3095 ivalue
= 0x10FFFFUL
;
3100 fvalue
= Target::FloatProperties::max
;
3105 fvalue
= Target::DoubleProperties::max
;
3110 fvalue
= Target::RealProperties::max
;
3114 else if (ident
== Id::min
)
3131 ivalue
= -2147483647L - 1;
3137 ivalue
= (-9223372036854775807LL-1LL);
3164 error(loc
, "use .min_normal property instead of .min");
3165 return new ErrorExp();
3168 else if (ident
== Id::min_normal
)
3175 fvalue
= Target::FloatProperties::min_normal
;
3180 fvalue
= Target::DoubleProperties::min_normal
;
3185 fvalue
= Target::RealProperties::min_normal
;
3189 else if (ident
== Id::nan
)
3202 fvalue
= Target::RealProperties::nan
;
3206 else if (ident
== Id::infinity
)
3219 fvalue
= Target::RealProperties::infinity
;
3223 else if (ident
== Id::dig
)
3230 ivalue
= Target::FloatProperties::dig
;
3235 ivalue
= Target::DoubleProperties::dig
;
3240 ivalue
= Target::RealProperties::dig
;
3244 else if (ident
== Id::epsilon
)
3251 fvalue
= Target::FloatProperties::epsilon
;
3256 fvalue
= Target::DoubleProperties::epsilon
;
3261 fvalue
= Target::RealProperties::epsilon
;
3265 else if (ident
== Id::mant_dig
)
3272 ivalue
= Target::FloatProperties::mant_dig
;
3277 ivalue
= Target::DoubleProperties::mant_dig
;
3282 ivalue
= Target::RealProperties::mant_dig
;
3286 else if (ident
== Id::max_10_exp
)
3293 ivalue
= Target::FloatProperties::max_10_exp
;
3298 ivalue
= Target::DoubleProperties::max_10_exp
;
3303 ivalue
= Target::RealProperties::max_10_exp
;
3307 else if (ident
== Id::max_exp
)
3314 ivalue
= Target::FloatProperties::max_exp
;
3319 ivalue
= Target::DoubleProperties::max_exp
;
3324 ivalue
= Target::RealProperties::max_exp
;
3328 else if (ident
== Id::min_10_exp
)
3335 ivalue
= Target::FloatProperties::min_10_exp
;
3340 ivalue
= Target::DoubleProperties::min_10_exp
;
3345 ivalue
= Target::RealProperties::min_10_exp
;
3349 else if (ident
== Id::min_exp
)
3356 ivalue
= Target::FloatProperties::min_exp
;
3361 ivalue
= Target::DoubleProperties::min_exp
;
3366 ivalue
= Target::RealProperties::min_exp
;
3371 return Type::getProperty(loc
, ident
, flag
);
3374 e
= new IntegerExp(loc
, ivalue
, this);
3378 if (isreal() || isimaginary())
3379 e
= new RealExp(loc
, fvalue
, this);
3382 complex_t cvalue
= complex_t(fvalue
, fvalue
);
3383 //for (int i = 0; i < 20; i++)
3384 // printf("%02x ", ((unsigned char *)&cvalue)[i]);
3386 e
= new ComplexExp(loc
, cvalue
, this);
3391 e
= new IntegerExp(loc
, ivalue
, Type::tint32
);
3395 Expression
*TypeBasic::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
, int flag
)
3399 if (ident
== Id::re
)
3403 case Tcomplex32
: t
= tfloat32
; goto L1
;
3404 case Tcomplex64
: t
= tfloat64
; goto L1
;
3405 case Tcomplex80
: t
= tfloat80
; goto L1
;
3407 e
= e
->castTo(sc
, t
);
3415 case Timaginary32
: t
= tfloat32
; goto L2
;
3416 case Timaginary64
: t
= tfloat64
; goto L2
;
3417 case Timaginary80
: t
= tfloat80
; goto L2
;
3419 e
= new RealExp(e
->loc
, CTFloat::zero
, t
);
3423 e
= Type::getProperty(e
->loc
, ident
, flag
);
3427 else if (ident
== Id::im
)
3432 case Tcomplex32
: t
= timaginary32
; t2
= tfloat32
; goto L3
;
3433 case Tcomplex64
: t
= timaginary64
; t2
= tfloat64
; goto L3
;
3434 case Tcomplex80
: t
= timaginary80
; t2
= tfloat80
; goto L3
;
3436 e
= e
->castTo(sc
, t
);
3440 case Timaginary32
: t
= tfloat32
; goto L4
;
3441 case Timaginary64
: t
= tfloat64
; goto L4
;
3442 case Timaginary80
: t
= tfloat80
; goto L4
;
3451 e
= new RealExp(e
->loc
, CTFloat::zero
, this);
3455 e
= Type::getProperty(e
->loc
, ident
, flag
);
3461 return Type::dotExp(sc
, e
, ident
, flag
);
3463 if (!(flag
& 1) || e
)
3464 e
= ::semantic(e
, sc
);
3468 Expression
*TypeBasic::defaultInit(Loc loc
)
3470 dinteger_t value
= 0;
3489 return new RealExp(loc
, Target::RealProperties::snan
, this);
3494 { // Can't use fvalue + I*fvalue (the im part becomes a quiet NaN).
3495 complex_t cvalue
= complex_t(Target::RealProperties::snan
, Target::RealProperties::snan
);
3496 return new ComplexExp(loc
, cvalue
, this);
3500 error(loc
, "void does not have a default initializer");
3501 return new ErrorExp();
3503 return new IntegerExp(loc
, value
, this);
3506 bool TypeBasic::isZeroInit(Loc
)
3528 bool TypeBasic::isintegral()
3530 //printf("TypeBasic::isintegral('%s') x%x\n", toChars(), flags);
3531 return (flags
& TFLAGSintegral
) != 0;
3534 bool TypeBasic::isfloating()
3536 return (flags
& TFLAGSfloating
) != 0;
3539 bool TypeBasic::isreal()
3541 return (flags
& TFLAGSreal
) != 0;
3544 bool TypeBasic::isimaginary()
3546 return (flags
& TFLAGSimaginary
) != 0;
3549 bool TypeBasic::iscomplex()
3551 return (flags
& TFLAGScomplex
) != 0;
3554 bool TypeBasic::isunsigned()
3556 return (flags
& TFLAGSunsigned
) != 0;
3559 bool TypeBasic::isscalar()
3561 return (flags
& (TFLAGSintegral
| TFLAGSfloating
)) != 0;
3564 MATCH
TypeBasic::implicitConvTo(Type
*to
)
3566 //printf("TypeBasic::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
3574 else if (MODimplicitConv(mod
, to
->mod
))
3576 else if (!((mod
^ to
->mod
) & MODshared
)) // for wild matching
3579 return MATCHconvert
;
3582 if (ty
== Tvoid
|| to
->ty
== Tvoid
)
3583 return MATCHnomatch
;
3584 if (to
->ty
== Tbool
)
3585 return MATCHnomatch
;
3588 if (to
->ty
== Tvector
&& to
->deco
)
3590 TypeVector
*tv
= (TypeVector
*)to
;
3591 tob
= tv
->elementType();
3593 else if (to
->ty
== Tenum
)
3595 EnumDeclaration
*ed
= ((TypeEnum
*)to
)->sym
;
3596 if (ed
->isSpecial())
3598 /* Special enums that allow implicit conversions to them. */
3599 tob
= to
->toBasetype()->isTypeBasic();
3601 return implicitConvTo(tob
);
3604 return MATCHnomatch
;
3607 tob
= to
->isTypeBasic();
3609 return MATCHnomatch
;
3611 if (flags
& TFLAGSintegral
)
3613 // Disallow implicit conversion of integers to imaginary or complex
3614 if (tob
->flags
& (TFLAGSimaginary
| TFLAGScomplex
))
3615 return MATCHnomatch
;
3617 // If converting from integral to integral
3618 if (tob
->flags
& TFLAGSintegral
)
3619 { d_uns64 sz
= size(Loc());
3620 d_uns64 tosz
= tob
->size(Loc());
3622 /* Can't convert to smaller size
3625 return MATCHnomatch
;
3627 /* Can't change sign if same size
3629 /*if (sz == tosz && (flags ^ tob->flags) & TFLAGSunsigned)
3630 return MATCHnomatch;*/
3633 else if (flags
& TFLAGSfloating
)
3635 // Disallow implicit conversion of floating point to integer
3636 if (tob
->flags
& TFLAGSintegral
)
3637 return MATCHnomatch
;
3639 assert(tob
->flags
& TFLAGSfloating
|| to
->ty
== Tvector
);
3641 // Disallow implicit conversion from complex to non-complex
3642 if (flags
& TFLAGScomplex
&& !(tob
->flags
& TFLAGScomplex
))
3643 return MATCHnomatch
;
3645 // Disallow implicit conversion of real or imaginary to complex
3646 if (flags
& (TFLAGSreal
| TFLAGSimaginary
) &&
3647 tob
->flags
& TFLAGScomplex
)
3648 return MATCHnomatch
;
3650 // Disallow implicit conversion to-from real and imaginary
3651 if ((flags
& (TFLAGSreal
| TFLAGSimaginary
)) !=
3652 (tob
->flags
& (TFLAGSreal
| TFLAGSimaginary
)))
3653 return MATCHnomatch
;
3655 return MATCHconvert
;
3658 TypeBasic
*TypeBasic::isTypeBasic()
3660 return (TypeBasic
*)this;
3663 /* ============================= TypeVector =========================== */
3665 /* The basetype must be one of:
3666 * byte[16],ubyte[16],short[8],ushort[8],int[4],uint[4],long[2],ulong[2],float[4],double[2]
3668 * byte[32],ubyte[32],short[16],ushort[16],int[8],uint[8],long[4],ulong[4],float[8],double[4]
3670 TypeVector::TypeVector(Type
*basetype
)
3673 this->basetype
= basetype
;
3676 TypeVector
*TypeVector::create(Loc
, Type
*basetype
)
3678 return new TypeVector(basetype
);
3681 const char *TypeVector::kind()
3686 Type
*TypeVector::syntaxCopy()
3688 return new TypeVector(basetype
->syntaxCopy());
3691 Type
*TypeVector::semantic(Loc loc
, Scope
*sc
)
3693 unsigned int errors
= global
.errors
;
3694 basetype
= basetype
->semantic(loc
, sc
);
3695 if (errors
!= global
.errors
)
3697 basetype
= basetype
->toBasetype()->mutableOf();
3698 if (basetype
->ty
!= Tsarray
)
3700 error(loc
, "T in __vector(T) must be a static array, not %s", basetype
->toChars());
3703 TypeSArray
*t
= (TypeSArray
*)basetype
;
3704 int sz
= (int)t
->size(loc
);
3705 switch (Target::isVectorTypeSupported(sz
, t
->nextOf()))
3709 case 1: // no support at all
3710 error(loc
, "SIMD vector types not supported on this platform");
3712 case 2: // invalid size
3713 error(loc
, "%d byte vector type %s is not supported on this platform", sz
, toChars());
3715 case 3: // invalid base type
3716 error(loc
, "vector type %s is not supported on this platform", toChars());
3724 TypeBasic
*TypeVector::elementType()
3726 assert(basetype
->ty
== Tsarray
);
3727 TypeSArray
*t
= (TypeSArray
*)basetype
;
3728 TypeBasic
*tb
= t
->nextOf()->isTypeBasic();
3733 bool TypeVector::isBoolean()
3738 d_uns64
TypeVector::size(Loc
)
3740 return basetype
->size();
3743 unsigned TypeVector::alignsize()
3745 return (unsigned)basetype
->size();
3748 Expression
*TypeVector::getProperty(Loc loc
, Identifier
*ident
, int flag
)
3750 return Type::getProperty(loc
, ident
, flag
);
3753 Expression
*TypeVector::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
, int flag
)
3755 if (ident
== Id::ptr
&& e
->op
== TOKcall
)
3757 /* The trouble with TOKcall is the return ABI for float[4] is different from
3758 * __vector(float[4]), and a type paint won't do.
3760 e
= new AddrExp(e
->loc
, e
);
3761 e
= ::semantic(e
, sc
);
3762 e
= e
->castTo(sc
, basetype
->nextOf()->pointerTo());
3765 if (ident
== Id::array
)
3767 //e = e->castTo(sc, basetype);
3769 e
= new VectorArrayExp(e
->loc
, e
);
3770 e
= ::semantic(e
, sc
);
3773 if (ident
== Id::_init
|| ident
== Id::offsetof
|| ident
== Id::stringof
|| ident
== Id::__xalignof
)
3775 // init should return a new VectorExp (Bugzilla 12776)
3776 // offsetof does not work on a cast expression, so use e directly
3777 // stringof should not add a cast to the output
3778 return Type::dotExp(sc
, e
, ident
, flag
);
3780 return basetype
->dotExp(sc
, e
->castTo(sc
, basetype
), ident
, flag
);
3783 Expression
*TypeVector::defaultInit(Loc loc
)
3785 //printf("TypeVector::defaultInit()\n");
3786 assert(basetype
->ty
== Tsarray
);
3787 Expression
*e
= basetype
->defaultInit(loc
);
3788 VectorExp
*ve
= new VectorExp(loc
, e
, this);
3790 ve
->dim
= (int)(basetype
->size(loc
) / elementType()->size(loc
));
3794 Expression
*TypeVector::defaultInitLiteral(Loc loc
)
3796 //printf("TypeVector::defaultInitLiteral()\n");
3797 assert(basetype
->ty
== Tsarray
);
3798 Expression
*e
= basetype
->defaultInitLiteral(loc
);
3799 VectorExp
*ve
= new VectorExp(loc
, e
, this);
3801 ve
->dim
= (int)(basetype
->size(loc
) / elementType()->size(loc
));
3805 bool TypeVector::isZeroInit(Loc loc
)
3807 return basetype
->isZeroInit(loc
);
3810 bool TypeVector::isintegral()
3812 //printf("TypeVector::isintegral('%s') x%x\n", toChars(), flags);
3813 return basetype
->nextOf()->isintegral();
3816 bool TypeVector::isfloating()
3818 return basetype
->nextOf()->isfloating();
3821 bool TypeVector::isunsigned()
3823 return basetype
->nextOf()->isunsigned();
3826 bool TypeVector::isscalar()
3828 return basetype
->nextOf()->isscalar();
3831 MATCH
TypeVector::implicitConvTo(Type
*to
)
3833 //printf("TypeVector::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
3837 if (to
->ty
== Tvector
)
3839 TypeVector
*tv
= (TypeVector
*)to
;
3840 assert(basetype
->ty
== Tsarray
&& tv
->basetype
->ty
== Tsarray
);
3842 // Can't convert to a vector which has different size.
3843 if (basetype
->size() != tv
->basetype
->size())
3844 return MATCHnomatch
;
3846 // Allow conversion to void[]
3847 if (tv
->basetype
->nextOf()->ty
== Tvoid
)
3848 return MATCHconvert
;
3850 // Otherwise implicitly convertible only if basetypes are.
3851 return basetype
->implicitConvTo(tv
->basetype
);
3855 return MATCHconvert
;
3857 return MATCHnomatch
;
3860 /***************************** TypeArray *****************************/
3862 TypeArray::TypeArray(TY ty
, Type
*next
)
3863 : TypeNext(ty
, next
)
3867 Expression
*TypeArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
, int flag
)
3869 e
= Type::dotExp(sc
, e
, ident
, flag
);
3871 if (!(flag
& 1) || e
)
3872 e
= ::semantic(e
, sc
);
3877 /***************************** TypeSArray *****************************/
3879 TypeSArray::TypeSArray(Type
*t
, Expression
*dim
)
3880 : TypeArray(Tsarray
, t
)
3882 //printf("TypeSArray(%s)\n", dim->toChars());
3886 const char *TypeSArray::kind()
3891 Type
*TypeSArray::syntaxCopy()
3893 Type
*t
= next
->syntaxCopy();
3894 Expression
*e
= dim
->syntaxCopy();
3895 t
= new TypeSArray(t
, e
);
3900 d_uns64
TypeSArray::size(Loc loc
)
3902 //printf("TypeSArray::size()\n");
3905 return Type::size(loc
);
3906 sz
= dim
->toInteger();
3909 bool overflow
= false;
3911 sz
= mulu(next
->size(), sz
, overflow
);
3915 if (sz
> UINT32_MAX
)
3920 error(loc
, "static array %s size overflowed to %lld", toChars(), (long long)sz
);
3921 return SIZE_INVALID
;
3924 unsigned TypeSArray::alignsize()
3926 return next
->alignsize();
3929 /**************************
3930 * This evaluates exp while setting length to be the number
3931 * of elements in the tuple t.
3933 Expression
*semanticLength(Scope
*sc
, Type
*t
, Expression
*exp
)
3935 if (t
->ty
== Ttuple
)
3937 ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, (TypeTuple
*)t
);
3938 sym
->parent
= sc
->scopesym
;
3941 sc
= sc
->startCTFE();
3942 exp
= ::semantic(exp
, sc
);
3949 sc
= sc
->startCTFE();
3950 exp
= ::semantic(exp
, sc
);
3957 Expression
*semanticLength(Scope
*sc
, TupleDeclaration
*s
, Expression
*exp
)
3959 ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, s
);
3960 sym
->parent
= sc
->scopesym
;
3963 sc
= sc
->startCTFE();
3964 exp
= ::semantic(exp
, sc
);
3971 void TypeSArray::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
, bool intypeid
)
3973 //printf("TypeSArray::resolve() %s\n", toChars());
3974 next
->resolve(loc
, sc
, pe
, pt
, ps
, intypeid
);
3975 //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
3978 // It's really an index expression
3979 if (Dsymbol
*s
= getDsymbol(*pe
))
3980 *pe
= new DsymbolExp(loc
, s
);
3981 *pe
= new ArrayExp(loc
, *pe
, dim
);
3986 TupleDeclaration
*td
= s
->isTupleDeclaration();
3989 ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, td
);
3990 sym
->parent
= sc
->scopesym
;
3992 sc
= sc
->startCTFE();
3993 dim
= ::semantic(dim
, sc
);
3997 dim
= dim
->ctfeInterpret();
3998 uinteger_t d
= dim
->toUInteger();
4000 if (d
>= td
->objects
->dim
)
4002 error(loc
, "tuple index %llu exceeds length %u", d
, td
->objects
->dim
);
4007 RootObject
*o
= (*td
->objects
)[(size_t)d
];
4008 if (o
->dyncast() == DYNCAST_DSYMBOL
)
4013 if (o
->dyncast() == DYNCAST_EXPRESSION
)
4015 Expression
*e
= (Expression
*)o
;
4016 if (e
->op
== TOKdsymbol
)
4018 *ps
= ((DsymbolExp
*)e
)->s
;
4028 if (o
->dyncast() == DYNCAST_TYPE
)
4031 *pt
= ((Type
*)o
)->addMod(this->mod
);
4035 /* Create a new TupleDeclaration which
4036 * is a slice [d..d+1] out of the old one.
4037 * Do it this way because TemplateInstance::semanticTiargs()
4038 * can handle unresolved Objects this way.
4040 Objects
*objects
= new Objects
;
4044 TupleDeclaration
*tds
= new TupleDeclaration(loc
, td
->ident
, objects
);
4052 if ((*pt
)->ty
!= Terror
)
4053 next
= *pt
; // prevent re-running semantic() on 'next'
4055 Type::resolve(loc
, sc
, pe
, pt
, ps
, intypeid
);
4059 Type
*TypeSArray::semantic(Loc loc
, Scope
*sc
)
4061 //printf("TypeSArray::semantic() %s\n", toChars());
4066 next
->resolve(loc
, sc
, &e
, &t
, &s
);
4067 if (dim
&& s
&& s
->isTupleDeclaration())
4068 { TupleDeclaration
*sd
= s
->isTupleDeclaration();
4070 dim
= semanticLength(sc
, sd
, dim
);
4071 dim
= dim
->ctfeInterpret();
4072 uinteger_t d
= dim
->toUInteger();
4074 if (d
>= sd
->objects
->dim
)
4075 { error(loc
, "tuple index %llu exceeds %u", d
, sd
->objects
->dim
);
4076 return Type::terror
;
4078 RootObject
*o
= (*sd
->objects
)[(size_t)d
];
4079 if (o
->dyncast() != DYNCAST_TYPE
)
4080 { error(loc
, "%s is not a type", toChars());
4081 return Type::terror
;
4083 t
= ((Type
*)o
)->addMod(this->mod
);
4087 Type
*tn
= next
->semantic(loc
, sc
);
4088 if (tn
->ty
== Terror
)
4091 Type
*tbn
= tn
->toBasetype();
4095 unsigned int errors
= global
.errors
;
4096 dim
= semanticLength(sc
, tbn
, dim
);
4097 if (errors
!= global
.errors
)
4100 dim
= dim
->optimize(WANTvalue
);
4101 dim
= dim
->ctfeInterpret();
4102 if (dim
->op
== TOKerror
)
4104 errors
= global
.errors
;
4105 dinteger_t d1
= dim
->toInteger();
4106 if (errors
!= global
.errors
)
4109 dim
= dim
->implicitCastTo(sc
, tsize_t
);
4110 dim
= dim
->optimize(WANTvalue
);
4111 if (dim
->op
== TOKerror
)
4113 errors
= global
.errors
;
4114 dinteger_t d2
= dim
->toInteger();
4115 if (errors
!= global
.errors
)
4118 if (dim
->op
== TOKerror
)
4124 error(loc
, "%s size %llu * %llu exceeds 0x%llx size limit for static array",
4125 toChars(), (unsigned long long)tbn
->size(loc
), (unsigned long long)d1
, Target::maxStaticDataSize
);
4129 Type
*tbx
= tbn
->baseElemOf();
4130 if ((tbx
->ty
== Tstruct
&& !((TypeStruct
*)tbx
)->sym
->members
) ||
4131 (tbx
->ty
== Tenum
&& !((TypeEnum
*)tbx
)->sym
->members
))
4133 /* To avoid meaningless error message, skip the total size limit check
4134 * when the bottom of element type is opaque.
4137 else if (tbn
->isintegral() ||
4138 tbn
->isfloating() ||
4139 tbn
->ty
== Tpointer
||
4140 tbn
->ty
== Tarray
||
4141 tbn
->ty
== Tsarray
||
4142 tbn
->ty
== Taarray
||
4143 (tbn
->ty
== Tstruct
&& (((TypeStruct
*)tbn
)->sym
->sizeok
== SIZEOKdone
)) ||
4146 /* Only do this for types that don't need to have semantic()
4147 * run on them for the size, since they may be forward referenced.
4149 bool overflow
= false;
4150 if (mulu(tbn
->size(loc
), d2
, overflow
) >= Target::maxStaticDataSize
|| overflow
)
4157 { // Index the tuple to get the type
4159 TypeTuple
*tt
= (TypeTuple
*)tbn
;
4160 uinteger_t d
= dim
->toUInteger();
4162 if (d
>= tt
->arguments
->dim
)
4163 { error(loc
, "tuple index %llu exceeds %u", d
, tt
->arguments
->dim
);
4166 Type
*telem
= (*tt
->arguments
)[(size_t)d
]->type
;
4167 return telem
->addMod(this->mod
);
4171 error(loc
, "can't have array of %s", tbn
->toChars());
4177 { error(loc
, "cannot have array of scope %s", tbn
->toChars());
4181 /* Ensure things like const(immutable(T)[3]) become immutable(T[3])
4182 * and const(T)[3] become const(T[3])
4186 t
= addMod(tn
->mod
);
4191 return Type::terror
;
4194 Expression
*TypeSArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
, int flag
)
4196 if (ident
== Id::length
)
4198 Loc oldLoc
= e
->loc
;
4202 else if (ident
== Id::ptr
)
4204 if (e
->op
== TOKtype
)
4206 e
->error("%s is not an expression", e
->toChars());
4207 return new ErrorExp();
4209 else if (!(flag
& 2) && sc
->func
&& !sc
->intypeof
&& sc
->func
->setUnsafe())
4211 e
->deprecation("%s.ptr cannot be used in @safe code, use &%s[0] instead", e
->toChars(), e
->toChars());
4212 // return new ErrorExp();
4214 e
= e
->castTo(sc
, e
->type
->nextOf()->pointerTo());
4218 e
= TypeArray::dotExp(sc
, e
, ident
, flag
);
4220 if (!(flag
& 1) || e
)
4221 e
= ::semantic(e
, sc
);
4225 structalign_t
TypeSArray::alignment()
4227 return next
->alignment();
4230 bool TypeSArray::isString()
4232 TY nty
= next
->toBasetype()->ty
;
4233 return nty
== Tchar
|| nty
== Twchar
|| nty
== Tdchar
;
4236 MATCH
TypeSArray::constConv(Type
*to
)
4238 if (to
->ty
== Tsarray
)
4240 TypeSArray
*tsa
= (TypeSArray
*)to
;
4241 if (!dim
->equals(tsa
->dim
))
4242 return MATCHnomatch
;
4244 return TypeNext::constConv(to
);
4247 MATCH
TypeSArray::implicitConvTo(Type
*to
)
4249 //printf("TypeSArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4251 if (to
->ty
== Tarray
)
4253 TypeDArray
*ta
= (TypeDArray
*)to
;
4255 if (!MODimplicitConv(next
->mod
, ta
->next
->mod
))
4256 return MATCHnomatch
;
4258 /* Allow conversion to void[]
4260 if (ta
->next
->ty
== Tvoid
)
4262 return MATCHconvert
;
4265 MATCH m
= next
->constConv(ta
->next
);
4266 if (m
> MATCHnomatch
)
4268 return MATCHconvert
;
4270 return MATCHnomatch
;
4273 if (to
->ty
== Tsarray
)
4278 TypeSArray
*tsa
= (TypeSArray
*)to
;
4280 if (dim
->equals(tsa
->dim
))
4282 /* Since static arrays are value types, allow
4283 * conversions from const elements to non-const
4284 * ones, just like we allow conversion from const int
4287 MATCH m
= next
->implicitConvTo(tsa
->next
);
4288 if (m
>= MATCHconst
)
4296 return MATCHnomatch
;
4299 Expression
*TypeSArray::defaultInit(Loc loc
)
4301 if (next
->ty
== Tvoid
)
4302 return tuns8
->defaultInit(loc
);
4304 return next
->defaultInit(loc
);
4307 bool TypeSArray::isZeroInit(Loc loc
)
4309 return next
->isZeroInit(loc
);
4312 bool TypeSArray::needsDestruction()
4314 return next
->needsDestruction();
4317 /*********************************
4321 bool TypeSArray::needsNested()
4323 return next
->needsNested();
4326 Expression
*TypeSArray::defaultInitLiteral(Loc loc
)
4328 size_t d
= (size_t)dim
->toInteger();
4329 Expression
*elementinit
;
4330 if (next
->ty
== Tvoid
)
4331 elementinit
= tuns8
->defaultInitLiteral(loc
);
4333 elementinit
= next
->defaultInitLiteral(loc
);
4334 Expressions
*elements
= new Expressions();
4335 elements
->setDim(d
);
4336 for (size_t i
= 0; i
< d
; i
++)
4337 (*elements
)[i
] = NULL
;
4338 ArrayLiteralExp
*ae
= new ArrayLiteralExp(Loc(), this, elementinit
, elements
);
4342 bool TypeSArray::hasPointers()
4344 /* Don't want to do this, because:
4345 * struct S { T* array[0]; }
4346 * may be a variable length struct.
4348 //if (dim->toInteger() == 0)
4351 if (next
->ty
== Tvoid
)
4353 // Arrays of void contain arbitrary data, which may include pointers
4357 return next
->hasPointers();
4360 /***************************** TypeDArray *****************************/
4362 TypeDArray::TypeDArray(Type
*t
)
4363 : TypeArray(Tarray
, t
)
4365 //printf("TypeDArray(t = %p)\n", t);
4368 const char *TypeDArray::kind()
4373 Type
*TypeDArray::syntaxCopy()
4375 Type
*t
= next
->syntaxCopy();
4380 t
= new TypeDArray(t
);
4386 d_uns64
TypeDArray::size(Loc
)
4388 //printf("TypeDArray::size()\n");
4389 return Target::ptrsize
* 2;
4392 unsigned TypeDArray::alignsize()
4394 // A DArray consists of two ptr-sized values, so align it on pointer size
4396 return Target::ptrsize
;
4399 Type
*TypeDArray::semantic(Loc loc
, Scope
*sc
)
4401 Type
*tn
= next
->semantic(loc
,sc
);
4402 Type
*tbn
= tn
->toBasetype();
4409 error(loc
, "can't have array of %s", tbn
->toChars());
4410 return Type::terror
;
4412 return Type::terror
;
4417 { error(loc
, "cannot have array of scope %s", tn
->toChars());
4418 return Type::terror
;
4425 void TypeDArray::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
, bool intypeid
)
4427 //printf("TypeDArray::resolve() %s\n", toChars());
4428 next
->resolve(loc
, sc
, pe
, pt
, ps
, intypeid
);
4429 //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
4432 // It's really a slice expression
4433 if (Dsymbol
*s
= getDsymbol(*pe
))
4434 *pe
= new DsymbolExp(loc
, s
);
4435 *pe
= new ArrayExp(loc
, *pe
);
4439 TupleDeclaration
*td
= (*ps
)->isTupleDeclaration();
4447 if ((*pt
)->ty
!= Terror
)
4448 next
= *pt
; // prevent re-running semantic() on 'next'
4450 Type::resolve(loc
, sc
, pe
, pt
, ps
, intypeid
);
4454 Expression
*TypeDArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
, int flag
)
4456 if (e
->op
== TOKtype
&&
4457 (ident
== Id::length
|| ident
== Id::ptr
))
4459 e
->error("%s is not an expression", e
->toChars());
4460 return new ErrorExp();
4462 if (ident
== Id::length
)
4464 if (e
->op
== TOKstring
)
4466 StringExp
*se
= (StringExp
*)e
;
4467 return new IntegerExp(se
->loc
, se
->len
, Type::tsize_t
);
4469 if (e
->op
== TOKnull
)
4470 return new IntegerExp(e
->loc
, 0, Type::tsize_t
);
4471 e
= new ArrayLengthExp(e
->loc
, e
);
4472 e
->type
= Type::tsize_t
;
4475 else if (ident
== Id::ptr
)
4477 if (!(flag
& 2) && sc
->func
&& !sc
->intypeof
&& sc
->func
->setUnsafe())
4479 e
->deprecation("%s.ptr cannot be used in @safe code, use &%s[0] instead", e
->toChars(), e
->toChars());
4480 // return new ErrorExp();
4482 e
= e
->castTo(sc
, next
->pointerTo());
4487 e
= TypeArray::dotExp(sc
, e
, ident
, flag
);
4492 bool TypeDArray::isString()
4494 TY nty
= next
->toBasetype()->ty
;
4495 return nty
== Tchar
|| nty
== Twchar
|| nty
== Tdchar
;
4498 MATCH
TypeDArray::implicitConvTo(Type
*to
)
4500 //printf("TypeDArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4504 if (to
->ty
== Tarray
)
4506 TypeDArray
*ta
= (TypeDArray
*)to
;
4508 if (!MODimplicitConv(next
->mod
, ta
->next
->mod
))
4509 return MATCHnomatch
; // not const-compatible
4511 /* Allow conversion to void[]
4513 if (next
->ty
!= Tvoid
&& ta
->next
->ty
== Tvoid
)
4515 return MATCHconvert
;
4518 MATCH m
= next
->constConv(ta
->next
);
4519 if (m
> MATCHnomatch
)
4521 if (m
== MATCHexact
&& mod
!= to
->mod
)
4526 return Type::implicitConvTo(to
);
4529 Expression
*TypeDArray::defaultInit(Loc loc
)
4531 return new NullExp(loc
, this);
4534 bool TypeDArray::isZeroInit(Loc
)
4539 bool TypeDArray::isBoolean()
4544 bool TypeDArray::hasPointers()
4550 /***************************** TypeAArray *****************************/
4552 TypeAArray::TypeAArray(Type
*t
, Type
*index
)
4553 : TypeArray(Taarray
, t
)
4555 this->index
= index
;
4560 TypeAArray
*TypeAArray::create(Type
*t
, Type
*index
)
4562 return new TypeAArray(t
, index
);
4565 const char *TypeAArray::kind()
4570 Type
*TypeAArray::syntaxCopy()
4572 Type
*t
= next
->syntaxCopy();
4573 Type
*ti
= index
->syntaxCopy();
4574 if (t
== next
&& ti
== index
)
4578 t
= new TypeAArray(t
, ti
);
4584 d_uns64
TypeAArray::size(Loc
)
4586 return Target::ptrsize
;
4589 Type
*TypeAArray::semantic(Loc loc
, Scope
*sc
)
4591 //printf("TypeAArray::semantic() %s index->ty = %d\n", toChars(), index->ty);
4600 // Deal with the case where we thought the index was a type, but
4601 // in reality it was an expression.
4602 if (index
->ty
== Tident
|| index
->ty
== Tinstance
|| index
->ty
== Tsarray
||
4603 index
->ty
== Ttypeof
|| index
->ty
== Treturn
)
4609 index
->resolve(loc
, sc
, &e
, &t
, &s
);
4612 // It was an expression -
4613 // Rewrite as a static array
4614 TypeSArray
*tsa
= new TypeSArray(next
, e
);
4615 return tsa
->semantic(loc
, sc
);
4618 index
= t
->semantic(loc
, sc
);
4621 index
->error(loc
, "index is not a type or an expression");
4622 return Type::terror
;
4626 index
= index
->semantic(loc
,sc
);
4627 index
= index
->merge2();
4629 if (index
->nextOf() && !index
->nextOf()->isImmutable())
4631 index
= index
->constOf()->mutableOf();
4634 switch (index
->toBasetype()->ty
)
4640 error(loc
, "can't have associative array key of %s", index
->toBasetype()->toChars());
4643 return Type::terror
;
4647 Type
*tbase
= index
->baseElemOf();
4648 while (tbase
->ty
== Tarray
)
4649 tbase
= tbase
->nextOf()->baseElemOf();
4650 if (tbase
->ty
== Tstruct
)
4652 /* AA's need typeid(index).equals() and getHash(). Issue error if not correctly set up.
4654 StructDeclaration
*sd
= ((TypeStruct
*)tbase
)->sym
;
4658 // duplicate a part of StructDeclaration::semanticTypeInfoMembers
4659 //printf("AA = %s, key: xeq = %p, xerreq = %p xhash = %p\n", toChars(), sd->xeq, sd->xerreq, sd->xhash);
4662 sd
->xeq
->semanticRun
< PASSsemantic3done
)
4664 unsigned errors
= global
.startGagging();
4665 sd
->xeq
->semantic3(sd
->xeq
->_scope
);
4666 if (global
.endGagging(errors
))
4667 sd
->xeq
= sd
->xerreq
;
4670 const char *s
= (index
->toBasetype()->ty
!= Tstruct
) ? "bottom of " : "";
4673 // If sd->xhash != NULL:
4674 // sd or its fields have user-defined toHash.
4675 // AA assumes that its result is consistent with bitwise equality.
4677 // bitwise equality & hashing
4679 else if (sd
->xeq
== sd
->xerreq
)
4681 if (search_function(sd
, Id::eq
))
4683 error(loc
, "%sAA key type %s does not have 'bool opEquals(ref const %s) const'",
4684 s
, sd
->toChars(), sd
->toChars());
4688 error(loc
, "%sAA key type %s does not support const equality",
4691 return Type::terror
;
4693 else if (!sd
->xhash
)
4695 if (search_function(sd
, Id::eq
))
4697 error(loc
, "%sAA key type %s should have 'size_t toHash() const nothrow @safe' if opEquals defined",
4702 error(loc
, "%sAA key type %s supports const equality but doesn't support const hashing",
4705 return Type::terror
;
4709 // defined equality & hashing
4710 assert(sd
->xeq
&& sd
->xhash
);
4712 /* xeq and xhash may be implicitly defined by compiler. For example:
4713 * struct S { int[] arr; }
4714 * With 'arr' field equality and hashing, compiler will implicitly
4715 * generate functions for xopEquals and xtoHash in TypeInfo_Struct.
4719 else if (tbase
->ty
== Tclass
&& !((TypeClass
*)tbase
)->sym
->isInterfaceDeclaration())
4721 ClassDeclaration
*cd
= ((TypeClass
*)tbase
)->sym
;
4725 if (!ClassDeclaration::object
)
4727 error(Loc(), "missing or corrupt object.d");
4731 static FuncDeclaration
*feq
= NULL
;
4732 static FuncDeclaration
*fcmp
= NULL
;
4733 static FuncDeclaration
*fhash
= NULL
;
4734 if (!feq
) feq
= search_function(ClassDeclaration::object
, Id::eq
)->isFuncDeclaration();
4735 if (!fcmp
) fcmp
= search_function(ClassDeclaration::object
, Id::cmp
)->isFuncDeclaration();
4736 if (!fhash
) fhash
= search_function(ClassDeclaration::object
, Id::tohash
)->isFuncDeclaration();
4737 assert(fcmp
&& feq
&& fhash
);
4739 if (feq
->vtblIndex
< (int)cd
->vtbl
.dim
&& cd
->vtbl
[feq
->vtblIndex
] == feq
)
4741 if (fcmp
->vtblIndex
< (int)cd
->vtbl
.dim
&& cd
->vtbl
[fcmp
->vtblIndex
] != fcmp
)
4743 const char *s
= (index
->toBasetype()->ty
!= Tclass
) ? "bottom of " : "";
4744 error(loc
, "%sAA key type %s now requires equality rather than comparison",
4746 errorSupplemental(loc
, "Please override Object.opEquals and toHash.");
4750 next
= next
->semantic(loc
,sc
)->merge2();
4753 switch (next
->toBasetype()->ty
)
4759 error(loc
, "can't have associative array of %s", next
->toChars());
4762 return Type::terror
;
4764 if (next
->isscope())
4765 { error(loc
, "cannot have array of scope %s", next
->toChars());
4766 return Type::terror
;
4771 void TypeAArray::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
, bool intypeid
)
4773 //printf("TypeAArray::resolve() %s\n", toChars());
4775 // Deal with the case where we thought the index was a type, but
4776 // in reality it was an expression.
4777 if (index
->ty
== Tident
|| index
->ty
== Tinstance
|| index
->ty
== Tsarray
)
4783 index
->resolve(loc
, sc
, &e
, &t
, &s
, intypeid
);
4786 // It was an expression -
4787 // Rewrite as a static array
4788 TypeSArray
*tsa
= new TypeSArray(next
, e
);
4789 tsa
->mod
= this->mod
; // just copy mod field so tsa's semantic is not yet done
4790 return tsa
->resolve(loc
, sc
, pe
, pt
, ps
, intypeid
);
4795 index
->error(loc
, "index is not a type or an expression");
4797 Type::resolve(loc
, sc
, pe
, pt
, ps
, intypeid
);
4801 Expression
*TypeAArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
, int flag
)
4803 if (ident
== Id::length
)
4805 static FuncDeclaration
*fd_aaLen
= NULL
;
4806 if (fd_aaLen
== NULL
)
4808 Parameters
*fparams
= new Parameters();
4809 fparams
->push(new Parameter(STCin
, this, NULL
, NULL
));
4810 fd_aaLen
= FuncDeclaration::genCfunc(fparams
, Type::tsize_t
, Id::aaLen
);
4811 TypeFunction
*tf
= fd_aaLen
->type
->toTypeFunction();
4812 tf
->purity
= PUREconst
;
4813 tf
->isnothrow
= true;
4816 Expression
*ev
= new VarExp(e
->loc
, fd_aaLen
, false);
4817 e
= new CallExp(e
->loc
, ev
, e
);
4818 e
->type
= fd_aaLen
->type
->toTypeFunction()->next
;
4821 e
= Type::dotExp(sc
, e
, ident
, flag
);
4825 Expression
*TypeAArray::defaultInit(Loc loc
)
4827 return new NullExp(loc
, this);
4830 bool TypeAArray::isZeroInit(Loc
)
4835 bool TypeAArray::isBoolean()
4840 bool TypeAArray::hasPointers()
4845 MATCH
TypeAArray::implicitConvTo(Type
*to
)
4847 //printf("TypeAArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
4851 if (to
->ty
== Taarray
)
4852 { TypeAArray
*ta
= (TypeAArray
*)to
;
4854 if (!MODimplicitConv(next
->mod
, ta
->next
->mod
))
4855 return MATCHnomatch
; // not const-compatible
4857 if (!MODimplicitConv(index
->mod
, ta
->index
->mod
))
4858 return MATCHnomatch
; // not const-compatible
4860 MATCH m
= next
->constConv(ta
->next
);
4861 MATCH mi
= index
->constConv(ta
->index
);
4862 if (m
> MATCHnomatch
&& mi
> MATCHnomatch
)
4864 return MODimplicitConv(mod
, to
->mod
) ? MATCHconst
: MATCHnomatch
;
4867 return Type::implicitConvTo(to
);
4870 MATCH
TypeAArray::constConv(Type
*to
)
4872 if (to
->ty
== Taarray
)
4874 TypeAArray
*taa
= (TypeAArray
*)to
;
4875 MATCH mindex
= index
->constConv(taa
->index
);
4876 MATCH mkey
= next
->constConv(taa
->next
);
4877 // Pick the worst match
4878 return mkey
< mindex
? mkey
: mindex
;
4880 return Type::constConv(to
);
4883 /***************************** TypePointer *****************************/
4885 TypePointer::TypePointer(Type
*t
)
4886 : TypeNext(Tpointer
, t
)
4890 TypePointer
*TypePointer::create(Type
*t
)
4892 return new TypePointer(t
);
4895 const char *TypePointer::kind()
4900 Type
*TypePointer::syntaxCopy()
4902 Type
*t
= next
->syntaxCopy();
4907 t
= new TypePointer(t
);
4913 Type
*TypePointer::semantic(Loc loc
, Scope
*sc
)
4915 //printf("TypePointer::semantic() %s\n", toChars());
4918 Type
*n
= next
->semantic(loc
, sc
);
4919 switch (n
->toBasetype()->ty
)
4922 error(loc
, "can't have pointer to %s", n
->toChars());
4925 return Type::terror
;
4934 if (next
->ty
!= Tfunction
)
4938 deco
= merge()->deco
;
4939 /* Don't return merge(), because arg identifiers and default args
4941 * even though the types match
4947 d_uns64
TypePointer::size(Loc
)
4949 return Target::ptrsize
;
4952 MATCH
TypePointer::implicitConvTo(Type
*to
)
4954 //printf("TypePointer::implicitConvTo(to = %s) %s\n", to->toChars(), toChars());
4958 if (next
->ty
== Tfunction
)
4960 if (to
->ty
== Tpointer
)
4962 TypePointer
*tp
= (TypePointer
*)to
;
4963 if (tp
->next
->ty
== Tfunction
)
4965 if (next
->equals(tp
->next
))
4968 if (next
->covariant(tp
->next
) == 1)
4970 Type
*tret
= this->next
->nextOf();
4971 Type
*toret
= tp
->next
->nextOf();
4972 if (tret
->ty
== Tclass
&& toret
->ty
== Tclass
)
4974 /* Bugzilla 10219: Check covariant interface return with offset tweaking.
4976 * class C : Object, I {}
4977 * I function() dg = function C() {} // should be error
4980 if (toret
->isBaseOf(tret
, &offset
) && offset
!= 0)
4981 return MATCHnomatch
;
4983 return MATCHconvert
;
4986 else if (tp
->next
->ty
== Tvoid
)
4988 // Allow conversions to void*
4989 return MATCHconvert
;
4992 return MATCHnomatch
;
4994 else if (to
->ty
== Tpointer
)
4996 TypePointer
*tp
= (TypePointer
*)to
;
4999 if (!MODimplicitConv(next
->mod
, tp
->next
->mod
))
5000 return MATCHnomatch
; // not const-compatible
5002 /* Alloc conversion to void*
5004 if (next
->ty
!= Tvoid
&& tp
->next
->ty
== Tvoid
)
5006 return MATCHconvert
;
5009 MATCH m
= next
->constConv(tp
->next
);
5010 if (m
> MATCHnomatch
)
5012 if (m
== MATCHexact
&& mod
!= to
->mod
)
5017 return MATCHnomatch
;
5020 MATCH
TypePointer::constConv(Type
*to
)
5022 if (next
->ty
== Tfunction
)
5024 if (to
->nextOf() && next
->equals(((TypeNext
*)to
)->next
))
5025 return Type::constConv(to
);
5027 return MATCHnomatch
;
5029 return TypeNext::constConv(to
);
5032 bool TypePointer::isscalar()
5037 Expression
*TypePointer::defaultInit(Loc loc
)
5039 return new NullExp(loc
, this);
5042 bool TypePointer::isZeroInit(Loc
)
5047 bool TypePointer::hasPointers()
5053 /***************************** TypeReference *****************************/
5055 TypeReference::TypeReference(Type
*t
)
5056 : TypeNext(Treference
, t
)
5058 // BUG: what about references to static arrays?
5061 const char *TypeReference::kind()
5066 Type
*TypeReference::syntaxCopy()
5068 Type
*t
= next
->syntaxCopy();
5073 t
= new TypeReference(t
);
5079 Type
*TypeReference::semantic(Loc loc
, Scope
*sc
)
5081 //printf("TypeReference::semantic()\n");
5082 Type
*n
= next
->semantic(loc
, sc
);
5091 d_uns64
TypeReference::size(Loc
)
5093 return Target::ptrsize
;
5096 Expression
*TypeReference::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
, int flag
)
5098 // References just forward things along
5099 return next
->dotExp(sc
, e
, ident
, flag
);
5102 Expression
*TypeReference::defaultInit(Loc loc
)
5104 return new NullExp(loc
, this);
5107 bool TypeReference::isZeroInit(Loc
)
5113 /***************************** TypeFunction *****************************/
5115 TypeFunction::TypeFunction(Parameters
*parameters
, Type
*treturn
, int varargs
, LINK linkage
, StorageClass stc
)
5116 : TypeNext(Tfunction
, treturn
)
5118 //if (!treturn) *(char*)0=0;
5120 assert(0 <= varargs
&& varargs
<= 2);
5121 this->parameters
= parameters
;
5122 this->varargs
= varargs
;
5123 this->linkage
= linkage
;
5125 this->isnothrow
= false;
5126 this->isnogc
= false;
5127 this->purity
= PUREimpure
;
5128 this->isproperty
= false;
5129 this->isref
= false;
5130 this->isreturn
= false;
5131 this->isscope
= false;
5132 this->isscopeinferred
= false;
5137 this->purity
= PUREfwdref
;
5138 if (stc
& STCnothrow
)
5139 this->isnothrow
= true;
5141 this->isnogc
= true;
5142 if (stc
& STCproperty
)
5143 this->isproperty
= true;
5147 if (stc
& STCreturn
)
5148 this->isreturn
= true;
5150 this->isscope
= true;
5151 if (stc
& STCscopeinferred
)
5152 this->isscopeinferred
= true;
5154 this->trust
= TRUSTdefault
;
5156 this->trust
= TRUSTsafe
;
5157 if (stc
& STCsystem
)
5158 this->trust
= TRUSTsystem
;
5159 if (stc
& STCtrusted
)
5160 this->trust
= TRUSTtrusted
;
5163 TypeFunction
*TypeFunction::create(Parameters
*parameters
, Type
*treturn
, int varargs
, LINK linkage
, StorageClass stc
)
5165 return new TypeFunction(parameters
, treturn
, varargs
, linkage
, stc
);
5168 const char *TypeFunction::kind()
5173 Type
*TypeFunction::syntaxCopy()
5175 Type
*treturn
= next
? next
->syntaxCopy() : NULL
;
5176 Parameters
*params
= Parameter::arraySyntaxCopy(parameters
);
5177 TypeFunction
*t
= new TypeFunction(params
, treturn
, varargs
, linkage
);
5179 t
->isnothrow
= isnothrow
;
5182 t
->isproperty
= isproperty
;
5184 t
->isreturn
= isreturn
;
5185 t
->isscope
= isscope
;
5186 t
->isscopeinferred
= isscopeinferred
;
5193 /*******************************
5194 * Covariant means that 'this' can substitute for 't',
5195 * i.e. a pure function is a match for an impure type.
5197 * t = type 'this' is covariant with
5198 * pstc = if not null, store STCxxxx which would make it covariant
5199 * fix17349 = enable fix https://issues.dlang.org/show_bug.cgi?id=17349
5201 * 0 types are distinct
5202 * 1 this is covariant with t
5203 * 2 arguments match as far as overloading goes,
5204 * but types are not covariant
5205 * 3 cannot determine covariance because of forward references
5206 * *pstc STCxxxx which would make it covariant
5209 int Type::covariant(Type
*t
, StorageClass
*pstc
, bool fix17349
)
5213 StorageClass stc
= 0;
5215 bool notcovariant
= false;
5221 return 1; // covariant
5223 if (ty
!= Tfunction
|| t
->ty
!= Tfunction
)
5226 t1
= (TypeFunction
*)this;
5227 t2
= (TypeFunction
*)t
;
5229 if (t1
->varargs
!= t2
->varargs
)
5232 if (t1
->parameters
&& t2
->parameters
)
5234 size_t dim
= Parameter::dim(t1
->parameters
);
5235 if (dim
!= Parameter::dim(t2
->parameters
))
5238 for (size_t i
= 0; i
< dim
; i
++)
5240 Parameter
*fparam1
= Parameter::getNth(t1
->parameters
, i
);
5241 Parameter
*fparam2
= Parameter::getNth(t2
->parameters
, i
);
5243 if (!fparam1
->type
->equals(fparam2
->type
))
5247 Type
*tp1
= fparam1
->type
;
5248 Type
*tp2
= fparam2
->type
;
5249 if (tp1
->ty
== tp2
->ty
)
5251 if (tp1
->ty
== Tclass
)
5253 if (((TypeClass
*)tp1
)->sym
== ((TypeClass
*)tp2
)->sym
&& MODimplicitConv(tp2
->mod
, tp1
->mod
))
5256 else if (tp1
->ty
== Tstruct
)
5258 if (((TypeStruct
*)tp1
)->sym
== ((TypeStruct
*)tp2
)->sym
&& MODimplicitConv(tp2
->mod
, tp1
->mod
))
5261 else if (tp1
->ty
== Tpointer
)
5263 if (tp2
->implicitConvTo(tp1
))
5266 else if (tp1
->ty
== Tarray
)
5268 if (tp2
->implicitConvTo(tp1
))
5271 else if (tp1
->ty
== Tdelegate
)
5273 if (tp1
->implicitConvTo(tp2
))
5280 notcovariant
|= !fparam1
->isCovariant(t1
->isref
, fparam2
);
5283 else if (t1
->parameters
!= t2
->parameters
)
5285 size_t dim1
= !t1
->parameters
? 0 : t1
->parameters
->dim
;
5286 size_t dim2
= !t2
->parameters
? 0 : t2
->parameters
->dim
;
5291 // The argument lists match
5294 if (t1
->linkage
!= t2
->linkage
)
5299 Type
*t1n
= t1
->next
;
5300 Type
*t2n
= t2
->next
;
5302 if (!t1n
|| !t2n
) // happens with return type inference
5305 if (t1n
->equals(t2n
))
5307 if (t1n
->ty
== Tclass
&& t2n
->ty
== Tclass
)
5309 /* If same class type, but t2n is const, then it's
5310 * covariant. Do this test first because it can work on
5311 * forward references.
5313 if (((TypeClass
*)t1n
)->sym
== ((TypeClass
*)t2n
)->sym
&&
5314 MODimplicitConv(t1n
->mod
, t2n
->mod
))
5317 // If t1n is forward referenced:
5318 ClassDeclaration
*cd
= ((TypeClass
*)t1n
)->sym
;
5321 if (!cd
->isBaseInfoComplete())
5323 return 3; // forward references
5326 if (t1n
->ty
== Tstruct
&& t2n
->ty
== Tstruct
)
5328 if (((TypeStruct
*)t1n
)->sym
== ((TypeStruct
*)t2n
)->sym
&&
5329 MODimplicitConv(t1n
->mod
, t2n
->mod
))
5332 else if (t1n
->ty
== t2n
->ty
&& t1n
->implicitConvTo(t2n
))
5334 else if (t1n
->ty
== Tnull
)
5336 // NULL is covariant with any pointer type, but not with any
5337 // dynamic arrays, associative arrays or delegates.
5338 // https://issues.dlang.org/show_bug.cgi?id=8589
5339 // https://issues.dlang.org/show_bug.cgi?id=19618
5340 Type
*t2bn
= t2n
->toBasetype();
5341 if (t2bn
->ty
== Tnull
|| t2bn
->ty
== Tpointer
|| t2bn
->ty
== Tclass
)
5348 if (t1
->isref
!= t2
->isref
)
5351 if (!t1
->isref
&& (t1
->isscope
|| t2
->isscope
))
5353 StorageClass stc1
= t1
->isscope
? STCscope
: 0;
5354 StorageClass stc2
= t2
->isscope
? STCscope
: 0;
5367 if (!Parameter::isCovariantScope(t1
->isref
, stc1
, stc2
))
5371 // We can subtract 'return ref' from 'this', but cannot add it
5372 else if (t1
->isreturn
&& !t2
->isreturn
)
5375 /* Can convert mutable to const
5377 if (!MODimplicitConv(t2
->mod
, t1
->mod
))
5382 /* Can convert pure to impure, nothrow to throw, and nogc to gc
5384 if (!t1
->purity
&& t2
->purity
)
5387 if (!t1
->isnothrow
&& t2
->isnothrow
)
5390 if (!t1
->isnogc
&& t2
->isnogc
)
5393 /* Can convert safe/trusted to system
5395 if (t1
->trust
<= TRUSTsystem
&& t2
->trust
>= TRUSTtrusted
)
5397 // Should we infer trusted or safe? Go with safe.
5407 //printf("\tcovaraint: 1\n");
5411 //printf("\tcovaraint: 0\n");
5415 //printf("\tcovaraint: 2\n");
5419 Type
*TypeFunction::semantic(Loc loc
, Scope
*sc
)
5421 if (deco
) // if semantic() already run
5423 //printf("already done\n");
5426 //printf("TypeFunction::semantic() this = %p\n", this);
5427 //printf("TypeFunction::semantic() %s, sc->stc = %llx, fargs = %p\n", toChars(), sc->stc, fargs);
5429 bool errors
= false;
5431 /* Copy in order to not mess up original.
5432 * This can produce redundant copies if inferring return type,
5433 * as semantic() will get called again on this.
5435 TypeFunction
*tf
= copy()->toTypeFunction();
5438 tf
->parameters
= parameters
->copy();
5439 for (size_t i
= 0; i
< parameters
->dim
; i
++)
5441 void *pp
= mem
.xmalloc(sizeof(Parameter
));
5442 Parameter
*p
= (Parameter
*)memcpy(pp
, (void *)(*parameters
)[i
], sizeof(Parameter
));
5443 (*tf
->parameters
)[i
] = p
;
5447 if (sc
->stc
& STCpure
)
5448 tf
->purity
= PUREfwdref
;
5449 if (sc
->stc
& STCnothrow
)
5450 tf
->isnothrow
= true;
5451 if (sc
->stc
& STCnogc
)
5453 if (sc
->stc
& STCref
)
5455 if (sc
->stc
& STCreturn
)
5456 tf
->isreturn
= true;
5457 if (sc
->stc
& STCscope
)
5459 if (sc
->stc
& STCscopeinferred
)
5460 tf
->isscopeinferred
= true;
5462 // if ((sc->stc & (STCreturn | STCref)) == STCreturn)
5463 // tf->isscope = true; // return by itself means 'return scope'
5465 if (tf
->trust
== TRUSTdefault
)
5467 if (sc
->stc
& STCsafe
)
5468 tf
->trust
= TRUSTsafe
;
5469 if (sc
->stc
& STCsystem
)
5470 tf
->trust
= TRUSTsystem
;
5471 if (sc
->stc
& STCtrusted
)
5472 tf
->trust
= TRUSTtrusted
;
5475 if (sc
->stc
& STCproperty
)
5476 tf
->isproperty
= true;
5478 tf
->linkage
= sc
->linkage
;
5479 bool wildreturn
= false;
5483 sc
->stc
&= ~(STC_TYPECTOR
| STC_FUNCATTR
);
5484 tf
->next
= tf
->next
->semantic(loc
, sc
);
5486 errors
|= tf
->checkRetType(loc
);
5487 if (tf
->next
->isscope() && !(sc
->flags
& SCOPEctor
))
5489 error(loc
, "functions cannot return scope %s", tf
->next
->toChars());
5492 if (tf
->next
->hasWild())
5495 if (tf
->isreturn
&& !tf
->isref
&& !tf
->next
->hasPointers())
5497 error(loc
, "function type '%s' has 'return' but does not return any indirections", tf
->toChars());
5501 unsigned char wildparams
= 0;
5504 /* Create a scope for evaluating the default arguments for the parameters
5506 Scope
*argsc
= sc
->push();
5507 argsc
->stc
= 0; // don't inherit storage class
5508 argsc
->protection
= Prot(PROTpublic
);
5511 size_t dim
= Parameter::dim(tf
->parameters
);
5512 for (size_t i
= 0; i
< dim
; i
++)
5514 Parameter
*fparam
= Parameter::getNth(tf
->parameters
, i
);
5516 fparam
->type
= fparam
->type
->semantic(loc
, argsc
);
5517 if (tf
->inuse
== 1) tf
->inuse
--;
5519 if (fparam
->type
->ty
== Terror
)
5525 fparam
->type
= fparam
->type
->addStorageClass(fparam
->storageClass
);
5527 if (fparam
->storageClass
& (STCauto
| STCalias
| STCstatic
))
5533 Type
*t
= fparam
->type
->toBasetype();
5535 if (t
->ty
== Tfunction
)
5537 error(loc
, "cannot have parameter of function type %s", fparam
->type
->toChars());
5540 else if (!(fparam
->storageClass
& (STCref
| STCout
)) &&
5541 (t
->ty
== Tstruct
|| t
->ty
== Tsarray
|| t
->ty
== Tenum
))
5543 Type
*tb2
= t
->baseElemOf();
5544 if ((tb2
->ty
== Tstruct
&& !((TypeStruct
*)tb2
)->sym
->members
) ||
5545 (tb2
->ty
== Tenum
&& !((TypeEnum
*)tb2
)->sym
->memtype
))
5547 error(loc
, "cannot have parameter of opaque type %s by value", fparam
->type
->toChars());
5551 else if (!(fparam
->storageClass
& STClazy
) && t
->ty
== Tvoid
)
5553 error(loc
, "cannot have parameter of type %s", fparam
->type
->toChars());
5557 if ((fparam
->storageClass
& (STCref
| STCwild
)) == (STCref
| STCwild
))
5559 // 'ref inout' implies 'return'
5560 fparam
->storageClass
|= STCreturn
;
5563 if (fparam
->storageClass
& STCreturn
)
5565 if (fparam
->storageClass
& (STCref
| STCout
))
5567 // Disabled for the moment awaiting improvement to allow return by ref
5568 // to be transformed into return by scope.
5569 if (0 && !tf
->isref
)
5571 StorageClass stc
= fparam
->storageClass
& (STCref
| STCout
);
5572 error(loc
, "parameter %s is 'return %s' but function does not return by ref",
5573 fparam
->ident
? fparam
->ident
->toChars() : "",
5580 fparam
->storageClass
|= STCscope
; // 'return' implies 'scope'
5584 else if (!tf
->isref
&& tf
->next
&& !tf
->next
->hasPointers())
5586 error(loc
, "parameter %s is 'return' but function does not return any indirections",
5587 fparam
->ident
? fparam
->ident
->toChars() : "");
5593 if (fparam
->storageClass
& (STCref
| STClazy
))
5596 else if (fparam
->storageClass
& STCout
)
5598 if (unsigned char m
= fparam
->type
->mod
& (MODimmutable
| MODconst
| MODwild
))
5600 error(loc
, "cannot have %s out parameter of type %s", MODtoChars(m
), t
->toChars());
5606 while (tv
->ty
== Tsarray
)
5607 tv
= tv
->nextOf()->toBasetype();
5608 if (tv
->ty
== Tstruct
&& ((TypeStruct
*)tv
)->sym
->noDefaultCtor
)
5610 error(loc
, "cannot have out parameter of type %s because the default construction is disabled",
5611 fparam
->type
->toChars());
5617 if (fparam
->storageClass
& STCscope
&& !fparam
->type
->hasPointers() && fparam
->type
->ty
!= Ttuple
)
5619 fparam
->storageClass
&= ~STCscope
;
5620 if (!(fparam
->storageClass
& STCref
))
5621 fparam
->storageClass
&= ~STCreturn
;
5627 //if (tf->next && !wildreturn)
5628 // error(loc, "inout on parameter means inout must be on return type as well (if from D1 code, replace with 'ref')");
5631 if (fparam
->defaultArg
)
5633 Expression
*e
= fparam
->defaultArg
;
5634 if (fparam
->storageClass
& (STCref
| STCout
))
5636 e
= ::semantic(e
, argsc
);
5637 e
= resolveProperties(argsc
, e
);
5641 e
= inferType(e
, fparam
->type
);
5642 Initializer
*iz
= new ExpInitializer(e
->loc
, e
);
5643 iz
= ::semantic(iz
, argsc
, fparam
->type
, INITnointerpret
);
5644 e
= initializerToExpression(iz
);
5646 if (e
->op
== TOKfunction
) // see Bugzilla 4820
5648 FuncExp
*fe
= (FuncExp
*)e
;
5649 // Replace function literal with a function symbol,
5650 // since default arg expression must be copied when used
5651 // and copying the literal itself is wrong.
5652 e
= new VarExp(e
->loc
, fe
->fd
, false);
5653 e
= new AddrExp(e
->loc
, e
);
5654 e
= ::semantic(e
, argsc
);
5656 e
= e
->implicitCastTo(argsc
, fparam
->type
);
5658 // default arg must be an lvalue
5659 if (fparam
->storageClass
& (STCout
| STCref
))
5660 e
= e
->toLvalue(argsc
, e
);
5662 fparam
->defaultArg
= e
;
5663 if (e
->op
== TOKerror
)
5667 /* If fparam after semantic() turns out to be a tuple, the number of parameters may
5670 if (t
->ty
== Ttuple
)
5672 /* TypeFunction::parameter also is used as the storage of
5673 * Parameter objects for FuncDeclaration. So we should copy
5674 * the elements of TypeTuple::arguments to avoid unintended
5675 * sharing of Parameter object among other functions.
5677 TypeTuple
*tt
= (TypeTuple
*)t
;
5678 if (tt
->arguments
&& tt
->arguments
->dim
)
5680 /* Propagate additional storage class from tuple parameters to their
5681 * element-parameters.
5682 * Make a copy, as original may be referenced elsewhere.
5684 size_t tdim
= tt
->arguments
->dim
;
5685 Parameters
*newparams
= new Parameters();
5686 newparams
->setDim(tdim
);
5687 for (size_t j
= 0; j
< tdim
; j
++)
5689 Parameter
*narg
= (*tt
->arguments
)[j
];
5691 // Bugzilla 12744: If the storage classes of narg
5692 // conflict with the ones in fparam, it's ignored.
5693 StorageClass stc
= fparam
->storageClass
| narg
->storageClass
;
5694 StorageClass stc1
= fparam
->storageClass
& (STCref
| STCout
| STClazy
);
5695 StorageClass stc2
= narg
->storageClass
& (STCref
| STCout
| STClazy
);
5696 if (stc1
&& stc2
&& stc1
!= stc2
)
5698 OutBuffer buf1
; stcToBuffer(&buf1
, stc1
| ((stc1
& STCref
) ? (fparam
->storageClass
& STCauto
) : 0));
5699 OutBuffer buf2
; stcToBuffer(&buf2
, stc2
);
5701 error(loc
, "incompatible parameter storage classes '%s' and '%s'",
5702 buf1
.peekString(), buf2
.peekString());
5704 stc
= stc1
| (stc
& ~(STCref
| STCout
| STClazy
));
5707 (*newparams
)[j
] = new Parameter(
5708 stc
, narg
->type
, narg
->ident
, narg
->defaultArg
);
5710 fparam
->type
= new TypeTuple(newparams
);
5712 fparam
->storageClass
= 0;
5714 /* Reset number of parameters, and back up one to do this fparam again,
5715 * now that it is a tuple
5717 dim
= Parameter::dim(tf
->parameters
);
5722 /* Resolve "auto ref" storage class to be either ref or value,
5723 * based on the argument matching the parameter
5725 if (fparam
->storageClass
& STCauto
)
5727 if (fargs
&& i
< fargs
->dim
&& (fparam
->storageClass
& STCref
))
5729 Expression
*farg
= (*fargs
)[i
];
5730 if (farg
->isLvalue())
5733 fparam
->storageClass
&= ~STCref
; // value parameter
5734 fparam
->storageClass
&= ~STCauto
; // Bugzilla 14656
5735 fparam
->storageClass
|= STCautoref
;
5739 error(loc
, "'auto' can only be used as part of 'auto ref' for template function parameters");
5744 // Remove redundant storage classes for type, they are already applied
5745 fparam
->storageClass
&= ~(STC_TYPECTOR
| STCin
);
5752 if (wildreturn
&& !wildparams
)
5754 error(loc
, "inout on return means inout must be on a parameter as well for %s", toChars());
5757 tf
->iswild
= wildparams
;
5761 error(loc
, "recursive type");
5766 if (tf
->isproperty
&& (tf
->varargs
|| Parameter::dim(tf
->parameters
) > 2))
5768 error(loc
, "properties can only have zero, one, or two parameter");
5772 if (tf
->varargs
== 1 && tf
->linkage
!= LINKd
&& Parameter::dim(tf
->parameters
) == 0)
5774 error(loc
, "variadic functions with non-D linkage must have at least one parameter");
5782 tf
->deco
= tf
->merge()->deco
;
5784 /* Don't return merge(), because arg identifiers and default args
5786 * even though the types match
5791 bool TypeFunction::checkRetType(Loc loc
)
5793 Type
*tb
= next
->toBasetype();
5794 if (tb
->ty
== Tfunction
)
5796 error(loc
, "functions cannot return a function");
5797 next
= Type::terror
;
5799 if (tb
->ty
== Ttuple
)
5801 error(loc
, "functions cannot return a tuple");
5802 next
= Type::terror
;
5804 if (!isref
&& (tb
->ty
== Tstruct
|| tb
->ty
== Tsarray
))
5806 Type
*tb2
= tb
->baseElemOf();
5807 if (tb2
->ty
== Tstruct
&& !((TypeStruct
*)tb2
)->sym
->members
)
5809 error(loc
, "functions cannot return opaque type %s by value", tb
->toChars());
5810 next
= Type::terror
;
5813 if (tb
->ty
== Terror
)
5819 /* Determine purity level based on mutability of t
5820 * and whether it is a 'ref' type or not.
5822 static PURE
purityOfType(bool isref
, Type
*t
)
5826 if (t
->mod
& MODimmutable
)
5828 if (t
->mod
& (MODconst
| MODwild
))
5833 t
= t
->baseElemOf();
5835 if (!t
->hasPointers() || t
->mod
& MODimmutable
)
5838 /* Accept immutable(T)[] and immutable(T)* as being strongly pure
5840 if (t
->ty
== Tarray
|| t
->ty
== Tpointer
)
5842 Type
*tn
= t
->nextOf()->toBasetype();
5843 if (tn
->mod
& MODimmutable
)
5845 if (tn
->mod
& (MODconst
| MODwild
))
5849 /* The rest of this is too strict; fix later.
5850 * For example, the only pointer members of a struct may be immutable,
5851 * which would maintain strong purity.
5852 * (Just like for dynamic arrays and pointers above.)
5854 if (t
->mod
& (MODconst
| MODwild
))
5857 /* Should catch delegates and function pointers, and fold in their purity
5862 /********************************************
5863 * Set 'purity' field of 'this'.
5864 * Do this lazily, as the parameter types might be forward referenced.
5866 void TypeFunction::purityLevel()
5868 TypeFunction
*tf
= this;
5869 if (tf
->purity
!= PUREfwdref
)
5872 purity
= PUREstrong
; // assume strong until something weakens it
5874 /* Evaluate what kind of purity based on the modifiers for the parameters
5876 const size_t dim
= Parameter::dim(tf
->parameters
);
5877 for (size_t i
= 0; i
< dim
; i
++)
5879 Parameter
*fparam
= Parameter::getNth(tf
->parameters
, i
);
5880 Type
*t
= fparam
->type
;
5884 if (fparam
->storageClass
& (STClazy
| STCout
))
5889 switch (purityOfType((fparam
->storageClass
& STCref
) != 0, t
))
5905 break; // since PUREweak, no need to check further
5908 if (purity
> PUREweak
&& tf
->nextOf())
5910 /* Adjust purity based on mutability of return type.
5911 * https://issues.dlang.org/show_bug.cgi?id=15862
5913 const PURE purity2
= purityOfType(tf
->isref
, tf
->nextOf());
5914 if (purity2
< purity
)
5917 tf
->purity
= purity
;
5920 /********************************
5921 * 'args' are being matched to function 'this'
5922 * Determine match level.
5924 * flag 1 performing a partial ordering match
5929 MATCH
TypeFunction::callMatch(Type
*tthis
, Expressions
*args
, int flag
)
5931 //printf("TypeFunction::callMatch() %s\n", toChars());
5932 MATCH match
= MATCHexact
; // assume exact match
5933 unsigned char wildmatch
= 0;
5938 if (t
->toBasetype()->ty
== Tpointer
)
5939 t
= t
->toBasetype()->nextOf(); // change struct* to struct
5942 if (MODimplicitConv(t
->mod
, mod
))
5944 else if ((mod
& MODwild
) && MODimplicitConv(t
->mod
, (mod
& ~MODwild
) | MODconst
))
5949 return MATCHnomatch
;
5954 wildmatch
|= MODwild
;
5955 else if (t
->isConst())
5956 wildmatch
|= MODconst
;
5957 else if (t
->isImmutable())
5958 wildmatch
|= MODimmutable
;
5960 wildmatch
|= MODmutable
;
5964 size_t nparams
= Parameter::dim(parameters
);
5965 size_t nargs
= args
? args
->dim
: 0;
5966 if (nparams
== nargs
)
5968 else if (nargs
> nparams
)
5971 goto Nomatch
; // too many args; no match
5972 match
= MATCHconvert
; // match ... with a "conversion" match level
5975 for (size_t u
= 0; u
< nargs
; u
++)
5979 Parameter
*p
= Parameter::getNth(parameters
, u
);
5980 Expression
*arg
= (*args
)[u
];
5982 Type
*tprm
= p
->type
;
5983 Type
*targ
= arg
->type
;
5985 if (!(p
->storageClass
& STClazy
&& tprm
->ty
== Tvoid
&& targ
->ty
!= Tvoid
))
5987 bool isRef
= (p
->storageClass
& (STCref
| STCout
)) != 0;
5988 wildmatch
|= targ
->deduceWild(tprm
, isRef
);
5993 /* Calculate wild matching modifier
5995 if (wildmatch
& MODconst
|| wildmatch
& (wildmatch
- 1))
5996 wildmatch
= MODconst
;
5997 else if (wildmatch
& MODimmutable
)
5998 wildmatch
= MODimmutable
;
5999 else if (wildmatch
& MODwild
)
6000 wildmatch
= MODwild
;
6003 assert(wildmatch
& MODmutable
);
6004 wildmatch
= MODmutable
;
6008 for (size_t u
= 0; u
< nparams
; u
++)
6012 Parameter
*p
= Parameter::getNth(parameters
, u
);
6018 goto L1
; // try typesafe variadics
6021 Expression
*arg
= (*args
)[u
];
6023 //printf("arg: %s, type: %s\n", arg->toChars(), arg->type->toChars());
6025 Type
*targ
= arg
->type
;
6026 Type
*tprm
= wildmatch
? p
->type
->substWildTo(wildmatch
) : p
->type
;
6028 if (p
->storageClass
& STClazy
&& tprm
->ty
== Tvoid
&& targ
->ty
!= Tvoid
)
6032 //printf("%s of type %s implicitConvTo %s\n", arg->toChars(), targ->toChars(), tprm->toChars());
6035 // for partial ordering, value is an irrelevant mockup, just look at the type
6036 m
= targ
->implicitConvTo(tprm
);
6039 m
= arg
->implicitConvTo(tprm
);
6040 //printf("match %d\n", m);
6043 // Non-lvalues do not match ref or out parameters
6044 if (p
->storageClass
& (STCref
| STCout
))
6046 // Bugzilla 13783: Don't use toBasetype() to handle enum types.
6049 //printf("fparam[%d] ta = %s, tp = %s\n", u, ta->toChars(), tp->toChars());
6051 if (m
&& !arg
->isLvalue())
6053 if (p
->storageClass
& STCout
)
6056 if (arg
->op
== TOKstring
&& tp
->ty
== Tsarray
)
6058 if (ta
->ty
!= Tsarray
)
6060 Type
*tn
= tp
->nextOf()->castMod(ta
->nextOf()->mod
);
6061 dinteger_t dim
= ((StringExp
*)arg
)->len
;
6062 ta
= tn
->sarrayOf(dim
);
6065 else if (arg
->op
== TOKslice
&& tp
->ty
== Tsarray
)
6067 // Allow conversion from T[lwr .. upr] to ref T[upr-lwr]
6068 if (ta
->ty
!= Tsarray
)
6070 Type
*tn
= ta
->nextOf();
6071 dinteger_t dim
= ((TypeSArray
*)tp
)->dim
->toUInteger();
6072 ta
= tn
->sarrayOf(dim
);
6079 /* Find most derived alias this type being matched.
6080 * Bugzilla 15674: Allow on both ref and out parameters.
6084 Type
*tat
= ta
->toBasetype()->aliasthisOf();
6085 if (!tat
|| !tat
->implicitConvTo(tprm
))
6090 /* A ref variable should work like a head-const reference.
6092 * ref T <- an lvalue of const(T) argument
6093 * ref T[dim] <- an lvalue of const(T[dim]) argument
6095 if (!ta
->constConv(tp
))
6100 /* prefer matching the element type rather than the array
6101 * type when more arguments are present with T[]...
6103 if (varargs
== 2 && u
+ 1 == nparams
&& nargs
> nparams
)
6106 //printf("\tm = %d\n", m);
6107 if (m
== MATCHnomatch
) // if no match
6110 if (varargs
== 2 && u
+ 1 == nparams
) // if last varargs param
6112 Type
*tb
= p
->type
->toBasetype();
6119 tsa
= (TypeSArray
*)tb
;
6120 sz
= tsa
->dim
->toInteger();
6121 if (sz
!= nargs
- u
)
6126 TypeArray
*ta
= (TypeArray
*)tb
;
6127 for (; u
< nargs
; u
++)
6129 Expression
*arg
= (*args
)[u
];
6132 /* If lazy array of delegates,
6133 * convert arg(s) to delegate(s)
6135 Type
*tret
= p
->isLazyArray();
6138 if (ta
->next
->equals(arg
->type
))
6140 else if (tret
->toBasetype()->ty
== Tvoid
)
6144 m
= arg
->implicitConvTo(tret
);
6145 if (m
== MATCHnomatch
)
6146 m
= arg
->implicitConvTo(ta
->next
);
6150 m
= arg
->implicitConvTo(ta
->next
);
6152 if (m
== MATCHnomatch
)
6160 // Should see if there's a constructor match?
6161 // Or just leave it ambiguous?
6171 match
= m
; // pick worst match
6175 //printf("match = %d\n", match);
6179 //printf("no match\n");
6180 return MATCHnomatch
;
6183 /********************************************
6184 * Return true if there are lazy parameters.
6186 bool TypeFunction::hasLazyParameters()
6188 size_t dim
= Parameter::dim(parameters
);
6189 for (size_t i
= 0; i
< dim
; i
++)
6191 Parameter
*fparam
= Parameter::getNth(parameters
, i
);
6192 if (fparam
->storageClass
& STClazy
)
6198 /***************************
6199 * Examine function signature for parameter p and see if
6200 * the value of p can 'escape' the scope of the function.
6201 * This is useful to minimize the needed annotations for the parameters.
6203 * p = parameter to this function
6205 * true if escapes via assignment to global or through a parameter
6208 bool TypeFunction::parameterEscapes(Parameter
*p
)
6210 /* Scope parameters do not escape.
6211 * Allow 'lazy' to imply 'scope' -
6212 * lazy parameters can be passed along
6213 * as lazy parameters to the next function, but that isn't
6216 if (parameterStorageClass(p
) & (STCscope
| STClazy
))
6221 /************************************
6222 * Take the specified storage class for p,
6223 * and use the function signature to infer whether
6224 * STCscope and STCreturn should be OR'd in.
6225 * (This will not affect the name mangling.)
6227 * p = one of the parameters to 'this'
6229 * storage class with STCscope or STCreturn OR'd in
6231 StorageClass
TypeFunction::parameterStorageClass(Parameter
*p
)
6233 StorageClass stc
= p
->storageClass
;
6234 if (!global
.params
.vsafe
)
6237 if (stc
& (STCscope
| STCreturn
| STClazy
) || purity
== PUREimpure
)
6240 /* If haven't inferred the return type yet, can't infer storage classes
6247 // See if p can escape via any of the other parameters
6248 if (purity
== PUREweak
)
6250 const size_t dim
= Parameter::dim(parameters
);
6251 for (size_t i
= 0; i
< dim
; i
++)
6253 Parameter
*fparam
= Parameter::getNth(parameters
, i
);
6254 Type
*t
= fparam
->type
;
6257 t
= t
->baseElemOf();
6258 if (t
->isMutable() && t
->hasPointers())
6260 if (fparam
->storageClass
& (STCref
| STCout
))
6263 else if (t
->ty
== Tarray
|| t
->ty
== Tpointer
)
6265 Type
*tn
= t
->nextOf()->toBasetype();
6266 if (!(tn
->isMutable() && tn
->hasPointers()))
6276 /* Inferring STCreturn here has false positives
6277 * for pure functions, producing spurious error messages
6278 * about escaping references.
6279 * Give up on it for now.
6284 Expression
*TypeFunction::defaultInit(Loc loc
)
6286 error(loc
, "function does not have a default initializer");
6287 return new ErrorExp();
6290 Type
*TypeFunction::addStorageClass(StorageClass stc
)
6292 //printf("addStorageClass(%llx) %d\n", stc, (stc & STCscope) != 0);
6293 TypeFunction
*t
= Type::addStorageClass(stc
)->toTypeFunction();
6294 if ((stc
& STCpure
&& !t
->purity
) ||
6295 (stc
& STCnothrow
&& !t
->isnothrow
) ||
6296 (stc
& STCnogc
&& !t
->isnogc
) ||
6297 (stc
& STCscope
&& !t
->isscope
) ||
6298 (stc
& STCsafe
&& t
->trust
< TRUSTtrusted
))
6300 // Klunky to change these
6301 TypeFunction
*tf
= new TypeFunction(t
->parameters
, t
->next
, t
->varargs
, t
->linkage
, 0);
6304 tf
->purity
= t
->purity
;
6305 tf
->isnothrow
= t
->isnothrow
;
6306 tf
->isnogc
= t
->isnogc
;
6307 tf
->isproperty
= t
->isproperty
;
6308 tf
->isref
= t
->isref
;
6309 tf
->isreturn
= t
->isreturn
;
6310 tf
->isscope
= t
->isscope
;
6311 tf
->isscopeinferred
= t
->isscopeinferred
;
6312 tf
->trust
= t
->trust
;
6313 tf
->iswild
= t
->iswild
;
6316 tf
->purity
= PUREfwdref
;
6317 if (stc
& STCnothrow
)
6318 tf
->isnothrow
= true;
6322 tf
->trust
= TRUSTsafe
;
6326 if (stc
& STCscopeinferred
)
6327 tf
->isscopeinferred
= true;
6330 tf
->deco
= tf
->merge()->deco
;
6336 /** For each active attribute (ref/const/nogc/etc) call fp with a void* for the
6337 work param and a string representation of the attribute. */
6338 int TypeFunction::attributesApply(void *param
, int (*fp
)(void *, const char *), TRUSTformat trustFormat
)
6342 if (purity
) res
= fp(param
, "pure");
6343 if (res
) return res
;
6345 if (isnothrow
) res
= fp(param
, "nothrow");
6346 if (res
) return res
;
6348 if (isnogc
) res
= fp(param
, "@nogc");
6349 if (res
) return res
;
6351 if (isproperty
) res
= fp(param
, "@property");
6352 if (res
) return res
;
6354 if (isref
) res
= fp(param
, "ref");
6355 if (res
) return res
;
6357 if (isreturn
) res
= fp(param
, "return");
6358 if (res
) return res
;
6360 if (isscope
&& !isscopeinferred
) res
= fp(param
, "scope");
6361 if (res
) return res
;
6363 TRUST trustAttrib
= trust
;
6365 if (trustAttrib
== TRUSTdefault
)
6367 // Print out "@system" when trust equals TRUSTdefault (if desired).
6368 if (trustFormat
== TRUSTformatSystem
)
6369 trustAttrib
= TRUSTsystem
;
6371 return res
; // avoid calling with an empty string
6374 return fp(param
, trustToChars(trustAttrib
));
6377 /***************************** TypeDelegate *****************************/
6379 TypeDelegate::TypeDelegate(Type
*t
)
6380 : TypeNext(Tfunction
, t
)
6385 TypeDelegate
*TypeDelegate::create(Type
*t
)
6387 return new TypeDelegate(t
);
6390 const char *TypeDelegate::kind()
6395 Type
*TypeDelegate::syntaxCopy()
6397 Type
*t
= next
->syntaxCopy();
6402 t
= new TypeDelegate(t
);
6408 Type
*TypeDelegate::semantic(Loc loc
, Scope
*sc
)
6410 //printf("TypeDelegate::semantic() %s\n", toChars());
6411 if (deco
) // if semantic() already run
6413 //printf("already done\n");
6416 next
= next
->semantic(loc
,sc
);
6417 if (next
->ty
!= Tfunction
)
6420 /* In order to deal with Bugzilla 4028, perhaps default arguments should
6421 * be removed from next before the merge.
6424 /* Don't return merge(), because arg identifiers and default args
6426 * even though the types match
6428 deco
= merge()->deco
;
6432 Type
*TypeDelegate::addStorageClass(StorageClass stc
)
6434 TypeDelegate
*t
= (TypeDelegate
*)Type::addStorageClass(stc
);
6435 if (!global
.params
.vsafe
)
6438 /* The rest is meant to add 'scope' to a delegate declaration if it is of the form:
6439 * alias dg_t = void* delegate();
6440 * scope dg_t dg = ...;
6444 Type
*n
= t
->next
->addStorageClass(STCscope
| STCscopeinferred
);
6448 t
->deco
= t
->merge()->deco
; // mangling supposed to not be changed due to STCscopeinferrred
6454 d_uns64
TypeDelegate::size(Loc
)
6456 return Target::ptrsize
* 2;
6459 unsigned TypeDelegate::alignsize()
6461 return Target::ptrsize
;
6464 MATCH
TypeDelegate::implicitConvTo(Type
*to
)
6466 //printf("TypeDelegate::implicitConvTo(this=%p, to=%p)\n", this, to);
6467 //printf("from: %s\n", toChars());
6468 //printf("to : %s\n", to->toChars());
6471 #if 1 // not allowing covariant conversions because it interferes with overriding
6472 if (to
->ty
== Tdelegate
&& this->nextOf()->covariant(to
->nextOf()) == 1)
6474 Type
*tret
= this->next
->nextOf();
6475 Type
*toret
= ((TypeDelegate
*)to
)->next
->nextOf();
6476 if (tret
->ty
== Tclass
&& toret
->ty
== Tclass
)
6478 /* Bugzilla 10219: Check covariant interface return with offset tweaking.
6480 * class C : Object, I {}
6481 * I delegate() dg = delegate C() {} // should be error
6484 if (toret
->isBaseOf(tret
, &offset
) && offset
!= 0)
6485 return MATCHnomatch
;
6487 return MATCHconvert
;
6490 return MATCHnomatch
;
6493 Expression
*TypeDelegate::defaultInit(Loc loc
)
6495 return new NullExp(loc
, this);
6498 bool TypeDelegate::isZeroInit(Loc
)
6503 bool TypeDelegate::isBoolean()
6508 Expression
*TypeDelegate::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
, int flag
)
6510 if (ident
== Id::ptr
)
6512 e
= new DelegatePtrExp(e
->loc
, e
);
6513 e
= ::semantic(e
, sc
);
6515 else if (ident
== Id::funcptr
)
6517 if (!(flag
& 2) && sc
->func
&& !sc
->intypeof
&& sc
->func
->setUnsafe())
6519 e
->error("%s.funcptr cannot be used in @safe code", e
->toChars());
6520 return new ErrorExp();
6522 e
= new DelegateFuncptrExp(e
->loc
, e
);
6523 e
= ::semantic(e
, sc
);
6527 e
= Type::dotExp(sc
, e
, ident
, flag
);
6532 bool TypeDelegate::hasPointers()
6539 /***************************** TypeQualified *****************************/
6541 TypeQualified::TypeQualified(TY ty
, Loc loc
)
6547 void TypeQualified::syntaxCopyHelper(TypeQualified
*t
)
6549 //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars());
6550 idents
.setDim(t
->idents
.dim
);
6551 for (size_t i
= 0; i
< idents
.dim
; i
++)
6553 RootObject
*id
= t
->idents
[i
];
6554 if (id
->dyncast() == DYNCAST_DSYMBOL
)
6556 TemplateInstance
*ti
= (TemplateInstance
*)id
;
6558 ti
= (TemplateInstance
*)ti
->syntaxCopy(NULL
);
6561 else if (id
->dyncast() == DYNCAST_EXPRESSION
)
6563 Expression
*e
= (Expression
*)id
;
6564 e
= e
->syntaxCopy();
6567 else if (id
->dyncast() == DYNCAST_TYPE
)
6569 Type
*tx
= (Type
*)id
;
6570 tx
= tx
->syntaxCopy();
6577 void TypeQualified::addIdent(Identifier
*ident
)
6582 void TypeQualified::addInst(TemplateInstance
*inst
)
6587 void TypeQualified::addIndex(RootObject
*e
)
6592 d_uns64
TypeQualified::size(Loc
)
6594 error(this->loc
, "size of type %s is not known", toChars());
6595 return SIZE_INVALID
;
6598 /*************************************
6599 * Resolve a tuple index.
6601 void TypeQualified::resolveTupleIndex(Loc loc
, Scope
*sc
, Dsymbol
*s
,
6602 Expression
**pe
, Type
**pt
, Dsymbol
**ps
, RootObject
*oindex
)
6608 TupleDeclaration
*td
= s
->isTupleDeclaration();
6610 Expression
*eindex
= isExpression(oindex
);
6611 Type
*tindex
= isType(oindex
);
6612 Dsymbol
*sindex
= isDsymbol(oindex
);
6616 // It's really an index expression
6618 eindex
= new TypeExp(loc
, tindex
);
6620 eindex
= ::resolve(loc
, sc
, sindex
, false);
6621 Expression
*e
= new IndexExp(loc
, ::resolve(loc
, sc
, s
, false), eindex
);
6622 e
= ::semantic(e
, sc
);
6623 resolveExp(e
, pt
, pe
, ps
);
6627 // Convert oindex to Expression, then try to resolve to constant.
6629 tindex
->resolve(loc
, sc
, &eindex
, &tindex
, &sindex
);
6631 eindex
= ::resolve(loc
, sc
, sindex
, false);
6634 ::error(loc
, "index is %s not an expression", oindex
->toChars());
6638 sc
= sc
->startCTFE();
6639 eindex
= ::semantic(eindex
, sc
);
6642 eindex
= eindex
->ctfeInterpret();
6643 if (eindex
->op
== TOKerror
)
6649 const uinteger_t d
= eindex
->toUInteger();
6650 if (d
>= td
->objects
->dim
)
6652 ::error(loc
, "tuple index %llu exceeds length %u", (ulonglong
)d
, (unsigned)td
->objects
->dim
);
6657 RootObject
*o
= (*td
->objects
)[(size_t)d
];
6660 *pe
= isExpression(o
);
6663 *pt
= (*pt
)->semantic(loc
, sc
);
6665 resolveExp(*pe
, pt
, pe
, ps
);
6668 /*************************************
6669 * Takes an array of Identifiers and figures out if
6670 * it represents a Type or an Expression.
6672 * if expression, *pe is set
6673 * if type, *pt is set
6675 void TypeQualified::resolveHelper(Loc loc
, Scope
*sc
,
6676 Dsymbol
*s
, Dsymbol
*,
6677 Expression
**pe
, Type
**pt
, Dsymbol
**ps
, bool intypeid
)
6684 //printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
6685 Declaration
*d
= s
->isDeclaration();
6686 if (d
&& (d
->storage_class
& STCtemplateparameter
))
6689 s
->checkDeprecated(loc
, sc
); // check for deprecated aliases
6692 //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
6693 for (size_t i
= 0; i
< idents
.dim
; i
++)
6695 RootObject
*id
= idents
[i
];
6697 if (id
->dyncast() == DYNCAST_EXPRESSION
||
6698 id
->dyncast() == DYNCAST_TYPE
)
6703 resolveTupleIndex(loc
, sc
, s
, &ex
, &tx
, &sx
, id
);
6710 ex
= new TypeExp(loc
, tx
);
6713 ex
= typeToExpressionHelper(this, ex
, i
+ 1);
6714 ex
= ::semantic(ex
, sc
);
6715 resolveExp(ex
, pt
, pe
, ps
);
6719 Type
*t
= s
->getType(); // type symbol, type alias, or type tuple?
6720 unsigned errorsave
= global
.errors
;
6721 Dsymbol
*sm
= s
->searchX(loc
, sc
, id
);
6722 if (sm
&& !(sc
->flags
& SCOPEignoresymbolvisibility
) && !symbolIsVisible(sc
, sm
))
6724 ::deprecation(loc
, "%s is not visible from module %s", sm
->toPrettyChars(), sc
->_module
->toChars());
6727 if (global
.errors
!= errorsave
)
6732 //printf("\t3: s = %p %s %s, sm = %p\n", s, s->kind(), s->toChars(), sm);
6733 if (intypeid
&& !t
&& sm
&& sm
->needThis())
6735 if (VarDeclaration
*v
= s
->isVarDeclaration())
6737 // https://issues.dlang.org/show_bug.cgi?id=19913
6738 // v->type would be null if it is a forward referenced member.
6739 if (v
->type
== NULL
)
6741 if (v
->storage_class
& (STCconst
| STCimmutable
| STCmanifest
) ||
6742 v
->type
->isConst() || v
->type
->isImmutable())
6744 // Bugzilla 13087: this.field is not constant always
6745 if (!v
->isThisDeclaration())
6753 if (s
->isDeclaration()) // var, func, or tuple declaration?
6755 t
= s
->isDeclaration()->type
;
6756 if (!t
&& s
->isTupleDeclaration()) // expression tuple?
6759 else if (s
->isTemplateInstance() ||
6760 s
->isImport() || s
->isPackage() || s
->isModule())
6767 sm
= t
->toDsymbol(sc
);
6768 if (sm
&& id
->dyncast() == DYNCAST_IDENTIFIER
)
6770 sm
= sm
->search(loc
, (Identifier
*)id
);
6776 VarDeclaration
*v
= s
->isVarDeclaration();
6777 FuncDeclaration
*f
= s
->isFuncDeclaration();
6778 if (intypeid
|| (!v
&& !f
))
6779 e
= ::resolve(loc
, sc
, s
, true);
6781 e
= new VarExp(loc
, s
->isDeclaration(), true);
6783 e
= typeToExpressionHelper(this, e
, i
);
6784 e
= ::semantic(e
, sc
);
6785 resolveExp(e
, pt
, pe
, ps
);
6790 if (id
->dyncast() == DYNCAST_DSYMBOL
)
6792 // searchX already handles errors for template instances
6793 assert(global
.errors
);
6797 assert(id
->dyncast() == DYNCAST_IDENTIFIER
);
6798 sm
= s
->search_correct((Identifier
*)id
);
6800 error(loc
, "identifier '%s' of '%s' is not defined, did you mean %s '%s'?",
6801 id
->toChars(), toChars(), sm
->kind(), sm
->toChars());
6803 error(loc
, "identifier '%s' of '%s' is not defined", id
->toChars(), toChars());
6805 *pe
= new ErrorExp();
6813 if (EnumMember
*em
= s
->isEnumMember())
6815 // It's not a type, it's an expression
6816 *pe
= em
->getVarExp(loc
, sc
);
6819 if (VarDeclaration
*v
= s
->isVarDeclaration())
6821 /* This is mostly same with DsymbolExp::semantic(), but we cannot use it
6822 * because some variables used in type context need to prevent lowering
6823 * to a literal or contextful expression. For example:
6825 * enum a = 1; alias b = a;
6826 * template X(alias e){ alias v = e; } alias x = X!(1);
6827 * struct S { int v; alias w = v; }
6828 * // TypeIdentifier 'a', 'e', and 'v' should be TOKvar,
6829 * // because getDsymbol() need to work in AliasDeclaration::semantic().
6832 (!v
->type
->deco
&& v
->inuse
))
6834 if (v
->inuse
) // Bugzilla 9494
6835 error(loc
, "circular reference to %s '%s'", v
->kind(), v
->toPrettyChars());
6837 error(loc
, "forward reference to %s '%s'", v
->kind(), v
->toPrettyChars());
6841 if (v
->type
->ty
== Terror
)
6844 *pe
= new VarExp(loc
, v
);
6847 if (FuncLiteralDeclaration
*fld
= s
->isFuncLiteralDeclaration())
6849 //printf("'%s' is a function literal\n", fld->toChars());
6850 *pe
= new FuncExp(loc
, fld
);
6851 *pe
= ::semantic(*pe
, sc
);
6855 Type
*t
= s
->getType();
6858 // If the symbol is an import, try looking inside the import
6859 if (Import
*si
= s
->isImport())
6861 s
= si
->search(loc
, s
->ident
);
6869 if (t
->ty
== Tinstance
&& t
!= this && !t
->deco
)
6871 if (!((TypeInstance
*)t
)->tempinst
->errors
)
6872 error(loc
, "forward reference to '%s'", t
->toChars());
6877 if (t
->ty
== Ttuple
)
6884 /* Look for what user might have intended
6886 const char *p
= mutableOf()->unSharedOf()->toChars();
6887 Identifier
*id
= Identifier::idPool(p
, strlen(p
));
6888 if (const char *n
= importHint(p
))
6889 error(loc
, "`%s` is not defined, perhaps `import %s;` ?", p
, n
);
6890 else if (Dsymbol
*s2
= sc
->search_correct(id
))
6891 error(loc
, "undefined identifier `%s`, did you mean %s `%s`?", p
, s2
->kind(), s2
->toChars());
6892 else if (const char *q
= Scope::search_correct_C(id
))
6893 error(loc
, "undefined identifier `%s`, did you mean `%s`?", p
, q
);
6895 error(loc
, "undefined identifier `%s`", p
);
6901 /***************************** TypeIdentifier *****************************/
6903 TypeIdentifier::TypeIdentifier(Loc loc
, Identifier
*ident
)
6904 : TypeQualified(Tident
, loc
)
6906 this->ident
= ident
;
6909 const char *TypeIdentifier::kind()
6911 return "identifier";
6914 Type
*TypeIdentifier::syntaxCopy()
6916 TypeIdentifier
*t
= new TypeIdentifier(loc
, ident
);
6917 t
->syntaxCopyHelper(this);
6922 /*************************************
6923 * Takes an array of Identifiers and figures out if
6924 * it represents a Type or an Expression.
6926 * if expression, *pe is set
6927 * if type, *pt is set
6930 void TypeIdentifier::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
, bool intypeid
)
6932 //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars());
6934 if ((ident
->equals(Id::_super
) || ident
->equals(Id::This
)) && !hasThis(sc
))
6936 AggregateDeclaration
*ad
= sc
->getStructClassScope();
6939 ClassDeclaration
*cd
= ad
->isClassDeclaration();
6942 if (ident
->equals(Id::This
))
6944 else if (cd
->baseClass
&& ident
->equals(Id::_super
))
6945 ident
= cd
->baseClass
->ident
;
6949 StructDeclaration
*sd
= ad
->isStructDeclaration();
6950 if (sd
&& ident
->equals(Id::This
))
6955 if (ident
== Id::ctfe
)
6957 error(loc
, "variable __ctfe cannot be read at compile time");
6965 Dsymbol
*s
= sc
->search(loc
, ident
, &scopesym
);
6966 resolveHelper(loc
, sc
, s
, scopesym
, pe
, pt
, ps
, intypeid
);
6968 (*pt
) = (*pt
)->addMod(mod
);
6971 /*****************************************
6972 * See if type resolves to a symbol, if so,
6973 * return that symbol.
6976 Dsymbol
*TypeIdentifier::toDsymbol(Scope
*sc
)
6978 //printf("TypeIdentifier::toDsymbol('%s')\n", toChars());
6986 resolve(loc
, sc
, &e
, &t
, &s
);
6987 if (t
&& t
->ty
!= Tident
)
6988 s
= t
->toDsymbol(sc
);
6995 Type
*TypeIdentifier::semantic(Loc loc
, Scope
*sc
)
7001 //printf("TypeIdentifier::semantic(%s)\n", toChars());
7002 resolve(loc
, sc
, &e
, &t
, &s
);
7005 //printf("\tit's a type %d, %s, %s\n", t->ty, t->toChars(), t->deco);
7012 s
->error(loc
, "is used as a type");
7016 error(loc
, "%s is used as a type", toChars());
7023 /***************************** TypeInstance *****************************/
7025 TypeInstance::TypeInstance(Loc loc
, TemplateInstance
*tempinst
)
7026 : TypeQualified(Tinstance
, loc
)
7028 this->tempinst
= tempinst
;
7031 const char *TypeInstance::kind()
7036 Type
*TypeInstance::syntaxCopy()
7038 //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim);
7039 TypeInstance
*t
= new TypeInstance(loc
, (TemplateInstance
*)tempinst
->syntaxCopy(NULL
));
7040 t
->syntaxCopyHelper(this);
7045 void TypeInstance::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
, bool intypeid
)
7047 // Note close similarity to TypeIdentifier::resolve()
7051 //printf("TypeInstance::resolve(sc = %p, tempinst = '%s')\n", sc, tempinst->toChars());
7052 tempinst
->semantic(sc
);
7053 if (!global
.gag
&& tempinst
->errors
)
7059 resolveHelper(loc
, sc
, tempinst
, NULL
, pe
, pt
, ps
, intypeid
);
7061 *pt
= (*pt
)->addMod(mod
);
7062 //if (*pt) printf("pt = '%s'\n", (*pt)->toChars());
7065 Type
*TypeInstance::semantic(Loc loc
, Scope
*sc
)
7071 //printf("TypeInstance::semantic(%p, %s)\n", this, toChars());
7073 unsigned errors
= global
.errors
;
7074 resolve(loc
, sc
, &e
, &t
, &s
);
7075 // if we had an error evaluating the symbol, suppress further errors
7076 if (!t
&& errors
!= global
.errors
)
7082 if (!e
&& s
&& s
->errors
)
7084 // if there was an error evaluating the symbol, it might actually
7085 // be a type. Avoid misleading error messages.
7086 error(loc
, "%s had previous errors", toChars());
7089 error(loc
, "%s is used as a type", toChars());
7095 Dsymbol
*TypeInstance::toDsymbol(Scope
*sc
)
7101 //printf("TypeInstance::semantic(%s)\n", toChars());
7102 resolve(loc
, sc
, &e
, &t
, &s
);
7103 if (t
&& t
->ty
!= Tinstance
)
7104 s
= t
->toDsymbol(sc
);
7110 /***************************** TypeTypeof *****************************/
7112 TypeTypeof::TypeTypeof(Loc loc
, Expression
*exp
)
7113 : TypeQualified(Ttypeof
, loc
)
7119 const char *TypeTypeof::kind()
7124 Type
*TypeTypeof::syntaxCopy()
7126 //printf("TypeTypeof::syntaxCopy() %s\n", toChars());
7127 TypeTypeof
*t
= new TypeTypeof(loc
, exp
->syntaxCopy());
7128 t
->syntaxCopyHelper(this);
7133 Dsymbol
*TypeTypeof::toDsymbol(Scope
*sc
)
7135 //printf("TypeTypeof::toDsymbol('%s')\n", toChars());
7139 resolve(loc
, sc
, &e
, &t
, &s
);
7144 void TypeTypeof::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
, bool intypeid
)
7150 //printf("TypeTypeof::resolve(sc = %p, idents = '%s')\n", sc, toChars());
7151 //static int nest; if (++nest == 50) *(char*)0=0;
7155 error(loc
, "circular typeof definition");
7165 /* Currently we cannot evalute 'exp' in speculative context, because
7166 * the type implementation may leak to the final execution. Consider:
7169 * string toString() const { return "x"; }
7172 * alias X = typeof(S!int());
7173 * assert(typeid(X).xtoString(null) == "x");
7176 Scope
*sc2
= sc
->push();
7178 Expression
*exp2
= ::semantic(exp
, sc2
);
7179 exp2
= resolvePropertiesOnly(sc2
, exp2
);
7182 if (exp2
->op
== TOKerror
)
7190 if (exp
->op
== TOKtype
||
7191 exp
->op
== TOKscope
)
7193 if (exp
->checkType())
7196 /* Today, 'typeof(func)' returns void if func is a
7197 * function template (TemplateExp), or
7198 * template lambda (FuncExp).
7199 * It's actually used in Phobos as an idiom, to branch code for
7200 * template functions.
7203 if (FuncDeclaration
*f
= exp
->op
== TOKvar
? (( VarExp
*)exp
)->var
->isFuncDeclaration()
7204 : exp
->op
== TOKdotvar
? ((DotVarExp
*)exp
)->var
->isFuncDeclaration() : NULL
)
7206 if (f
->checkForwardRef(loc
))
7209 if (FuncDeclaration
*f
= isFuncAddress(exp
))
7211 if (f
->checkForwardRef(loc
))
7218 error(loc
, "expression (%s) has no type", exp
->toChars());
7221 if (t
->ty
== Ttypeof
)
7223 error(loc
, "forward reference to %s", toChars());
7227 if (idents
.dim
== 0)
7231 if (Dsymbol
*s
= t
->toDsymbol(sc
))
7232 resolveHelper(loc
, sc
, s
, NULL
, pe
, pt
, ps
, intypeid
);
7235 Expression
*e
= typeToExpressionHelper(this, new TypeExp(loc
, t
));
7236 e
= ::semantic(e
, sc
);
7237 resolveExp(e
, pt
, pe
, ps
);
7241 (*pt
) = (*pt
)->addMod(mod
);
7246 Type
*TypeTypeof::semantic(Loc loc
, Scope
*sc
)
7248 //printf("TypeTypeof::semantic() %s\n", toChars());
7253 resolve(loc
, sc
, &e
, &t
, &s
);
7254 if (s
&& (t
= s
->getType()) != NULL
)
7258 error(loc
, "%s is used as a type", toChars());
7264 d_uns64
TypeTypeof::size(Loc loc
)
7267 return exp
->type
->size(loc
);
7269 return TypeQualified::size(loc
);
7274 /***************************** TypeReturn *****************************/
7276 TypeReturn::TypeReturn(Loc loc
)
7277 : TypeQualified(Treturn
, loc
)
7281 const char *TypeReturn::kind()
7286 Type
*TypeReturn::syntaxCopy()
7288 TypeReturn
*t
= new TypeReturn(loc
);
7289 t
->syntaxCopyHelper(this);
7294 Dsymbol
*TypeReturn::toDsymbol(Scope
*sc
)
7299 resolve(loc
, sc
, &e
, &t
, &s
);
7304 void TypeReturn::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
, bool intypeid
)
7310 //printf("TypeReturn::resolve(sc = %p, idents = '%s')\n", sc, toChars());
7313 FuncDeclaration
*func
= sc
->func
;
7316 error(loc
, "typeof(return) must be inside function");
7320 func
= func
->fes
->func
;
7322 t
= func
->type
->nextOf();
7325 error(loc
, "cannot use typeof(return) inside function %s with inferred return type", sc
->func
->toChars());
7329 if (idents
.dim
== 0)
7333 if (Dsymbol
*s
= t
->toDsymbol(sc
))
7334 resolveHelper(loc
, sc
, s
, NULL
, pe
, pt
, ps
, intypeid
);
7337 Expression
*e
= typeToExpressionHelper(this, new TypeExp(loc
, t
));
7338 e
= ::semantic(e
, sc
);
7339 resolveExp(e
, pt
, pe
, ps
);
7343 (*pt
) = (*pt
)->addMod(mod
);
7351 Type
*TypeReturn::semantic(Loc loc
, Scope
*sc
)
7353 //printf("TypeReturn::semantic() %s\n", toChars());
7358 resolve(loc
, sc
, &e
, &t
, &s
);
7359 if (s
&& (t
= s
->getType()) != NULL
)
7363 error(loc
, "%s is used as a type", toChars());
7369 /***************************** TypeEnum *****************************/
7371 TypeEnum::TypeEnum(EnumDeclaration
*sym
)
7377 const char *TypeEnum::kind()
7382 Type
*TypeEnum::syntaxCopy()
7387 Type
*TypeEnum::semantic(Loc
, Scope
*)
7389 //printf("TypeEnum::semantic() %s\n", toChars());
7395 d_uns64
TypeEnum::size(Loc loc
)
7397 return sym
->getMemtype(loc
)->size(loc
);
7400 unsigned TypeEnum::alignsize()
7402 Type
*t
= sym
->getMemtype(Loc());
7403 if (t
->ty
== Terror
)
7405 return t
->alignsize();
7408 Dsymbol
*TypeEnum::toDsymbol(Scope
*)
7413 Type
*TypeEnum::toBasetype()
7415 if (!sym
->members
&& !sym
->memtype
)
7417 Type
*tb
= sym
->getMemtype(Loc())->toBasetype();
7418 return tb
->castMod(mod
); // retain modifier bits from 'this'
7421 Expression
*TypeEnum::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
, int flag
)
7424 if (ident
== Id::_mangleof
)
7425 return getProperty(e
->loc
, ident
, flag
& 1);
7428 sym
->semantic(sym
->_scope
);
7431 if (sym
->isSpecial())
7433 /* Special enums forward to the base type
7435 e
= sym
->memtype
->dotExp(sc
, e
, ident
, flag
);
7437 else if (!(flag
& 1))
7439 sym
->error("is forward referenced when looking for '%s'", ident
->toChars());
7447 Dsymbol
*s
= sym
->search(e
->loc
, ident
);
7450 if (ident
== Id::max
||
7454 return getProperty(e
->loc
, ident
, flag
& 1);
7456 Expression
*res
= sym
->getMemtype(Loc())->dotExp(sc
, e
, ident
, 1);
7457 if (!(flag
& 1) && !res
)
7459 if (Dsymbol
*ns
= sym
->search_correct(ident
))
7460 e
->error("no property '%s' for type '%s'. Did you mean '%s.%s' ?",
7461 ident
->toChars(), toChars(), toChars(), ns
->toChars());
7463 e
->error("no property '%s' for type '%s'",
7464 ident
->toChars(), toChars());
7466 return new ErrorExp();
7470 EnumMember
*m
= s
->isEnumMember();
7471 return m
->getVarExp(e
->loc
, sc
);
7474 Expression
*TypeEnum::getProperty(Loc loc
, Identifier
*ident
, int flag
)
7477 if (ident
== Id::max
|| ident
== Id::min
)
7479 return sym
->getMaxMinValue(loc
, ident
);
7481 else if (ident
== Id::_init
)
7483 e
= defaultInitLiteral(loc
);
7485 else if (ident
== Id::stringof
)
7487 const char *s
= toChars();
7488 e
= new StringExp(loc
, const_cast<char *>(s
), strlen(s
));
7490 e
= ::semantic(e
, &sc
);
7492 else if (ident
== Id::_mangleof
)
7494 e
= Type::getProperty(loc
, ident
, flag
);
7498 e
= toBasetype()->getProperty(loc
, ident
, flag
);
7503 bool TypeEnum::isintegral()
7505 return sym
->getMemtype(Loc())->isintegral();
7508 bool TypeEnum::isfloating()
7510 return sym
->getMemtype(Loc())->isfloating();
7513 bool TypeEnum::isreal()
7515 return sym
->getMemtype(Loc())->isreal();
7518 bool TypeEnum::isimaginary()
7520 return sym
->getMemtype(Loc())->isimaginary();
7523 bool TypeEnum::iscomplex()
7525 return sym
->getMemtype(Loc())->iscomplex();
7528 bool TypeEnum::isunsigned()
7530 return sym
->getMemtype(Loc())->isunsigned();
7533 bool TypeEnum::isscalar()
7535 return sym
->getMemtype(Loc())->isscalar();
7538 bool TypeEnum::isString()
7540 return sym
->getMemtype(Loc())->isString();
7543 bool TypeEnum::isAssignable()
7545 return sym
->getMemtype(Loc())->isAssignable();
7548 bool TypeEnum::isBoolean()
7550 return sym
->getMemtype(Loc())->isBoolean();
7553 bool TypeEnum::needsDestruction()
7555 return sym
->getMemtype(Loc())->needsDestruction();
7558 bool TypeEnum::needsNested()
7560 return sym
->getMemtype(Loc())->needsNested();
7563 MATCH
TypeEnum::implicitConvTo(Type
*to
)
7567 //printf("TypeEnum::implicitConvTo()\n");
7568 if (ty
== to
->ty
&& sym
== ((TypeEnum
*)to
)->sym
)
7569 m
= (mod
== to
->mod
) ? MATCHexact
: MATCHconst
;
7570 else if (sym
->getMemtype(Loc())->implicitConvTo(to
))
7571 m
= MATCHconvert
; // match with conversions
7573 m
= MATCHnomatch
; // no match
7577 MATCH
TypeEnum::constConv(Type
*to
)
7581 if (ty
== to
->ty
&& sym
== ((TypeEnum
*)to
)->sym
&&
7582 MODimplicitConv(mod
, to
->mod
))
7584 return MATCHnomatch
;
7588 Expression
*TypeEnum::defaultInit(Loc loc
)
7590 // Initialize to first member of enum
7591 Expression
*e
= sym
->getDefaultValue(loc
);
7594 e
->type
= this; // to deal with const, immutable, etc., variants
7598 bool TypeEnum::isZeroInit(Loc loc
)
7600 return sym
->getDefaultValue(loc
)->isBool(false);
7603 bool TypeEnum::hasPointers()
7605 return sym
->getMemtype(Loc())->hasPointers();
7608 bool TypeEnum::hasVoidInitPointers()
7610 return sym
->getMemtype(Loc())->hasVoidInitPointers();
7613 Type
*TypeEnum::nextOf()
7615 return sym
->getMemtype(Loc())->nextOf();
7618 /***************************** TypeStruct *****************************/
7620 TypeStruct::TypeStruct(StructDeclaration
*sym
)
7624 this->att
= RECfwdref
;
7625 this->cppmangle
= CPPMANGLEdefault
;
7628 TypeStruct
*TypeStruct::create(StructDeclaration
*sym
)
7630 return new TypeStruct(sym
);
7633 const char *TypeStruct::kind()
7638 Type
*TypeStruct::syntaxCopy()
7643 Type
*TypeStruct::semantic(Loc
, Scope
*sc
)
7645 //printf("TypeStruct::semantic('%s')\n", sym->toChars());
7648 if (sc
&& sc
->cppmangle
!= CPPMANGLEdefault
)
7650 if (this->cppmangle
== CPPMANGLEdefault
)
7651 this->cppmangle
= sc
->cppmangle
;
7653 assert(this->cppmangle
== sc
->cppmangle
);
7658 /* Don't semantic for sym because it should be deferred until
7659 * sizeof needed or its members accessed.
7661 // instead, parent should be set correctly
7662 assert(sym
->parent
);
7664 if (sym
->type
->ty
== Terror
)
7665 return Type::terror
;
7667 this->cppmangle
= sc
->cppmangle
;
7671 d_uns64
TypeStruct::size(Loc loc
)
7673 return sym
->size(loc
);
7676 unsigned TypeStruct::alignsize()
7678 sym
->size(Loc()); // give error for forward references
7679 return sym
->alignsize
;
7682 Dsymbol
*TypeStruct::toDsymbol(Scope
*)
7687 static Dsymbol
*searchSymStruct(Scope
*sc
, Dsymbol
*sym
, Expression
*e
, Identifier
*ident
)
7689 int flags
= sc
->flags
& SCOPEignoresymbolvisibility
? IgnoreSymbolVisibility
: 0;
7690 Dsymbol
*sold
= NULL
;
7691 if (global
.params
.bug10378
|| global
.params
.check10378
)
7693 sold
= sym
->search(e
->loc
, ident
, flags
);
7694 if (!global
.params
.check10378
)
7698 Dsymbol
*s
= sym
->search(e
->loc
, ident
, flags
| SearchLocalsOnly
);
7699 if (global
.params
.check10378
)
7703 Scope::deprecation10378(e
->loc
, sold
, snew
);
7704 if (global
.params
.bug10378
)
7710 Expression
*TypeStruct::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
, int flag
)
7714 assert(e
->op
!= TOKdot
);
7717 if (ident
== Id::_mangleof
)
7718 return getProperty(e
->loc
, ident
, flag
& 1);
7722 if (ident
== Id::_tupleof
)
7724 /* Create a TupleExp out of the fields of the struct e:
7725 * (e.field0, e.field1, e.field2, ...)
7727 e
= ::semantic(e
, sc
); // do this before turning on noaccesscheck
7729 sym
->size(e
->loc
); // do semantic of type
7731 Expression
*e0
= NULL
;
7732 Expression
*ev
= e
->op
== TOKtype
? NULL
: e
;
7734 ev
= extractSideEffect(sc
, "__tup", &e0
, ev
);
7736 Expressions
*exps
= new Expressions
;
7737 exps
->reserve(sym
->fields
.dim
);
7738 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
7740 VarDeclaration
*v
= sym
->fields
[i
];
7743 ex
= new DotVarExp(e
->loc
, ev
, v
);
7746 ex
= new VarExp(e
->loc
, v
);
7747 ex
->type
= ex
->type
->addMod(e
->type
->mod
);
7752 e
= new TupleExp(e
->loc
, e0
, exps
);
7753 Scope
*sc2
= sc
->push();
7754 sc2
->flags
= sc
->flags
| SCOPEnoaccesscheck
;
7755 e
= ::semantic(e
, sc2
);
7760 s
= searchSymStruct(sc
, sym
, e
, ident
);
7764 return noMember(sc
, e
, ident
, flag
);
7766 if (!(sc
->flags
& SCOPEignoresymbolvisibility
) && !symbolIsVisible(sc
, s
))
7768 ::deprecation(e
->loc
, "%s is not visible from module %s", s
->toPrettyChars(), sc
->_module
->toPrettyChars());
7769 // return noMember(sc, e, ident, flag);
7771 if (!s
->isFuncDeclaration()) // because of overloading
7772 s
->checkDeprecated(e
->loc
, sc
);
7775 EnumMember
*em
= s
->isEnumMember();
7778 return em
->getVarExp(e
->loc
, sc
);
7781 if (VarDeclaration
*v
= s
->isVarDeclaration())
7784 (!v
->type
->deco
&& v
->inuse
))
7786 if (v
->inuse
) // Bugzilla 9494
7787 e
->error("circular reference to %s '%s'", v
->kind(), v
->toPrettyChars());
7789 e
->error("forward reference to %s '%s'", v
->kind(), v
->toPrettyChars());
7790 return new ErrorExp();
7792 if (v
->type
->ty
== Terror
)
7793 return new ErrorExp();
7795 if ((v
->storage_class
& STCmanifest
) && v
->_init
)
7799 e
->error("circular initialization of %s '%s'", v
->kind(), v
->toPrettyChars());
7800 return new ErrorExp();
7802 checkAccess(e
->loc
, sc
, NULL
, v
);
7803 Expression
*ve
= new VarExp(e
->loc
, v
);
7804 ve
= ::semantic(ve
, sc
);
7809 if (Type
*t
= s
->getType())
7811 return ::semantic(new TypeExp(e
->loc
, t
), sc
);
7814 TemplateMixin
*tm
= s
->isTemplateMixin();
7817 Expression
*de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, tm
));
7822 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
7825 if (e
->op
== TOKtype
)
7826 e
= new TemplateExp(e
->loc
, td
);
7828 e
= new DotTemplateExp(e
->loc
, e
, td
);
7829 e
= ::semantic(e
, sc
);
7833 TemplateInstance
*ti
= s
->isTemplateInstance();
7836 if (!ti
->semanticRun
)
7839 if (!ti
->inst
|| ti
->errors
) // if template failed to expand
7840 return new ErrorExp();
7842 s
= ti
->inst
->toAlias();
7843 if (!s
->isTemplateInstance())
7845 if (e
->op
== TOKtype
)
7846 e
= new ScopeExp(e
->loc
, ti
);
7848 e
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, ti
));
7849 return ::semantic(e
, sc
);
7852 if (s
->isImport() || s
->isModule() || s
->isPackage())
7854 e
= ::resolve(e
->loc
, sc
, s
, false);
7858 OverloadSet
*o
= s
->isOverloadSet();
7861 OverExp
*oe
= new OverExp(e
->loc
, o
);
7862 if (e
->op
== TOKtype
)
7864 return new DotExp(e
->loc
, e
, oe
);
7867 Declaration
*d
= s
->isDeclaration();
7870 e
->error("%s.%s is not a declaration", e
->toChars(), ident
->toChars());
7871 return new ErrorExp();
7874 if (e
->op
== TOKtype
)
7879 if (TupleDeclaration
*tup
= d
->isTupleDeclaration())
7881 e
= new TupleExp(e
->loc
, tup
);
7882 e
= ::semantic(e
, sc
);
7885 if (d
->needThis() && sc
->intypeof
!= 1)
7892 e
= new DotVarExp(e
->loc
, new ThisExp(e
->loc
), d
);
7893 e
= ::semantic(e
, sc
);
7897 if (d
->semanticRun
== PASSinit
&& d
->_scope
)
7898 d
->semantic(d
->_scope
);
7899 checkAccess(e
->loc
, sc
, e
, d
);
7900 VarExp
*ve
= new VarExp(e
->loc
, d
);
7901 if (d
->isVarDeclaration() && d
->needThis())
7902 ve
->type
= d
->type
->addMod(e
->type
->mod
);
7906 bool unreal
= e
->op
== TOKvar
&& ((VarExp
*)e
)->var
->isField();
7907 if (d
->isDataseg() || (unreal
&& d
->isField()))
7910 checkAccess(e
->loc
, sc
, e
, d
);
7911 Expression
*ve
= new VarExp(e
->loc
, d
);
7912 e
= unreal
? ve
: new CommaExp(e
->loc
, e
, ve
);
7913 e
= ::semantic(e
, sc
);
7917 e
= new DotVarExp(e
->loc
, e
, d
);
7918 e
= ::semantic(e
, sc
);
7922 structalign_t
TypeStruct::alignment()
7924 if (sym
->alignment
== 0)
7925 sym
->size(sym
->loc
);
7926 return sym
->alignment
;
7929 Expression
*TypeStruct::defaultInit(Loc
)
7931 Declaration
*d
= new SymbolDeclaration(sym
->loc
, sym
);
7934 d
->storage_class
|= STCrvalue
; // Bugzilla 14398
7935 return new VarExp(sym
->loc
, d
);
7938 /***************************************
7939 * Use when we prefer the default initializer to be a literal,
7940 * rather than a global immutable variable.
7942 Expression
*TypeStruct::defaultInitLiteral(Loc loc
)
7945 if (sym
->sizeok
!= SIZEOKdone
)
7946 return new ErrorExp();
7947 Expressions
*structelems
= new Expressions();
7948 structelems
->setDim(sym
->fields
.dim
- sym
->isNested());
7949 unsigned offset
= 0;
7950 for (size_t j
= 0; j
< structelems
->dim
; j
++)
7952 VarDeclaration
*vd
= sym
->fields
[j
];
7956 error(loc
, "circular reference to '%s'", vd
->toPrettyChars());
7957 return new ErrorExp();
7959 if (vd
->offset
< offset
|| vd
->type
->size() == 0)
7963 if (vd
->_init
->isVoidInitializer())
7966 e
= vd
->getConstInitializer(false);
7969 e
= vd
->type
->defaultInitLiteral(loc
);
7970 if (e
&& e
->op
== TOKerror
)
7973 offset
= vd
->offset
+ (unsigned)vd
->type
->size();
7974 (*structelems
)[j
] = e
;
7976 StructLiteralExp
*structinit
= new StructLiteralExp(loc
, (StructDeclaration
*)sym
, structelems
);
7978 /* Copy from the initializer symbol for larger symbols,
7979 * otherwise the literals expressed as code get excessively large.
7981 if (size(loc
) > Target::ptrsize
* 4U && !needsNested())
7982 structinit
->useStaticInit
= true;
7984 structinit
->type
= this;
7989 bool TypeStruct::isZeroInit(Loc
)
7991 return sym
->zeroInit
!= 0;
7994 bool TypeStruct::isBoolean()
7999 bool TypeStruct::needsDestruction()
8001 return sym
->dtor
!= NULL
;
8004 bool TypeStruct::needsNested()
8006 if (sym
->isNested())
8009 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
8011 VarDeclaration
*v
= sym
->fields
[i
];
8012 if (!v
->isDataseg() && v
->type
->needsNested())
8018 bool TypeStruct::isAssignable()
8020 bool assignable
= true;
8021 unsigned offset
= ~0; // dead-store initialize to prevent spurious warning
8023 /* If any of the fields are const or immutable,
8024 * then one cannot assign this struct.
8026 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
8028 VarDeclaration
*v
= sym
->fields
[i
];
8029 //printf("%s [%d] v = (%s) %s, v->offset = %d, v->parent = %s", sym->toChars(), i, v->kind(), v->toChars(), v->offset, v->parent->kind());
8032 else if (v
->offset
== offset
)
8034 /* If any fields of anonymous union are assignable,
8035 * then regard union as assignable.
8036 * This is to support unsafe things like Rebindable templates.
8046 assignable
= v
->type
->isMutable() && v
->type
->isAssignable();
8048 //printf(" -> assignable = %d\n", assignable);
8054 bool TypeStruct::hasPointers()
8056 // Probably should cache this information in sym rather than recompute
8057 StructDeclaration
*s
= sym
;
8059 sym
->size(Loc()); // give error for forward references
8060 for (size_t i
= 0; i
< s
->fields
.dim
; i
++)
8062 Declaration
*d
= s
->fields
[i
];
8063 if (d
->storage_class
& STCref
|| d
->hasPointers())
8069 bool TypeStruct::hasVoidInitPointers()
8071 // Probably should cache this information in sym rather than recompute
8072 StructDeclaration
*s
= sym
;
8074 sym
->size(Loc()); // give error for forward references
8075 for (size_t i
= 0; i
< s
->fields
.dim
; i
++)
8077 VarDeclaration
*v
= s
->fields
[i
];
8078 if (v
->_init
&& v
->_init
->isVoidInitializer() && v
->type
->hasPointers())
8080 if (!v
->_init
&& v
->type
->hasVoidInitPointers())
8086 MATCH
TypeStruct::implicitConvTo(Type
*to
)
8089 //printf("TypeStruct::implicitConvTo(%s => %s)\n", toChars(), to->toChars());
8091 if (ty
== to
->ty
&& sym
== ((TypeStruct
*)to
)->sym
)
8093 m
= MATCHexact
; // exact match
8097 if (MODimplicitConv(mod
, to
->mod
))
8101 /* Check all the fields. If they can all be converted,
8102 * allow the conversion.
8104 unsigned offset
= ~0; // dead-store to prevent spurious warning
8105 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
8107 VarDeclaration
*v
= sym
->fields
[i
];
8110 else if (v
->offset
== offset
)
8112 if (m
> MATCHnomatch
)
8117 if (m
<= MATCHnomatch
)
8122 Type
*tvf
= v
->type
->addMod(mod
);
8125 Type
*tv
= v
->type
->addMod(to
->mod
);
8128 MATCH mf
= tvf
->implicitConvTo(tv
);
8129 //printf("\t%s => %s, match = %d\n", v->type->toChars(), tv->toChars(), mf);
8131 if (mf
<= MATCHnomatch
)
8133 if (mf
< m
) // if field match is worse
8140 else if (sym
->aliasthis
&& !(att
& RECtracing
))
8142 att
= (AliasThisRec
)(att
| RECtracing
);
8143 m
= aliasthisOf()->implicitConvTo(to
);
8144 att
= (AliasThisRec
)(att
& ~RECtracing
);
8147 m
= MATCHnomatch
; // no match
8151 MATCH
TypeStruct::constConv(Type
*to
)
8155 if (ty
== to
->ty
&& sym
== ((TypeStruct
*)to
)->sym
&&
8156 MODimplicitConv(mod
, to
->mod
))
8158 return MATCHnomatch
;
8161 unsigned char TypeStruct::deduceWild(Type
*t
, bool isRef
)
8163 if (ty
== t
->ty
&& sym
== ((TypeStruct
*)t
)->sym
)
8164 return Type::deduceWild(t
, isRef
);
8166 unsigned char wm
= 0;
8168 if (t
->hasWild() && sym
->aliasthis
&& !(att
& RECtracing
))
8170 att
= (AliasThisRec
)(att
| RECtracing
);
8171 wm
= aliasthisOf()->deduceWild(t
, isRef
);
8172 att
= (AliasThisRec
)(att
& ~RECtracing
);
8178 Type
*TypeStruct::toHeadMutable()
8184 /***************************** TypeClass *****************************/
8186 TypeClass::TypeClass(ClassDeclaration
*sym
)
8190 this->att
= RECfwdref
;
8191 this->cppmangle
= CPPMANGLEdefault
;
8194 const char *TypeClass::kind()
8199 Type
*TypeClass::syntaxCopy()
8204 Type
*TypeClass::semantic(Loc
, Scope
*sc
)
8206 //printf("TypeClass::semantic(%s)\n", sym->toChars());
8209 if (sc
&& sc
->cppmangle
!= CPPMANGLEdefault
)
8211 if (this->cppmangle
== CPPMANGLEdefault
)
8212 this->cppmangle
= sc
->cppmangle
;
8214 assert(this->cppmangle
== sc
->cppmangle
);
8219 /* Don't semantic for sym because it should be deferred until
8220 * sizeof needed or its members accessed.
8222 // instead, parent should be set correctly
8223 assert(sym
->parent
);
8225 if (sym
->type
->ty
== Terror
)
8226 return Type::terror
;
8228 this->cppmangle
= sc
->cppmangle
;
8232 d_uns64
TypeClass::size(Loc
)
8234 return Target::ptrsize
;
8237 Dsymbol
*TypeClass::toDsymbol(Scope
*)
8242 static Dsymbol
*searchSymClass(Scope
*sc
, Dsymbol
*sym
, Expression
*e
, Identifier
*ident
)
8244 int flags
= sc
->flags
& SCOPEignoresymbolvisibility
? IgnoreSymbolVisibility
: 0;
8245 Dsymbol
*sold
= NULL
;
8246 if (global
.params
.bug10378
|| global
.params
.check10378
)
8248 sold
= sym
->search(e
->loc
, ident
, flags
| IgnoreSymbolVisibility
);
8249 if (!global
.params
.check10378
)
8253 Dsymbol
*s
= sym
->search(e
->loc
, ident
, flags
| SearchLocalsOnly
);
8254 if (!s
&& !(flags
& IgnoreSymbolVisibility
))
8256 s
= sym
->search(e
->loc
, ident
, flags
| SearchLocalsOnly
| IgnoreSymbolVisibility
);
8257 if (s
&& !(flags
& IgnoreErrors
))
8258 ::deprecation(e
->loc
, "%s is not visible from class %s", s
->toPrettyChars(), sym
->toChars());
8260 if (global
.params
.check10378
)
8264 Scope::deprecation10378(e
->loc
, sold
, snew
);
8265 if (global
.params
.bug10378
)
8271 Expression
*TypeClass::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
, int flag
)
8274 assert(e
->op
!= TOKdot
);
8277 if (ident
== Id::__sizeof
|| ident
== Id::__xalignof
|| ident
== Id::_mangleof
)
8279 return Type::getProperty(e
->loc
, ident
, 0);
8284 if (ident
== Id::_tupleof
)
8286 /* Create a TupleExp
8288 e
= ::semantic(e
, sc
); // do this before turning on noaccesscheck
8290 sym
->size(e
->loc
); // do semantic of type
8292 Expression
*e0
= NULL
;
8293 Expression
*ev
= e
->op
== TOKtype
? NULL
: e
;
8295 ev
= extractSideEffect(sc
, "__tup", &e0
, ev
);
8297 Expressions
*exps
= new Expressions
;
8298 exps
->reserve(sym
->fields
.dim
);
8299 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
8301 VarDeclaration
*v
= sym
->fields
[i
];
8302 // Don't include hidden 'this' pointer
8303 if (v
->isThisDeclaration())
8307 ex
= new DotVarExp(e
->loc
, ev
, v
);
8310 ex
= new VarExp(e
->loc
, v
);
8311 ex
->type
= ex
->type
->addMod(e
->type
->mod
);
8316 e
= new TupleExp(e
->loc
, e0
, exps
);
8317 Scope
*sc2
= sc
->push();
8318 sc2
->flags
= sc
->flags
| SCOPEnoaccesscheck
;
8319 e
= ::semantic(e
, sc2
);
8324 s
= searchSymClass(sc
, sym
, e
, ident
);
8328 // See if it's 'this' class or a base class
8329 if (sym
->ident
== ident
)
8331 if (e
->op
== TOKtype
)
8332 return Type::getProperty(e
->loc
, ident
, 0);
8333 e
= new DotTypeExp(e
->loc
, e
, sym
);
8334 e
= ::semantic(e
, sc
);
8337 if (ClassDeclaration
*cbase
= sym
->searchBase(ident
))
8339 if (e
->op
== TOKtype
)
8340 return Type::getProperty(e
->loc
, ident
, 0);
8341 if (InterfaceDeclaration
*ifbase
= cbase
->isInterfaceDeclaration())
8342 e
= new CastExp(e
->loc
, e
, ifbase
->type
);
8344 e
= new DotTypeExp(e
->loc
, e
, cbase
);
8345 e
= ::semantic(e
, sc
);
8349 if (ident
== Id::classinfo
)
8351 assert(Type::typeinfoclass
);
8352 Type
*t
= Type::typeinfoclass
->type
;
8353 if (e
->op
== TOKtype
|| e
->op
== TOKdottype
)
8355 /* For type.classinfo, we know the classinfo
8358 if (!sym
->vclassinfo
)
8359 sym
->vclassinfo
= new TypeInfoClassDeclaration(sym
->type
);
8360 e
= new VarExp(e
->loc
, sym
->vclassinfo
);
8362 e
->type
= t
; // do this so we don't get redundant dereference
8366 /* For class objects, the classinfo reference is the first
8367 * entry in the vtbl[]
8369 e
= new PtrExp(e
->loc
, e
);
8370 e
->type
= t
->pointerTo();
8371 if (sym
->isInterfaceDeclaration())
8373 if (sym
->isCPPinterface())
8375 /* C++ interface vtbl[]s are different in that the
8376 * first entry is always pointer to the first virtual
8377 * function, not classinfo.
8378 * We can't get a .classinfo for it.
8380 error(e
->loc
, "no .classinfo for C++ interface objects");
8382 /* For an interface, the first entry in the vtbl[]
8383 * is actually a pointer to an instance of struct Interface.
8384 * The first member of Interface is the .classinfo,
8385 * so add an extra pointer indirection.
8387 e
->type
= e
->type
->pointerTo();
8388 e
= new PtrExp(e
->loc
, e
);
8389 e
->type
= t
->pointerTo();
8391 e
= new PtrExp(e
->loc
, e
, t
);
8396 if (ident
== Id::__vptr
)
8398 /* The pointer to the vtbl[]
8399 * *cast(immutable(void*)**)e
8401 e
= e
->castTo(sc
, tvoidptr
->immutableOf()->pointerTo()->pointerTo());
8402 e
= new PtrExp(e
->loc
, e
);
8403 e
= ::semantic(e
, sc
);
8407 if (ident
== Id::__monitor
)
8409 /* The handle to the monitor (call it a void*)
8410 * *(cast(void**)e + 1)
8412 e
= e
->castTo(sc
, tvoidptr
->pointerTo());
8413 e
= new AddExp(e
->loc
, e
, new IntegerExp(1));
8414 e
= new PtrExp(e
->loc
, e
);
8415 e
= ::semantic(e
, sc
);
8419 if (ident
== Id::outer
&& sym
->vthis
)
8421 if (sym
->vthis
->_scope
)
8422 sym
->vthis
->semantic(NULL
);
8424 if (ClassDeclaration
*cdp
= sym
->toParent2()->isClassDeclaration())
8426 DotVarExp
*dve
= new DotVarExp(e
->loc
, e
, sym
->vthis
);
8427 dve
->type
= cdp
->type
->addMod(e
->type
->mod
);
8431 /* Bugzilla 15839: Find closest parent class through nested functions.
8433 for (Dsymbol
*p
= sym
->toParent2(); p
; p
= p
->toParent2())
8435 FuncDeclaration
*fd
= p
->isFuncDeclaration();
8440 AggregateDeclaration
*ad
= fd
->isThis();
8443 if (ad
->isClassDeclaration())
8445 ThisExp
*ve
= new ThisExp(e
->loc
);
8447 ve
->var
= fd
->vthis
;
8448 const bool nestedError
= fd
->vthis
->checkNestedReference(sc
, e
->loc
);
8449 assert(!nestedError
);
8451 ve
->type
= fd
->vthis
->type
->addMod(e
->type
->mod
);
8457 // Continue to show enclosing function's frame (stack or closure).
8458 DotVarExp
*dve
= new DotVarExp(e
->loc
, e
, sym
->vthis
);
8459 dve
->type
= sym
->vthis
->type
->addMod(e
->type
->mod
);
8463 return noMember(sc
, e
, ident
, flag
& 1);
8465 if (!(sc
->flags
& SCOPEignoresymbolvisibility
) && !symbolIsVisible(sc
, s
))
8467 ::deprecation(e
->loc
, "%s is not visible from module %s", s
->toPrettyChars(), sc
->_module
->toPrettyChars());
8468 // return noMember(sc, e, ident, flag);
8470 if (!s
->isFuncDeclaration()) // because of overloading
8471 s
->checkDeprecated(e
->loc
, sc
);
8474 EnumMember
*em
= s
->isEnumMember();
8477 return em
->getVarExp(e
->loc
, sc
);
8480 if (VarDeclaration
*v
= s
->isVarDeclaration())
8483 (!v
->type
->deco
&& v
->inuse
))
8485 if (v
->inuse
) // Bugzilla 9494
8486 e
->error("circular reference to %s '%s'", v
->kind(), v
->toPrettyChars());
8488 e
->error("forward reference to %s '%s'", v
->kind(), v
->toPrettyChars());
8489 return new ErrorExp();
8491 if (v
->type
->ty
== Terror
)
8492 return new ErrorExp();
8494 if ((v
->storage_class
& STCmanifest
) && v
->_init
)
8498 e
->error("circular initialization of %s '%s'", v
->kind(), v
->toPrettyChars());
8499 return new ErrorExp();
8501 checkAccess(e
->loc
, sc
, NULL
, v
);
8502 Expression
*ve
= new VarExp(e
->loc
, v
);
8503 ve
= ::semantic(ve
, sc
);
8508 if (Type
*t
= s
->getType())
8510 return ::semantic(new TypeExp(e
->loc
, t
), sc
);
8513 TemplateMixin
*tm
= s
->isTemplateMixin();
8516 Expression
*de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, tm
));
8521 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
8524 if (e
->op
== TOKtype
)
8525 e
= new TemplateExp(e
->loc
, td
);
8527 e
= new DotTemplateExp(e
->loc
, e
, td
);
8528 e
= ::semantic(e
, sc
);
8532 TemplateInstance
*ti
= s
->isTemplateInstance();
8535 if (!ti
->semanticRun
)
8538 if (!ti
->inst
|| ti
->errors
) // if template failed to expand
8539 return new ErrorExp();
8541 s
= ti
->inst
->toAlias();
8542 if (!s
->isTemplateInstance())
8544 if (e
->op
== TOKtype
)
8545 e
= new ScopeExp(e
->loc
, ti
);
8547 e
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, ti
));
8548 return ::semantic(e
, sc
);
8551 if (s
->isImport() || s
->isModule() || s
->isPackage())
8553 e
= ::resolve(e
->loc
, sc
, s
, false);
8557 OverloadSet
*o
= s
->isOverloadSet();
8560 OverExp
*oe
= new OverExp(e
->loc
, o
);
8561 if (e
->op
== TOKtype
)
8563 return new DotExp(e
->loc
, e
, oe
);
8566 Declaration
*d
= s
->isDeclaration();
8569 e
->error("%s.%s is not a declaration", e
->toChars(), ident
->toChars());
8570 return new ErrorExp();
8573 if (e
->op
== TOKtype
)
8578 if (TupleDeclaration
*tup
= d
->isTupleDeclaration())
8580 e
= new TupleExp(e
->loc
, tup
);
8581 e
= ::semantic(e
, sc
);
8584 if (d
->needThis() && sc
->intypeof
!= 1)
8591 // This is almost same as getRightThis() in expression.c
8592 Expression
*e1
= new ThisExp(e
->loc
);
8593 e1
= ::semantic(e1
, sc
);
8595 Type
*t
= e1
->type
->toBasetype();
8596 ClassDeclaration
*cd
= e
->type
->isClassHandle();
8597 ClassDeclaration
*tcd
= t
->isClassHandle();
8598 if (cd
&& tcd
&& (tcd
== cd
|| cd
->isBaseOf(tcd
, NULL
)))
8600 e
= new DotTypeExp(e1
->loc
, e1
, cd
);
8601 e
= new DotVarExp(e
->loc
, e
, d
);
8602 e
= ::semantic(e
, sc
);
8605 if (tcd
&& tcd
->isNested())
8606 { /* e1 is the 'this' pointer for an inner class: tcd.
8607 * Rewrite it as the 'this' pointer for the outer class.
8610 e1
= new DotVarExp(e
->loc
, e1
, tcd
->vthis
);
8611 e1
->type
= tcd
->vthis
->type
;
8612 e1
->type
= e1
->type
->addMod(t
->mod
);
8613 // Do not call checkNestedRef()
8614 //e1 = ::semantic(e1, sc);
8616 // Skip up over nested functions, and get the enclosing
8619 for (s
= tcd
->toParent();
8620 s
&& s
->isFuncDeclaration();
8622 { FuncDeclaration
*f
= s
->isFuncDeclaration();
8625 //printf("rewriting e1 to %s's this\n", f->toChars());
8627 e1
= new VarExp(e
->loc
, f
->vthis
);
8631 e
= new VarExp(e
->loc
, d
);
8635 if (s
&& s
->isClassDeclaration())
8636 { e1
->type
= s
->isClassDeclaration()->type
;
8637 e1
->type
= e1
->type
->addMod(t
->mod
);
8639 e1
= ::semantic(e1
, sc
);
8642 e1
= ::semantic(e1
, sc
);
8647 //printf("e = %s, d = %s\n", e->toChars(), d->toChars());
8648 if (d
->semanticRun
== PASSinit
&& d
->_scope
)
8649 d
->semantic(d
->_scope
);
8650 checkAccess(e
->loc
, sc
, e
, d
);
8651 VarExp
*ve
= new VarExp(e
->loc
, d
);
8652 if (d
->isVarDeclaration() && d
->needThis())
8653 ve
->type
= d
->type
->addMod(e
->type
->mod
);
8657 bool unreal
= e
->op
== TOKvar
&& ((VarExp
*)e
)->var
->isField();
8658 if (d
->isDataseg() || (unreal
&& d
->isField()))
8661 checkAccess(e
->loc
, sc
, e
, d
);
8662 Expression
*ve
= new VarExp(e
->loc
, d
);
8663 e
= unreal
? ve
: new CommaExp(e
->loc
, e
, ve
);
8664 e
= ::semantic(e
, sc
);
8668 e
= new DotVarExp(e
->loc
, e
, d
);
8669 e
= ::semantic(e
, sc
);
8673 ClassDeclaration
*TypeClass::isClassHandle()
8678 bool TypeClass::isscope()
8680 return sym
->isscope
;
8683 bool TypeClass::isBaseOf(Type
*t
, int *poffset
)
8685 if (t
&& t
->ty
== Tclass
)
8687 ClassDeclaration
*cd
= ((TypeClass
*)t
)->sym
;
8688 if (sym
->isBaseOf(cd
, poffset
))
8694 MATCH
TypeClass::implicitConvTo(Type
*to
)
8696 //printf("TypeClass::implicitConvTo(to = '%s') %s\n", to->toChars(), toChars());
8697 MATCH m
= constConv(to
);
8698 if (m
> MATCHnomatch
)
8701 ClassDeclaration
*cdto
= to
->isClassHandle();
8704 //printf("TypeClass::implicitConvTo(to = '%s') %s, isbase = %d %d\n", to->toChars(), toChars(), cdto->isBaseInfoComplete(), sym->isBaseInfoComplete());
8705 if (cdto
->_scope
&& !cdto
->isBaseInfoComplete())
8706 cdto
->semantic(NULL
);
8707 if (sym
->_scope
&& !sym
->isBaseInfoComplete())
8708 sym
->semantic(NULL
);
8709 if (cdto
->isBaseOf(sym
, NULL
) && MODimplicitConv(mod
, to
->mod
))
8711 //printf("'to' is base\n");
8712 return MATCHconvert
;
8717 if (sym
->aliasthis
&& !(att
& RECtracing
))
8719 att
= (AliasThisRec
)(att
| RECtracing
);
8720 m
= aliasthisOf()->implicitConvTo(to
);
8721 att
= (AliasThisRec
)(att
& ~RECtracing
);
8727 MATCH
TypeClass::constConv(Type
*to
)
8731 if (ty
== to
->ty
&& sym
== ((TypeClass
*)to
)->sym
&&
8732 MODimplicitConv(mod
, to
->mod
))
8735 /* Conversion derived to const(base)
8738 if (to
->isBaseOf(this, &offset
) && offset
== 0 &&
8739 MODimplicitConv(mod
, to
->mod
))
8743 // inout(derived) to inout(base)
8744 if (!to
->isMutable() && !to
->isWild())
8745 return MATCHconvert
;
8748 return MATCHnomatch
;
8751 unsigned char TypeClass::deduceWild(Type
*t
, bool isRef
)
8753 ClassDeclaration
*cd
= t
->isClassHandle();
8754 if (cd
&& (sym
== cd
|| cd
->isBaseOf(sym
, NULL
)))
8755 return Type::deduceWild(t
, isRef
);
8757 unsigned char wm
= 0;
8759 if (t
->hasWild() && sym
->aliasthis
&& !(att
& RECtracing
))
8761 att
= (AliasThisRec
)(att
| RECtracing
);
8762 wm
= aliasthisOf()->deduceWild(t
, isRef
);
8763 att
= (AliasThisRec
)(att
& ~RECtracing
);
8769 Type
*TypeClass::toHeadMutable()
8774 Expression
*TypeClass::defaultInit(Loc loc
)
8776 return new NullExp(loc
, this);
8779 bool TypeClass::isZeroInit(Loc
)
8784 bool TypeClass::isBoolean()
8789 bool TypeClass::hasPointers()
8794 /***************************** TypeTuple *****************************/
8796 TypeTuple::TypeTuple(Parameters
*arguments
)
8799 //printf("TypeTuple(this = %p)\n", this);
8800 this->arguments
= arguments
;
8801 //printf("TypeTuple() %p, %s\n", this, toChars());
8805 * Form TypeTuple from the types of the expressions.
8806 * Assume exps[] is already tuple expanded.
8809 TypeTuple::TypeTuple(Expressions
*exps
)
8812 Parameters
*arguments
= new Parameters
;
8815 arguments
->setDim(exps
->dim
);
8816 for (size_t i
= 0; i
< exps
->dim
; i
++)
8817 { Expression
*e
= (*exps
)[i
];
8818 if (e
->type
->ty
== Ttuple
)
8819 e
->error("cannot form tuple of tuples");
8820 Parameter
*arg
= new Parameter(STCundefined
, e
->type
, NULL
, NULL
);
8821 (*arguments
)[i
] = arg
;
8824 this->arguments
= arguments
;
8825 //printf("TypeTuple() %p, %s\n", this, toChars());
8828 TypeTuple
*TypeTuple::create(Parameters
*arguments
)
8830 return new TypeTuple(arguments
);
8833 /*******************************************
8834 * Type tuple with 0, 1 or 2 types in it.
8836 TypeTuple::TypeTuple()
8839 arguments
= new Parameters();
8842 TypeTuple::TypeTuple(Type
*t1
)
8845 arguments
= new Parameters();
8846 arguments
->push(new Parameter(0, t1
, NULL
, NULL
));
8849 TypeTuple::TypeTuple(Type
*t1
, Type
*t2
)
8852 arguments
= new Parameters();
8853 arguments
->push(new Parameter(0, t1
, NULL
, NULL
));
8854 arguments
->push(new Parameter(0, t2
, NULL
, NULL
));
8857 const char *TypeTuple::kind()
8862 Type
*TypeTuple::syntaxCopy()
8864 Parameters
*args
= Parameter::arraySyntaxCopy(arguments
);
8865 Type
*t
= new TypeTuple(args
);
8870 Type
*TypeTuple::semantic(Loc
, Scope
*)
8872 //printf("TypeTuple::semantic(this = %p)\n", this);
8873 //printf("TypeTuple::semantic() %p, %s\n", this, toChars());
8875 deco
= merge()->deco
;
8877 /* Don't return merge(), because a tuple with one type has the
8878 * same deco as that type.
8883 bool TypeTuple::equals(RootObject
*o
)
8885 Type
*t
= (Type
*)o
;
8886 //printf("TypeTuple::equals(%s, %s)\n", toChars(), t->toChars());
8889 if (t
->ty
== Ttuple
)
8891 TypeTuple
*tt
= (TypeTuple
*)t
;
8892 if (arguments
->dim
== tt
->arguments
->dim
)
8894 for (size_t i
= 0; i
< tt
->arguments
->dim
; i
++)
8896 Parameter
*arg1
= (*arguments
)[i
];
8897 Parameter
*arg2
= (*tt
->arguments
)[i
];
8898 if (!arg1
->type
->equals(arg2
->type
))
8907 Expression
*TypeTuple::getProperty(Loc loc
, Identifier
*ident
, int flag
)
8911 if (ident
== Id::length
)
8913 e
= new IntegerExp(loc
, arguments
->dim
, Type::tsize_t
);
8915 else if (ident
== Id::_init
)
8917 e
= defaultInitLiteral(loc
);
8925 error(loc
, "no property '%s' for tuple '%s'", ident
->toChars(), toChars());
8931 Expression
*TypeTuple::defaultInit(Loc loc
)
8933 Expressions
*exps
= new Expressions();
8934 exps
->setDim(arguments
->dim
);
8935 for (size_t i
= 0; i
< arguments
->dim
; i
++)
8937 Parameter
*p
= (*arguments
)[i
];
8939 Expression
*e
= p
->type
->defaultInitLiteral(loc
);
8940 if (e
->op
== TOKerror
)
8944 return new TupleExp(loc
, exps
);
8947 /***************************** TypeSlice *****************************/
8949 /* This is so we can slice a TypeTuple */
8951 TypeSlice::TypeSlice(Type
*next
, Expression
*lwr
, Expression
*upr
)
8952 : TypeNext(Tslice
, next
)
8954 //printf("TypeSlice[%s .. %s]\n", lwr->toChars(), upr->toChars());
8959 const char *TypeSlice::kind()
8964 Type
*TypeSlice::syntaxCopy()
8966 Type
*t
= new TypeSlice(next
->syntaxCopy(), lwr
->syntaxCopy(), upr
->syntaxCopy());
8971 Type
*TypeSlice::semantic(Loc loc
, Scope
*sc
)
8973 //printf("TypeSlice::semantic() %s\n", toChars());
8974 Type
*tn
= next
->semantic(loc
, sc
);
8975 //printf("next: %s\n", tn->toChars());
8977 Type
*tbn
= tn
->toBasetype();
8978 if (tbn
->ty
!= Ttuple
)
8980 error(loc
, "can only slice tuple types, not %s", tbn
->toChars());
8981 return Type::terror
;
8983 TypeTuple
*tt
= (TypeTuple
*)tbn
;
8985 lwr
= semanticLength(sc
, tbn
, lwr
);
8986 lwr
= lwr
->ctfeInterpret();
8987 uinteger_t i1
= lwr
->toUInteger();
8989 upr
= semanticLength(sc
, tbn
, upr
);
8990 upr
= upr
->ctfeInterpret();
8991 uinteger_t i2
= upr
->toUInteger();
8993 if (!(i1
<= i2
&& i2
<= tt
->arguments
->dim
))
8995 error(loc
, "slice [%llu..%llu] is out of range of [0..%u]", i1
, i2
, tt
->arguments
->dim
);
8996 return Type::terror
;
9002 Parameters
*args
= new Parameters
;
9003 args
->reserve((size_t)(i2
- i1
));
9004 for (size_t i
= (size_t)i1
; i
< (size_t)i2
; i
++)
9006 Parameter
*arg
= (*tt
->arguments
)[i
];
9009 Type
*t
= new TypeTuple(args
);
9010 return t
->semantic(loc
, sc
);
9013 void TypeSlice::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
, bool intypeid
)
9015 next
->resolve(loc
, sc
, pe
, pt
, ps
, intypeid
);
9018 // It's really a slice expression
9019 if (Dsymbol
*s
= getDsymbol(*pe
))
9020 *pe
= new DsymbolExp(loc
, s
);
9021 *pe
= new ArrayExp(loc
, *pe
, new IntervalExp(loc
, lwr
, upr
));
9026 TupleDeclaration
*td
= s
->isTupleDeclaration();
9029 /* It's a slice of a TupleDeclaration
9031 ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, td
);
9032 sym
->parent
= sc
->scopesym
;
9034 sc
= sc
->startCTFE();
9035 lwr
= ::semantic(lwr
, sc
);
9036 upr
= ::semantic(upr
, sc
);
9040 lwr
= lwr
->ctfeInterpret();
9041 upr
= upr
->ctfeInterpret();
9042 uinteger_t i1
= lwr
->toUInteger();
9043 uinteger_t i2
= upr
->toUInteger();
9045 if (!(i1
<= i2
&& i2
<= td
->objects
->dim
))
9047 error(loc
, "slice [%llu..%llu] is out of range of [0..%u]", i1
, i2
, td
->objects
->dim
);
9053 if (i1
== 0 && i2
== td
->objects
->dim
)
9059 /* Create a new TupleDeclaration which
9060 * is a slice [i1..i2] out of the old one.
9062 Objects
*objects
= new Objects
;
9063 objects
->setDim((size_t)(i2
- i1
));
9064 for (size_t i
= 0; i
< objects
->dim
; i
++)
9066 (*objects
)[i
] = (*td
->objects
)[(size_t)i1
+ i
];
9069 TupleDeclaration
*tds
= new TupleDeclaration(loc
, td
->ident
, objects
);
9077 if ((*pt
)->ty
!= Terror
)
9078 next
= *pt
; // prevent re-running semantic() on 'next'
9080 Type::resolve(loc
, sc
, pe
, pt
, ps
, intypeid
);
9084 /***************************** TypeNull *****************************/
9086 TypeNull::TypeNull()
9091 const char *TypeNull::kind()
9096 Type
*TypeNull::syntaxCopy()
9098 // No semantic analysis done, no need to copy
9102 MATCH
TypeNull::implicitConvTo(Type
*to
)
9104 //printf("TypeNull::implicitConvTo(this=%p, to=%p)\n", this, to);
9105 //printf("from: %s\n", toChars());
9106 //printf("to : %s\n", to->toChars());
9107 MATCH m
= Type::implicitConvTo(to
);
9108 if (m
!= MATCHnomatch
)
9111 // NULL implicitly converts to any pointer type or dynamic array
9112 //if (type->ty == Tpointer && type->nextOf()->ty == Tvoid)
9114 Type
*tb
= to
->toBasetype();
9115 if (tb
->ty
== Tnull
||
9116 tb
->ty
== Tpointer
|| tb
->ty
== Tarray
||
9117 tb
->ty
== Taarray
|| tb
->ty
== Tclass
||
9118 tb
->ty
== Tdelegate
)
9122 return MATCHnomatch
;
9125 bool TypeNull::isBoolean()
9130 d_uns64
TypeNull::size(Loc loc
)
9132 return tvoidptr
->size(loc
);
9135 Expression
*TypeNull::defaultInit(Loc
)
9137 return new NullExp(Loc(), Type::tnull
);
9140 /***************************** Parameter *****************************/
9142 Parameter::Parameter(StorageClass storageClass
, Type
*type
, Identifier
*ident
, Expression
*defaultArg
)
9145 this->ident
= ident
;
9146 this->storageClass
= storageClass
;
9147 this->defaultArg
= defaultArg
;
9150 Parameter
*Parameter::create(StorageClass storageClass
, Type
*type
, Identifier
*ident
, Expression
*defaultArg
)
9152 return new Parameter(storageClass
, type
, ident
, defaultArg
);
9155 Parameter
*Parameter::syntaxCopy()
9157 return new Parameter(storageClass
,
9158 type
? type
->syntaxCopy() : NULL
,
9160 defaultArg
? defaultArg
->syntaxCopy() : NULL
);
9163 Parameters
*Parameter::arraySyntaxCopy(Parameters
*parameters
)
9165 Parameters
*params
= NULL
;
9168 params
= new Parameters();
9169 params
->setDim(parameters
->dim
);
9170 for (size_t i
= 0; i
< params
->dim
; i
++)
9171 (*params
)[i
] = (*parameters
)[i
]->syntaxCopy();
9176 /****************************************************
9177 * Determine if parameter is a lazy array of delegates.
9178 * If so, return the return type of those delegates.
9179 * If not, return NULL.
9181 * Returns T if the type is one of the following forms:
9186 Type
*Parameter::isLazyArray()
9188 Type
*tb
= type
->toBasetype();
9189 if (tb
->ty
== Tsarray
|| tb
->ty
== Tarray
)
9191 Type
*tel
= ((TypeArray
*)tb
)->next
->toBasetype();
9192 if (tel
->ty
== Tdelegate
)
9194 TypeDelegate
*td
= (TypeDelegate
*)tel
;
9195 TypeFunction
*tf
= td
->next
->toTypeFunction();
9197 if (!tf
->varargs
&& Parameter::dim(tf
->parameters
) == 0)
9199 return tf
->next
; // return type of delegate
9206 /***************************************
9207 * Determine number of arguments, folding in tuples.
9210 static int dimDg(void *ctx
, size_t, Parameter
*)
9216 size_t Parameter::dim(Parameters
*parameters
)
9219 Parameter_foreach(parameters
, &dimDg
, &n
);
9223 /***************************************
9224 * Get nth Parameter, folding in tuples.
9226 * Parameter* nth Parameter
9227 * NULL not found, *pn gets incremented by the number
9231 struct GetNthParamCtx
9237 static int getNthParamDg(void *ctx
, size_t n
, Parameter
*p
)
9239 GetNthParamCtx
*c
= (GetNthParamCtx
*)ctx
;
9248 Parameter
*Parameter::getNth(Parameters
*parameters
, size_t nth
, size_t *)
9250 GetNthParamCtx ctx
= { nth
, NULL
};
9251 int res
= Parameter_foreach(parameters
, &getNthParamDg
, &ctx
);
9252 return res
? ctx
.param
: NULL
;
9255 /***************************************
9256 * Expands tuples in args in depth first order. Calls
9257 * dg(void *ctx, size_t argidx, Parameter *arg) for each Parameter.
9258 * If dg returns !=0, stops and returns that value else returns 0.
9259 * Use this function to avoid the O(N + N^2/2) complexity of
9260 * calculating dim and calling N times getNth.
9263 int Parameter_foreach(Parameters
*parameters
, ForeachDg dg
, void *ctx
, size_t *pn
)
9269 size_t n
= pn
? *pn
: 0; // take over index
9271 for (size_t i
= 0; i
< parameters
->dim
; i
++)
9273 Parameter
*p
= (*parameters
)[i
];
9274 Type
*t
= p
->type
->toBasetype();
9276 if (t
->ty
== Ttuple
)
9278 TypeTuple
*tu
= (TypeTuple
*)t
;
9279 result
= Parameter_foreach(tu
->arguments
, dg
, ctx
, &n
);
9282 result
= dg(ctx
, n
++, p
);
9289 *pn
= n
; // update index
9294 const char *Parameter::toChars()
9296 return ident
? ident
->toChars() : "__anonymous_param";
9299 /*********************************
9300 * Compute covariance of parameters `this` and `p`
9301 * as determined by the storage classes of both.
9303 * p = Parameter to compare with
9305 * true = `this` can be used in place of `p`
9308 bool Parameter::isCovariant(bool returnByRef
, const Parameter
*p
) const
9310 const StorageClass stc
= STCref
| STCin
| STCout
| STClazy
;
9311 if ((this->storageClass
& stc
) != (p
->storageClass
& stc
))
9314 return isCovariantScope(returnByRef
, this->storageClass
, p
->storageClass
);
9317 bool Parameter::isCovariantScope(bool returnByRef
, StorageClass from
, StorageClass to
)
9324 /* Classification of 'scope-return-ref' possibilities
9339 /* Shrinking the representation is necessary because StorageClass is so wide
9341 * returnByRef = true if the function returns by ref
9342 * stc = storage class of parameter
9344 static unsigned buildSR(bool returnByRef
, StorageClass stc
)
9347 StorageClass stc2
= stc
& (STCref
| STCscope
| STCreturn
);
9350 else if (stc2
== STCref
)
9352 else if (stc2
== STCscope
)
9354 else if (stc2
== (STCscope
| STCreturn
))
9355 result
= SRReturnScope
;
9356 else if (stc2
== (STCref
| STCreturn
))
9357 result
= SRReturnRef
;
9358 else if (stc2
== (STCscope
| STCref
))
9359 result
= SRRefScope
;
9360 else if (stc2
== (STCscope
| STCref
| STCreturn
))
9361 result
= returnByRef
? SRReturnRef_Scope
: SRRef_ReturnScope
;
9367 static void covariantInit(bool covariant
[SRMAX
][SRMAX
])
9369 /* Initialize covariant[][] with this:
9376 From\To r rr rs rr-s r-rs
9381 Ref-ReturnScope X X X
9383 for (int i
= 0; i
< SRMAX
; i
++)
9385 covariant
[i
][i
] = true;
9386 covariant
[SRRefScope
][i
] = true;
9388 covariant
[SRReturnScope
][SRNone
] = true;
9389 covariant
[SRScope
][SRNone
] = true;
9390 covariant
[SRScope
][SRReturnScope
] = true;
9392 covariant
[SRRef
][SRReturnRef
] = true;
9393 covariant
[SRReturnRef_Scope
][SRReturnRef
] = true;
9394 covariant
[SRRef_ReturnScope
][SRRef
] = true;
9395 covariant
[SRRef_ReturnScope
][SRReturnRef
] = true;
9399 /* result is true if the 'from' can be used as a 'to'
9402 if ((from
^ to
) & STCref
) // differing in 'ref' means no covariance
9405 static bool covariant
[SR::SRMAX
][SR::SRMAX
];
9406 static bool init
= false;
9409 SR::covariantInit(covariant
);
9413 return covariant
[SR::buildSR(returnByRef
, from
)][SR::buildSR(returnByRef
, to
)];