2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars
5 // written by Walter Bright
6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
9 // See the included readme.txt for details.
11 /* NOTE: This file has been patched from the original DMD distribution to
12 work with the GDC compiler.
14 Modified by David Friedman, December 2006
17 // Issues with using -include total.h (defines integer_t) and then complex.h fails...
20 #define __USE_ISOC99 1 // so signbit() gets defined
27 #include "gdc_alloca.h"
33 // TODO%% this undefines signbit and includes is the wrong complex.h anyway
34 // -- not sure why this is needed, anyway
35 // don't need to worry about all this if the 'nan negative by default' issue is resolved
41 // includes the wrong complex.h in C++
49 static double zero
= 0;
52 // %% shouldn't be necessary
53 //#include <bits/nan.h>
54 //#include <bits/mathdef.h>
55 static double zero
= 0;
59 #define NAN (nan("0"))
62 #define INFINITY (infinity())
68 #define integer_t dmd_integer_t
78 #include "expression.h"
80 #include "declaration.h"
85 #include "aggregate.h"
88 FuncDeclaration
*hasThis(Scope
*sc
);
91 #define LOGDOTEXP 0 // log ::dotExp()
92 #define LOGDEFAULTINIT 0 // log ::defaultInit()
94 // Allow implicit conversion of T[] to T*
95 #define IMPLICIT_ARRAY_TO_PTR global.params.useDeprecated
97 /* These have default values for 32 bit code, they get
98 * adjusted for 64 bit code.
109 int Tsize_t
= Tuns32
;
110 int Tptrdiff_t
= Tint32
;
112 int CLASSINFO_SIZE
= 0x3c+12;
114 /***************************** Type *****************************/
116 ClassDeclaration
*Type::typeinfo
;
117 ClassDeclaration
*Type::typeinfoclass
;
118 ClassDeclaration
*Type::typeinfointerface
;
119 ClassDeclaration
*Type::typeinfostruct
;
120 ClassDeclaration
*Type::typeinfotypedef
;
121 ClassDeclaration
*Type::typeinfopointer
;
122 ClassDeclaration
*Type::typeinfoarray
;
123 ClassDeclaration
*Type::typeinfostaticarray
;
124 ClassDeclaration
*Type::typeinfoassociativearray
;
125 ClassDeclaration
*Type::typeinfoenum
;
126 ClassDeclaration
*Type::typeinfofunction
;
127 ClassDeclaration
*Type::typeinfodelegate
;
128 ClassDeclaration
*Type::typeinfotypelist
;
129 ClassDeclaration
*Type::typeinfoconst
;
130 ClassDeclaration
*Type::typeinfoinvariant
;
132 Type
*Type::tvoidptr
;
133 Type
*Type::basic
[TMAX
];
134 unsigned char Type::mangleChar
[TMAX
];
135 unsigned char Type::sizeTy
[TMAX
];
136 StringTable
Type::stringtable
;
151 this->arrayof
= NULL
;
156 Type
*Type::syntaxCopy()
159 fprintf(stdmsg
, "ty = %d\n", ty
);
164 int Type::equals(Object
*o
)
168 //printf("Type::equals(%s, %s)\n", toChars(), t->toChars());
170 (t
&& deco
== t
->deco
) && // deco strings are unique
171 deco
!= NULL
) // and semantic() has been run
173 //printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
176 //if (deco && t && t->deco) printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
180 char Type::needThisPrefix()
182 return 'M'; // name mangling prefix for functions needing 'this'
189 Lexer::initKeywords();
191 for (i
= 0; i
< TMAX
; i
++)
192 sizeTy
[i
] = sizeof(TypeBasic
);
193 sizeTy
[Tsarray
] = sizeof(TypeSArray
);
194 sizeTy
[Tarray
] = sizeof(TypeDArray
);
195 sizeTy
[Taarray
] = sizeof(TypeAArray
);
196 sizeTy
[Tpointer
] = sizeof(TypePointer
);
197 sizeTy
[Treference
] = sizeof(TypeReference
);
198 sizeTy
[Tfunction
] = sizeof(TypeFunction
);
199 sizeTy
[Tdelegate
] = sizeof(TypeDelegate
);
200 sizeTy
[Tident
] = sizeof(TypeIdentifier
);
201 sizeTy
[Tinstance
] = sizeof(TypeInstance
);
202 sizeTy
[Ttypeof
] = sizeof(TypeTypeof
);
203 sizeTy
[Tenum
] = sizeof(TypeEnum
);
204 sizeTy
[Ttypedef
] = sizeof(TypeTypedef
);
205 sizeTy
[Tstruct
] = sizeof(TypeStruct
);
206 sizeTy
[Tclass
] = sizeof(TypeClass
);
207 sizeTy
[Ttuple
] = sizeof(TypeTuple
);
208 sizeTy
[Tslice
] = sizeof(TypeSlice
);
209 sizeTy
[Treturn
] = sizeof(TypeReturn
);
211 mangleChar
[Tarray
] = 'A';
212 mangleChar
[Tsarray
] = 'G';
213 mangleChar
[Taarray
] = 'H';
214 mangleChar
[Tpointer
] = 'P';
216 // For compat with D libraries, the maybe qualifier gets stripped from
217 // symbol names. In TypeInfo names, it is replaced by 'Q'.
218 mangleChar
[Tmaybe
] = '?';
220 mangleChar
[Treference
] = 'R';
221 mangleChar
[Tfunction
] = 'F';
222 mangleChar
[Tident
] = 'I';
223 mangleChar
[Tclass
] = 'C';
224 mangleChar
[Tstruct
] = 'S';
225 mangleChar
[Tenum
] = 'E';
226 mangleChar
[Ttypedef
] = 'T';
227 mangleChar
[Tdelegate
] = 'D';
229 mangleChar
[Tnone
] = 'n';
230 mangleChar
[Tvoid
] = 'v';
231 mangleChar
[Tint8
] = 'g';
232 mangleChar
[Tuns8
] = 'h';
233 mangleChar
[Tint16
] = 's';
234 mangleChar
[Tuns16
] = 't';
235 mangleChar
[Tint32
] = 'i';
236 mangleChar
[Tuns32
] = 'k';
237 mangleChar
[Tint64
] = 'l';
238 mangleChar
[Tuns64
] = 'm';
239 mangleChar
[Tfloat32
] = 'f';
240 mangleChar
[Tfloat64
] = 'd';
241 mangleChar
[Tfloat80
] = 'e';
243 mangleChar
[Timaginary32
] = 'o';
244 mangleChar
[Timaginary64
] = 'p';
245 mangleChar
[Timaginary80
] = 'j';
246 mangleChar
[Tcomplex32
] = 'q';
247 mangleChar
[Tcomplex64
] = 'r';
248 mangleChar
[Tcomplex80
] = 'c';
250 mangleChar
[Tbool
] = 'b';
251 mangleChar
[Tascii
] = 'a';
252 mangleChar
[Twchar
] = 'u';
253 mangleChar
[Tdchar
] = 'w';
255 mangleChar
[Tbit
] = '@';
256 mangleChar
[Tinstance
] = '@';
257 mangleChar
[Terror
] = '@';
258 mangleChar
[Ttypeof
] = '@';
259 mangleChar
[Ttuple
] = 'B';
260 mangleChar
[Tslice
] = '@';
261 mangleChar
[Treturn
] = '@';
263 for (i
= 0; i
< TMAX
; i
++)
264 { if (!mangleChar
[i
])
265 fprintf(stdmsg
, "ty = %d\n", i
);
266 assert(mangleChar
[i
]);
270 static TY basetab
[] =
271 { Tvoid
, Tint8
, Tuns8
, Tint16
, Tuns16
, Tint32
, Tuns32
, Tint64
, Tuns64
,
272 Tfloat32
, Tfloat64
, Tfloat80
,
273 Timaginary32
, Timaginary64
, Timaginary80
,
274 Tcomplex32
, Tcomplex64
, Tcomplex80
,
276 Tascii
, Twchar
, Tdchar
};
278 for (i
= 0; i
< sizeof(basetab
) / sizeof(basetab
[0]); i
++)
279 { Type
*t
= new TypeBasic(basetab
[i
]);
281 basic
[basetab
[i
]] = t
;
283 basic
[Terror
] = basic
[Tint32
];
285 tvoidptr
= tvoid
->pointerTo();
287 if (global
.params
.isX86_64
)
290 if (global
.params
.isLinux
)
311 CLASSINFO_SIZE
= 18 * PTRSIZE
;
319 d_uns64
Type::size(Loc loc
)
321 error(loc
, "no size for type %s", toChars());
325 unsigned Type::alignsize()
330 Type
*Type::semantic(Loc loc
, Scope
*sc
)
335 /*******************************
336 * Determine if converting 'this' to 'to' is an identity operation,
337 * a conversion to const operation, or the types aren't the same.
339 * MATCHequal 'this' == 'to'
340 * MATCHconst 'to' is const
341 * MATCHnomatch conversion to mutable or invariant
344 MATCH
Type::constConv(Type
*to
)
348 if (ty
== to
->ty
&& to
->mod
== MODconst
)
353 Type
*Type::constOf()
355 //printf("Type::constOf() %p %s\n", this, toChars());
360 Type
*t
= makeConst();
365 //if (t->nextOf()) assert(t->nextOf()->isConst());
366 //printf("-Type::constOf() %p %s\n", t, toChars());
370 Type
*Type::invariantOf()
372 //printf("Type::invariantOf() %p %s\n", this, toChars());
379 //if (!ito->isInvariant()) printf("\tito is %p %s\n", ito, ito->toChars());
380 assert(ito
->isInvariant());
383 Type
*t
= makeInvariant();
388 #if 0 // fails for function types
389 if (t
->nextOf() && !t
->nextOf()->isInvariant())
394 //printf("\t%p\n", t);
398 Type
*Type::mutableOf()
400 //printf("Type::mutableOf() %p, %s\n", this, toChars());
404 assert(!t
|| t
->isMutable());
406 else if (isInvariant())
408 assert(!t
|| t
->isMutable());
412 unsigned sz
= sizeTy
[ty
];
413 t
= (Type
*)mem
.malloc(sz
);
424 { TypeSArray
*ta
= (TypeSArray
*)t
;
425 //ta->next = ta->next->mutableOf();
434 else if (isInvariant())
444 Type
*Type::makeConst()
446 //printf("Type::makeConst() %p, %s\n", this, toChars());
449 unsigned sz
= sizeTy
[ty
];
450 Type
*t
= (Type
*)mem
.malloc(sz
);
460 //printf("-Type::makeConst() %p, %s\n", t, toChars());
464 Type
*Type::makeInvariant()
468 unsigned sz
= sizeTy
[ty
];
469 Type
*t
= (Type
*)mem
.malloc(sz
);
471 t
->mod
= MODinvariant
;
482 /**************************
483 * Return type with the top level of it being mutable.
485 Type
*Type::toHeadMutable()
493 // If this type can be null, wrap it in TypeMaybe.
494 // Otherwise just, returns itself. This is so that
495 // we can try wrapping everything in D source easily.
496 // merge should be false if we haven't yet run semantic
498 Type
*Type::maybe(bool merge
)
505 // For some reason, "void*?" causes problems.
506 // Since it's not type safe anyway, don't worry about it.
507 if (ty
== Tpointer
&& nextOf()->ty
== Tvoid
)
510 if (ty
!= Tpointer
&& ty
!= Tclass
&& ty
!= Tident
)
511 return this; // Can't be null
516 t
= new TypeMaybe(this);
517 if (!merge
|| t
->reliesOnTident())
525 Type
*Type::pointerTo()
530 t
= new TypePointer(this);
536 Type
*Type::referenceTo()
541 t
= new TypeReference(this);
547 Type
*Type::arrayOf()
552 t
= new TypeDArray(this);
553 arrayof
= t
->merge();
558 Dsymbol
*Type::toDsymbol(Scope
*sc
)
563 /*******************************
564 * If this is a shell around another type,
565 * get that other type.
568 Type
*Type::toBasetype()
573 /********************************
576 * flag 0x100 do not do const/invariant
579 void Type::toDecoBuffer(OutBuffer
*buf
, int flag
)
581 if (flag
!= mod
&& flag
!= 0x100)
586 case MODconst
: buf
->writeByte('x'); break;
587 case MODinvariant
: buf
->writeByte('y'); break;
591 buf
->writeByte(mangleChar
[ty
]);
594 /********************************
595 * For pretty-printing a type.
598 char *Type::toChars()
602 buf
= new OutBuffer();
603 toCBuffer(buf
, NULL
, &hgs
);
604 return buf
->toChars();
607 void Type::toCBuffer(OutBuffer
*buf
, Identifier
*ident
, HdrGenState
*hgs
)
609 toCBuffer2(buf
, hgs
, 0);
611 { buf
->writeByte(' ');
612 buf
->writestring(ident
->toChars());
616 void Type::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
618 if (mod
!= this->mod
)
619 { toCBuffer3(buf
, hgs
, mod
);
622 buf
->writestring(toChars());
625 void Type::toCBuffer3(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
627 if (mod
!= this->mod
)
633 toCBuffer2(buf
, hgs
, this->mod
);
640 L1
: buf
->writestring(p
);
641 toCBuffer2(buf
, hgs
, this->mod
);
650 /************************************
655 //printf("merge(%s)\n", toChars());
664 //next = next->merge();
666 sv
= stringtable
.update((char *)buf
.data
, buf
.offset
);
668 { t
= (Type
*) sv
->ptrvalue
;
670 fprintf(stderr
, "nooooooooooooooooooooooo! %s %s\n", toChars(), t
->toChars());
673 //printf("old value, deco = '%s' %p\n", t->deco, t->deco);
678 deco
= sv
->lstring
.string
;
680 fprintf(stderr
, "yeeeeeeeeeeeeeeeeeeeeeeeesss!\n");
683 //printf("new value, deco = '%s' %p\n", t->deco, t->deco);
689 int Type::isintegral()
694 int Type::isfloating()
704 int Type::isimaginary()
709 int Type::iscomplex()
719 int Type::isunsigned()
724 ClassDeclaration
*Type::isClassHandle()
739 /**************************
746 int Type::isAssignable()
751 int Type::checkBoolean()
756 /*********************************
757 * Check type to see if it is based on a deprecated symbol.
760 void Type::checkDeprecated(Loc loc
, Scope
*sc
)
762 Dsymbol
*s
= toDsymbol(sc
);
765 s
->checkDeprecated(loc
, sc
);
769 Expression
*Type::defaultInit(Loc loc
)
772 printf("Type::defaultInit() '%s'\n", toChars());
777 int Type::isZeroInit()
779 return 0; // assume not
782 int Type::isBaseOf(Type
*t
, target_ptrdiff_t
*poffset
)
784 return 0; // assume not
787 /********************************
788 * Determine if 'this' can be implicitly converted
792 * 1 can convert using implicit conversions
793 * 2 this and to are the same type
796 MATCH
Type::implicitConvTo(Type
*to
)
798 //printf("Type::implicitConvTo(this=%p, to=%p)\n", this, to);
804 Expression
*Type::getProperty(Loc loc
, Identifier
*ident
)
808 printf("Type::getProperty(type = '%s', ident = '%s')\n", toChars(), ident
->toChars());
810 if (ident
== Id::__sizeof
)
812 e
= new IntegerExp(loc
, size(loc
), Type::tsize_t
);
814 else if (ident
== Id::size
)
816 error(loc
, ".size property should be replaced with .sizeof");
817 e
= new IntegerExp(loc
, size(loc
), Type::tsize_t
);
819 else if (ident
== Id::alignof
)
821 e
= new IntegerExp(loc
, alignsize(), Type::tsize_t
);
823 else if (ident
== Id::typeinfo
)
825 if (!global
.params
.useDeprecated
)
826 error(loc
, ".typeinfo deprecated, use typeid(type)");
827 e
= getTypeInfo(NULL
);
829 else if (ident
== Id::init
)
832 error(loc
, "void does not have an initializer");
833 e
= defaultInit(loc
);
835 else if (ident
== Id::mangleof
)
838 e
= new StringExp(loc
, deco
, strlen(deco
), 'c');
840 e
= e
->semantic(&sc
);
842 else if (ident
== Id::stringof
)
843 { char *s
= toChars();
844 e
= new StringExp(loc
, s
, strlen(s
), 'c');
846 e
= e
->semantic(&sc
);
850 error(loc
, "no property '%s' for type '%s'", ident
->toChars(), toChars());
851 e
= new IntegerExp(loc
, 1, Type::tint32
);
856 Expression
*Type::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
857 { VarDeclaration
*v
= NULL
;
860 printf("Type::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
862 if (e
->op
== TOKdotvar
)
864 DotVarExp
*dv
= (DotVarExp
*)e
;
865 v
= dv
->var
->isVarDeclaration();
867 else if (e
->op
== TOKvar
)
869 VarExp
*ve
= (VarExp
*)e
;
870 v
= ve
->var
->isVarDeclaration();
874 if (ident
== Id::offset
)
876 if (!global
.params
.useDeprecated
)
877 error(e
->loc
, ".offset deprecated, use .offsetof");
880 else if (ident
== Id::offsetof
)
883 if (v
->storage_class
& STCfield
)
885 e
= new IntegerExp(e
->loc
, v
->offset
, Type::tsize_t
);
889 else if (ident
== Id::init
)
894 if (v
->init
->isVoidInitializer())
895 error(e
->loc
, "%s.init is void", v
->toChars());
898 e
= v
->init
->toExpression();
899 if (e
->op
== TOKassign
|| e
->op
== TOKconstruct
|| e
->op
== TOKblit
)
901 e
= ((AssignExp
*)e
)->e2
;
903 /* Take care of case where we used a 0
904 * to initialize the struct.
906 if (e
->type
== Type::tint32
&&
908 v
->type
->toBasetype()->ty
== Tstruct
)
910 e
= v
->type
->defaultInit(e
->loc
);
913 e
= e
->optimize(WANTvalue
| WANTinterpret
);
914 // if (!e->isConst())
915 // error(loc, ".init cannot be evaluated at compile time");
920 Expression
*ex
= defaultInit(e
->loc
);
924 if (ident
== Id::typeinfo
)
926 if (!global
.params
.useDeprecated
)
927 error(e
->loc
, ".typeinfo deprecated, use typeid(type)");
931 if (ident
== Id::stringof
)
932 { char *s
= e
->toChars();
933 e
= new StringExp(e
->loc
, s
, strlen(s
), 'c');
935 e
= e
->semantic(&sc
);
938 return getProperty(e
->loc
, ident
);
941 unsigned Type::memalign(unsigned salign
)
946 void Type::error(Loc loc
, const char *format
, ...)
949 va_start(ap
, format
);
950 ::verror(loc
, format
, ap
);
954 Identifier
*Type::getTypeInfoIdent(int internal
)
956 // _init_10TypeInfo_%s
963 { buf
.writeByte(mangleChar
[ty
]);
965 buf
.writeByte(mangleChar
[((TypeArray
*)this)->next
->ty
]);
971 name
= (char *)alloca(19 + sizeof(len
) * 3 + len
+ 1);
973 /* Maybe types contain invalid char ?, because they don't appear in
974 * mangled names. Use unused char Q for TypeInfo instead.
976 for (int i
= 0; i
< buf
.offset
; i
++)
978 if (buf
.data
[i
] == '?')
984 sprintf(name
, "_D%dTypeInfo_%s6__initZ", 9 + len
, buf
.data
);
985 if (global
.params
.isWindows
)
986 name
++; // C mangling will add it back in
987 //printf("name = %s\n", name);
988 id
= Lexer::idPool(name
);
992 TypeBasic
*Type::isTypeBasic()
998 void Type::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
1000 //printf("Type::resolve() %s, %d\n", toChars(), ty);
1001 Type
*t
= semantic(loc
, sc
);
1007 /*******************************
1008 * If one of the subtypes of this type is a TypeIdentifier,
1009 * i.e. it's an unresolved type, return that type.
1012 Type
*Type::reliesOnTident()
1017 /********************************
1018 * We've mistakenly parsed this as a type.
1019 * Redo it as an Expression.
1023 Expression
*Type::toExpression()
1028 /***************************************
1029 * Return !=0 if type has pointers that need to
1030 * be scanned by the GC during a collection cycle.
1033 int Type::hasPointers()
1038 /*************************************
1039 * If this is a type of something, return that something.
1042 Type
*Type::nextOf()
1047 /* ============================= TypeNext =========================== */
1049 TypeNext::TypeNext(TY ty
, Type
*next
)
1055 void TypeNext::toDecoBuffer(OutBuffer
*buf
, int flag
)
1057 Type::toDecoBuffer(buf
, flag
);
1058 assert(next
!= this);
1059 //printf("this = %p, ty = %d, next = %p, ty = %d\n", this, this->ty, next, next->ty);
1060 next
->toDecoBuffer(buf
, (flag
& 0x100) ? 0 : mod
);
1063 void TypeNext::checkDeprecated(Loc loc
, Scope
*sc
)
1065 Type::checkDeprecated(loc
, sc
);
1066 next
->checkDeprecated(loc
, sc
);
1070 Type
*TypeNext::reliesOnTident()
1072 return next
->reliesOnTident();
1075 Type
*TypeNext::nextOf()
1080 Type
*TypeNext::makeConst()
1082 //printf("TypeNext::makeConst() %p, %s\n", this, toChars());
1085 TypeNext
*t
= (TypeNext
*)Type::makeConst();
1086 if (ty
!= Tfunction
&& ty
!= Tdelegate
&& next
->deco
&&
1087 !next
->isInvariant())
1088 t
->next
= next
->constOf();
1089 //printf("TypeNext::makeConst() returns %p, %s\n", t, t->toChars());
1093 Type
*TypeNext::makeInvariant()
1095 //printf("TypeNext::makeInvariant() %s\n", toChars());
1097 { assert(ito
->isInvariant());
1100 TypeNext
*t
= (TypeNext
*)Type::makeInvariant();
1101 if (ty
!= Tfunction
&& ty
!= Tdelegate
&& next
->deco
)
1102 { t
->next
= next
->invariantOf();
1107 MATCH
TypeNext::constConv(Type
*to
)
1108 { MATCH m
= Type::constConv(to
);
1110 if (m
== MATCHconst
&&
1111 next
->constConv(((TypeNext
*)to
)->next
) == MATCHnomatch
)
1117 /* ============================= TypeBasic =========================== */
1119 TypeBasic::TypeBasic(TY ty
)
1124 #define TFLAGSintegral 1
1125 #define TFLAGSfloating 2
1126 #define TFLAGSunsigned 4
1127 #define TFLAGSreal 8
1128 #define TFLAGSimaginary 0x10
1129 #define TFLAGScomplex 0x20
1134 case Tvoid
: d
= Token::toChars(TOKvoid
);
1137 case Tint8
: d
= Token::toChars(TOKint8
);
1138 flags
|= TFLAGSintegral
;
1141 case Tuns8
: d
= Token::toChars(TOKuns8
);
1142 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
1145 case Tint16
: d
= Token::toChars(TOKint16
);
1146 flags
|= TFLAGSintegral
;
1149 case Tuns16
: d
= Token::toChars(TOKuns16
);
1150 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
1153 case Tint32
: d
= Token::toChars(TOKint32
);
1154 flags
|= TFLAGSintegral
;
1157 case Tuns32
: d
= Token::toChars(TOKuns32
);
1158 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
1161 case Tfloat32
: d
= Token::toChars(TOKfloat32
);
1162 flags
|= TFLAGSfloating
| TFLAGSreal
;
1165 case Tint64
: d
= Token::toChars(TOKint64
);
1166 flags
|= TFLAGSintegral
;
1169 case Tuns64
: d
= Token::toChars(TOKuns64
);
1170 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
1173 case Tfloat64
: d
= Token::toChars(TOKfloat64
);
1174 flags
|= TFLAGSfloating
| TFLAGSreal
;
1177 case Tfloat80
: d
= Token::toChars(TOKfloat80
);
1178 flags
|= TFLAGSfloating
| TFLAGSreal
;
1181 case Timaginary32
: d
= Token::toChars(TOKimaginary32
);
1182 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
1185 case Timaginary64
: d
= Token::toChars(TOKimaginary64
);
1186 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
1189 case Timaginary80
: d
= Token::toChars(TOKimaginary80
);
1190 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
1193 case Tcomplex32
: d
= Token::toChars(TOKcomplex32
);
1194 flags
|= TFLAGSfloating
| TFLAGScomplex
;
1197 case Tcomplex64
: d
= Token::toChars(TOKcomplex64
);
1198 flags
|= TFLAGSfloating
| TFLAGScomplex
;
1201 case Tcomplex80
: d
= Token::toChars(TOKcomplex80
);
1202 flags
|= TFLAGSfloating
| TFLAGScomplex
;
1205 case Tbool
: d
= "bool";
1206 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
1209 case Tascii
: d
= Token::toChars(TOKchar
);
1210 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
1213 case Twchar
: d
= Token::toChars(TOKwchar
);
1214 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
1217 case Tdchar
: d
= Token::toChars(TOKdchar
);
1218 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
1224 this->flags
= flags
;
1228 Type
*TypeBasic::syntaxCopy()
1230 // No semantic analysis done on basic types, no need to copy
1235 char *TypeBasic::toChars()
1237 return Type::toChars();
1240 void TypeBasic::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
1242 //printf("TypeBasic::toCBuffer2(mod = %d, this->mod = %d)\n", mod, this->mod);
1243 if (mod
!= this->mod
)
1244 { toCBuffer3(buf
, hgs
, mod
);
1247 buf
->writestring(dstring
);
1250 d_uns64
TypeBasic::size(Loc loc
)
1253 //printf("TypeBasic::size()\n");
1257 case Tuns8
: size
= 1; break;
1259 case Tuns16
: size
= 2; break;
1272 size
= REALSIZE
; break;
1278 size
= REALSIZE
* 2; break;
1281 //size = Type::size(); // error message
1285 case Tbool
: size
= 1; break;
1286 case Tascii
: size
= 1; break;
1287 case Twchar
: size
= 2; break;
1288 case Tdchar
: size
= 4; break;
1294 //printf("TypeBasic::size() = %d\n", size);
1298 unsigned TypeBasic::alignsize()
1317 Expression
*TypeBasic::getProperty(Loc loc
, Identifier
*ident
)
1327 //printf("TypeBasic::getProperty('%s')\n", ident->toChars());
1328 if (ident
== Id::max
)
1332 case Tint8
: ivalue
= 0x7F; goto Livalue
;
1333 case Tuns8
: ivalue
= 0xFF; goto Livalue
;
1334 case Tint16
: ivalue
= 0x7FFFUL
; goto Livalue
;
1335 case Tuns16
: ivalue
= 0xFFFFUL
; goto Livalue
;
1336 case Tint32
: ivalue
= 0x7FFFFFFFUL
; goto Livalue
;
1337 case Tuns32
: ivalue
= 0xFFFFFFFFUL
; goto Livalue
;
1338 case Tint64
: ivalue
= 0x7FFFFFFFFFFFFFFFLL
; goto Livalue
;
1339 case Tuns64
: ivalue
= 0xFFFFFFFFFFFFFFFFULL
; goto Livalue
;
1340 case Tbool
: ivalue
= 1; goto Livalue
;
1341 case Tchar
: ivalue
= 0xFF; goto Livalue
;
1342 case Twchar
: ivalue
= 0xFFFFUL
; goto Livalue
;
1343 case Tdchar
: ivalue
= 0x10FFFFUL
; goto Livalue
;
1349 #define FLT_MAX real_t_properties[real_t::Float].maxval;
1350 #define DBL_MAX real_t_properties[real_t::Double].maxval;
1351 #define LDBL_MAX real_t_properties[real_t::LongDouble].maxval;
1352 #define FLT_MIN real_t_properties[real_t::Float].minval;
1353 #define DBL_MIN real_t_properties[real_t::Double].minval;
1354 #define LDBL_MIN real_t_properties[real_t::LongDouble].minval;
1355 #define FLT_DIG real_t_properties[real_t::Float].dig;
1356 #define DBL_DIG real_t_properties[real_t::Double].dig;
1357 #define LDBL_DIG real_t_properties[real_t::LongDouble].dig;
1358 #define FLT_MANT_DIG real_t_properties[real_t::Float].mant_dig;
1359 #define DBL_MANT_DIG real_t_properties[real_t::Double].mant_dig;
1360 #define LDBL_MANT_DIG real_t_properties[real_t::LongDouble].mant_dig;
1361 #define FLT_MAX_10_EXP real_t_properties[real_t::Float].max_10_exp;
1362 #define DBL_MAX_10_EXP real_t_properties[real_t::Double].max_10_exp;
1363 #define LDBL_MAX_10_EXP real_t_properties[real_t::LongDouble].max_10_exp;
1364 #define FLT_MIN_10_EXP real_t_properties[real_t::Float].min_10_exp;
1365 #define DBL_MIN_10_EXP real_t_properties[real_t::Double].min_10_exp;
1366 #define LDBL_MIN_10_EXP real_t_properties[real_t::LongDouble].min_10_exp;
1367 #define FLT_MAX_EXP real_t_properties[real_t::Float].max_exp;
1368 #define DBL_MAX_EXP real_t_properties[real_t::Double].max_exp;
1369 #define LDBL_MAX_EXP real_t_properties[real_t::LongDouble].max_exp;
1370 #define FLT_MIN_EXP real_t_properties[real_t::Float].min_exp;
1371 #define DBL_MIN_EXP real_t_properties[real_t::Double].min_exp;
1372 #define LDBL_MIN_EXP real_t_properties[real_t::LongDouble].min_exp;
1373 #define FLT_EPSILON real_t_properties[real_t::Float].epsilonval;
1374 #define DBL_EPSILON real_t_properties[real_t::Double].epsilonval;
1375 #define LDBL_EPSILON real_t_properties[real_t::LongDouble].epsilonval;
1379 case Tfloat32
: fvalue
= FLT_MAX
; goto Lfvalue
;
1382 case Tfloat64
: fvalue
= DBL_MAX
; goto Lfvalue
;
1385 case Tfloat80
: fvalue
= LDBL_MAX
; goto Lfvalue
;
1388 else if (ident
== Id::min
)
1392 case Tint8
: ivalue
= -128; goto Livalue
;
1393 case Tuns8
: ivalue
= 0; goto Livalue
;
1394 case Tint16
: ivalue
= -32768; goto Livalue
;
1395 case Tuns16
: ivalue
= 0; goto Livalue
;
1396 case Tint32
: ivalue
= -2147483647L - 1; goto Livalue
;
1397 case Tuns32
: ivalue
= 0; goto Livalue
;
1398 case Tint64
: ivalue
= (-9223372036854775807LL-1LL); goto Livalue
;
1399 case Tuns64
: ivalue
= 0; goto Livalue
;
1400 case Tbool
: ivalue
= 0; goto Livalue
;
1401 case Tchar
: ivalue
= 0; goto Livalue
;
1402 case Twchar
: ivalue
= 0; goto Livalue
;
1403 case Tdchar
: ivalue
= 0; goto Livalue
;
1407 case Tfloat32
: fvalue
= FLT_MIN
; goto Lfvalue
;
1410 case Tfloat64
: fvalue
= DBL_MIN
; goto Lfvalue
;
1413 case Tfloat80
: fvalue
= LDBL_MIN
; goto Lfvalue
;
1416 else if (ident
== Id::nan
)
1431 // mode doesn't matter, will be converted in RealExp anyway
1432 fvalue
= real_t::getnan(real_t::LongDouble
);
1434 // gcc nan's have the sign bit set by default, so turn it off
1435 // Need the volatile to prevent gcc from doing incorrect
1436 // constant folding.
1437 volatile d_float80 foo
;
1439 if (signbit(foo
)) // signbit sometimes, not always, set
1440 foo
= -foo
; // turn off sign bit
1443 unsigned long nan
[2]= { 0xFFFFFFFF, 0x7FFFFFFF };
1444 fvalue
= *(double*)nan
;
1452 else if (ident
== Id::infinity
)
1466 fvalue
= real_t::getinfinity();
1470 fvalue
= std::numeric_limits
<long double>::infinity();
1477 else if (ident
== Id::dig
)
1483 case Tfloat32
: ivalue
= FLT_DIG
; goto Lint
;
1486 case Tfloat64
: ivalue
= DBL_DIG
; goto Lint
;
1489 case Tfloat80
: ivalue
= LDBL_DIG
; goto Lint
;
1492 else if (ident
== Id::epsilon
)
1498 case Tfloat32
: fvalue
= FLT_EPSILON
; goto Lfvalue
;
1501 case Tfloat64
: fvalue
= DBL_EPSILON
; goto Lfvalue
;
1504 case Tfloat80
: fvalue
= LDBL_EPSILON
; goto Lfvalue
;
1507 else if (ident
== Id::mant_dig
)
1513 case Tfloat32
: ivalue
= FLT_MANT_DIG
; goto Lint
;
1516 case Tfloat64
: ivalue
= DBL_MANT_DIG
; goto Lint
;
1519 case Tfloat80
: ivalue
= LDBL_MANT_DIG
; goto Lint
;
1522 else if (ident
== Id::max_10_exp
)
1528 case Tfloat32
: ivalue
= FLT_MAX_10_EXP
; goto Lint
;
1531 case Tfloat64
: ivalue
= DBL_MAX_10_EXP
; goto Lint
;
1534 case Tfloat80
: ivalue
= LDBL_MAX_10_EXP
; goto Lint
;
1537 else if (ident
== Id::max_exp
)
1543 case Tfloat32
: ivalue
= FLT_MAX_EXP
; goto Lint
;
1546 case Tfloat64
: ivalue
= DBL_MAX_EXP
; goto Lint
;
1549 case Tfloat80
: ivalue
= LDBL_MAX_EXP
; goto Lint
;
1552 else if (ident
== Id::min_10_exp
)
1558 case Tfloat32
: ivalue
= FLT_MIN_10_EXP
; goto Lint
;
1561 case Tfloat64
: ivalue
= DBL_MIN_10_EXP
; goto Lint
;
1564 case Tfloat80
: ivalue
= LDBL_MIN_10_EXP
; goto Lint
;
1567 else if (ident
== Id::min_exp
)
1573 case Tfloat32
: ivalue
= FLT_MIN_EXP
; goto Lint
;
1576 case Tfloat64
: ivalue
= DBL_MIN_EXP
; goto Lint
;
1579 case Tfloat80
: ivalue
= LDBL_MIN_EXP
; goto Lint
;
1584 return Type::getProperty(loc
, ident
);
1587 e
= new IntegerExp(loc
, ivalue
, this);
1591 if (isreal() || isimaginary())
1592 e
= new RealExp(loc
, fvalue
, this);
1598 //((real_t *)&cvalue)[0] = fvalue;
1599 //((real_t *)&cvalue)[1] = fvalue;
1600 cvalue
= fvalue
+ fvalue
* I
;
1605 //for (int i = 0; i < 20; i++)
1606 // printf("%02x ", ((unsigned char *)&cvalue)[i]);
1608 e
= new ComplexExp(loc
, cvalue
, this);
1613 e
= new IntegerExp(loc
, ivalue
, Type::tint32
);
1617 Expression
*TypeBasic::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
1620 printf("TypeBasic::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
1624 if (ident
== Id::re
)
1628 case Tcomplex32
: t
= tfloat32
; goto L1
;
1629 case Tcomplex64
: t
= tfloat64
; goto L1
;
1630 case Tcomplex80
: t
= tfloat80
; goto L1
;
1632 e
= e
->castTo(sc
, t
);
1640 case Timaginary32
: t
= tfloat32
; goto L2
;
1641 case Timaginary64
: t
= tfloat64
; goto L2
;
1642 case Timaginary80
: t
= tfloat80
; goto L2
;
1644 e
= new RealExp(0, 0, t
);
1648 return Type::getProperty(e
->loc
, ident
);
1651 else if (ident
== Id::im
)
1656 case Tcomplex32
: t
= timaginary32
; t2
= tfloat32
; goto L3
;
1657 case Tcomplex64
: t
= timaginary64
; t2
= tfloat64
; goto L3
;
1658 case Tcomplex80
: t
= timaginary80
; t2
= tfloat80
; goto L3
;
1660 e
= e
->castTo(sc
, t
);
1664 case Timaginary32
: t
= tfloat32
; goto L4
;
1665 case Timaginary64
: t
= tfloat64
; goto L4
;
1666 case Timaginary80
: t
= tfloat80
; goto L4
;
1675 e
= new RealExp(0, 0, this);
1679 return Type::getProperty(e
->loc
, ident
);
1684 return Type::dotExp(sc
, e
, ident
);
1689 Expression
*TypeBasic::defaultInit(Loc loc
)
1690 { integer_t value
= 0;
1693 printf("TypeBasic::defaultInit() '%s'\n", toChars());
1715 return getProperty(loc
, Id::nan
);
1718 error(loc
, "void does not have a default initializer");
1720 return new IntegerExp(loc
, value
, this);
1723 int TypeBasic::isZeroInit()
1744 int TypeBasic::isintegral()
1746 //printf("TypeBasic::isintegral('%s') x%x\n", toChars(), flags);
1747 return flags
& TFLAGSintegral
;
1750 int TypeBasic::isfloating()
1752 return flags
& TFLAGSfloating
;
1755 int TypeBasic::isreal()
1757 return flags
& TFLAGSreal
;
1760 int TypeBasic::isimaginary()
1762 return flags
& TFLAGSimaginary
;
1765 int TypeBasic::iscomplex()
1767 return flags
& TFLAGScomplex
;
1770 int TypeBasic::isunsigned()
1772 return flags
& TFLAGSunsigned
;
1775 int TypeBasic::isscalar()
1777 return flags
& (TFLAGSintegral
| TFLAGSfloating
);
1780 MATCH
TypeBasic::implicitConvTo(Type
*to
)
1782 //printf("TypeBasic::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
1788 return (mod
== to
->mod
) ? MATCHexact
: MATCHconst
;
1791 if (ty
== Tvoid
|| to
->ty
== Tvoid
)
1792 return MATCHnomatch
;
1793 if (1 || global
.params
.Dversion
== 1)
1795 if (to
->ty
== Tbool
)
1796 return MATCHnomatch
;
1800 if (ty
== Tbool
|| to
->ty
== Tbool
)
1801 return MATCHnomatch
;
1803 if (!to
->isTypeBasic())
1804 return MATCHnomatch
;
1806 TypeBasic
*tob
= (TypeBasic
*)to
;
1807 if (flags
& TFLAGSintegral
)
1809 // Disallow implicit conversion of integers to imaginary or complex
1810 if (tob
->flags
& (TFLAGSimaginary
| TFLAGScomplex
))
1811 return MATCHnomatch
;
1813 // If converting to integral
1814 if (0 && global
.params
.Dversion
> 1 && tob
->flags
& TFLAGSintegral
)
1815 { d_uns64 sz
= size(0);
1816 d_uns64 tosz
= tob
->size(0);
1818 /* Can't convert to smaller size or, if same size, change sign
1821 return MATCHnomatch
;
1823 /*if (sz == tosz && (flags ^ tob->flags) & TFLAGSunsigned)
1824 return MATCHnomatch;*/
1827 else if (flags
& TFLAGSfloating
)
1829 // Disallow implicit conversion of floating point to integer
1830 if (tob
->flags
& TFLAGSintegral
)
1831 return MATCHnomatch
;
1833 assert(tob
->flags
& TFLAGSfloating
);
1835 // Disallow implicit conversion from complex to non-complex
1836 if (flags
& TFLAGScomplex
&& !(tob
->flags
& TFLAGScomplex
))
1837 return MATCHnomatch
;
1839 // Disallow implicit conversion of real or imaginary to complex
1840 if (flags
& (TFLAGSreal
| TFLAGSimaginary
) &&
1841 tob
->flags
& TFLAGScomplex
)
1842 return MATCHnomatch
;
1844 // Disallow implicit conversion to-from real and imaginary
1845 if ((flags
& (TFLAGSreal
| TFLAGSimaginary
)) !=
1846 (tob
->flags
& (TFLAGSreal
| TFLAGSimaginary
)))
1847 return MATCHnomatch
;
1849 return MATCHconvert
;
1852 TypeBasic
*TypeBasic::isTypeBasic()
1854 return (TypeBasic
*)this;
1857 /***************************** TypeArray *****************************/
1859 TypeArray::TypeArray(TY ty
, Type
*next
)
1860 : TypeNext(ty
, next
)
1864 Expression
*TypeArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
1866 Type
*n
= this->next
->toBasetype(); // uncover any typedef's
1869 printf("TypeArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
1871 if (ident
== Id::reverse
&& (n
->ty
== Tchar
|| n
->ty
== Twchar
))
1874 FuncDeclaration
*fd
;
1875 Expressions
*arguments
;
1877 static char *name
[2] = { "_adReverseChar", "_adReverseWchar" };
1879 nm
= name
[n
->ty
== Twchar
];
1880 fd
= FuncDeclaration::genCfunc(next
->arrayOf(), nm
, Type::tvoid
->arrayOf());
1881 ec
= new VarExp(0, fd
);
1882 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1883 arguments
= new Expressions();
1885 e
= new CallExp(e
->loc
, ec
, arguments
);
1886 e
->type
= next
->arrayOf();
1888 else if (ident
== Id::sort
&& (n
->ty
== Tchar
|| n
->ty
== Twchar
))
1891 FuncDeclaration
*fd
;
1892 Expressions
*arguments
;
1894 static char *name
[2] = { "_adSortChar", "_adSortWchar" };
1896 nm
= name
[n
->ty
== Twchar
];
1897 fd
= FuncDeclaration::genCfunc(next
->arrayOf(), nm
, Type::tvoid
->arrayOf());
1898 ec
= new VarExp(0, fd
);
1899 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1900 arguments
= new Expressions();
1902 e
= new CallExp(e
->loc
, ec
, arguments
);
1903 e
->type
= next
->arrayOf();
1905 else if (ident
== Id::reverse
|| ident
== Id::dup
|| ident
== Id::idup
)
1908 FuncDeclaration
*fd
;
1909 Expressions
*arguments
;
1910 target_size_t size
= next
->size(e
->loc
);
1914 dup
= (ident
== Id::dup
|| ident
== Id::idup
);
1916 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::adDup
,
1917 Type::typeinfo
->type
, Type::tvoid
->arrayOf());
1919 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::adReverse
,
1920 Type::tvoid
->arrayOf(), Type::tsize_t
);
1921 ec
= new VarExp(0, fd
);
1922 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1923 arguments
= new Expressions();
1925 arguments
->push(getTypeInfo(sc
));
1928 arguments
->push(new IntegerExp(0, size
, Type::tsize_t
));
1929 e
= new CallExp(e
->loc
, ec
, arguments
);
1930 if (ident
== Id::idup
)
1931 { Type
*einv
= next
->invariantOf();
1932 if (next
->implicitConvTo(einv
) < MATCHconst
)
1933 error(e
->loc
, "cannot implicitly convert element type %s to invariant", next
->toChars());
1934 e
->type
= einv
->arrayOf();
1937 e
->type
= next
->mutableOf()->arrayOf();
1939 else if (ident
== Id::sort
)
1942 FuncDeclaration
*fd
;
1943 Expressions
*arguments
;
1945 fd
= FuncDeclaration::genCfunc(tint32
->arrayOf(), "_adSort",
1946 Type::tvoid
->arrayOf(), Type::tvoid
->pointerTo());
1947 ec
= new VarExp(0, fd
);
1948 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1949 arguments
= new Expressions();
1951 arguments
->push(n
->ty
== Tsarray
1952 ? n
->getTypeInfo(sc
) // don't convert to dynamic array
1953 : n
->getInternalTypeInfo(sc
));
1954 e
= new CallExp(e
->loc
, ec
, arguments
);
1955 e
->type
= next
->arrayOf();
1959 e
= Type::dotExp(sc
, e
, ident
);
1966 /***************************** TypeSArray *****************************/
1968 TypeSArray::TypeSArray(Type
*t
, Expression
*dim
)
1969 : TypeArray(Tsarray
, t
)
1971 //printf("TypeSArray(%s)\n", dim->toChars());
1975 Type
*TypeSArray::syntaxCopy()
1977 Type
*t
= next
->syntaxCopy();
1978 Expression
*e
= dim
->syntaxCopy();
1979 t
= new TypeSArray(t
, e
);
1984 d_uns64
TypeSArray::size(Loc loc
)
1988 return Type::size(loc
);
1989 sz
= dim
->toInteger();
1995 if (n
&& (n2
/ n
) != sz
)
2002 error(loc
, "index %"PRIdMAX
" overflow for static array", sz
);
2006 unsigned TypeSArray::alignsize()
2008 return next
->alignsize();
2011 /**************************
2012 * This evaluates exp while setting length to be the number
2013 * of elements in the tuple t.
2015 Expression
*semanticLength(Scope
*sc
, Type
*t
, Expression
*exp
)
2017 if (t
->ty
== Ttuple
)
2018 { ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, (TypeTuple
*)t
);
2019 sym
->parent
= sc
->scopesym
;
2022 exp
= exp
->semantic(sc
);
2027 exp
= exp
->semantic(sc
);
2031 Expression
*semanticLength(Scope
*sc
, TupleDeclaration
*s
, Expression
*exp
)
2033 ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, s
);
2034 sym
->parent
= sc
->scopesym
;
2037 exp
= exp
->semantic(sc
);
2043 void TypeSArray::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
2045 //printf("TypeSArray::resolve() %s\n", toChars());
2046 next
->resolve(loc
, sc
, pe
, pt
, ps
);
2047 //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
2049 { // It's really an index expression
2050 Expression
*e
= new IndexExp(loc
, *pe
, dim
);
2055 TupleDeclaration
*td
= s
->isTupleDeclaration();
2058 ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, td
);
2059 sym
->parent
= sc
->scopesym
;
2062 dim
= dim
->semantic(sc
);
2063 dim
= dim
->optimize(WANTvalue
| WANTinterpret
);
2064 uinteger_t d
= dim
->toUInteger();
2068 if (d
>= td
->objects
->dim
)
2069 { error(loc
, "tuple index %"PRIuMAX
" exceeds %u", d
, td
->objects
->dim
);
2072 Object
*o
= (Object
*)td
->objects
->data
[(size_t)d
];
2073 if (o
->dyncast() == DYNCAST_DSYMBOL
)
2078 if (o
->dyncast() == DYNCAST_EXPRESSION
)
2081 *pe
= (Expression
*)o
;
2085 /* Create a new TupleDeclaration which
2086 * is a slice [d..d+1] out of the old one.
2087 * Do it this way because TemplateInstance::semanticTiargs()
2088 * can handle unresolved Objects this way.
2090 Objects
*objects
= new Objects
;
2092 objects
->data
[0] = o
;
2094 TupleDeclaration
*tds
= new TupleDeclaration(loc
, td
->ident
, objects
);
2103 Type::resolve(loc
, sc
, pe
, pt
, ps
);
2107 Type
*TypeSArray::semantic(Loc loc
, Scope
*sc
)
2109 //printf("TypeSArray::semantic() %s\n", toChars());
2114 next
->resolve(loc
, sc
, &e
, &t
, &s
);
2115 if (dim
&& s
&& s
->isTupleDeclaration())
2116 { TupleDeclaration
*sd
= s
->isTupleDeclaration();
2118 dim
= semanticLength(sc
, sd
, dim
);
2119 dim
= dim
->optimize(WANTvalue
| WANTinterpret
);
2120 uinteger_t d
= dim
->toUInteger();
2122 if (d
>= sd
->objects
->dim
)
2123 { error(loc
, "tuple index %ju exceeds %u", d
, sd
->objects
->dim
);
2124 return Type::terror
;
2126 Object
*o
= (Object
*)sd
->objects
->data
[(size_t)d
];
2127 if (o
->dyncast() != DYNCAST_TYPE
)
2128 { error(loc
, "%s is not a type", toChars());
2129 return Type::terror
;
2135 next
= next
->semantic(loc
,sc
);
2136 if (mod
== MODconst
&& !next
->isInvariant())
2137 next
= next
->constOf();
2138 else if (mod
== MODinvariant
)
2139 next
= next
->invariantOf();
2141 Type
*tbn
= next
->toBasetype();
2146 dim
= semanticLength(sc
, tbn
, dim
);
2148 dim
= dim
->optimize(WANTvalue
| WANTinterpret
);
2149 if (sc
->parameterSpecialization
&& dim
->op
== TOKvar
&&
2150 ((VarExp
*)dim
)->var
->storage_class
& STCtemplateparameter
)
2152 /* It could be a template parameter N which has no value yet:
2153 * template Foo(T : T[N], size_t N);
2157 integer_t d1
= dim
->toInteger();
2158 dim
= dim
->castTo(sc
, tsize_t
);
2159 dim
= dim
->optimize(WANTvalue
);
2160 integer_t d2
= dim
->toInteger();
2165 if (tbn
->isintegral() ||
2166 tbn
->isfloating() ||
2167 tbn
->ty
== Tpointer
||
2168 tbn
->ty
== Tarray
||
2169 tbn
->ty
== Tsarray
||
2170 tbn
->ty
== Taarray
||
2173 /* Only do this for types that don't need to have semantic()
2174 * run on them for the size, since they may be forward referenced.
2180 if (n2
>= 0x1000000) // put a 'reasonable' limit on it
2182 if (n
&& n2
/ n
!= d2
)
2185 error(loc
, "index %"PRIdMAX
" overflow for static array", d1
);
2186 dim
= new IntegerExp(0, 1, tsize_t
);
2193 { // Index the tuple to get the type
2195 TypeTuple
*tt
= (TypeTuple
*)tbn
;
2196 uinteger_t d
= dim
->toUInteger();
2198 if (d
>= tt
->arguments
->dim
)
2199 { error(loc
, "tuple index %"PRIuMAX
" exceeds %u", d
, tt
->arguments
->dim
);
2200 return Type::terror
;
2202 Argument
*arg
= (Argument
*)tt
->arguments
->data
[(size_t)d
];
2207 error(loc
, "can't have array of %s", tbn
->toChars());
2208 tbn
= next
= tint32
;
2212 error(loc
, "cannot have array of auto %s", tbn
->toChars());
2216 void TypeSArray::toDecoBuffer(OutBuffer
*buf
, int flag
)
2218 Type::toDecoBuffer(buf
, flag
);
2220 buf
->printf("%"PRIuMAX
, dim
->toInteger());
2222 /* Note that static arrays are value types, so
2223 * for a parameter, propagate the 0x100 to the next
2224 * level, since for T[4][3], any const should apply to the T,
2227 next
->toDecoBuffer(buf
, (flag
& 0x100) ? flag
: mod
);
2230 void TypeSArray::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2232 if (mod
!= this->mod
)
2233 { toCBuffer3(buf
, hgs
, mod
);
2236 next
->toCBuffer2(buf
, hgs
, this->mod
);
2237 buf
->printf("[%s]", dim
->toChars());
2240 Expression
*TypeSArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2243 printf("TypeSArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
2245 if (ident
== Id::length
)
2249 else if (ident
== Id::ptr
)
2251 e
= e
->castTo(sc
, next
->pointerTo());
2255 e
= TypeArray::dotExp(sc
, e
, ident
);
2260 int TypeSArray::isString()
2262 TY nty
= next
->toBasetype()->ty
;
2263 return nty
== Tchar
|| nty
== Twchar
|| nty
== Tdchar
;
2266 unsigned TypeSArray::memalign(unsigned salign
)
2268 return next
->memalign(salign
);
2271 MATCH
TypeSArray::constConv(Type
*to
)
2273 if (to
->ty
== Tsarray
)
2275 TypeSArray
*tsa
= (TypeSArray
*)to
;
2276 if (!dim
->equals(tsa
->dim
))
2277 return MATCHnomatch
;
2279 return TypeNext::constConv(to
);
2282 MATCH
TypeSArray::implicitConvTo(Type
*to
)
2284 //printf("TypeSArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
2286 if (to
->ty
== Tmaybe
&& to
->nextOf())
2289 // Allow implicit conversion of static array to pointer or dynamic array
2290 if (IMPLICIT_ARRAY_TO_PTR
&& to
->ty
== Tpointer
)
2292 TypePointer
*tp
= (TypePointer
*)to
;
2294 if (next
->mod
!= tp
->next
->mod
&& tp
->next
->mod
!= MODconst
)
2295 return MATCHnomatch
;
2297 if (tp
->next
->ty
== Tvoid
|| next
->constConv(tp
->next
) != MATCHnomatch
)
2299 return MATCHconvert
;
2301 return MATCHnomatch
;
2303 if (to
->ty
== Tarray
)
2304 { target_ptrdiff_t offset
= 0;
2305 TypeDArray
*ta
= (TypeDArray
*)to
;
2307 if (next
->mod
!= ta
->next
->mod
&& ta
->next
->mod
!= MODconst
)
2308 return MATCHnomatch
;
2310 if (next
->equals(ta
->next
) ||
2311 next
->implicitConvTo(ta
->next
) >= MATCHconst
||
2312 (ta
->next
->isBaseOf(next
, &offset
) && offset
== 0) ||
2313 ta
->next
->ty
== Tvoid
)
2314 return MATCHconvert
;
2315 return MATCHnomatch
;
2317 if (to
->ty
== Tsarray
)
2322 TypeSArray
*tsa
= (TypeSArray
*)to
;
2324 if (dim
->equals(tsa
->dim
))
2326 /* Since static arrays are value types, allow
2327 * conversions from const elements to non-const
2328 * ones, just like we allow conversion from const int
2331 MATCH m
= next
->implicitConvTo(tsa
->next
);
2332 if (m
>= MATCHconst
)
2340 return MATCHnomatch
;
2343 Expression
*TypeSArray::defaultInit(Loc loc
)
2346 printf("TypeSArray::defaultInit() '%s'\n", toChars());
2348 return next
->defaultInit(loc
);
2351 int TypeSArray::isZeroInit()
2353 return next
->isZeroInit();
2357 Expression
*TypeSArray::toExpression()
2359 Expression
*e
= next
->toExpression();
2361 { Expressions
*arguments
= new Expressions();
2362 arguments
->push(dim
);
2363 e
= new ArrayExp(dim
->loc
, e
, arguments
);
2368 int TypeSArray::hasPointers()
2370 return next
->hasPointers();
2373 /***************************** TypeDArray *****************************/
2375 TypeDArray::TypeDArray(Type
*t
)
2376 : TypeArray(Tarray
, t
)
2378 //printf("TypeDArray(t = %p)\n", t);
2381 Type
*TypeDArray::syntaxCopy()
2383 Type
*t
= next
->syntaxCopy();
2387 { t
= new TypeDArray(t
);
2393 d_uns64
TypeDArray::size(Loc loc
)
2395 //printf("TypeDArray::size()\n");
2399 unsigned TypeDArray::alignsize()
2401 // A DArray consists of two ptr-sized values, so align it on pointer size
2406 Type
*TypeDArray::semantic(Loc loc
, Scope
*sc
)
2409 tn
= next
->semantic(loc
,sc
);
2410 Type
*tbn
= tn
->toBasetype();
2416 error(loc
, "can't have array of %s", tbn
->toChars());
2421 error(loc
, "cannot have array of auto %s", tn
->toChars());
2423 if (mod
== MODconst
&& !tn
->isInvariant())
2425 else if (mod
== MODinvariant
)
2426 tn
= tn
->invariantOf();
2432 void TypeDArray::toDecoBuffer(OutBuffer
*buf
, int flag
)
2434 Type::toDecoBuffer(buf
, flag
);
2436 next
->toDecoBuffer(buf
, (flag
& 0x100) ? 0 : mod
);
2439 void TypeDArray::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2441 if (mod
!= this->mod
)
2442 { toCBuffer3(buf
, hgs
, mod
);
2445 next
->toCBuffer2(buf
, hgs
, this->mod
);
2446 buf
->writestring("[]");
2449 Expression
*TypeDArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2452 printf("TypeDArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
2454 if (ident
== Id::length
)
2456 if (e
->op
== TOKstring
)
2457 { StringExp
*se
= (StringExp
*)e
;
2459 return new IntegerExp(se
->loc
, se
->len
, Type::tindex
);
2461 e
= new ArrayLengthExp(e
->loc
, e
);
2462 e
->type
= Type::tsize_t
;
2465 else if (ident
== Id::ptr
)
2468 e
= e
->castTo(sc
, next
->pointerTo());
2470 e
= e
->castTo(sc
, next
->pointerTo()->maybe(true));
2475 e
= TypeArray::dotExp(sc
, e
, ident
);
2480 int TypeDArray::isString()
2482 TY nty
= next
->toBasetype()->ty
;
2483 return nty
== Tchar
|| nty
== Twchar
|| nty
== Tdchar
;
2486 MATCH
TypeDArray::implicitConvTo(Type
*to
)
2488 //printf("TypeDArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
2492 if (to
->ty
== Tmaybe
)
2495 // Allow implicit conversion of array to pointer
2496 if (IMPLICIT_ARRAY_TO_PTR
&& to
->ty
== Tpointer
)
2498 TypePointer
*tp
= (TypePointer
*)to
;
2500 /* Allow conversion to void*
2502 if (tp
->next
->ty
== Tvoid
&&
2503 (next
->mod
== tp
->next
->mod
|| tp
->next
->mod
== MODconst
))
2505 return MATCHconvert
;
2508 return next
->constConv(to
);
2511 if (to
->ty
== Tarray
)
2512 { target_ptrdiff_t offset
= 0;
2513 TypeDArray
*ta
= (TypeDArray
*)to
;
2515 if (!(next
->mod
== ta
->next
->mod
|| ta
->next
->mod
== MODconst
))
2516 return MATCHnomatch
; // not const-compatible
2518 /* Allow conversion to void[]
2520 if (next
->ty
!= Tvoid
&& ta
->next
->ty
== Tvoid
)
2522 return MATCHconvert
;
2525 MATCH m
= next
->constConv(ta
->next
);
2526 if (m
!= MATCHnomatch
)
2528 if (m
== MATCHexact
&& mod
!= to
->mod
)
2533 /* Allow conversions of T[][] to const(T)[][]
2535 if (mod
== ta
->mod
&& next
->ty
== Tarray
&& ta
->next
->ty
== Tarray
)
2537 m
= next
->implicitConvTo(ta
->next
);
2538 if (m
== MATCHconst
)
2542 /* Conversion of array of derived to array of base
2544 if (ta
->next
->isBaseOf(next
, &offset
) && offset
== 0)
2545 return MATCHconvert
;
2547 return Type::implicitConvTo(to
);
2550 Expression
*TypeDArray::defaultInit(Loc loc
)
2553 printf("TypeDArray::defaultInit() '%s'\n", toChars());
2556 e
= new NullExp(loc
);
2561 int TypeDArray::isZeroInit()
2566 int TypeDArray::checkBoolean()
2571 int TypeDArray::hasPointers()
2576 /***************************** TypeAArray *****************************/
2578 TypeAArray::TypeAArray(Type
*t
, Type
*index
)
2579 : TypeArray(Taarray
, t
)
2581 this->index
= index
;
2584 Type
*TypeAArray::syntaxCopy()
2586 Type
*t
= next
->syntaxCopy();
2587 Type
*ti
= index
->syntaxCopy();
2588 if (t
== next
&& ti
== index
)
2591 { t
= new TypeAArray(t
, ti
);
2597 d_uns64
TypeAArray::size(Loc loc
)
2599 return PTRSIZE
/* * 2*/;
2603 Type
*TypeAArray::semantic(Loc loc
, Scope
*sc
)
2605 //printf("TypeAArray::semantic() %s index->ty = %d\n", toChars(), index->ty);
2607 // Deal with the case where we thought the index was a type, but
2608 // in reality it was an expression.
2609 if (index
->ty
== Tident
|| index
->ty
== Tinstance
|| index
->ty
== Tsarray
)
2615 index
->resolve(loc
, sc
, &e
, &t
, &s
);
2617 { // It was an expression -
2618 // Rewrite as a static array
2621 tsa
= new TypeSArray(next
, e
);
2622 return tsa
->semantic(loc
,sc
);
2627 index
->error(loc
, "index is not a type or an expression");
2630 index
= index
->semantic(loc
,sc
);
2632 if (index
->nextOf() && !index
->nextOf()->isInvariant())
2634 index
= index
->constOf()->mutableOf();
2637 switch (index
->toBasetype()->ty
)
2643 error(loc
, "can't have associative array key of %s", index
->toBasetype()->toChars());
2646 next
= next
->semantic(loc
,sc
);
2647 if (mod
== MODconst
&& !next
->isInvariant())
2648 next
= next
->constOf();
2649 else if (mod
== MODinvariant
)
2650 next
= next
->invariantOf();
2652 switch (next
->toBasetype()->ty
)
2656 error(loc
, "can't have associative array of %s", next
->toChars());
2660 error(loc
, "cannot have array of auto %s", next
->toChars());
2665 void TypeAArray::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
2667 //printf("TypeAArray::resolve() %s\n", toChars());
2669 // Deal with the case where we thought the index was a type, but
2670 // in reality it was an expression.
2671 if (index
->ty
== Tident
|| index
->ty
== Tinstance
|| index
->ty
== Tsarray
)
2677 index
->resolve(loc
, sc
, &e
, &t
, &s
);
2679 { // It was an expression -
2680 // Rewrite as a static array
2682 TypeSArray
*tsa
= new TypeSArray(next
, e
);
2683 return tsa
->resolve(loc
, sc
, pe
, pt
, ps
);
2688 index
->error(loc
, "index is not a type or an expression");
2690 Type::resolve(loc
, sc
, pe
, pt
, ps
);
2694 Expression
*TypeAArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2697 printf("TypeAArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
2699 if (ident
== Id::length
)
2702 FuncDeclaration
*fd
;
2703 Expressions
*arguments
;
2705 fd
= FuncDeclaration::genCfunc(Type::tsize_t
, Id::aaLen
, Type::tvoid
->arrayOf());
2706 ec
= new VarExp(0, fd
);
2707 arguments
= new Expressions();
2709 e
= new CallExp(e
->loc
, ec
, arguments
);
2710 e
->type
= ((TypeFunction
*)fd
->type
)->next
;
2712 else if (ident
== Id::keys
)
2715 FuncDeclaration
*fd
;
2716 Expressions
*arguments
;
2717 int size
= index
->size(e
->loc
);
2720 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::aaKeys
,
2721 Type::tvoid
->arrayOf(), Type::tsize_t
);
2722 ec
= new VarExp(0, fd
);
2723 arguments
= new Expressions();
2725 arguments
->push(new IntegerExp(0, size
, Type::tsize_t
));
2726 e
= new CallExp(e
->loc
, ec
, arguments
);
2727 e
->type
= index
->arrayOf();
2729 else if (ident
== Id::values
)
2732 FuncDeclaration
*fd
;
2733 Expressions
*arguments
;
2735 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::aaValues
,
2736 Type::tvoid
->arrayOf(), Type::tsize_t
, Type::tsize_t
);
2737 ec
= new VarExp(0, fd
);
2738 arguments
= new Expressions();
2740 size_t keysize
= index
->size(e
->loc
);
2741 keysize
= (keysize
+ (PTRSIZE
-1)) & ~(PTRSIZE
-1);
2742 arguments
->push(new IntegerExp(0, keysize
, Type::tsize_t
));
2743 arguments
->push(new IntegerExp(0, next
->size(e
->loc
), Type::tsize_t
));
2744 e
= new CallExp(e
->loc
, ec
, arguments
);
2745 e
->type
= next
->arrayOf();
2747 else if (ident
== Id::rehash
)
2750 FuncDeclaration
*fd
;
2751 Expressions
*arguments
;
2753 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::aaRehash
);
2754 ec
= new VarExp(0, fd
);
2755 arguments
= new Expressions();
2756 arguments
->push(e
->addressOf(sc
));
2757 arguments
->push(index
->getInternalTypeInfo(sc
));
2758 e
= new CallExp(e
->loc
, ec
, arguments
);
2763 e
= Type::dotExp(sc
, e
, ident
);
2768 void TypeAArray::toDecoBuffer(OutBuffer
*buf
, int flag
)
2770 Type::toDecoBuffer(buf
, flag
);
2771 index
->toDecoBuffer(buf
);
2772 next
->toDecoBuffer(buf
, (flag
& 0x100) ? 0 : mod
);
2775 void TypeAArray::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2777 if (mod
!= this->mod
)
2778 { toCBuffer3(buf
, hgs
, mod
);
2781 next
->toCBuffer2(buf
, hgs
, this->mod
);
2782 buf
->writeByte('[');
2783 index
->toCBuffer2(buf
, hgs
, 0);
2784 buf
->writeByte(']');
2787 Expression
*TypeAArray::defaultInit(Loc loc
)
2790 printf("TypeAArray::defaultInit() '%s'\n", toChars());
2793 e
= new NullExp(loc
);
2798 int TypeAArray::checkBoolean()
2803 int TypeAArray::hasPointers()
2808 MATCH
TypeAArray::implicitConvTo(Type
*to
)
2810 //printf("TypeAArray::implicitConvTo(to = %s) this = %s\n", to->toChars(), toChars());
2813 if (to
->ty
== Taarray
)
2814 { TypeAArray
*ta
= (TypeAArray
*)to
;
2816 if (!(next
->mod
== ta
->next
->mod
|| ta
->next
->mod
== MODconst
))
2817 return MATCHnomatch
; // not const-compatible
2819 if (!(index
->mod
== ta
->index
->mod
|| ta
->index
->mod
== MODconst
))
2820 return MATCHnomatch
; // not const-compatible
2822 MATCH m
= next
->constConv(ta
->next
);
2823 MATCH mi
= index
->constConv(ta
->index
);
2824 if (m
!= MATCHnomatch
&& mi
!= MATCHnomatch
)
2826 if (m
== MATCHexact
&& mod
!= to
->mod
)
2833 return Type::implicitConvTo(to
);
2836 MATCH
TypeAArray::constConv(Type
*to
)
2838 if (to
->ty
== Taarray
)
2840 TypeAArray
*taa
= (TypeAArray
*)to
;
2841 MATCH mindex
= index
->constConv(taa
->index
);
2842 MATCH mkey
= next
->constConv(taa
->next
);
2843 // Pick the worst match
2844 return mkey
< mindex
? mkey
: mindex
;
2847 return Type::constConv(to
);
2850 /***************************** TypeMaybe *****************************/
2852 TypeMaybe::TypeMaybe(Type
*t
)
2853 : TypeNext(Tmaybe
, t
)
2857 Type
*TypeMaybe::syntaxCopy()
2859 Type
*t
= next
->syntaxCopy();
2863 t
= new TypeMaybe(t
);
2867 Type
*TypeMaybe::toBasetype()
2869 return next
->toBasetype();
2872 Expression
*TypeMaybe::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2874 if (sc
->module
->isDltFile
)
2875 e
->error("attempt to access property '%s' for '%s' of type '%s', which may be null.",
2876 ident
->string
, e
->toChars(), toChars());
2877 // else it came from D - ignore any problems since we can't check
2878 return next
->dotExp(sc
, e
, ident
);
2881 Type
*TypeMaybe::semantic(Loc loc
, Scope
*sc
)
2883 //printf("TypeMaybe::semantic()\n");
2884 Type
*n
= next
->semantic(loc
, sc
);
2889 if (n
->nextOf()->ty
== Tvoid
)
2895 error(loc
, "can't have maybe for %s of type %d", n
->toChars(), n
->toBasetype()->ty
);
2904 d_uns64
TypeMaybe::size(Loc loc
)
2906 return next
->size();
2909 void TypeMaybe::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2911 //printf("TypeMaybe::toCBuffer2() next = %d\n", next->ty);
2912 if (mod
!= this->mod
)
2913 { toCBuffer3(buf
, hgs
, mod
);
2916 next
->toCBuffer2(buf
, hgs
, this->mod
);
2917 buf
->writeByte('?');
2920 MATCH
TypeMaybe::implicitConvTo(Type
*to
)
2922 //printf("TypeMaybe::implicitConvTo(%s)\n", to->toChars());
2927 if (to
->ty
== Tmaybe
)
2929 // Allow (Subclass?) -> (ParentClass?)
2930 return next
->implicitConvTo(to
->nextOf());
2933 // Deny (Subclass?) -> (ParentClass)
2934 // (Subclass) -> (ParentClass?) handled in TypeClass
2936 // Can always convert Foo*? to void*
2937 if (to
->ty
== Tpointer
&& to
->nextOf())
2939 if (to
->nextOf()->ty
== Tvoid
)
2940 return MATCHconvert
;
2943 return MATCHnomatch
;
2946 int TypeMaybe::isscalar()
2948 return next
->isscalar();
2951 Expression
*TypeMaybe::defaultInit(Loc loc
)
2954 printf("TypeMaybe::defaultInit() '%s'\n", toChars());
2956 return next
->defaultInit();
2959 int TypeMaybe::isZeroInit()
2961 return next
->isZeroInit();
2964 int TypeMaybe::hasPointers()
2966 return next
->hasPointers();
2969 int TypeMaybe::checkBoolean()
2974 /***************************** TypePointer *****************************/
2976 TypePointer::TypePointer(Type
*t
)
2977 : TypeNext(Tpointer
, t
)
2981 Type
*TypePointer::syntaxCopy()
2983 Type
*t
= next
->syntaxCopy();
2987 { t
= new TypePointer(t
);
2993 Type
*TypePointer::semantic(Loc loc
, Scope
*sc
)
2995 //printf("TypePointer::semantic()\n");
2996 Type
*n
= next
->semantic(loc
, sc
);
2997 switch (n
->toBasetype()->ty
)
3000 error(loc
, "can't have pointer to %s", n
->toChars());
3007 if (mod
== MODconst
&& !next
->isInvariant())
3008 next
= next
->constOf();
3009 else if (mod
== MODinvariant
)
3010 next
= next
->invariantOf();
3015 d_uns64
TypePointer::size(Loc loc
)
3020 void TypePointer::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3022 //printf("TypePointer::toCBuffer2() next = %d\n", next->ty);
3023 if (mod
!= this->mod
)
3024 { toCBuffer3(buf
, hgs
, mod
);
3027 next
->toCBuffer2(buf
, hgs
, this->mod
);
3028 if (next
->ty
!= Tfunction
)
3029 buf
->writeByte('*');
3032 MATCH
TypePointer::implicitConvTo(Type
*to
)
3034 //printf("TypePointer::implicitConvTo(to = %s) %s\n", to->toChars(), toChars());
3039 // Can always convert a "Foo*" to a "Foo*?"
3040 if (to
->ty
== Tmaybe
)
3043 if (to
->ty
== Tpointer
)
3044 { TypePointer
*tp
= (TypePointer
*)to
;
3047 if (!(next
->mod
== tp
->next
->mod
|| tp
->next
->mod
== MODconst
))
3048 return MATCHnomatch
; // not const-compatible
3050 /* Alloc conversion to void[]
3052 if (next
->ty
!= Tvoid
&& tp
->next
->ty
== Tvoid
)
3054 return MATCHconvert
;
3057 MATCH m
= next
->constConv(tp
->next
);
3058 if (m
!= MATCHnomatch
)
3060 if (m
== MATCHexact
&& mod
!= to
->mod
)
3065 /* Conversion of ptr to derived to ptr to base
3067 target_ptrdiff_t offset
= 0;
3068 if (tp
->next
->isBaseOf(next
, &offset
) && offset
== 0)
3069 return MATCHconvert
;
3071 return MATCHnomatch
;
3074 int TypePointer::isscalar()
3079 Expression
*TypePointer::defaultInit(Loc loc
)
3082 printf("TypePointer::defaultInit() '%s'\n", toChars());
3085 e
= new NullExp(loc
);
3090 int TypePointer::isZeroInit()
3095 int TypePointer::hasPointers()
3101 /***************************** TypeReference *****************************/
3103 TypeReference::TypeReference(Type
*t
)
3104 : TypeNext(Treference
, t
)
3106 // BUG: what about references to static arrays?
3109 Type
*TypeReference::syntaxCopy()
3111 Type
*t
= next
->syntaxCopy();
3115 { t
= new TypeReference(t
);
3121 Type
*TypeReference::semantic(Loc loc
, Scope
*sc
)
3123 //printf("TypeReference::semantic()\n");
3124 Type
*n
= next
->semantic(loc
, sc
);
3128 if (mod
== MODconst
&& !next
->isInvariant())
3129 next
= next
->constOf();
3130 else if (mod
== MODinvariant
)
3131 next
= next
->invariantOf();
3136 d_uns64
TypeReference::size(Loc loc
)
3141 void TypeReference::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3143 if (mod
!= this->mod
)
3144 { toCBuffer3(buf
, hgs
, mod
);
3147 next
->toCBuffer2(buf
, hgs
, this->mod
);
3148 buf
->writeByte('&');
3151 Expression
*TypeReference::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
3154 printf("TypeReference::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
3157 // References just forward things along
3158 return next
->dotExp(sc
, e
, ident
);
3161 Expression
*TypeReference::defaultInit(Loc loc
)
3164 printf("TypeReference::defaultInit() '%s'\n", toChars());
3167 e
= new NullExp(loc
);
3172 int TypeReference::isZeroInit()
3178 /***************************** TypeFunction *****************************/
3180 TypeFunction::TypeFunction(Arguments
*parameters
, Type
*treturn
, int varargs
, enum LINK linkage
)
3181 : TypeNext(Tfunction
, treturn
)
3183 //if (!treturn) *(char*)0=0;
3185 this->parameters
= parameters
;
3186 this->varargs
= varargs
;
3187 this->linkage
= linkage
;
3189 this->isnothrow
= false;
3190 this->ispure
= false;
3193 Type
*TypeFunction::syntaxCopy()
3195 Type
*treturn
= next
? next
->syntaxCopy() : NULL
;
3196 Arguments
*params
= Argument::arraySyntaxCopy(parameters
);
3197 TypeFunction
*t
= new TypeFunction(params
, treturn
, varargs
, linkage
);
3199 t
->isnothrow
= isnothrow
;
3204 /*******************************
3206 * 0 types are distinct
3207 * 1 this is covariant with t
3208 * 2 arguments match as far as overloading goes,
3209 * but types are not covariant
3210 * 3 cannot determine covariance because of forward references
3213 int Type::covariant(Type
*t
)
3216 printf("Type::covariant(t = %s) %s\n", t
->toChars(), toChars());
3217 printf("deco = %p, %p\n", deco
, t
->deco
);
3218 //printf("ty = %d\n", next->ty);
3221 int inoutmismatch
= 0;
3225 if (ty
!= Tfunction
|| t
->ty
!= Tfunction
)
3229 TypeFunction
*t1
= (TypeFunction
*)this;
3230 TypeFunction
*t2
= (TypeFunction
*)t
;
3232 if (t1
->varargs
!= t2
->varargs
)
3235 /* Can convert pure to impure, and nothrow to throw
3237 if (!t1
->ispure
&& t2
->ispure
)
3240 if (!t1
->isnothrow
&& t2
->isnothrow
)
3243 if (t1
->parameters
&& t2
->parameters
)
3245 size_t dim
= Argument::dim(t1
->parameters
);
3246 if (dim
!= Argument::dim(t2
->parameters
))
3249 for (size_t i
= 0; i
< dim
; i
++)
3250 { Argument
*arg1
= Argument::getNth(t1
->parameters
, i
);
3251 Argument
*arg2
= Argument::getNth(t2
->parameters
, i
);
3253 if (!arg1
->type
->equals(arg2
->type
))
3255 if (arg1
->storageClass
!= arg2
->storageClass
)
3259 else if (t1
->parameters
!= t2
->parameters
)
3262 // The argument lists match
3265 if (t1
->linkage
!= t2
->linkage
)
3269 Type
*t1n
= t1
->next
;
3270 Type
*t2n
= t2
->next
;
3272 if (t1n
->equals(t2n
))
3275 if (t2n
->ty
== Tmaybe
)
3277 t2n
= t2n
->nextOf(); // Foo -> Foo? is OK
3278 if (t1n
->ty
== Tmaybe
)
3279 t1n
= t1n
->nextOf(); // Foo? -> Foo? is OK
3282 if (t1n
->ty
== Tclass
&& t2n
->ty
== Tclass
)
3284 /* If same class type, but t2n is const, then it's
3285 * covariant. Do this test first because it can work on
3286 * forward references.
3288 if (((TypeClass
*)t1n
)->sym
== ((TypeClass
*)t2n
)->sym
&&
3289 t2n
->mod
== MODconst
)
3292 // If t1n is forward referenced:
3293 ClassDeclaration
*cd
= ((TypeClass
*)t1n
)->sym
;
3294 if (!cd
->baseClass
&& cd
->baseclasses
.dim
&& !cd
->isInterfaceDeclaration())
3299 if (t1n
->implicitConvTo(t2n
))
3305 //printf("\tcovaraint: 1\n");
3309 //printf("\tcovaraint: 0\n");
3313 //printf("\tcovaraint: 2\n");
3317 void TypeFunction::toDecoBuffer(OutBuffer
*buf
, int flag
)
3320 //printf("TypeFunction::toDecoBuffer() this = %p %s\n", this, toChars());
3321 //static int nest; if (++nest == 50) *(char*)0=0;
3323 { inuse
= 2; // flag error to caller
3328 if (mod
== MODconst
)
3329 buf
->writeByte('x');
3330 else if (mod
== MODinvariant
)
3331 buf
->writeByte('y');
3335 case LINKd
: mc
= 'F'; break;
3336 case LINKc
: mc
= 'U'; break;
3337 case LINKwindows
: mc
= 'W'; break;
3338 case LINKpascal
: mc
= 'V'; break;
3339 case LINKcpp
: mc
= 'R'; break;
3340 case LINKgobject
: mc
= 'O'; break;
3345 if (ispure
|| isnothrow
)
3346 { buf
->writeByte('N');
3347 buf
->writeByte(ispure
? 'a' : 'b');
3349 // Write argument types
3350 Argument::argsToDecoBuffer(buf
, parameters
);
3351 //if (buf->data[buf->offset - 1] == '@') halt();
3352 buf
->writeByte('Z' - varargs
); // mark end of arg list
3353 next
->toDecoBuffer(buf
);
3357 void TypeFunction::toCBuffer(OutBuffer
*buf
, Identifier
*ident
, HdrGenState
*hgs
)
3359 //printf("TypeFunction::toCBuffer() this = %p %s\n", this, toChars());
3363 { inuse
= 2; // flag error to caller
3368 /* Use 'storage class' style for attributes
3375 buf
->writestring("const ");
3378 buf
->writestring("invariant ");
3385 buf
->writestring("pure ");
3387 buf
->writestring("pure ");
3389 if (next
&& (!ident
|| ident
->toHChars2() == ident
->toChars()))
3390 next
->toCBuffer2(buf
, hgs
, 0);
3395 case LINKd
: p
= NULL
; break;
3396 case LINKc
: p
= "C "; break;
3397 case LINKwindows
: p
= "Windows "; break;
3398 case LINKpascal
: p
= "Pascal "; break;
3399 case LINKcpp
: p
= "C++ "; break;
3405 if (!hgs
->hdrgen
&& p
)
3406 buf
->writestring(p
);
3408 { buf
->writeByte(' ');
3409 buf
->writestring(ident
->toHChars2());
3411 Argument::argsToCBuffer(buf
, hgs
, parameters
, varargs
);
3415 void TypeFunction::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3417 //printf("TypeFunction::toCBuffer2() this = %p %s\n", this, toChars());
3421 { inuse
= 2; // flag error to caller
3426 next
->toCBuffer2(buf
, hgs
, 0);
3431 case LINKd
: p
= NULL
; break;
3432 case LINKc
: p
= "C "; break;
3433 case LINKwindows
: p
= "Windows "; break;
3434 case LINKpascal
: p
= "Pascal "; break;
3435 case LINKcpp
: p
= "C++ "; break;
3441 if (!hgs
->hdrgen
&& p
)
3442 buf
->writestring(p
);
3443 buf
->writestring(" function");
3444 Argument::argsToCBuffer(buf
, hgs
, parameters
, varargs
);
3446 /* Use postfix style for attributes
3448 if (mod
!= this->mod
)
3455 buf
->writestring(" const");
3458 buf
->writestring(" invariant");
3466 buf
->writestring(" pure");
3468 buf
->writestring(" pure");
3473 Type
*TypeFunction::semantic(Loc loc
, Scope
*sc
)
3475 if (deco
) // if semantic() already run
3477 //printf("already done\n");
3480 //printf("TypeFunction::semantic() this = %p\n", this);
3482 TypeFunction
*tf
= (TypeFunction
*)mem
.malloc(sizeof(TypeFunction
));
3483 memcpy(tf
, this, sizeof(TypeFunction
));
3485 { tf
->parameters
= (Arguments
*)parameters
->copy();
3486 for (size_t i
= 0; i
< parameters
->dim
; i
++)
3487 { Argument
*arg
= (Argument
*)parameters
->data
[i
];
3488 Argument
*cpy
= (Argument
*)mem
.malloc(sizeof(Argument
));
3489 memcpy(cpy
, arg
, sizeof(Argument
));
3490 tf
->parameters
->data
[i
] = (void *)cpy
;
3494 tf
->linkage
= sc
->linkage
;
3497 assert(global
.errors
);
3500 tf
->next
= tf
->next
->semantic(loc
,sc
);
3501 if (tf
->next
->toBasetype()->ty
== Tsarray
)
3502 { error(loc
, "functions cannot return static array %s", tf
->next
->toChars());
3503 tf
->next
= Type::terror
;
3505 if (tf
->next
->toBasetype()->ty
== Tfunction
)
3506 { error(loc
, "functions cannot return a function");
3507 tf
->next
= Type::terror
;
3509 if (tf
->next
->toBasetype()->ty
== Ttuple
)
3510 { error(loc
, "functions cannot return a tuple");
3511 tf
->next
= Type::terror
;
3513 if (tf
->next
->isauto() && !(sc
->flags
& SCOPEctor
))
3514 error(loc
, "functions cannot return auto %s", tf
->next
->toChars());
3517 { size_t dim
= Argument::dim(tf
->parameters
);
3519 for (size_t i
= 0; i
< dim
; i
++)
3520 { Argument
*arg
= Argument::getNth(tf
->parameters
, i
);
3524 arg
->type
= arg
->type
->semantic(loc
,sc
);
3525 if (tf
->inuse
== 1) tf
->inuse
--;
3527 if (arg
->storageClass
& (STCconst
| STCin
))
3529 if (!arg
->type
->isInvariant())
3530 arg
->type
= arg
->type
->constOf();
3532 else if (arg
->storageClass
& STCinvariant
)
3533 arg
->type
= arg
->type
->invariantOf();
3535 t
= arg
->type
->toBasetype();
3537 if (arg
->storageClass
& (STCout
| STCref
| STClazy
))
3539 if (t
->ty
== Tsarray
)
3540 error(loc
, "cannot have out or ref parameter of type %s", t
->toChars());
3541 if (arg
->storageClass
& STCout
&& arg
->type
->mod
)
3542 error(loc
, "cannot have const/invariant out parameter of type %s", t
->toChars());
3544 if (!(arg
->storageClass
& STClazy
) && t
->ty
== Tvoid
)
3545 error(loc
, "cannot have parameter of type %s", arg
->type
->toChars());
3547 if (arg
->defaultArg
)
3549 arg
->defaultArg
= arg
->defaultArg
->semantic(sc
);
3550 arg
->defaultArg
= resolveProperties(sc
, arg
->defaultArg
);
3551 arg
->defaultArg
= arg
->defaultArg
->implicitCastTo(sc
, arg
->type
);
3554 /* If arg turns out to be a tuple, the number of parameters may
3557 if (t
->ty
== Ttuple
)
3558 { dim
= Argument::dim(tf
->parameters
);
3563 tf
->deco
= tf
->merge()->deco
;
3566 { error(loc
, "recursive type");
3571 if (tf
->varargs
== 1 && tf
->linkage
!= LINKd
&& Argument::dim(tf
->parameters
) == 0)
3572 error(loc
, "variadic functions with non-D linkage must have at least one parameter");
3574 /* Don't return merge(), because arg identifiers and default args
3576 * even though the types match
3581 /********************************
3582 * 'args' are being matched to function 'this'
3583 * Determine match level.
3588 int TypeFunction::callMatch(Expression
*ethis
, Expressions
*args
)
3590 //printf("TypeFunction::callMatch() %s\n", toChars());
3591 MATCH match
= MATCHexact
; // assume exact match
3594 { Type
*t
= ethis
->type
;
3595 if (t
->toBasetype()->ty
== Tpointer
)
3596 t
= t
->toBasetype()->nextOf(); // change struct* to struct
3599 if (mod
== MODconst
)
3602 return MATCHnomatch
;
3606 size_t nparams
= Argument::dim(parameters
);
3607 size_t nargs
= args
? args
->dim
: 0;
3608 if (nparams
== nargs
)
3610 else if (nargs
> nparams
)
3613 goto Nomatch
; // too many args; no match
3614 match
= MATCHconvert
; // match ... with a "conversion" match level
3617 for (size_t u
= 0; u
< nparams
; u
++)
3621 // BUG: what about out and ref?
3623 Argument
*p
= Argument::getNth(parameters
, u
);
3629 if (varargs
== 2 && u
+ 1 == nparams
)
3631 goto Nomatch
; // not enough arguments
3633 arg
= (Expression
*)args
->data
[u
];
3635 if (p
->storageClass
& STClazy
&& p
->type
->ty
== Tvoid
&&
3636 arg
->type
->ty
!= Tvoid
)
3639 m
= arg
->implicitConvTo(p
->type
);
3640 //printf("\tm = %d\n", m);
3641 if (m
== MATCHnomatch
) // if no match
3644 if (varargs
== 2 && u
+ 1 == nparams
) // if last varargs param
3645 { Type
*tb
= p
->type
->toBasetype();
3652 tsa
= (TypeSArray
*)tb
;
3653 sz
= tsa
->dim
->toInteger();
3654 if (sz
!= nargs
- u
)
3657 { TypeArray
*ta
= (TypeArray
*)tb
;
3658 for (; u
< nargs
; u
++)
3660 arg
= (Expression
*)args
->data
[u
];
3663 /* If lazy array of delegates,
3664 * convert arg(s) to delegate(s)
3666 Type
*tret
= p
->isLazyArray();
3669 if (ta
->next
->equals(arg
->type
))
3674 m
= arg
->implicitConvTo(tret
);
3675 if (m
== MATCHnomatch
)
3677 if (tret
->toBasetype()->ty
== Tvoid
)
3683 m
= arg
->implicitConvTo(ta
->next
);
3685 m
= arg
->implicitConvTo(ta
->next
);
3687 if (m
== MATCHnomatch
)
3695 // Should see if there's a constructor match?
3696 // Or just leave it ambiguous?
3706 match
= m
; // pick worst match
3710 //printf("match = %d\n", match);
3714 //printf("no match\n");
3715 return MATCHnomatch
;
3718 Type
*TypeFunction::reliesOnTident()
3722 for (size_t i
= 0; i
< parameters
->dim
; i
++)
3723 { Argument
*arg
= (Argument
*)parameters
->data
[i
];
3724 Type
*t
= arg
->type
->reliesOnTident();
3729 return next
->reliesOnTident();
3732 /***************************** TypeDelegate *****************************/
3734 TypeDelegate::TypeDelegate(Type
*t
)
3735 : TypeNext(Tfunction
, t
)
3740 Type
*TypeDelegate::syntaxCopy()
3742 Type
*t
= next
->syntaxCopy();
3746 { t
= new TypeDelegate(t
);
3752 Type
*TypeDelegate::semantic(Loc loc
, Scope
*sc
)
3754 if (deco
) // if semantic() already run
3756 //printf("already done\n");
3759 next
= next
->semantic(loc
,sc
);
3763 d_uns64
TypeDelegate::size(Loc loc
)
3768 void TypeDelegate::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3770 if (mod
!= this->mod
)
3771 { toCBuffer3(buf
, hgs
, mod
);
3774 TypeFunction
*tf
= (TypeFunction
*)next
;
3776 tf
->next
->toCBuffer2(buf
, hgs
, 0);
3777 buf
->writestring(" delegate");
3778 Argument::argsToCBuffer(buf
, hgs
, tf
->parameters
, tf
->varargs
);
3781 Expression
*TypeDelegate::defaultInit(Loc loc
)
3784 printf("TypeDelegate::defaultInit() '%s'\n", toChars());
3787 e
= new NullExp(loc
);
3792 int TypeDelegate::isZeroInit()
3797 int TypeDelegate::checkBoolean()
3802 Expression
*TypeDelegate::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
3805 printf("TypeDelegate::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
3807 if (ident
== Id::ptr
)
3812 if (e
->op
== TOKdelegate
|| e
->op
== TOKcast
)
3813 e
= e
->castTo(sc
, tvoidptr
); // Not an lvalue
3816 e
= e
->addressOf(sc
);
3817 e
= e
->castTo(sc
, tvoidptr
->pointerTo());
3818 e
= new PtrExp(e
->loc
, e
);
3824 else if (ident
== Id::funcptr
)
3826 e
= e
->addressOf(sc
);
3828 e
= new AddExp(e
->loc
, e
, new IntegerExp(PTRSIZE
));
3830 e
= new PtrExp(e
->loc
, e
);
3831 e
->type
= next
->pointerTo();
3836 e
= Type::dotExp(sc
, e
, ident
);
3841 int TypeDelegate::hasPointers()
3848 /***************************** TypeQualified *****************************/
3850 TypeQualified::TypeQualified(TY ty
, Loc loc
)
3856 void TypeQualified::syntaxCopyHelper(TypeQualified
*t
)
3858 //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars());
3859 idents
.setDim(t
->idents
.dim
);
3860 for (int i
= 0; i
< idents
.dim
; i
++)
3862 Identifier
*id
= (Identifier
*)t
->idents
.data
[i
];
3863 if (id
->dyncast() == DYNCAST_DSYMBOL
)
3865 TemplateInstance
*ti
= (TemplateInstance
*)id
;
3867 ti
= (TemplateInstance
*)ti
->syntaxCopy(NULL
);
3868 id
= (Identifier
*)ti
;
3870 idents
.data
[i
] = id
;
3875 void TypeQualified::addIdent(Identifier
*ident
)
3880 void TypeQualified::toCBuffer2Helper(OutBuffer
*buf
, HdrGenState
*hgs
)
3884 for (i
= 0; i
< idents
.dim
; i
++)
3885 { Identifier
*id
= (Identifier
*)idents
.data
[i
];
3887 buf
->writeByte('.');
3889 if (id
->dyncast() == DYNCAST_DSYMBOL
)
3891 TemplateInstance
*ti
= (TemplateInstance
*)id
;
3892 ti
->toCBuffer(buf
, hgs
);
3895 buf
->writestring(id
->toChars());
3899 d_uns64
TypeQualified::size(Loc loc
)
3901 error(this->loc
, "size of type %s is not known", toChars());
3905 /*************************************
3906 * Takes an array of Identifiers and figures out if
3907 * it represents a Type or an Expression.
3909 * if expression, *pe is set
3910 * if type, *pt is set
3913 void TypeQualified::resolveHelper(Loc loc
, Scope
*sc
,
3914 Dsymbol
*s
, Dsymbol
*scopesym
,
3915 Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
3919 TupleDeclaration
*td
;
3923 printf("TypeQualified::resolveHelper(sc = %p, idents = '%s')\n", sc
, toChars());
3925 printf("\tscopesym = '%s'\n", scopesym
->toChars());
3932 //printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
3934 //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
3935 for (int i
= 0; i
< idents
.dim
; i
++)
3937 Identifier
*id
= (Identifier
*)idents
.data
[i
];
3938 Dsymbol
*sm
= s
->searchX(loc
, sc
, id
);
3939 //printf("\t3: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
3940 //printf("\tgetType = '%s'\n", s->getType()->toChars());
3944 v
= s
->isVarDeclaration();
3945 if (v
&& id
== Id::length
)
3947 e
= v
->getConstInitializer();
3949 e
= new VarExp(loc
, v
);
3956 if (!t
&& s
->isDeclaration())
3957 t
= s
->isDeclaration()->type
;
3960 sm
= t
->toDsymbol(sc
);
3962 { sm
= sm
->search(loc
, id
, 0);
3966 //e = t->getProperty(loc, id);
3967 e
= new TypeExp(loc
, t
);
3968 e
= t
->dotExp(sc
, e
, id
);
3971 for (; i
< idents
.dim
; i
++)
3973 id
= (Identifier
*)idents
.data
[i
];
3974 //printf("e: '%s', id: '%s', type = %p\n", e->toChars(), id->toChars(), e->type);
3975 if (id
== Id::offsetof
)
3976 { e
= new DotIdExp(e
->loc
, e
, id
);
3977 e
= e
->semantic(sc
);
3980 e
= e
->type
->dotExp(sc
, e
, id
);
3986 error(loc
, "identifier '%s' of '%s' is not defined", id
->toChars(), toChars());
3993 v
= s
->isVarDeclaration();
3997 // It's not a type, it's an expression
3998 Expression
*e
= v
->getConstInitializer();
4001 *pe
= e
->copy(); // make copy so we can change loc
4008 WithScopeSymbol
*withsym
;
4009 if (scopesym
&& (withsym
= scopesym
->isWithScopeSymbol()) != NULL
)
4011 // Same as wthis.ident
4012 e
= new VarExp(loc
, withsym
->withstate
->wthis
);
4013 e
= new DotIdExp(loc
, e
, ident
);
4014 //assert(0); // BUG: should handle this
4018 *pe
= new VarExp(loc
, v
);
4022 em
= s
->isEnumMember();
4025 // It's not a type, it's an expression
4026 *pe
= em
->value
->copy();
4031 Type
*t
= s
->getType();
4034 // If the symbol is an import, try looking inside the import
4040 s
= si
->search(loc
, s
->ident
, 0);
4048 if (t
->ty
== Tinstance
&& t
!= this && !t
->deco
)
4049 { error(loc
, "forward reference to '%s'", t
->toChars());
4055 if (t
->reliesOnTident())
4059 for (scx
= sc
; 1; scx
= scx
->enclosing
)
4062 { error(loc
, "forward reference to '%s'", t
->toChars());
4065 if (scx
->scopesym
== scopesym
)
4068 t
= t
->semantic(loc
, scx
);
4069 //((TypeIdentifier *)t)->resolve(loc, scx, pe, &t, ps);
4072 if (t
->ty
== Ttuple
)
4079 error(loc
, "identifier '%s' is not defined", toChars());
4083 /***************************** TypeIdentifier *****************************/
4085 TypeIdentifier::TypeIdentifier(Loc loc
, Identifier
*ident
)
4086 : TypeQualified(Tident
, loc
)
4088 this->ident
= ident
;
4093 Type
*TypeIdentifier::syntaxCopy()
4097 t
= new TypeIdentifier(loc
, ident
);
4099 t
->syntaxCopyHelper(this);
4104 void TypeIdentifier::toDecoBuffer(OutBuffer
*buf
, int flag
)
4108 Type::toDecoBuffer(buf
, flag
);
4109 name
= ident
->toChars();
4111 buf
->printf("%d%s", len
, name
);
4114 void TypeIdentifier::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4116 if (mod
!= this->mod
)
4117 { toCBuffer3(buf
, hgs
, mod
);
4120 buf
->writestring(this->ident
->toChars());
4121 toCBuffer2Helper(buf
, hgs
);
4124 /*************************************
4125 * Takes an array of Identifiers and figures out if
4126 * it represents a Type or an Expression.
4128 * if expression, *pe is set
4129 * if type, *pt is set
4132 void TypeIdentifier::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
4136 //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars());
4137 s
= sc
->search(loc
, ident
, &scopesym
);
4138 resolveHelper(loc
, sc
, s
, scopesym
, pe
, pt
, ps
);
4142 *pt
= (*pt
)->constOf();
4143 else if (mod
& MODinvariant
)
4144 *pt
= (*pt
)->invariantOf();
4148 /*****************************************
4149 * See if type resolves to a symbol, if so,
4150 * return that symbol.
4153 Dsymbol
*TypeIdentifier::toDsymbol(Scope
*sc
)
4155 //printf("TypeIdentifier::toDsymbol('%s')\n", toChars());
4158 //printf("ident = '%s'\n", ident->toChars());
4161 Dsymbol
*s
= sc
->search(loc
, ident
, &scopesym
);
4164 for (int i
= 0; i
< idents
.dim
; i
++)
4166 Identifier
*id
= (Identifier
*)idents
.data
[i
];
4167 s
= s
->searchX(loc
, sc
, id
);
4168 if (!s
) // failed to find a symbol
4169 { //printf("\tdidn't find a symbol\n");
4177 Type
*TypeIdentifier::semantic(Loc loc
, Scope
*sc
)
4183 //printf("TypeIdentifier::semantic(%s)\n", toChars());
4184 resolve(loc
, sc
, &e
, &t
, &s
);
4187 //printf("\tit's a type %d, %s, %s\n", t->ty, t->toChars(), t->deco);
4189 if (t
->ty
== Ttypedef
)
4190 { TypeTypedef
*tt
= (TypeTypedef
*)t
;
4192 if (tt
->sym
->sem
== 1)
4193 error(loc
, "circular reference of typedef %s", tt
->toChars());
4197 else if (isInvariant())
4198 t
= t
->invariantOf();
4200 // Do the delayed wrapping now we're sure it's a type
4202 return t
->maybe(false)->semantic(loc
, sc
);
4213 s
->error(loc
, "is used as a type");
4217 error(loc
, "%s is used as a type", toChars());
4224 Type
*TypeIdentifier::reliesOnTident()
4229 Expression
*TypeIdentifier::toExpression()
4231 Expression
*e
= new IdentifierExp(loc
, ident
);
4232 for (int i
= 0; i
< idents
.dim
; i
++)
4234 Identifier
*id
= (Identifier
*)idents
.data
[i
];
4235 e
= new DotIdExp(loc
, e
, id
);
4241 /***************************** TypeInstance *****************************/
4243 TypeInstance::TypeInstance(Loc loc
, TemplateInstance
*tempinst
)
4244 : TypeQualified(Tinstance
, loc
)
4246 this->tempinst
= tempinst
;
4249 Type
*TypeInstance::syntaxCopy()
4251 //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim);
4254 t
= new TypeInstance(loc
, (TemplateInstance
*)tempinst
->syntaxCopy(NULL
));
4255 t
->syntaxCopyHelper(this);
4261 void TypeInstance::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4263 if (mod
!= this->mod
)
4264 { toCBuffer3(buf
, hgs
, mod
);
4267 tempinst
->toCBuffer(buf
, hgs
);
4268 toCBuffer2Helper(buf
, hgs
);
4271 void TypeInstance::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
4273 // Note close similarity to TypeIdentifier::resolve()
4284 error(loc
, "template instance '%s' has no identifier", toChars());
4288 //id = (Identifier *)idents.data[0];
4289 //printf("TypeInstance::resolve(sc = %p, idents = '%s')\n", sc, id->toChars());
4293 resolveHelper(loc
, sc
, s
, NULL
, pe
, pt
, ps
);
4297 *pt
= (*pt
)->constOf();
4298 else if (mod
& MODinvariant
)
4299 *pt
= (*pt
)->invariantOf();
4301 //printf("pt = '%s'\n", (*pt)->toChars());
4304 Type
*TypeInstance::semantic(Loc loc
, Scope
*sc
)
4310 //printf("TypeInstance::semantic(%s)\n", toChars());
4312 if (sc
->parameterSpecialization
)
4314 unsigned errors
= global
.errors
;
4317 resolve(loc
, sc
, &e
, &t
, &s
);
4320 if (errors
!= global
.errors
)
4321 { if (global
.gag
== 0)
4322 global
.errors
= errors
;
4327 resolve(loc
, sc
, &e
, &t
, &s
);
4334 error(loc
, "%s is used as a type", toChars());
4341 /***************************** TypeTypeof *****************************/
4343 TypeTypeof::TypeTypeof(Loc loc
, Expression
*exp
)
4344 : TypeQualified(Ttypeof
, loc
)
4349 Type
*TypeTypeof::syntaxCopy()
4353 t
= new TypeTypeof(loc
, exp
->syntaxCopy());
4354 t
->syntaxCopyHelper(this);
4359 Dsymbol
*TypeTypeof::toDsymbol(Scope
*sc
)
4363 t
= semantic(0, sc
);
4366 return t
->toDsymbol(sc
);
4369 void TypeTypeof::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4371 if (mod
!= this->mod
)
4372 { toCBuffer3(buf
, hgs
, mod
);
4375 buf
->writestring("typeof(");
4376 exp
->toCBuffer(buf
, hgs
);
4377 buf
->writeByte(')');
4378 toCBuffer2Helper(buf
, hgs
);
4381 Type
*TypeTypeof::semantic(Loc loc
, Scope
*sc
)
4385 //printf("TypeTypeof::semantic() %p\n", this);
4387 //static int nest; if (++nest == 50) *(char*)0=0;
4390 /* Special case for typeof(this) and typeof(super) since both
4391 * should work even if they are not inside a non-static member function
4393 if (exp
->op
== TOKthis
|| exp
->op
== TOKsuper
)
4395 // Find enclosing struct or class
4396 for (Dsymbol
*s
= sc
->parent
; 1; s
= s
->parent
)
4398 ClassDeclaration
*cd
;
4399 StructDeclaration
*sd
;
4403 error(loc
, "%s is not in a struct or class scope", exp
->toChars());
4406 cd
= s
->isClassDeclaration();
4409 if (exp
->op
== TOKsuper
)
4413 { error(loc
, "class %s has no 'super'", s
->toChars());
4420 sd
= s
->isStructDeclaration();
4423 if (exp
->op
== TOKsuper
)
4425 error(loc
, "struct %s has no 'super'", sd
->toChars());
4428 t
= sd
->type
->pointerTo();
4437 exp
= exp
->semantic(sc
);
4442 error(loc
, "expression (%s) has no type", exp
->toChars());
4445 if (t
->ty
== Ttypeof
)
4446 error(loc
, "forward reference to %s", toChars());
4448 /* typeof should reflect the true type,
4449 * not what 'auto' would have gotten us.
4451 //t = t->toHeadMutable();
4456 Dsymbol
*s
= t
->toDsymbol(sc
);
4457 for (size_t i
= 0; i
< idents
.dim
; i
++)
4461 Identifier
*id
= (Identifier
*)idents
.data
[i
];
4462 s
= s
->searchX(loc
, sc
, id
);
4468 { error(loc
, "%s is not a type", s
->toChars());
4473 { error(loc
, "cannot resolve .property for %s", toChars());
4483 d_uns64
TypeTypeof::size(Loc loc
)
4486 return exp
->type
->size(loc
);
4488 return TypeQualified::size(loc
);
4493 /***************************** TypeReturn *****************************/
4495 TypeReturn::TypeReturn(Loc loc
)
4496 : TypeQualified(Treturn
, loc
)
4500 Type
*TypeReturn::syntaxCopy()
4502 TypeReturn
*t
= new TypeReturn(loc
);
4503 t
->syntaxCopyHelper(this);
4508 Dsymbol
*TypeReturn::toDsymbol(Scope
*sc
)
4510 Type
*t
= semantic(0, sc
);
4513 return t
->toDsymbol(sc
);
4516 Type
*TypeReturn::semantic(Loc loc
, Scope
*sc
)
4520 { error(loc
, "typeof(return) must be inside function");
4523 t
= sc
->func
->type
->nextOf();
4525 if (mod
& MODinvariant
)
4526 t
= t
->invariantOf();
4527 else if (mod
& MODconst
)
4532 Dsymbol
*s
= t
->toDsymbol(sc
);
4533 for (size_t i
= 0; i
< idents
.dim
; i
++)
4537 Identifier
*id
= (Identifier
*)idents
.data
[i
];
4538 s
= s
->searchX(loc
, sc
, id
);
4544 { error(loc
, "%s is not a type", s
->toChars());
4549 { error(loc
, "cannot resolve .property for %s", toChars());
4559 void TypeReturn::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4561 if (mod
!= this->mod
)
4562 { toCBuffer3(buf
, hgs
, mod
);
4565 buf
->writestring("typeof(return)");
4566 toCBuffer2Helper(buf
, hgs
);
4570 /***************************** TypeEnum *****************************/
4572 TypeEnum::TypeEnum(EnumDeclaration
*sym
)
4578 char *TypeEnum::toChars()
4581 return Type::toChars();
4582 return sym
->toChars();
4585 Type
*TypeEnum::semantic(Loc loc
, Scope
*sc
)
4587 //printf("TypeEnum::semantic() %s\n", toChars());
4592 d_uns64
TypeEnum::size(Loc loc
)
4596 error(loc
, "enum %s is forward referenced", sym
->toChars());
4599 return sym
->memtype
->size(loc
);
4602 unsigned TypeEnum::alignsize()
4609 error(0, "enum %s is forward referenced", sym
->toChars());
4612 return sym
->memtype
->alignsize();
4615 Dsymbol
*TypeEnum::toDsymbol(Scope
*sc
)
4620 Type
*TypeEnum::toBasetype()
4627 error(sym
->loc
, "enum %s is forward referenced", sym
->toChars());
4630 return sym
->memtype
->toBasetype();
4633 void TypeEnum::toDecoBuffer(OutBuffer
*buf
, int flag
)
4636 name
= sym
->mangle();
4637 Type::toDecoBuffer(buf
, flag
);
4638 buf
->printf("%s", name
);
4641 void TypeEnum::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4643 if (mod
!= this->mod
)
4644 { toCBuffer3(buf
, hgs
, mod
);
4647 buf
->writestring(sym
->toChars());
4650 Expression
*TypeEnum::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
4653 printf("TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\n", e
->toChars(), ident
->toChars(), toChars());
4655 Dsymbol
*s
= sym
->search(e
->loc
, ident
, 0);
4658 return getProperty(e
->loc
, ident
);
4660 EnumMember
*m
= s
->isEnumMember();
4661 Expression
*em
= m
->value
->copy();
4666 Expression
*TypeEnum::getProperty(Loc loc
, Identifier
*ident
)
4669 if (ident
== Id::max
)
4675 else if (ident
== Id::min
)
4681 else if (ident
== Id::init
)
4683 e
= defaultInit(loc
);
4687 e
= toBasetype()->getProperty(loc
, ident
);
4692 error(loc
, "forward reference of %s.%s", toChars(), ident
->toChars());
4693 return new IntegerExp(0, 0, this);
4696 int TypeEnum::isintegral()
4701 int TypeEnum::isfloating()
4706 int TypeEnum::isunsigned()
4708 return sym
->memtype
->isunsigned();
4711 int TypeEnum::isscalar()
4714 //return sym->memtype->isscalar();
4717 MATCH
TypeEnum::implicitConvTo(Type
*to
)
4720 //printf("TypeEnum::implicitConvTo()\n");
4721 if (ty
== to
->ty
&& sym
== ((TypeEnum
*)to
)->sym
)
4722 m
= (mod
== to
->mod
) ? MATCHexact
: MATCHconst
;
4723 else if (sym
->memtype
->implicitConvTo(to
))
4724 m
= MATCHconvert
; // match with conversions
4726 m
= MATCHnomatch
; // no match
4730 MATCH
TypeEnum::constConv(Type
*to
)
4734 if (ty
== to
->ty
&& sym
== ((TypeEnum
*)to
)->sym
&&
4735 to
->mod
== MODconst
)
4737 return MATCHnomatch
;
4741 Expression
*TypeEnum::defaultInit(Loc loc
)
4744 printf("TypeEnum::defaultInit() '%s'\n", toChars());
4746 // Initialize to first member of enum
4747 //printf("%s\n", sym->defaultval->type->toChars());
4748 if (!sym
->defaultval
)
4750 error(loc
, "forward reference of %s.init", toChars());
4751 return new IntegerExp(0, 0, this);
4753 return sym
->defaultval
;
4756 int TypeEnum::isZeroInit()
4758 return sym
->defaultval
->isBool(FALSE
);
4761 int TypeEnum::hasPointers()
4763 return toBasetype()->hasPointers();
4766 /***************************** TypeTypedef *****************************/
4768 TypeTypedef::TypeTypedef(TypedefDeclaration
*sym
)
4774 Type
*TypeTypedef::syntaxCopy()
4779 char *TypeTypedef::toChars()
4781 return Type::toChars();
4784 Type
*TypeTypedef::semantic(Loc loc
, Scope
*sc
)
4786 //printf("TypeTypedef::semantic(%s), sem = %d\n", toChars(), sym->sem);
4791 d_uns64
TypeTypedef::size(Loc loc
)
4793 return sym
->basetype
->size(loc
);
4796 unsigned TypeTypedef::alignsize()
4798 return sym
->basetype
->alignsize();
4801 Dsymbol
*TypeTypedef::toDsymbol(Scope
*sc
)
4806 Type
*TypeTypedef::toHeadMutable()
4811 Type
*tb
= toBasetype();
4812 Type
*t
= tb
->toHeadMutable();
4819 void TypeTypedef::toDecoBuffer(OutBuffer
*buf
, int flag
)
4823 Type::toDecoBuffer(buf
, flag
);
4824 name
= sym
->mangle();
4825 buf
->printf("%s", name
);
4828 void TypeTypedef::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4830 //printf("TypeTypedef::toCBuffer2() '%s'\n", sym->toChars());
4831 if (mod
!= this->mod
)
4832 { toCBuffer3(buf
, hgs
, mod
);
4835 buf
->writestring(sym
->toChars());
4838 Expression
*TypeTypedef::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
4841 printf("TypeTypedef::dotExp(e = '%s', ident = '%s') '%s'\n", e
->toChars(), ident
->toChars(), toChars());
4843 if (ident
== Id::init
)
4845 return Type::dotExp(sc
, e
, ident
);
4847 return sym
->basetype
->dotExp(sc
, e
, ident
);
4850 Expression
*TypeTypedef::getProperty(Loc loc
, Identifier
*ident
)
4853 printf("TypeTypedef::getProperty(ident = '%s') '%s'\n", ident
->toChars(), toChars());
4855 if (ident
== Id::init
)
4857 return Type::getProperty(loc
, ident
);
4859 return sym
->basetype
->getProperty(loc
, ident
);
4862 int TypeTypedef::isintegral()
4864 //printf("TypeTypedef::isintegral()\n");
4865 //printf("sym = '%s'\n", sym->toChars());
4866 //printf("basetype = '%s'\n", sym->basetype->toChars());
4867 return sym
->basetype
->isintegral();
4870 int TypeTypedef::isfloating()
4872 return sym
->basetype
->isfloating();
4875 int TypeTypedef::isreal()
4877 return sym
->basetype
->isreal();
4880 int TypeTypedef::isimaginary()
4882 return sym
->basetype
->isimaginary();
4885 int TypeTypedef::iscomplex()
4887 return sym
->basetype
->iscomplex();
4890 int TypeTypedef::isunsigned()
4892 return sym
->basetype
->isunsigned();
4895 int TypeTypedef::isscalar()
4897 return sym
->basetype
->isscalar();
4900 int TypeTypedef::isAssignable()
4902 return sym
->basetype
->isAssignable();
4905 int TypeTypedef::checkBoolean()
4907 return sym
->basetype
->checkBoolean();
4910 Type
*TypeTypedef::toBasetype()
4914 sym
->error("circular definition");
4915 sym
->basetype
= Type::terror
;
4916 return Type::terror
;
4919 Type
*t
= sym
->basetype
->toBasetype();
4921 if (mod
== MODconst
&& !t
->isInvariant())
4923 else if (mod
== MODinvariant
)
4924 t
= t
->invariantOf();
4928 MATCH
TypeTypedef::implicitConvTo(Type
*to
)
4931 //printf("TypeTypedef::implicitConvTo(to = %s) %s\n", to->toChars(), toChars());
4933 m
= MATCHexact
; // exact match
4934 else if (sym
->basetype
->implicitConvTo(to
))
4935 m
= MATCHconvert
; // match with conversions
4936 else if (ty
== to
->ty
&& sym
== ((TypeTypedef
*)to
)->sym
)
4941 m
= MATCHnomatch
; // no match
4945 MATCH
TypeTypedef::constConv(Type
*to
)
4949 if (ty
== to
->ty
&& sym
== ((TypeTypedef
*)to
)->sym
)
4950 return sym
->basetype
->implicitConvTo(((TypeTypedef
*)to
)->sym
->basetype
);
4951 return MATCHnomatch
;
4955 Expression
*TypeTypedef::defaultInit(Loc loc
)
4960 printf("TypeTypedef::defaultInit() '%s'\n", toChars());
4964 //sym->init->toExpression()->print();
4965 return sym
->init
->toExpression();
4968 e
= bt
->defaultInit(loc
);
4970 while (bt
->ty
== Tsarray
)
4971 { TypeSArray
*tsa
= (TypeSArray
*)bt
;
4972 e
->type
= tsa
->next
;
4973 bt
= tsa
->next
->toBasetype();
4978 int TypeTypedef::isZeroInit()
4982 if (sym
->init
->isVoidInitializer())
4983 return 1; // initialize voids to 0
4984 Expression
*e
= sym
->init
->toExpression();
4985 if (e
&& e
->isBool(FALSE
))
4987 return 0; // assume not
4991 sym
->error("circular definition");
4992 sym
->basetype
= Type::terror
;
4995 int result
= sym
->basetype
->isZeroInit();
5000 int TypeTypedef::hasPointers()
5002 return toBasetype()->hasPointers();
5005 /***************************** TypeStruct *****************************/
5007 TypeStruct::TypeStruct(StructDeclaration
*sym
)
5013 char *TypeStruct::toChars()
5015 //printf("sym.parent: %s, deco = %s\n", sym->parent->toChars(), deco);
5017 return Type::toChars();
5018 TemplateInstance
*ti
= sym
->parent
->isTemplateInstance();
5019 if (ti
&& ti
->toAlias() == sym
)
5021 return ti
->toChars();
5023 return sym
->toChars();
5026 Type
*TypeStruct::syntaxCopy()
5031 Type
*TypeStruct::semantic(Loc loc
, Scope
*sc
)
5033 //printf("TypeStruct::semantic('%s')\n", sym->toChars());
5035 /* Cannot do semantic for sym because scope chain may not
5038 //sym->semantic(sc);
5043 d_uns64
TypeStruct::size(Loc loc
)
5045 return sym
->size(loc
);
5048 unsigned TypeStruct::alignsize()
5051 sym
->size(0); // give error for forward references
5052 sz
= sym
->alignsize
;
5053 if (sz
> sym
->structalign
)
5054 sz
= sym
->structalign
;
5058 Dsymbol
*TypeStruct::toDsymbol(Scope
*sc
)
5063 void TypeStruct::toDecoBuffer(OutBuffer
*buf
, int flag
)
5067 name
= sym
->mangle();
5068 //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", toChars(), name);
5069 Type::toDecoBuffer(buf
, flag
);
5070 buf
->printf("%s", name
);
5073 void TypeStruct::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
5075 if (mod
!= this->mod
)
5076 { toCBuffer3(buf
, hgs
, mod
);
5079 TemplateInstance
*ti
= sym
->parent
->isTemplateInstance();
5080 if (ti
&& ti
->toAlias() == sym
)
5081 buf
->writestring(ti
->toChars());
5083 buf
->writestring(sym
->toChars());
5086 Expression
*TypeStruct::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
5096 printf("TypeStruct::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
5100 error(e
->loc
, "struct %s is forward referenced", sym
->toChars());
5101 return new IntegerExp(e
->loc
, 0, Type::tint32
);
5106 if (ident
== Id::tupleof
)
5108 /* Create a TupleExp out of the fields of the struct e:
5109 * (e.field0, e.field1, e.field2, ...)
5111 e
= e
->semantic(sc
); // do this before turning on noaccesscheck
5112 Expressions
*exps
= new Expressions
;
5113 exps
->reserve(sym
->fields
.dim
);
5114 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
5115 { VarDeclaration
*v
= (VarDeclaration
*)sym
->fields
.data
[i
];
5116 Expression
*fe
= new DotVarExp(e
->loc
, e
, v
);
5119 e
= new TupleExp(e
->loc
, exps
);
5121 sc
->noaccesscheck
= 1;
5122 e
= e
->semantic(sc
);
5127 if (e
->op
== TOKdotexp
)
5128 { DotExp
*de
= (DotExp
*)e
;
5130 if (de
->e1
->op
== TOKimport
)
5132 assert(0); // cannot find a case where this happens; leave
5133 // assert in until we do
5134 ScopeExp
*se
= (ScopeExp
*)de
->e1
;
5136 s
= se
->sds
->search(e
->loc
, ident
, 0);
5142 s
= sym
->search(e
->loc
, ident
, 0);
5146 if (ident
!= Id::__sizeof
&&
5147 ident
!= Id::alignof
&&
5148 ident
!= Id::init
&&
5149 ident
!= Id::mangleof
&&
5150 ident
!= Id::stringof
&&
5151 ident
!= Id::offsetof
)
5153 /* Look for overloaded opDot() to see if we should forward request
5156 Dsymbol
*fd
= search_function(sym
, Id::opDot
);
5158 { /* Rewrite e.ident as:
5161 e
= build_overload(e
->loc
, sc
, e
, NULL
, fd
->ident
);
5162 e
= new DotIdExp(e
->loc
, e
, ident
);
5163 return e
->semantic(sc
);
5166 return Type::dotExp(sc
, e
, ident
);
5170 v
= s
->isVarDeclaration();
5171 if (v
&& !v
->isDataseg())
5173 Expression
*ei
= v
->getConstInitializer();
5175 { e
= ei
->copy(); // need to copy it if it's a StringExp
5176 e
= e
->semantic(sc
);
5183 //return new DotTypeExp(e->loc, e, s);
5184 return new TypeExp(e
->loc
, s
->getType());
5187 EnumMember
*em
= s
->isEnumMember();
5191 return em
->value
->copy();
5194 TemplateMixin
*tm
= s
->isTemplateMixin();
5197 Expression
*de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, tm
));
5202 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
5205 e
= new DotTemplateExp(e
->loc
, e
, td
);
5210 TemplateInstance
*ti
= s
->isTemplateInstance();
5212 { if (!ti
->semanticdone
)
5214 s
= ti
->inst
->toAlias();
5215 if (!s
->isTemplateInstance())
5217 Expression
*de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, ti
));
5222 d
= s
->isDeclaration();
5225 printf("d = %s '%s'\n", s
->kind(), s
->toChars());
5229 if (e
->op
== TOKtype
)
5230 { FuncDeclaration
*fd
= sc
->func
;
5232 if (d
->needThis() && fd
&& fd
->vthis
)
5234 e
= new DotVarExp(e
->loc
, new ThisExp(e
->loc
), d
);
5235 e
= e
->semantic(sc
);
5238 if (d
->isTupleDeclaration())
5240 e
= new TupleExp(e
->loc
, d
->isTupleDeclaration());
5241 e
= e
->semantic(sc
);
5244 return new VarExp(e
->loc
, d
, 1);
5252 accessCheck(e
->loc
, sc
, e
, d
);
5253 ve
= new VarExp(e
->loc
, d
);
5254 e
= new CommaExp(e
->loc
, e
, ve
);
5261 if (v
->toParent() != sym
)
5262 sym
->error(e
->loc
, "'%s' is not a member", v
->toChars());
5265 accessCheck(e
->loc
, sc
, e
, d
);
5266 b
= new AddrExp(e
->loc
, e
);
5267 b
->type
= e
->type
->pointerTo();
5268 b
= new AddExp(e
->loc
, b
, new IntegerExp(e
->loc
, v
->offset
, Type::tsize_t
));
5269 b
->type
= v
->type
->pointerTo();
5270 b
= new PtrExp(e
->loc
, b
);
5272 if (e
->type
->isConst())
5273 b
->type
= b
->type
->constOf();
5274 else if (e
->type
->isInvariant())
5275 b
->type
= b
->type
->invariantOf();
5279 de
= new DotVarExp(e
->loc
, e
, d
);
5280 return de
->semantic(sc
);
5283 unsigned TypeStruct::memalign(unsigned salign
)
5285 sym
->size(0); // give error for forward references
5286 return sym
->structalign
;
5289 Expression
*TypeStruct::defaultInit(Loc loc
)
5294 printf("TypeStruct::defaultInit() '%s'\n", toChars());
5296 s
= sym
->toInitializer();
5297 d
= new SymbolDeclaration(sym
->loc
, s
, sym
);
5300 return new VarExp(sym
->loc
, d
);
5303 int TypeStruct::isZeroInit()
5305 return sym
->zeroInit
;
5308 int TypeStruct::checkBoolean()
5313 int TypeStruct::isAssignable()
5315 /* If any of the fields are const or invariant,
5316 * then one cannot assign this struct.
5318 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
5319 { VarDeclaration
*v
= (VarDeclaration
*)sym
->fields
.data
[i
];
5320 if (v
->isConst() || v
->isInvariant())
5326 int TypeStruct::hasPointers()
5328 StructDeclaration
*s
= sym
;
5330 sym
->size(0); // give error for forward references
5331 for (size_t i
= 0; i
< s
->fields
.dim
; i
++)
5333 Dsymbol
*sm
= (Dsymbol
*)s
->fields
.data
[i
];
5334 if (sm
->hasPointers())
5340 MATCH
TypeStruct::implicitConvTo(Type
*to
)
5343 //printf("TypeStruct::implicitConvTo(%s => %s)\n", toChars(), to->toChars());
5344 if (ty
== to
->ty
&& sym
== ((TypeStruct
*)to
)->sym
)
5345 { m
= MATCHexact
; // exact match
5348 if (to
->mod
== MODconst
)
5351 { /* Check all the fields. If they can all be converted,
5352 * allow the conversion.
5354 for (int i
= 0; i
< sym
->fields
.dim
; i
++)
5355 { Dsymbol
*s
= (Dsymbol
*)sym
->fields
.data
[i
];
5356 VarDeclaration
*v
= s
->isVarDeclaration();
5357 assert(v
&& v
->storage_class
& STCfield
);
5360 Type
*tvf
= v
->type
;
5361 if (mod
== MODconst
)
5362 tvf
= tvf
->constOf();
5363 else if (mod
== MODinvariant
)
5364 tvf
= tvf
->invariantOf();
5369 tv
= tv
->mutableOf();
5371 { assert(to
->mod
== MODinvariant
);
5372 tv
= tv
->invariantOf();
5375 //printf("\t%s => %s, match = %d\n", v->type->toChars(), tv->toChars(), tvf->implicitConvTo(tv));
5376 if (tvf
->implicitConvTo(tv
) < MATCHconst
)
5377 return MATCHnomatch
;
5384 m
= MATCHnomatch
; // no match
5388 Type
*TypeStruct::toHeadMutable()
5393 MATCH
TypeStruct::constConv(Type
*to
)
5397 if (ty
== to
->ty
&& sym
== ((TypeStruct
*)to
)->sym
&&
5398 to
->mod
== MODconst
)
5400 return MATCHnomatch
;
5404 /***************************** TypeClass *****************************/
5406 TypeClass::TypeClass(ClassDeclaration
*sym
)
5412 char *TypeClass::toChars()
5415 return Type::toChars();
5416 return sym
->toPrettyChars();
5419 Type
*TypeClass::syntaxCopy()
5424 Type
*TypeClass::semantic(Loc loc
, Scope
*sc
)
5426 //printf("TypeClass::semantic(%s)\n", sym->toChars());
5428 sym
->semantic(sym
->scope
);
5432 d_uns64
TypeClass::size(Loc loc
)
5437 Dsymbol
*TypeClass::toDsymbol(Scope
*sc
)
5442 void TypeClass::toDecoBuffer(OutBuffer
*buf
, int flag
)
5446 name
= sym
->mangle();
5447 //printf("TypeClass::toDecoBuffer('%s' flag=%d mod=%x) = '%s'\n", toChars(), flag, mod, name);
5448 Type::toDecoBuffer(buf
, flag
);
5449 buf
->printf("%s", name
);
5452 void TypeClass::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
5454 if (mod
!= this->mod
)
5455 { toCBuffer3(buf
, hgs
, mod
);
5458 buf
->writestring(sym
->toChars());
5461 Expression
*TypeClass::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
5469 printf("TypeClass::dotExp(e='%s', ident='%s')\n", e
->toChars(), ident
->toChars());
5472 if (e
->op
== TOKdotexp
)
5473 { DotExp
*de
= (DotExp
*)e
;
5475 if (de
->e1
->op
== TOKimport
)
5477 ScopeExp
*se
= (ScopeExp
*)de
->e1
;
5479 s
= se
->sds
->search(e
->loc
, ident
, 0);
5485 if (ident
== Id::tupleof
)
5487 /* Create a TupleExp
5489 e
= e
->semantic(sc
); // do this before turning on noaccesscheck
5490 Expressions
*exps
= new Expressions
;
5491 exps
->reserve(sym
->fields
.dim
);
5492 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
5493 { VarDeclaration
*v
= (VarDeclaration
*)sym
->fields
.data
[i
];
5494 Expression
*fe
= new DotVarExp(e
->loc
, e
, v
);
5497 e
= new TupleExp(e
->loc
, exps
);
5499 sc
->noaccesscheck
= 1;
5500 e
= e
->semantic(sc
);
5505 s
= sym
->search(e
->loc
, ident
, 0);
5509 // See if it's a base class
5510 ClassDeclaration
*cbase
;
5511 for (cbase
= sym
->baseClass
; cbase
; cbase
= cbase
->baseClass
)
5513 if (cbase
->ident
->equals(ident
))
5515 e
= new DotTypeExp(0, e
, cbase
);
5520 if (ident
== Id::classinfo
)
5522 assert(ClassDeclaration::classinfo
);
5523 Type
*t
= ClassDeclaration::classinfo
->type
;
5524 if (e
->op
== TOKtype
|| e
->op
== TOKdottype
)
5526 /* For type.classinfo, we know the classinfo
5529 if (!sym
->vclassinfo
)
5530 sym
->vclassinfo
= new ClassInfoDeclaration(sym
);
5531 e
= new VarExp(e
->loc
, sym
->vclassinfo
);
5532 e
= e
->addressOf(sc
);
5533 e
->type
= t
; // do this so we don't get redundant dereference
5536 { /* For class objects, the classinfo reference is the first
5537 * entry in the vtbl[]
5539 e
= new PtrExp(e
->loc
, e
);
5540 e
->type
= t
->pointerTo();
5541 if (sym
->isInterfaceDeclaration())
5543 if (sym
->isCPPinterface())
5544 { /* C++ interface vtbl[]s are different in that the
5545 * first entry is always pointer to the first virtual
5546 * function, not classinfo.
5547 * We can't get a .classinfo for it.
5549 error(e
->loc
, "no .classinfo for C++ interface objects");
5551 /* For an interface, the first entry in the vtbl[]
5552 * is actually a pointer to an instance of struct Interface.
5553 * The first member of Interface is the .classinfo,
5554 * so add an extra pointer indirection.
5556 e
->type
= e
->type
->pointerTo();
5557 e
= new PtrExp(e
->loc
, e
);
5558 e
->type
= t
->pointerTo();
5560 e
= new PtrExp(e
->loc
, e
, t
);
5565 if (ident
== Id::typeinfo
)
5567 if (!global
.params
.useDeprecated
)
5568 error(e
->loc
, ".typeinfo deprecated, use typeid(type)");
5569 return getTypeInfo(sc
);
5571 if (ident
== Id::outer
&& sym
->vthis
)
5578 if (ident
!= Id::__sizeof
&&
5579 ident
!= Id::alignof
&&
5580 ident
!= Id::init
&&
5581 ident
!= Id::mangleof
&&
5582 ident
!= Id::stringof
&&
5583 ident
!= Id::offsetof
)
5585 /* Look for overloaded opDot() to see if we should forward request
5588 Dsymbol
*fd
= search_function(sym
, Id::opDot
);
5590 { /* Rewrite e.ident as:
5593 e
= build_overload(e
->loc
, sc
, e
, NULL
, fd
->ident
);
5594 e
= new DotIdExp(e
->loc
, e
, ident
);
5595 return e
->semantic(sc
);
5599 return Type::dotExp(sc
, e
, ident
);
5603 v
= s
->isVarDeclaration();
5604 if (v
&& !v
->isDataseg())
5605 { Expression
*ei
= v
->getConstInitializer();
5608 { e
= ei
->copy(); // need to copy it if it's a StringExp
5609 e
= e
->semantic(sc
);
5616 // if (e->op == TOKtype)
5617 return new TypeExp(e
->loc
, s
->getType());
5618 // return new DotTypeExp(e->loc, e, s);
5621 EnumMember
*em
= s
->isEnumMember();
5625 return em
->value
->copy();
5628 TemplateMixin
*tm
= s
->isTemplateMixin();
5631 Expression
*de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, tm
));
5636 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
5639 e
= new DotTemplateExp(e
->loc
, e
, td
);
5644 TemplateInstance
*ti
= s
->isTemplateInstance();
5646 { if (!ti
->semanticdone
)
5648 s
= ti
->inst
->toAlias();
5649 if (!s
->isTemplateInstance())
5651 Expression
*de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, ti
));
5656 Declaration
*d
= s
->isDeclaration();
5659 e
->error("%s.%s is not a declaration", e
->toChars(), ident
->toChars());
5660 return new IntegerExp(e
->loc
, 1, Type::tint32
);
5663 if (e
->op
== TOKtype
)
5668 if (d
->needThis() && (hasThis(sc
) || !d
->isFuncDeclaration()))
5672 ClassDeclaration
*thiscd
;
5673 thiscd
= sc
->func
->toParent()->isClassDeclaration();
5677 ClassDeclaration
*cd
= e
->type
->isClassHandle();
5681 e
= new ThisExp(e
->loc
);
5682 e
= new DotTypeExp(e
->loc
, e
, cd
);
5683 DotVarExp
*de
= new DotVarExp(e
->loc
, e
, d
);
5684 e
= de
->semantic(sc
);
5687 else if ((!cd
|| !cd
->isBaseOf(thiscd
, NULL
)) &&
5688 !d
->isFuncDeclaration())
5689 e
->error("'this' is required, but %s is not a base class of %s", e
->type
->toChars(), thiscd
->toChars());
5696 DotVarExp
*de
= new DotVarExp(e
->loc
, new ThisExp(e
->loc
), d
);
5697 e
= de
->semantic(sc
);
5700 else if (d
->isTupleDeclaration())
5702 e
= new TupleExp(e
->loc
, d
->isTupleDeclaration());
5703 e
= e
->semantic(sc
);
5708 VarExp
*ve
= new VarExp(e
->loc
, d
, 1);
5718 accessCheck(e
->loc
, sc
, e
, d
);
5719 ve
= new VarExp(e
->loc
, d
);
5720 e
= new CommaExp(e
->loc
, e
, ve
);
5725 if (d
->parent
&& d
->toParent()->isModule())
5729 VarExp
*ve
= new VarExp(e
->loc
, d
, 1);
5730 e
= new CommaExp(e
->loc
, e
, ve
);
5735 DotVarExp
*de
= new DotVarExp(e
->loc
, e
, d
);
5736 return de
->semantic(sc
);
5739 ClassDeclaration
*TypeClass::isClassHandle()
5744 int TypeClass::isauto()
5749 int TypeClass::isBaseOf(Type
*t
, target_ptrdiff_t
*poffset
)
5751 if (t
->ty
== Tclass
)
5752 { ClassDeclaration
*cd
;
5754 cd
= ((TypeClass
*)t
)->sym
;
5755 if (sym
->isBaseOf(cd
, poffset
))
5761 MATCH
TypeClass::implicitConvTo(Type
*to
)
5763 //printf("TypeClass::implicitConvTo(to = '%s') %s\n", to->toChars(), toChars());
5765 // Can always convert a "Foo" to a "Foo?"
5766 if (to
->ty
== Tmaybe
)
5769 MATCH m
= constConv(to
);
5770 if (m
!= MATCHnomatch
)
5773 ClassDeclaration
*cdto
= to
->isClassHandle();
5774 if (cdto
&& cdto
->isBaseOf(sym
, NULL
))
5775 { //printf("'to' is base\n");
5776 return MATCHconvert
;
5779 // Can convert any (D) instance to Object
5780 if (cdto
== ClassDeclaration::object
)
5782 if (sym
->linkage
!= LINKd
)
5783 return MATCHnomatch
;
5784 return MATCHconvert
;
5787 if (global
.params
.Dversion
== 1)
5789 // Allow conversion to (void *)
5790 if (to
->ty
== Tpointer
&& ((TypePointer
*)to
)->next
->ty
== Tvoid
)
5791 return MATCHconvert
;
5794 return MATCHnomatch
;
5797 MATCH
TypeClass::constConv(Type
*to
)
5801 if (ty
== to
->ty
&& sym
== ((TypeClass
*)to
)->sym
&&
5802 to
->mod
== MODconst
)
5804 return MATCHnomatch
;
5807 Type
*TypeClass::toHeadMutable()
5812 Expression
*TypeClass::defaultInit(Loc loc
)
5815 printf("TypeClass::defaultInit() '%s'\n", toChars());
5818 e
= new NullExp(loc
);
5823 int TypeClass::isZeroInit()
5828 int TypeClass::checkBoolean()
5833 int TypeClass::hasPointers()
5838 /***************************** TypeTuple *****************************/
5840 TypeTuple::TypeTuple(Arguments
*arguments
)
5843 //printf("TypeTuple(this = %p)\n", this);
5844 this->arguments
= arguments
;
5845 //printf("TypeTuple() %s\n", toChars());
5849 for (size_t i
= 0; i
< arguments
->dim
; i
++)
5851 Argument
*arg
= (Argument
*)arguments
->data
[i
];
5852 assert(arg
&& arg
->type
);
5859 * Form TypeTuple from the types of the expressions.
5860 * Assume exps[] is already tuple expanded.
5863 TypeTuple::TypeTuple(Expressions
*exps
)
5866 Arguments
*arguments
= new Arguments
;
5869 arguments
->setDim(exps
->dim
);
5870 for (size_t i
= 0; i
< exps
->dim
; i
++)
5871 { Expression
*e
= (Expression
*)exps
->data
[i
];
5872 if (e
->type
->ty
== Ttuple
)
5873 e
->error("cannot form tuple of tuples");
5874 Argument
*arg
= new Argument(STCundefined
, e
->type
, NULL
, NULL
);
5875 arguments
->data
[i
] = (void *)arg
;
5878 this->arguments
= arguments
;
5881 Type
*TypeTuple::syntaxCopy()
5883 Arguments
*args
= Argument::arraySyntaxCopy(arguments
);
5884 Type
*t
= new TypeTuple(args
);
5889 Type
*TypeTuple::semantic(Loc loc
, Scope
*sc
)
5891 //printf("TypeTuple::semantic(this = %p)\n", this);
5892 //printf("TypeTuple::semantic() %s\n", toChars());
5894 deco
= merge()->deco
;
5896 /* Don't return merge(), because a tuple with one type has the
5897 * same deco as that type.
5902 int TypeTuple::equals(Object
*o
)
5906 //printf("TypeTuple::equals(%s, %s)\n", toChars(), t->toChars());
5911 if (t
->ty
== Ttuple
)
5912 { TypeTuple
*tt
= (TypeTuple
*)t
;
5914 if (arguments
->dim
== tt
->arguments
->dim
)
5916 for (size_t i
= 0; i
< tt
->arguments
->dim
; i
++)
5917 { Argument
*arg1
= (Argument
*)arguments
->data
[i
];
5918 Argument
*arg2
= (Argument
*)tt
->arguments
->data
[i
];
5920 if (!arg1
->type
->equals(arg2
->type
))
5929 Type
*TypeTuple::reliesOnTident()
5933 for (size_t i
= 0; i
< arguments
->dim
; i
++)
5935 Argument
*arg
= (Argument
*)arguments
->data
[i
];
5936 Type
*t
= arg
->type
->reliesOnTident();
5945 Type
*TypeTuple::makeConst()
5947 //printf("TypeTuple::makeConst() %s\n", toChars());
5950 TypeTuple
*t
= (TypeTuple
*)Type::makeConst();
5951 t
->arguments
= new Arguments();
5952 t
->arguments
->setDim(arguments
->dim
);
5953 for (size_t i
= 0; i
< arguments
->dim
; i
++)
5954 { Argument
*arg
= (Argument
*)arguments
->data
[i
];
5955 Argument
*narg
= new Argument(arg
->storageClass
, arg
->type
->constOf(), arg
->ident
, arg
->defaultArg
);
5956 t
->arguments
->data
[i
] = (Argument
*)narg
;
5962 void TypeTuple::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
5964 Argument::argsToCBuffer(buf
, hgs
, arguments
, 0);
5967 void TypeTuple::toDecoBuffer(OutBuffer
*buf
, int flag
)
5969 //printf("TypeTuple::toDecoBuffer() this = %p, %s\n", this, toChars());
5970 Type::toDecoBuffer(buf
, flag
);
5972 Argument::argsToDecoBuffer(&buf2
, arguments
);
5973 unsigned len
= buf2
.offset
;
5975 // newlib bug as of 1.14.0
5976 char * p
= (char*) buf2
.extractData();
5977 buf
->printf("%d%.*s", len
, len
, p
? p
: "");
5979 buf
->printf("%d%.*s", len
, len
, (char *)buf2
.extractData());
5983 Expression
*TypeTuple::getProperty(Loc loc
, Identifier
*ident
)
5987 printf("TypeTuple::getProperty(type = '%s', ident = '%s')\n", toChars(), ident
->toChars());
5989 if (ident
== Id::length
)
5991 e
= new IntegerExp(loc
, arguments
->dim
, Type::tsize_t
);
5995 error(loc
, "no property '%s' for tuple '%s'", ident
->toChars(), toChars());
5996 e
= new IntegerExp(loc
, 1, Type::tint32
);
6001 /***************************** TypeSlice *****************************/
6003 /* This is so we can slice a TypeTuple */
6005 TypeSlice::TypeSlice(Type
*next
, Expression
*lwr
, Expression
*upr
)
6006 : TypeNext(Tslice
, next
)
6008 //printf("TypeSlice[%s .. %s]\n", lwr->toChars(), upr->toChars());
6013 Type
*TypeSlice::syntaxCopy()
6015 Type
*t
= new TypeSlice(next
->syntaxCopy(), lwr
->syntaxCopy(), upr
->syntaxCopy());
6020 Type
*TypeSlice::semantic(Loc loc
, Scope
*sc
)
6022 //printf("TypeSlice::semantic() %s\n", toChars());
6023 next
= next
->semantic(loc
, sc
);
6024 if (mod
== MODconst
&& !next
->isInvariant())
6025 next
= next
->constOf();
6026 else if (mod
== MODinvariant
)
6027 next
= next
->invariantOf();
6028 //printf("next: %s\n", next->toChars());
6030 Type
*tbn
= next
->toBasetype();
6031 if (tbn
->ty
!= Ttuple
)
6032 { error(loc
, "can only slice tuple types, not %s", tbn
->toChars());
6033 return Type::terror
;
6035 TypeTuple
*tt
= (TypeTuple
*)tbn
;
6037 lwr
= semanticLength(sc
, tbn
, lwr
);
6038 lwr
= lwr
->optimize(WANTvalue
);
6039 uinteger_t i1
= lwr
->toUInteger();
6041 upr
= semanticLength(sc
, tbn
, upr
);
6042 upr
= upr
->optimize(WANTvalue
);
6043 uinteger_t i2
= upr
->toUInteger();
6045 if (!(i1
<= i2
&& i2
<= tt
->arguments
->dim
))
6046 { error(loc
, "slice [%"PRIuMAX
"..%"PRIuMAX
"] is out of range of [0..%u]", i1
, i2
, tt
->arguments
->dim
);
6047 return Type::terror
;
6050 Arguments
*args
= new Arguments
;
6051 args
->reserve(i2
- i1
);
6052 for (size_t i
= i1
; i
< i2
; i
++)
6053 { Argument
*arg
= (Argument
*)tt
->arguments
->data
[i
];
6057 return new TypeTuple(args
);
6060 void TypeSlice::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
6062 next
->resolve(loc
, sc
, pe
, pt
, ps
);
6064 { // It's really a slice expression
6066 e
= new SliceExp(loc
, *pe
, lwr
, upr
);
6071 TupleDeclaration
*td
= s
->isTupleDeclaration();
6074 /* It's a slice of a TupleDeclaration
6076 ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, td
);
6077 sym
->parent
= sc
->scopesym
;
6080 lwr
= lwr
->semantic(sc
);
6081 lwr
= lwr
->optimize(WANTvalue
);
6082 uinteger_t i1
= lwr
->toUInteger();
6084 upr
= upr
->semantic(sc
);
6085 upr
= upr
->optimize(WANTvalue
);
6086 uinteger_t i2
= upr
->toUInteger();
6090 if (!(i1
<= i2
&& i2
<= td
->objects
->dim
))
6091 { error(loc
, "slice [%"PRIuMAX
"u..%"PRIuMAX
"u] is out of range of [0..%u]", i1
, i2
, td
->objects
->dim
);
6095 if (i1
== 0 && i2
== td
->objects
->dim
)
6101 /* Create a new TupleDeclaration which
6102 * is a slice [i1..i2] out of the old one.
6104 Objects
*objects
= new Objects
;
6105 objects
->setDim(i2
- i1
);
6106 for (size_t i
= 0; i
< objects
->dim
; i
++)
6108 objects
->data
[i
] = td
->objects
->data
[(size_t)i1
+ i
];
6111 TupleDeclaration
*tds
= new TupleDeclaration(loc
, td
->ident
, objects
);
6120 Type::resolve(loc
, sc
, pe
, pt
, ps
);
6124 void TypeSlice::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
6126 if (mod
!= this->mod
)
6127 { toCBuffer3(buf
, hgs
, mod
);
6130 next
->toCBuffer2(buf
, hgs
, this->mod
);
6132 buf
->printf("[%s .. ", lwr
->toChars());
6133 buf
->printf("%s]", upr
->toChars());
6136 /***************************** Argument *****************************/
6138 Argument::Argument(unsigned storageClass
, Type
*type
, Identifier
*ident
, Expression
*defaultArg
)
6141 this->ident
= ident
;
6142 this->storageClass
= storageClass
;
6143 this->defaultArg
= defaultArg
;
6146 Argument
*Argument::syntaxCopy()
6148 Argument
*a
= new Argument(storageClass
,
6149 type
? type
->syntaxCopy() : NULL
,
6151 defaultArg
? defaultArg
->syntaxCopy() : NULL
);
6155 Arguments
*Argument::arraySyntaxCopy(Arguments
*args
)
6156 { Arguments
*a
= NULL
;
6160 a
= new Arguments();
6161 a
->setDim(args
->dim
);
6162 for (size_t i
= 0; i
< a
->dim
; i
++)
6163 { Argument
*arg
= (Argument
*)args
->data
[i
];
6165 arg
= arg
->syntaxCopy();
6166 a
->data
[i
] = (void *)arg
;
6172 char *Argument::argsTypesToChars(Arguments
*args
, int varargs
)
6175 buf
= new OutBuffer();
6177 buf
->writeByte('(');
6183 for (i
= 0; i
< args
->dim
; i
++)
6187 buf
->writeByte(',');
6188 arg
= (Argument
*)args
->data
[i
];
6190 arg
->type
->toCBuffer2(&argbuf
, &hgs
, 0);
6191 buf
->write(&argbuf
);
6195 if (i
&& varargs
== 1)
6196 buf
->writeByte(',');
6197 buf
->writestring("...");
6200 buf
->writeByte(')');
6202 return buf
->toChars();
6205 void Argument::argsToCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
, Arguments
*arguments
, int varargs
)
6207 buf
->writeByte('(');
6212 for (i
= 0; i
< arguments
->dim
; i
++)
6216 buf
->writestring(", ");
6217 arg
= (Argument
*)arguments
->data
[i
];
6218 if (arg
->storageClass
& STCout
)
6219 buf
->writestring("out ");
6220 else if (arg
->storageClass
& STCref
)
6221 buf
->writestring((global
.params
.Dversion
== 1)
6222 ? (char *)"inout " : (char *)"ref ");
6223 else if (arg
->storageClass
& STCin
)
6224 buf
->writestring("in ");
6225 else if (arg
->storageClass
& STClazy
)
6226 buf
->writestring("lazy ");
6227 if (arg
->storageClass
& STCconst
)
6228 buf
->writestring("const ");
6229 if (arg
->storageClass
& STCinvariant
)
6230 buf
->writestring("invariant ");
6232 arg
->type
->toCBuffer(&argbuf
, arg
->ident
, hgs
);
6233 if (arg
->defaultArg
)
6235 argbuf
.writestring(" = ");
6236 arg
->defaultArg
->toCBuffer(&argbuf
, hgs
);
6238 buf
->write(&argbuf
);
6242 if (i
&& varargs
== 1)
6243 buf
->writeByte(',');
6244 buf
->writestring("...");
6247 buf
->writeByte(')');
6251 void Argument::argsToDecoBuffer(OutBuffer
*buf
, Arguments
*arguments
)
6253 //printf("Argument::argsToDecoBuffer()\n");
6255 // Write argument types
6258 size_t dim
= Argument::dim(arguments
);
6259 for (size_t i
= 0; i
< dim
; i
++)
6261 Argument
*arg
= Argument::getNth(arguments
, i
);
6262 arg
->toDecoBuffer(buf
);
6267 /****************************************************
6268 * Determine if parameter is a lazy array of delegates.
6269 * If so, return the return type of those delegates.
6270 * If not, return NULL.
6273 Type
*Argument::isLazyArray()
6275 // if (inout == Lazy)
6277 Type
*tb
= type
->toBasetype();
6278 if (tb
->ty
== Tsarray
|| tb
->ty
== Tarray
)
6280 Type
*tel
= ((TypeArray
*)tb
)->next
->toBasetype();
6281 if (tel
->ty
== Tdelegate
)
6283 TypeDelegate
*td
= (TypeDelegate
*)tel
;
6284 TypeFunction
*tf
= (TypeFunction
*)td
->next
;
6286 if (!tf
->varargs
&& Argument::dim(tf
->parameters
) == 0)
6288 return tf
->next
; // return type of delegate
6296 void Argument::toDecoBuffer(OutBuffer
*buf
)
6298 switch (storageClass
& (STCin
| STCout
| STCref
| STClazy
))
6303 buf
->writeByte('J');
6306 buf
->writeByte('K');
6309 buf
->writeByte('L');
6319 if (type
->toBasetype()->ty
== Tclass
)
6321 type
->toDecoBuffer(buf
, mod
);
6323 //type->toHeadMutable()->toDecoBuffer(buf, 0);
6324 type
->toDecoBuffer(buf
, 0);
6328 /***************************************
6329 * Determine number of arguments, folding in tuples.
6332 size_t Argument::dim(Arguments
*args
)
6337 for (size_t i
= 0; i
< args
->dim
; i
++)
6338 { Argument
*arg
= (Argument
*)args
->data
[i
];
6339 Type
*t
= arg
->type
->toBasetype();
6341 if (t
->ty
== Ttuple
)
6342 { TypeTuple
*tu
= (TypeTuple
*)t
;
6343 n
+= dim(tu
->arguments
);
6352 /***************************************
6353 * Get nth Argument, folding in tuples.
6355 * Argument* nth Argument
6356 * NULL not found, *pn gets incremented by the number
6360 Argument
*Argument::getNth(Arguments
*args
, size_t nth
, size_t *pn
)
6366 for (size_t i
= 0; i
< args
->dim
; i
++)
6367 { Argument
*arg
= (Argument
*)args
->data
[i
];
6368 Type
*t
= arg
->type
->toBasetype();
6370 if (t
->ty
== Ttuple
)
6371 { TypeTuple
*tu
= (TypeTuple
*)t
;
6372 arg
= getNth(tu
->arguments
, nth
- n
, &n
);