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::typeinfomaybe
;
123 ClassDeclaration
*Type::typeinfoarray
;
124 ClassDeclaration
*Type::typeinfostaticarray
;
125 ClassDeclaration
*Type::typeinfoassociativearray
;
126 ClassDeclaration
*Type::typeinfoenum
;
127 ClassDeclaration
*Type::typeinfofunction
;
128 ClassDeclaration
*Type::typeinfodelegate
;
129 ClassDeclaration
*Type::typeinfotypelist
;
131 Type
*Type::tvoidptr
;
132 Type
*Type::basic
[TMAX
];
133 unsigned char Type::mangleChar
[TMAX
];
134 StringTable
Type::stringtable
;
137 Type::Type(TY ty
, Type
*next
)
150 this->arrayof
= NULL
;
155 Type
*Type::syntaxCopy()
158 fprintf(stdmsg
, "ty = %d\n", ty
);
163 int Type::equals(Object
*o
)
167 //printf("Type::equals(%s, %s)\n", toChars(), t->toChars());
169 (t
&& deco
== t
->deco
) && // deco strings are unique
170 deco
!= NULL
) // and semantic() has been run
172 //printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
175 //if (deco && t && t->deco) printf("deco = '%s', t->deco = '%s'\n", deco, t->deco);
179 char Type::needThisPrefix()
181 return 'M'; // name mangling prefix for functions needing 'this'
188 Lexer::initKeywords();
190 mangleChar
[Tarray
] = 'A';
191 mangleChar
[Tsarray
] = 'G';
192 mangleChar
[Taarray
] = 'H';
193 mangleChar
[Tpointer
] = 'P';
194 mangleChar
[Tmaybe
] = 'Q';
195 mangleChar
[Treference
] = 'R';
196 mangleChar
[Tfunction
] = 'F';
197 mangleChar
[Tident
] = 'I';
198 mangleChar
[Tclass
] = 'C';
199 mangleChar
[Tstruct
] = 'S';
200 mangleChar
[Tenum
] = 'E';
201 mangleChar
[Ttypedef
] = 'T';
202 mangleChar
[Tdelegate
] = 'D';
204 mangleChar
[Tnone
] = 'n';
205 mangleChar
[Tvoid
] = 'v';
206 mangleChar
[Tint8
] = 'g';
207 mangleChar
[Tuns8
] = 'h';
208 mangleChar
[Tint16
] = 's';
209 mangleChar
[Tuns16
] = 't';
210 mangleChar
[Tint32
] = 'i';
211 mangleChar
[Tuns32
] = 'k';
212 mangleChar
[Tint64
] = 'l';
213 mangleChar
[Tuns64
] = 'm';
214 mangleChar
[Tfloat32
] = 'f';
215 mangleChar
[Tfloat64
] = 'd';
216 mangleChar
[Tfloat80
] = 'e';
218 mangleChar
[Timaginary32
] = 'o';
219 mangleChar
[Timaginary64
] = 'p';
220 mangleChar
[Timaginary80
] = 'j';
221 mangleChar
[Tcomplex32
] = 'q';
222 mangleChar
[Tcomplex64
] = 'r';
223 mangleChar
[Tcomplex80
] = 'c';
225 mangleChar
[Tbool
] = 'b';
226 mangleChar
[Tascii
] = 'a';
227 mangleChar
[Twchar
] = 'u';
228 mangleChar
[Tdchar
] = 'w';
230 mangleChar
[Tbit
] = '@';
231 mangleChar
[Tinstance
] = '@';
232 mangleChar
[Terror
] = '@';
233 mangleChar
[Ttypeof
] = '@';
234 mangleChar
[Ttuple
] = 'B';
235 mangleChar
[Tslice
] = '@';
237 for (i
= 0; i
< TMAX
; i
++)
238 { if (!mangleChar
[i
])
239 fprintf(stdmsg
, "ty = %d\n", i
);
240 assert(mangleChar
[i
]);
244 static TY basetab
[] =
245 { Tvoid
, Tint8
, Tuns8
, Tint16
, Tuns16
, Tint32
, Tuns32
, Tint64
, Tuns64
,
246 Tfloat32
, Tfloat64
, Tfloat80
,
247 Timaginary32
, Timaginary64
, Timaginary80
,
248 Tcomplex32
, Tcomplex64
, Tcomplex80
,
250 Tascii
, Twchar
, Tdchar
};
252 for (i
= 0; i
< sizeof(basetab
) / sizeof(basetab
[0]); i
++)
253 basic
[basetab
[i
]] = new TypeBasic(basetab
[i
]);
254 basic
[Terror
] = basic
[Tint32
];
256 tvoidptr
= tvoid
->pointerTo();
258 if (global
.params
.isX86_64
)
261 if (global
.params
.isLinux
)
282 CLASSINFO_SIZE
= 18 * PTRSIZE
;
290 d_uns64
Type::size(Loc loc
)
292 error(loc
, "no size for type %s", toChars());
296 unsigned Type::alignsize()
301 Type
*Type::semantic(Loc loc
, Scope
*sc
)
304 next
= next
->semantic(loc
,sc
);
313 t
= new TypeMaybe(this);
319 Type
*Type::pointerTo()
324 t
= new TypePointer(this);
330 Type
*Type::referenceTo()
335 t
= new TypeReference(this);
341 Type
*Type::arrayOf()
346 t
= new TypeDArray(this);
347 arrayof
= t
->merge();
352 Dsymbol
*Type::toDsymbol(Scope
*sc
)
357 /*******************************
358 * If this is a shell around another type,
359 * get that other type.
362 Type
*Type::toBasetype()
367 /********************************
371 void Type::toDecoBuffer(OutBuffer
*buf
)
373 buf
->writeByte(mangleChar
[ty
]);
376 assert(next
!= this);
377 //printf("this = %p, ty = %d, next = %p, ty = %d\n", this, this->ty, next, next->ty);
378 next
->toDecoBuffer(buf
);
382 /********************************
383 * For pretty-printing a type.
386 char *Type::toChars()
390 buf
= new OutBuffer();
391 toCBuffer(buf
, NULL
, &hgs
);
392 return buf
->toChars();
395 void Type::toCBuffer(OutBuffer
*buf
, Identifier
*ident
, HdrGenState
*hgs
)
397 toCBuffer2(buf
, hgs
, 0);
399 { buf
->writeByte(' ');
400 buf
->writestring(ident
->toChars());
404 void Type::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
406 if (mod
!= this->mod
)
407 { toCBuffer3(buf
, hgs
, mod
);
410 buf
->writestring(toChars());
413 void Type::toCBuffer3(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
415 if (mod
!= this->mod
)
421 toCBuffer2(buf
, hgs
, this->mod
);
428 L1
: buf
->writestring(p
);
429 toCBuffer2(buf
, hgs
, this->mod
);
439 /************************************
445 //printf("merge(%s)\n", toChars());
454 next
= next
->merge();
456 sv
= stringtable
.update((char *)buf
.data
, buf
.offset
);
458 { t
= (Type
*) sv
->ptrvalue
;
460 //printf("old value, deco = '%s' %p\n", t->deco, t->deco);
465 deco
= sv
->lstring
.string
;
466 //printf("new value, deco = '%s' %p\n", t->deco, t->deco);
477 int Type::isintegral()
482 int Type::isfloating()
492 int Type::isimaginary()
497 int Type::iscomplex()
507 int Type::isunsigned()
512 ClassDeclaration
*Type::isClassHandle()
527 int Type::checkBoolean()
532 /*********************************
533 * Check type to see if it is based on a deprecated symbol.
536 void Type::checkDeprecated(Loc loc
, Scope
*sc
)
541 for (t
= this; t
; t
= t
->next
)
543 s
= t
->toDsymbol(sc
);
545 s
->checkDeprecated(loc
, sc
);
550 Expression
*Type::defaultInit(Loc loc
)
553 printf("Type::defaultInit() '%s'\n", toChars());
558 int Type::isZeroInit()
560 return 0; // assume not
563 int Type::isBaseOf(Type
*t
, target_ptrdiff_t
*poffset
)
565 return 0; // assume not
568 /********************************
569 * Determine if 'this' can be implicitly converted
573 * 1 can convert using implicit conversions
574 * 2 this and to are the same type
577 MATCH
Type::implicitConvTo(Type
*to
)
579 //printf("Type::implicitConvTo(this=%p, to=%p)\n", this, to);
580 //printf("\tthis->next=%p, to->next=%p\n", this->next, to->next);
583 // if (to->ty == Tvoid)
588 Expression
*Type::getProperty(Loc loc
, Identifier
*ident
)
592 printf("Type::getProperty(type = '%s', ident = '%s')\n", toChars(), ident
->toChars());
594 if (ident
== Id::__sizeof
)
596 e
= new IntegerExp(loc
, size(loc
), Type::tsize_t
);
598 else if (ident
== Id::size
)
600 error(loc
, ".size property should be replaced with .sizeof");
601 e
= new IntegerExp(loc
, size(loc
), Type::tsize_t
);
603 else if (ident
== Id::alignof
)
605 e
= new IntegerExp(loc
, alignsize(), Type::tsize_t
);
607 else if (ident
== Id::typeinfo
)
609 if (!global
.params
.useDeprecated
)
610 error(loc
, ".typeinfo deprecated, use typeid(type)");
611 e
= getTypeInfo(NULL
);
613 else if (ident
== Id::init
)
616 error(loc
, "void does not have an initializer");
617 e
= defaultInit(loc
);
619 else if (ident
== Id::mangleof
)
622 e
= new StringExp(loc
, deco
, strlen(deco
), 'c');
624 e
= e
->semantic(&sc
);
626 else if (ident
== Id::stringof
)
627 { char *s
= toChars();
628 e
= new StringExp(loc
, s
, strlen(s
), 'c');
630 e
= e
->semantic(&sc
);
634 error(loc
, "no property '%s' for type '%s'", ident
->toChars(), toChars());
635 e
= new IntegerExp(loc
, 1, Type::tint32
);
640 Expression
*Type::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
641 { VarDeclaration
*v
= NULL
;
644 printf("Type::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
646 if (e
->op
== TOKdotvar
)
648 DotVarExp
*dv
= (DotVarExp
*)e
;
649 v
= dv
->var
->isVarDeclaration();
651 else if (e
->op
== TOKvar
)
653 VarExp
*ve
= (VarExp
*)e
;
654 v
= ve
->var
->isVarDeclaration();
658 if (ident
== Id::offset
)
660 if (!global
.params
.useDeprecated
)
661 error(e
->loc
, ".offset deprecated, use .offsetof");
664 else if (ident
== Id::offsetof
)
667 if (v
->storage_class
& STCfield
)
669 e
= new IntegerExp(e
->loc
, v
->offset
, Type::tsize_t
);
673 else if (ident
== Id::init
)
678 if (v
->init
->isVoidInitializer())
679 error(e
->loc
, "%s.init is void", v
->toChars());
682 e
= v
->init
->toExpression();
683 if (e
->op
== TOKassign
|| e
->op
== TOKconstruct
)
685 e
= ((AssignExp
*)e
)->e2
;
687 /* Take care of case where we used a 0
688 * to initialize the struct.
690 if (e
->type
== Type::tint32
&&
692 v
->type
->toBasetype()->ty
== Tstruct
)
694 e
= v
->type
->defaultInit(loc
);
697 e
= e
->optimize(WANTvalue
| WANTinterpret
);
698 // if (!e->isConst())
699 // error(loc, ".init cannot be evaluated at compile time");
704 Expression
*ex
= defaultInit(e
->loc
);
708 if (ident
== Id::typeinfo
)
710 if (!global
.params
.useDeprecated
)
711 error(e
->loc
, ".typeinfo deprecated, use typeid(type)");
715 if (ident
== Id::stringof
)
716 { char *s
= e
->toChars();
717 e
= new StringExp(e
->loc
, s
, strlen(s
), 'c');
719 e
= e
->semantic(&sc
);
722 return getProperty(e
->loc
, ident
);
725 unsigned Type::memalign(unsigned salign
)
730 void Type::error(Loc loc
, const char *format
, ...)
733 va_start(ap
, format
);
734 ::verror(loc
, format
, ap
);
738 Identifier
*Type::getTypeInfoIdent(int internal
)
740 // _init_10TypeInfo_%s
746 //toTypeInfoBuffer(&buf);
748 { buf
.writeByte(mangleChar
[ty
]);
750 buf
.writeByte(mangleChar
[next
->ty
]);
755 name
= (char *)alloca(19 + sizeof(len
) * 3 + len
+ 1);
757 sprintf(name
, "_D%dTypeInfo_%s6__initZ", 9 + len
, buf
.data
);
758 if (global
.params
.isWindows
)
759 name
++; // C mangling will add it back in
760 //printf("name = %s\n", name);
761 id
= Lexer::idPool(name
);
765 TypeBasic
*Type::isTypeBasic()
771 void Type::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
775 t
= semantic(loc
, sc
);
781 /*******************************
782 * If one of the subtypes of this type is a TypeIdentifier,
783 * i.e. it's an unresolved type, return that type.
786 Type
*Type::reliesOnTident()
791 return next
->reliesOnTident();
794 /********************************
795 * We've mistakenly parsed this as a type.
796 * Redo it as an Expression.
800 Expression
*Type::toExpression()
805 /***************************************
806 * Return !=0 if type has pointers that need to
807 * be scanned by the GC during a collection cycle.
810 int Type::hasPointers()
815 /* ============================= TypeBasic =========================== */
817 TypeBasic::TypeBasic(TY ty
)
823 #define TFLAGSintegral 1
824 #define TFLAGSfloating 2
825 #define TFLAGSunsigned 4
827 #define TFLAGSimaginary 0x10
828 #define TFLAGScomplex 0x20
833 case Tvoid
: d
= Token::toChars(TOKvoid
);
837 case Tint8
: d
= Token::toChars(TOKint8
);
839 flags
|= TFLAGSintegral
;
842 case Tuns8
: d
= Token::toChars(TOKuns8
);
844 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
847 case Tint16
: d
= Token::toChars(TOKint16
);
849 flags
|= TFLAGSintegral
;
852 case Tuns16
: d
= Token::toChars(TOKuns16
);
854 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
857 case Tint32
: d
= Token::toChars(TOKint32
);
859 flags
|= TFLAGSintegral
;
862 case Tuns32
: d
= Token::toChars(TOKuns32
);
864 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
867 case Tfloat32
: d
= Token::toChars(TOKfloat32
);
869 flags
|= TFLAGSfloating
| TFLAGSreal
;
872 case Tint64
: d
= Token::toChars(TOKint64
);
874 flags
|= TFLAGSintegral
;
877 case Tuns64
: d
= Token::toChars(TOKuns64
);
879 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
882 case Tfloat64
: d
= Token::toChars(TOKfloat64
);
884 flags
|= TFLAGSfloating
| TFLAGSreal
;
887 case Tfloat80
: d
= Token::toChars(TOKfloat80
);
889 flags
|= TFLAGSfloating
| TFLAGSreal
;
892 case Timaginary32
: d
= Token::toChars(TOKimaginary32
);
894 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
897 case Timaginary64
: d
= Token::toChars(TOKimaginary64
);
899 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
902 case Timaginary80
: d
= Token::toChars(TOKimaginary80
);
904 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
907 case Tcomplex32
: d
= Token::toChars(TOKcomplex32
);
909 flags
|= TFLAGSfloating
| TFLAGScomplex
;
912 case Tcomplex64
: d
= Token::toChars(TOKcomplex64
);
914 flags
|= TFLAGSfloating
| TFLAGScomplex
;
917 case Tcomplex80
: d
= Token::toChars(TOKcomplex80
);
919 flags
|= TFLAGSfloating
| TFLAGScomplex
;
923 case Tbit
: d
= Token::toChars(TOKbit
);
925 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
928 case Tbool
: d
= "bool";
930 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
933 case Tascii
: d
= Token::toChars(TOKchar
);
935 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
938 case Twchar
: d
= Token::toChars(TOKwchar
);
940 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
943 case Tdchar
: d
= Token::toChars(TOKdchar
);
945 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
956 Type
*TypeBasic::syntaxCopy()
958 // No semantic analysis done on basic types, no need to copy
963 char *TypeBasic::toChars()
968 void TypeBasic::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
970 //printf("TypeBasic::toCBuffer2(mod = %d, this->mod = %d)\n", mod, this->mod);
971 if (mod
!= this->mod
)
972 { toCBuffer3(buf
, hgs
, mod
);
975 buf
->writestring(dstring
);
978 d_uns64
TypeBasic::size(Loc loc
)
981 //printf("TypeBasic::size()\n");
985 case Tuns8
: size
= 1; break;
987 case Tuns16
: size
= 2; break;
1000 size
= REALSIZE
; break;
1006 size
= REALSIZE
* 2; break;
1009 //size = Type::size(); // error message
1013 case Tbit
: size
= 1; break;
1014 case Tbool
: size
= 1; break;
1015 case Tascii
: size
= 1; break;
1016 case Twchar
: size
= 2; break;
1017 case Tdchar
: size
= 4; break;
1023 //printf("TypeBasic::size() = %d\n", size);
1027 unsigned TypeBasic::alignsize()
1046 Expression
*TypeBasic::getProperty(Loc loc
, Identifier
*ident
)
1056 //printf("TypeBasic::getProperty('%s')\n", ident->toChars());
1057 if (ident
== Id::max
)
1061 case Tint8
: ivalue
= 0x7F; goto Livalue
;
1062 case Tuns8
: ivalue
= 0xFF; goto Livalue
;
1063 case Tint16
: ivalue
= 0x7FFFUL
; goto Livalue
;
1064 case Tuns16
: ivalue
= 0xFFFFUL
; goto Livalue
;
1065 case Tint32
: ivalue
= 0x7FFFFFFFUL
; goto Livalue
;
1066 case Tuns32
: ivalue
= 0xFFFFFFFFUL
; goto Livalue
;
1067 case Tint64
: ivalue
= 0x7FFFFFFFFFFFFFFFLL
; goto Livalue
;
1068 case Tuns64
: ivalue
= 0xFFFFFFFFFFFFFFFFULL
; goto Livalue
;
1069 case Tbit
: ivalue
= 1; goto Livalue
;
1070 case Tbool
: ivalue
= 1; goto Livalue
;
1071 case Tchar
: ivalue
= 0xFF; goto Livalue
;
1072 case Twchar
: ivalue
= 0xFFFFUL
; goto Livalue
;
1073 case Tdchar
: ivalue
= 0x10FFFFUL
; goto Livalue
;
1079 #define FLT_MAX real_t_properties[real_t::Float].maxval;
1080 #define DBL_MAX real_t_properties[real_t::Double].maxval;
1081 #define LDBL_MAX real_t_properties[real_t::LongDouble].maxval;
1082 #define FLT_MIN real_t_properties[real_t::Float].minval;
1083 #define DBL_MIN real_t_properties[real_t::Double].minval;
1084 #define LDBL_MIN real_t_properties[real_t::LongDouble].minval;
1085 #define FLT_DIG real_t_properties[real_t::Float].dig;
1086 #define DBL_DIG real_t_properties[real_t::Double].dig;
1087 #define LDBL_DIG real_t_properties[real_t::LongDouble].dig;
1088 #define FLT_MANT_DIG real_t_properties[real_t::Float].mant_dig;
1089 #define DBL_MANT_DIG real_t_properties[real_t::Double].mant_dig;
1090 #define LDBL_MANT_DIG real_t_properties[real_t::LongDouble].mant_dig;
1091 #define FLT_MAX_10_EXP real_t_properties[real_t::Float].max_10_exp;
1092 #define DBL_MAX_10_EXP real_t_properties[real_t::Double].max_10_exp;
1093 #define LDBL_MAX_10_EXP real_t_properties[real_t::LongDouble].max_10_exp;
1094 #define FLT_MIN_10_EXP real_t_properties[real_t::Float].min_10_exp;
1095 #define DBL_MIN_10_EXP real_t_properties[real_t::Double].min_10_exp;
1096 #define LDBL_MIN_10_EXP real_t_properties[real_t::LongDouble].min_10_exp;
1097 #define FLT_MAX_EXP real_t_properties[real_t::Float].max_exp;
1098 #define DBL_MAX_EXP real_t_properties[real_t::Double].max_exp;
1099 #define LDBL_MAX_EXP real_t_properties[real_t::LongDouble].max_exp;
1100 #define FLT_MIN_EXP real_t_properties[real_t::Float].min_exp;
1101 #define DBL_MIN_EXP real_t_properties[real_t::Double].min_exp;
1102 #define LDBL_MIN_EXP real_t_properties[real_t::LongDouble].min_exp;
1103 #define FLT_EPSILON real_t_properties[real_t::Float].epsilonval;
1104 #define DBL_EPSILON real_t_properties[real_t::Double].epsilonval;
1105 #define LDBL_EPSILON real_t_properties[real_t::LongDouble].epsilonval;
1109 case Tfloat32
: fvalue
= FLT_MAX
; goto Lfvalue
;
1112 case Tfloat64
: fvalue
= DBL_MAX
; goto Lfvalue
;
1115 case Tfloat80
: fvalue
= LDBL_MAX
; goto Lfvalue
;
1118 else if (ident
== Id::min
)
1122 case Tint8
: ivalue
= -128; goto Livalue
;
1123 case Tuns8
: ivalue
= 0; goto Livalue
;
1124 case Tint16
: ivalue
= -32768; goto Livalue
;
1125 case Tuns16
: ivalue
= 0; goto Livalue
;
1126 case Tint32
: ivalue
= -2147483647L - 1; goto Livalue
;
1127 case Tuns32
: ivalue
= 0; goto Livalue
;
1128 case Tint64
: ivalue
= (-9223372036854775807LL-1LL); goto Livalue
;
1129 case Tuns64
: ivalue
= 0; goto Livalue
;
1130 case Tbit
: ivalue
= 0; goto Livalue
;
1131 case Tbool
: ivalue
= 0; goto Livalue
;
1132 case Tchar
: ivalue
= 0; goto Livalue
;
1133 case Twchar
: ivalue
= 0; goto Livalue
;
1134 case Tdchar
: ivalue
= 0; goto Livalue
;
1138 case Tfloat32
: fvalue
= FLT_MIN
; goto Lfvalue
;
1141 case Tfloat64
: fvalue
= DBL_MIN
; goto Lfvalue
;
1144 case Tfloat80
: fvalue
= LDBL_MIN
; goto Lfvalue
;
1147 else if (ident
== Id::nan
)
1162 // mode doesn't matter, will be converted in RealExp anyway
1163 fvalue
= real_t::getnan(real_t::LongDouble
);
1165 // gcc nan's have the sign bit set by default, so turn it off
1166 // Need the volatile to prevent gcc from doing incorrect
1167 // constant folding.
1168 volatile d_float80 foo
;
1170 if (signbit(foo
)) // signbit sometimes, not always, set
1171 foo
= -foo
; // turn off sign bit
1174 unsigned long nan
[2]= { 0xFFFFFFFF, 0x7FFFFFFF };
1175 fvalue
= *(double*)nan
;
1183 else if (ident
== Id::infinity
)
1197 fvalue
= real_t::getinfinity();
1201 fvalue
= std::numeric_limits
<long double>::infinity();
1208 else if (ident
== Id::dig
)
1214 case Tfloat32
: ivalue
= FLT_DIG
; goto Lint
;
1217 case Tfloat64
: ivalue
= DBL_DIG
; goto Lint
;
1220 case Tfloat80
: ivalue
= LDBL_DIG
; goto Lint
;
1223 else if (ident
== Id::epsilon
)
1229 case Tfloat32
: fvalue
= FLT_EPSILON
; goto Lfvalue
;
1232 case Tfloat64
: fvalue
= DBL_EPSILON
; goto Lfvalue
;
1235 case Tfloat80
: fvalue
= LDBL_EPSILON
; goto Lfvalue
;
1238 else if (ident
== Id::mant_dig
)
1244 case Tfloat32
: ivalue
= FLT_MANT_DIG
; goto Lint
;
1247 case Tfloat64
: ivalue
= DBL_MANT_DIG
; goto Lint
;
1250 case Tfloat80
: ivalue
= LDBL_MANT_DIG
; goto Lint
;
1253 else if (ident
== Id::max_10_exp
)
1259 case Tfloat32
: ivalue
= FLT_MAX_10_EXP
; goto Lint
;
1262 case Tfloat64
: ivalue
= DBL_MAX_10_EXP
; goto Lint
;
1265 case Tfloat80
: ivalue
= LDBL_MAX_10_EXP
; goto Lint
;
1268 else if (ident
== Id::max_exp
)
1274 case Tfloat32
: ivalue
= FLT_MAX_EXP
; goto Lint
;
1277 case Tfloat64
: ivalue
= DBL_MAX_EXP
; goto Lint
;
1280 case Tfloat80
: ivalue
= LDBL_MAX_EXP
; goto Lint
;
1283 else if (ident
== Id::min_10_exp
)
1289 case Tfloat32
: ivalue
= FLT_MIN_10_EXP
; goto Lint
;
1292 case Tfloat64
: ivalue
= DBL_MIN_10_EXP
; goto Lint
;
1295 case Tfloat80
: ivalue
= LDBL_MIN_10_EXP
; goto Lint
;
1298 else if (ident
== Id::min_exp
)
1304 case Tfloat32
: ivalue
= FLT_MIN_EXP
; goto Lint
;
1307 case Tfloat64
: ivalue
= DBL_MIN_EXP
; goto Lint
;
1310 case Tfloat80
: ivalue
= LDBL_MIN_EXP
; goto Lint
;
1315 return Type::getProperty(loc
, ident
);
1318 e
= new IntegerExp(loc
, ivalue
, this);
1322 if (isreal() || isimaginary())
1323 e
= new RealExp(loc
, fvalue
, this);
1329 //((real_t *)&cvalue)[0] = fvalue;
1330 //((real_t *)&cvalue)[1] = fvalue;
1331 cvalue
= fvalue
+ fvalue
* I
;
1336 //for (int i = 0; i < 20; i++)
1337 // printf("%02x ", ((unsigned char *)&cvalue)[i]);
1339 e
= new ComplexExp(loc
, cvalue
, this);
1344 e
= new IntegerExp(loc
, ivalue
, Type::tint32
);
1348 Expression
*TypeBasic::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
1351 printf("TypeBasic::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
1355 if (ident
== Id::re
)
1359 case Tcomplex32
: t
= tfloat32
; goto L1
;
1360 case Tcomplex64
: t
= tfloat64
; goto L1
;
1361 case Tcomplex80
: t
= tfloat80
; goto L1
;
1363 e
= e
->castTo(sc
, t
);
1371 case Timaginary32
: t
= tfloat32
; goto L2
;
1372 case Timaginary64
: t
= tfloat64
; goto L2
;
1373 case Timaginary80
: t
= tfloat80
; goto L2
;
1375 e
= new RealExp(0, 0, t
);
1379 return Type::getProperty(e
->loc
, ident
);
1382 else if (ident
== Id::im
)
1387 case Tcomplex32
: t
= timaginary32
; t2
= tfloat32
; goto L3
;
1388 case Tcomplex64
: t
= timaginary64
; t2
= tfloat64
; goto L3
;
1389 case Tcomplex80
: t
= timaginary80
; t2
= tfloat80
; goto L3
;
1391 e
= e
->castTo(sc
, t
);
1395 case Timaginary32
: t
= tfloat32
; goto L4
;
1396 case Timaginary64
: t
= tfloat64
; goto L4
;
1397 case Timaginary80
: t
= tfloat80
; goto L4
;
1405 e
= new RealExp(0, 0, this);
1409 return Type::getProperty(e
->loc
, ident
);
1414 return Type::dotExp(sc
, e
, ident
);
1419 Expression
*TypeBasic::defaultInit(Loc loc
)
1420 { integer_t value
= 0;
1423 printf("TypeBasic::defaultInit() '%s'\n", toChars());
1445 return getProperty(loc
, Id::nan
);
1447 return new IntegerExp(loc
, value
, this);
1450 int TypeBasic::isZeroInit()
1471 int TypeBasic::isbit()
1473 return (ty
== Tbit
);
1476 int TypeBasic::isintegral()
1478 //printf("TypeBasic::isintegral('%s') x%x\n", toChars(), flags);
1479 return flags
& TFLAGSintegral
;
1482 int TypeBasic::isfloating()
1484 return flags
& TFLAGSfloating
;
1487 int TypeBasic::isreal()
1489 return flags
& TFLAGSreal
;
1492 int TypeBasic::isimaginary()
1494 return flags
& TFLAGSimaginary
;
1497 int TypeBasic::iscomplex()
1499 return flags
& TFLAGScomplex
;
1502 int TypeBasic::isunsigned()
1504 return flags
& TFLAGSunsigned
;
1507 int TypeBasic::isscalar()
1509 return flags
& (TFLAGSintegral
| TFLAGSfloating
);
1512 MATCH
TypeBasic::implicitConvTo(Type
*to
)
1514 //printf("TypeBasic::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
1518 if (ty
== Tvoid
|| to
->ty
== Tvoid
)
1519 return MATCHnomatch
;
1520 if (1 || global
.params
.Dversion
== 1)
1522 if (to
->ty
== Tbool
)
1523 return MATCHnomatch
;
1527 if (ty
== Tbool
|| to
->ty
== Tbool
)
1528 return MATCHnomatch
;
1530 if (!to
->isTypeBasic())
1531 return MATCHnomatch
;
1533 TypeBasic
*tob
= (TypeBasic
*)to
;
1534 if (flags
& TFLAGSintegral
)
1536 // Disallow implicit conversion of integers to imaginary or complex
1537 if (tob
->flags
& (TFLAGSimaginary
| TFLAGScomplex
))
1538 return MATCHnomatch
;
1540 // If converting to integral
1541 if (0 && global
.params
.Dversion
> 1 && tob
->flags
& TFLAGSintegral
)
1542 { d_uns64 sz
= size(0);
1543 d_uns64 tosz
= tob
->size(0);
1545 /* Can't convert to smaller size or, if same size, change sign
1548 return MATCHnomatch
;
1550 /*if (sz == tosz && (flags ^ tob->flags) & TFLAGSunsigned)
1551 return MATCHnomatch;*/
1554 else if (flags
& TFLAGSfloating
)
1556 // Disallow implicit conversion of floating point to integer
1557 if (tob
->flags
& TFLAGSintegral
)
1558 return MATCHnomatch
;
1560 assert(tob
->flags
& TFLAGSfloating
);
1562 // Disallow implicit conversion from complex to non-complex
1563 if (flags
& TFLAGScomplex
&& !(tob
->flags
& TFLAGScomplex
))
1564 return MATCHnomatch
;
1566 // Disallow implicit conversion of real or imaginary to complex
1567 if (flags
& (TFLAGSreal
| TFLAGSimaginary
) &&
1568 tob
->flags
& TFLAGScomplex
)
1569 return MATCHnomatch
;
1571 // Disallow implicit conversion to-from real and imaginary
1572 if ((flags
& (TFLAGSreal
| TFLAGSimaginary
)) !=
1573 (tob
->flags
& (TFLAGSreal
| TFLAGSimaginary
)))
1574 return MATCHnomatch
;
1576 return MATCHconvert
;
1579 TypeBasic
*TypeBasic::isTypeBasic()
1581 return (TypeBasic
*)this;
1584 /***************************** TypeArray *****************************/
1586 TypeArray::TypeArray(TY ty
, Type
*next
)
1591 Expression
*TypeArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
1593 Type
*n
= this->next
->toBasetype(); // uncover any typedef's
1596 printf("TypeArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
1598 if (ident
== Id::reverse
&& (n
->ty
== Tchar
|| n
->ty
== Twchar
))
1601 FuncDeclaration
*fd
;
1602 Expressions
*arguments
;
1604 static char *name
[2] = { "_adReverseChar", "_adReverseWchar" };
1606 nm
= name
[n
->ty
== Twchar
];
1607 fd
= FuncDeclaration::genCfunc(next
->arrayOf(), nm
, Type::tvoid
->arrayOf());
1608 ec
= new VarExp(0, fd
);
1609 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1610 arguments
= new Expressions();
1612 e
= new CallExp(e
->loc
, ec
, arguments
);
1613 e
->type
= next
->arrayOf();
1615 else if (ident
== Id::sort
&& (n
->ty
== Tchar
|| n
->ty
== Twchar
))
1618 FuncDeclaration
*fd
;
1619 Expressions
*arguments
;
1621 static char *name
[2] = { "_adSortChar", "_adSortWchar" };
1623 nm
= name
[n
->ty
== Twchar
];
1624 fd
= FuncDeclaration::genCfunc(next
->arrayOf(), nm
, Type::tvoid
->arrayOf());
1625 ec
= new VarExp(0, fd
);
1626 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1627 arguments
= new Expressions();
1629 e
= new CallExp(e
->loc
, ec
, arguments
);
1630 e
->type
= next
->arrayOf();
1632 else if (ident
== Id::reverse
|| ident
== Id::dup
)
1635 FuncDeclaration
*fd
;
1636 Expressions
*arguments
;
1637 target_size_t size
= next
->size(e
->loc
);
1641 dup
= (ident
== Id::dup
);
1643 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::adDup
,
1644 Type::typeinfo
->type
, Type::tvoid
->arrayOf());
1646 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::adReverse
,
1647 Type::tvoid
->arrayOf(), Type::tsize_t
);
1648 ec
= new VarExp(0, fd
);
1649 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1650 arguments
= new Expressions();
1652 arguments
->push(getTypeInfo(sc
));
1655 arguments
->push(new IntegerExp(0, size
, Type::tsize_t
));
1656 e
= new CallExp(e
->loc
, ec
, arguments
);
1657 e
->type
= next
->arrayOf();
1659 else if (ident
== Id::sort
)
1662 FuncDeclaration
*fd
;
1663 Expressions
*arguments
;
1665 fd
= FuncDeclaration::genCfunc(tint32
->arrayOf(),
1666 (char*)(n
->ty
== Tbit
? "_adSortBit" : "_adSort"),
1667 Type::tvoid
->arrayOf(),
1668 n
->ty
== Tbit
? NULL
: Type::tvoid
->pointerTo());
1669 ec
= new VarExp(0, fd
);
1670 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1671 arguments
= new Expressions();
1673 if (next
->ty
!= Tbit
)
1674 arguments
->push(n
->ty
== Tsarray
1675 ? n
->getTypeInfo(sc
) // don't convert to dynamic array
1676 : n
->getInternalTypeInfo(sc
));
1677 e
= new CallExp(e
->loc
, ec
, arguments
);
1678 e
->type
= next
->arrayOf();
1682 e
= Type::dotExp(sc
, e
, ident
);
1688 /***************************** TypeSArray *****************************/
1690 TypeSArray::TypeSArray(Type
*t
, Expression
*dim
)
1691 : TypeArray(Tsarray
, t
)
1693 //printf("TypeSArray(%s)\n", dim->toChars());
1697 Type
*TypeSArray::syntaxCopy()
1699 Type
*t
= next
->syntaxCopy();
1700 Expression
*e
= dim
->syntaxCopy();
1701 t
= new TypeSArray(t
, e
);
1705 d_uns64
TypeSArray::size(Loc loc
)
1709 return Type::size(loc
);
1710 sz
= dim
->toInteger();
1711 if (next
->toBasetype()->ty
== Tbit
) // if array of bits
1715 sz
= ((sz
+ 31) & ~31) / 8; // size in bytes, rounded up to 32 bit dwords
1722 if (n
&& (n2
/ n
) != sz
)
1729 error(loc
, "index %"PRIdMAX
" overflow for static array", sz
);
1733 unsigned TypeSArray::alignsize()
1735 return next
->alignsize();
1738 /**************************
1739 * This evaluates exp while setting length to be the number
1740 * of elements in the tuple t.
1742 Expression
*semanticLength(Scope
*sc
, Type
*t
, Expression
*exp
)
1744 if (t
->ty
== Ttuple
)
1745 { ScopeDsymbol
*sym
= new ArrayScopeSymbol((TypeTuple
*)t
);
1746 sym
->parent
= sc
->scopesym
;
1749 exp
= exp
->semantic(sc
);
1754 exp
= exp
->semantic(sc
);
1758 Expression
*semanticLength(Scope
*sc
, TupleDeclaration
*s
, Expression
*exp
)
1760 ScopeDsymbol
*sym
= new ArrayScopeSymbol(s
);
1761 sym
->parent
= sc
->scopesym
;
1764 exp
= exp
->semantic(sc
);
1770 void TypeSArray::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
1772 //printf("TypeSArray::resolve() %s\n", toChars());
1773 next
->resolve(loc
, sc
, pe
, pt
, ps
);
1774 //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
1776 { // It's really an index expression
1778 e
= new IndexExp(loc
, *pe
, dim
);
1783 TupleDeclaration
*td
= s
->isTupleDeclaration();
1786 ScopeDsymbol
*sym
= new ArrayScopeSymbol(td
);
1787 sym
->parent
= sc
->scopesym
;
1790 dim
= dim
->semantic(sc
);
1791 dim
= dim
->optimize(WANTvalue
| WANTinterpret
);
1792 uinteger_t d
= dim
->toUInteger();
1796 if (d
>= td
->objects
->dim
)
1797 { error(loc
, "tuple index %"PRIuMAX
" exceeds %u", d
, td
->objects
->dim
);
1800 Object
*o
= (Object
*)td
->objects
->data
[(size_t)d
];
1801 if (o
->dyncast() == DYNCAST_DSYMBOL
)
1806 if (o
->dyncast() == DYNCAST_EXPRESSION
)
1809 *pe
= (Expression
*)o
;
1813 /* Create a new TupleDeclaration which
1814 * is a slice [d..d+1] out of the old one.
1815 * Do it this way because TemplateInstance::semanticTiargs()
1816 * can handle unresolved Objects this way.
1818 Objects
*objects
= new Objects
;
1820 objects
->data
[0] = o
;
1822 TupleDeclaration
*tds
= new TupleDeclaration(loc
, td
->ident
, objects
);
1831 Type::resolve(loc
, sc
, pe
, pt
, ps
);
1835 Type
*TypeSArray::semantic(Loc loc
, Scope
*sc
)
1837 //printf("TypeSArray::semantic() %s\n", toChars());
1842 next
->resolve(loc
, sc
, &e
, &t
, &s
);
1843 if (dim
&& s
&& s
->isTupleDeclaration())
1844 { TupleDeclaration
*sd
= s
->isTupleDeclaration();
1846 dim
= semanticLength(sc
, sd
, dim
);
1847 dim
= dim
->optimize(WANTvalue
| WANTinterpret
);
1848 uinteger_t d
= dim
->toUInteger();
1850 if (d
>= sd
->objects
->dim
)
1851 { error(loc
, "tuple index %ju exceeds %u", d
, sd
->objects
->dim
);
1852 return Type::terror
;
1854 Object
*o
= (Object
*)sd
->objects
->data
[(size_t)d
];
1855 if (o
->dyncast() != DYNCAST_TYPE
)
1856 { error(loc
, "%s is not a type", toChars());
1857 return Type::terror
;
1863 next
= next
->semantic(loc
,sc
);
1864 Type
*tbn
= next
->toBasetype();
1869 dim
= semanticLength(sc
, tbn
, dim
);
1871 dim
= dim
->optimize(WANTvalue
| WANTinterpret
);
1872 if (sc
->parameterSpecialization
&& dim
->op
== TOKvar
&&
1873 ((VarExp
*)dim
)->var
->storage_class
& STCtemplateparameter
)
1875 /* It could be a template parameter N which has no value yet:
1876 * template Foo(T : T[N], size_t N);
1880 integer_t d1
= dim
->toInteger();
1881 dim
= dim
->castTo(sc
, tsize_t
);
1882 dim
= dim
->optimize(WANTvalue
);
1883 integer_t d2
= dim
->toInteger();
1888 if (tbn
->isintegral() ||
1889 tbn
->isfloating() ||
1890 tbn
->ty
== Tpointer
||
1891 tbn
->ty
== Tarray
||
1892 tbn
->ty
== Tsarray
||
1893 tbn
->ty
== Taarray
||
1896 /* Only do this for types that don't need to have semantic()
1897 * run on them for the size, since they may be forward referenced.
1903 if (n2
>= 0x1000000) // put a 'reasonable' limit on it
1905 if (n
&& n2
/ n
!= d2
)
1908 error(loc
, "index %"PRIdMAX
" overflow for static array", d1
);
1909 dim
= new IntegerExp(0, 1, tsize_t
);
1916 { // Index the tuple to get the type
1918 TypeTuple
*tt
= (TypeTuple
*)tbn
;
1919 uinteger_t d
= dim
->toUInteger();
1921 if (d
>= tt
->arguments
->dim
)
1922 { error(loc
, "tuple index %"PRIuMAX
" exceeds %u", d
, tt
->arguments
->dim
);
1923 return Type::terror
;
1925 Argument
*arg
= (Argument
*)tt
->arguments
->data
[(size_t)d
];
1930 error(loc
, "can't have array of %s", tbn
->toChars());
1931 tbn
= next
= tint32
;
1935 error(loc
, "cannot have array of auto %s", tbn
->toChars());
1939 void TypeSArray::toDecoBuffer(OutBuffer
*buf
)
1941 buf
->writeByte(mangleChar
[ty
]);
1943 buf
->printf("%"PRIuMAX
, dim
->toInteger());
1945 next
->toDecoBuffer(buf
);
1948 void TypeSArray::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
1950 if (mod
!= this->mod
)
1951 { toCBuffer3(buf
, hgs
, mod
);
1954 next
->toCBuffer2(buf
, hgs
, this->mod
);
1955 buf
->printf("[%s]", dim
->toChars());
1958 Expression
*TypeSArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
1961 printf("TypeSArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
1963 if (ident
== Id::length
)
1967 else if (ident
== Id::ptr
)
1969 e
= e
->castTo(sc
, next
->pointerTo());
1973 e
= TypeArray::dotExp(sc
, e
, ident
);
1978 int TypeSArray::isString()
1980 TY nty
= next
->toBasetype()->ty
;
1981 return nty
== Tchar
|| nty
== Twchar
|| nty
== Tdchar
;
1984 unsigned TypeSArray::memalign(unsigned salign
)
1986 return next
->memalign(salign
);
1989 MATCH
TypeSArray::implicitConvTo(Type
*to
)
1991 //printf("TypeSArray::implicitConvTo()\n");
1993 // Allow implicit conversion of static array to pointer or dynamic array
1994 if ((IMPLICIT_ARRAY_TO_PTR
&& to
->ty
== Tpointer
) &&
1995 (to
->next
->ty
== Tvoid
|| next
->equals(to
->next
)
1996 /*|| to->next->isBaseOf(next)*/))
1998 return MATCHconvert
;
2000 if (to
->ty
== Tarray
)
2001 { target_ptrdiff_t offset
= 0;
2003 if (next
->equals(to
->next
) ||
2004 (to
->next
->isBaseOf(next
, &offset
) && offset
== 0) ||
2005 to
->next
->ty
== Tvoid
)
2006 return MATCHconvert
;
2009 if (to
->ty
== Tsarray
)
2011 TypeSArray
*tsa
= (TypeSArray
*)to
;
2013 if (next
->equals(tsa
->next
) && dim
->equals(tsa
->dim
))
2015 return MATCHconvert
;
2019 return Type::implicitConvTo(to
);
2022 Expression
*TypeSArray::defaultInit(Loc loc
)
2025 printf("TypeSArray::defaultInit() '%s'\n", toChars());
2027 return next
->defaultInit(loc
);
2030 int TypeSArray::isZeroInit()
2032 return next
->isZeroInit();
2036 Expression
*TypeSArray::toExpression()
2038 Expression
*e
= next
->toExpression();
2040 { Expressions
*arguments
= new Expressions();
2041 arguments
->push(dim
);
2042 e
= new ArrayExp(dim
->loc
, e
, arguments
);
2047 int TypeSArray::hasPointers()
2049 return next
->hasPointers();
2052 /***************************** TypeDArray *****************************/
2054 TypeDArray::TypeDArray(Type
*t
)
2055 : TypeArray(Tarray
, t
)
2057 //printf("TypeDArray(t = %p)\n", t);
2060 Type
*TypeDArray::syntaxCopy()
2062 Type
*t
= next
->syntaxCopy();
2066 t
= new TypeDArray(t
);
2070 d_uns64
TypeDArray::size(Loc loc
)
2072 //printf("TypeDArray::size()\n");
2076 unsigned TypeDArray::alignsize()
2078 // A DArray consists of two ptr-sized values, so align it on pointer size
2083 Type
*TypeDArray::semantic(Loc loc
, Scope
*sc
)
2086 tn
= next
->semantic(loc
,sc
);
2087 Type
*tbn
= tn
->toBasetype();
2093 error(loc
, "can't have array of %s", tbn
->toChars());
2098 error(loc
, "cannot have array of auto %s", tn
->toChars());
2100 //deco = NULL; // redo
2101 return tn
->arrayOf();
2105 void TypeDArray::toDecoBuffer(OutBuffer
*buf
)
2107 buf
->writeByte(mangleChar
[ty
]);
2109 next
->toDecoBuffer(buf
);
2112 void TypeDArray::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2114 if (mod
!= this->mod
)
2115 { toCBuffer3(buf
, hgs
, mod
);
2118 next
->toCBuffer2(buf
, hgs
, this->mod
);
2119 buf
->writestring("[]");
2122 Expression
*TypeDArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2125 printf("TypeDArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
2127 if (ident
== Id::length
)
2129 if (e
->op
== TOKstring
)
2130 { StringExp
*se
= (StringExp
*)e
;
2132 return new IntegerExp(se
->loc
, se
->len
, Type::tindex
);
2134 e
= new ArrayLengthExp(e
->loc
, e
);
2135 e
->type
= Type::tsize_t
;
2138 else if (ident
== Id::ptr
)
2140 e
= e
->castTo(sc
, next
->pointerTo());
2145 e
= TypeArray::dotExp(sc
, e
, ident
);
2150 int TypeDArray::isString()
2152 TY nty
= next
->toBasetype()->ty
;
2153 return nty
== Tchar
|| nty
== Twchar
|| nty
== Tdchar
;
2156 MATCH
TypeDArray::implicitConvTo(Type
*to
)
2158 //printf("TypeDArray::implicitConvTo()\n");
2160 // Allow implicit conversion of array to pointer
2161 if (IMPLICIT_ARRAY_TO_PTR
&&
2162 to
->ty
== Tpointer
&&
2163 (to
->next
->ty
== Tvoid
|| next
->equals(to
->next
) /*|| to->next->isBaseOf(next)*/))
2165 return MATCHconvert
;
2168 if (to
->ty
== Tarray
)
2169 { target_ptrdiff_t offset
= 0;
2171 if ((to
->next
->isBaseOf(next
, &offset
) && offset
== 0) ||
2172 to
->next
->ty
== Tvoid
)
2173 return MATCHconvert
;
2175 return Type::implicitConvTo(to
);
2178 Expression
*TypeDArray::defaultInit(Loc loc
)
2181 printf("TypeDArray::defaultInit() '%s'\n", toChars());
2184 e
= new NullExp(loc
);
2189 int TypeDArray::isZeroInit()
2194 int TypeDArray::checkBoolean()
2199 int TypeDArray::hasPointers()
2204 /***************************** TypeAArray *****************************/
2206 TypeAArray::TypeAArray(Type
*t
, Type
*index
)
2207 : TypeArray(Taarray
, t
)
2209 this->index
= index
;
2213 Type
*TypeAArray::syntaxCopy()
2215 Type
*t
= next
->syntaxCopy();
2216 Type
*ti
= index
->syntaxCopy();
2217 if (t
== next
&& ti
== index
)
2220 t
= new TypeAArray(t
, ti
);
2224 d_uns64
TypeAArray::size(Loc loc
)
2226 return PTRSIZE
/* * 2*/;
2230 Type
*TypeAArray::semantic(Loc loc
, Scope
*sc
)
2232 //printf("TypeAArray::semantic() %s index->ty = %d\n", toChars(), index->ty);
2234 // Deal with the case where we thought the index was a type, but
2235 // in reality it was an expression.
2236 if (index
->ty
== Tident
|| index
->ty
== Tinstance
|| index
->ty
== Tsarray
)
2242 index
->resolve(loc
, sc
, &e
, &t
, &s
);
2244 { // It was an expression -
2245 // Rewrite as a static array
2248 tsa
= new TypeSArray(next
, e
);
2249 return tsa
->semantic(loc
,sc
);
2254 index
->error(loc
, "index is not a type or an expression");
2257 index
= index
->semantic(loc
,sc
);
2259 // Compute key type; the purpose of the key type is to
2260 // minimize the permutations of runtime library
2261 // routines as much as possible.
2262 key
= index
->toBasetype();
2276 // Convert to Tarray
2277 key
= key
->next
->arrayOf();
2285 error(loc
, "can't have associative array key of %s", key
->toChars());
2288 next
= next
->semantic(loc
,sc
);
2289 switch (next
->toBasetype()->ty
)
2293 error(loc
, "can't have associative array of %s", next
->toChars());
2297 error(loc
, "cannot have array of auto %s", next
->toChars());
2302 void TypeAArray::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
2304 //printf("TypeAArray::resolve() %s\n", toChars());
2306 // Deal with the case where we thought the index was a type, but
2307 // in reality it was an expression.
2308 if (index
->ty
== Tident
|| index
->ty
== Tinstance
|| index
->ty
== Tsarray
)
2314 index
->resolve(loc
, sc
, &e
, &t
, &s
);
2316 { // It was an expression -
2317 // Rewrite as a static array
2319 TypeSArray
*tsa
= new TypeSArray(next
, e
);
2320 return tsa
->resolve(loc
, sc
, pe
, pt
, ps
);
2325 index
->error(loc
, "index is not a type or an expression");
2327 Type::resolve(loc
, sc
, pe
, pt
, ps
);
2331 Expression
*TypeAArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2334 printf("TypeAArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
2336 if (ident
== Id::length
)
2339 FuncDeclaration
*fd
;
2340 Expressions
*arguments
;
2342 fd
= FuncDeclaration::genCfunc(Type::tsize_t
, Id::aaLen
, Type::tvoid
->arrayOf());
2343 ec
= new VarExp(0, fd
);
2344 arguments
= new Expressions();
2346 e
= new CallExp(e
->loc
, ec
, arguments
);
2347 e
->type
= fd
->type
->next
;
2349 else if (ident
== Id::keys
)
2352 FuncDeclaration
*fd
;
2353 Expressions
*arguments
;
2354 int size
= key
->size(e
->loc
);
2357 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::aaKeys
,
2358 Type::tvoid
->arrayOf(), Type::tsize_t
);
2359 ec
= new VarExp(0, fd
);
2360 arguments
= new Expressions();
2362 arguments
->push(new IntegerExp(0, size
, Type::tsize_t
));
2363 e
= new CallExp(e
->loc
, ec
, arguments
);
2364 e
->type
= index
->arrayOf();
2366 else if (ident
== Id::values
)
2369 FuncDeclaration
*fd
;
2370 Expressions
*arguments
;
2372 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::aaValues
,
2373 Type::tvoid
->arrayOf(), Type::tsize_t
, Type::tsize_t
);
2374 ec
= new VarExp(0, fd
);
2375 arguments
= new Expressions();
2377 size_t keysize
= key
->size(e
->loc
);
2378 keysize
= (keysize
+ (PTRSIZE
-1)) & ~(PTRSIZE
-1);
2379 arguments
->push(new IntegerExp(0, keysize
, Type::tsize_t
));
2380 arguments
->push(new IntegerExp(0, next
->size(e
->loc
), Type::tsize_t
));
2381 e
= new CallExp(e
->loc
, ec
, arguments
);
2382 e
->type
= next
->arrayOf();
2384 else if (ident
== Id::rehash
)
2387 FuncDeclaration
*fd
;
2388 Expressions
*arguments
;
2390 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::aaRehash
);
2391 ec
= new VarExp(0, fd
);
2392 arguments
= new Expressions();
2393 arguments
->push(e
->addressOf(sc
));
2394 arguments
->push(key
->getInternalTypeInfo(sc
));
2395 e
= new CallExp(e
->loc
, ec
, arguments
);
2400 e
= Type::dotExp(sc
, e
, ident
);
2405 void TypeAArray::toDecoBuffer(OutBuffer
*buf
)
2407 buf
->writeByte(mangleChar
[ty
]);
2408 index
->toDecoBuffer(buf
);
2409 next
->toDecoBuffer(buf
);
2412 void TypeAArray::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2414 if (mod
!= this->mod
)
2415 { toCBuffer3(buf
, hgs
, mod
);
2418 next
->toCBuffer2(buf
, hgs
, this->mod
);
2419 buf
->writeByte('[');
2420 index
->toCBuffer2(buf
, hgs
, 0);
2421 buf
->writeByte(']');
2424 Expression
*TypeAArray::defaultInit(Loc loc
)
2427 printf("TypeAArray::defaultInit() '%s'\n", toChars());
2430 e
= new NullExp(loc
);
2435 int TypeAArray::checkBoolean()
2440 int TypeAArray::hasPointers()
2445 /***************************** TypeMaybe *****************************/
2447 TypeMaybe::TypeMaybe(Type
*t
)
2452 Type
*TypeMaybe::syntaxCopy()
2454 Type
*t
= next
->syntaxCopy();
2458 t
= new TypeMaybe(t
);
2462 Type
*TypeMaybe::semantic(Loc loc
, Scope
*sc
)
2464 //printf("TypeMaybe::semantic()\n");
2465 Type
*n
= next
->semantic(loc
, sc
);
2471 error(loc
, "can't have maybe for %s of type %d", n
->toChars(), n
->toBasetype()->ty
);
2480 d_uns64
TypeMaybe::size(Loc loc
)
2485 void TypeMaybe::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2487 //printf("TypePointer::toCBuffer2() next = %d\n", next->ty);
2488 if (mod
!= this->mod
)
2489 { toCBuffer3(buf
, hgs
, mod
);
2492 next
->toCBuffer2(buf
, hgs
, this->mod
);
2493 if (next
->ty
!= Tfunction
)
2494 buf
->writeByte('?');
2497 MATCH
TypeMaybe::implicitConvTo(Type
*to
)
2499 printf("TypeMaybe::implicitConvTo(%s)\n", to
->toChars());
2504 if (to->ty == Tpointer && to->next)
2506 if (to->next->ty == Tvoid)
2507 return MATCHconvert;
2510 if (to->next->isBaseOf(next))
2511 return MATCHconvert;
2514 if (next->ty == Tfunction && to->next->ty == Tfunction)
2518 tf = (TypeFunction *)(next);
2519 tfto = (TypeFunction *)(to->next);
2520 return tfto->equals(tf) ? MATCHexact : MATCHnomatch;
2523 // if (to->ty == Tvoid)
2524 // return MATCHconvert;
2526 return MATCHnomatch
;
2529 int TypeMaybe::isscalar()
2534 Expression
*TypeMaybe::defaultInit(Loc loc
)
2537 printf("TypeMaybe::defaultInit() '%s'\n", toChars());
2540 e
= new NullExp(loc
);
2545 int TypeMaybe::isZeroInit()
2550 int TypeMaybe::hasPointers()
2555 /***************************** TypePointer *****************************/
2557 TypePointer::TypePointer(Type
*t
)
2562 Type
*TypePointer::syntaxCopy()
2564 Type
*t
= next
->syntaxCopy();
2568 t
= new TypePointer(t
);
2572 Type
*TypePointer::semantic(Loc loc
, Scope
*sc
)
2574 //printf("TypePointer::semantic()\n");
2575 Type
*n
= next
->semantic(loc
, sc
);
2576 switch (n
->toBasetype()->ty
)
2579 error(loc
, "can't have pointer to %s", n
->toChars());
2590 d_uns64
TypePointer::size(Loc loc
)
2595 void TypePointer::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2597 //printf("TypePointer::toCBuffer2() next = %d\n", next->ty);
2598 if (mod
!= this->mod
)
2599 { toCBuffer3(buf
, hgs
, mod
);
2602 next
->toCBuffer2(buf
, hgs
, this->mod
);
2603 if (next
->ty
!= Tfunction
)
2604 buf
->writeByte('*');
2607 MATCH
TypePointer::implicitConvTo(Type
*to
)
2609 //printf("TypePointer::implicitConvTo()\n");
2613 if (to
->ty
== Tpointer
&& to
->next
)
2615 if (to
->next
->ty
== Tvoid
)
2616 return MATCHconvert
;
2619 if (to
->next
->isBaseOf(next
))
2620 return MATCHconvert
;
2623 if (next
->ty
== Tfunction
&& to
->next
->ty
== Tfunction
)
2627 tf
= (TypeFunction
*)(next
);
2628 tfto
= (TypeFunction
*)(to
->next
);
2629 return tfto
->equals(tf
) ? MATCHexact
: MATCHnomatch
;
2632 // if (to->ty == Tvoid)
2633 // return MATCHconvert;
2634 return MATCHnomatch
;
2637 int TypePointer::isscalar()
2642 Expression
*TypePointer::defaultInit(Loc loc
)
2645 printf("TypePointer::defaultInit() '%s'\n", toChars());
2648 e
= new NullExp(loc
);
2653 int TypePointer::isZeroInit()
2658 int TypePointer::hasPointers()
2664 /***************************** TypeReference *****************************/
2666 TypeReference::TypeReference(Type
*t
)
2667 : Type(Treference
, t
)
2670 error(0,"cannot make reference to a bit");
2671 // BUG: what about references to static arrays?
2674 Type
*TypeReference::syntaxCopy()
2676 Type
*t
= next
->syntaxCopy();
2680 t
= new TypeReference(t
);
2684 d_uns64
TypeReference::size(Loc loc
)
2689 void TypeReference::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2691 if (mod
!= this->mod
)
2692 { toCBuffer3(buf
, hgs
, mod
);
2695 next
->toCBuffer2(buf
, hgs
, this->mod
);
2696 buf
->writeByte('&');
2699 Expression
*TypeReference::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2702 printf("TypeReference::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
2705 // References just forward things along
2706 return next
->dotExp(sc
, e
, ident
);
2709 Expression
*TypeReference::defaultInit(Loc loc
)
2712 printf("TypeReference::defaultInit() '%s'\n", toChars());
2715 e
= new NullExp(loc
);
2720 int TypeReference::isZeroInit()
2726 /***************************** TypeFunction *****************************/
2728 TypeFunction::TypeFunction(Arguments
*parameters
, Type
*treturn
, int varargs
, enum LINK linkage
)
2729 : Type(Tfunction
, treturn
)
2731 //if (!treturn) *(char*)0=0;
2733 this->parameters
= parameters
;
2734 this->varargs
= varargs
;
2735 this->linkage
= linkage
;
2739 Type
*TypeFunction::syntaxCopy()
2741 Type
*treturn
= next
? next
->syntaxCopy() : NULL
;
2742 Arguments
*params
= Argument::arraySyntaxCopy(parameters
);
2743 Type
*t
= new TypeFunction(params
, treturn
, varargs
, linkage
);
2747 /*******************************
2749 * 0 types are distinct
2750 * 1 this is covariant with t
2751 * 2 arguments match as far as overloading goes,
2752 * but types are not covariant
2753 * 3 cannot determine covariance because of forward references
2756 int Type::covariant(Type
*t
)
2759 printf("Type::covariant(t = %s) %s\n", t
->toChars(), toChars());
2760 printf("deco = %p, %p\n", deco
, t
->deco
);
2761 printf("ty = %d\n", next
->ty
);
2764 int inoutmismatch
= 0;
2768 if (ty
!= Tfunction
|| t
->ty
!= Tfunction
)
2772 TypeFunction
*t1
= (TypeFunction
*)this;
2773 TypeFunction
*t2
= (TypeFunction
*)t
;
2775 if (t1
->varargs
!= t2
->varargs
)
2778 if (t1
->parameters
&& t2
->parameters
)
2780 size_t dim
= Argument::dim(t1
->parameters
);
2781 if (dim
!= Argument::dim(t2
->parameters
))
2784 for (size_t i
= 0; i
< dim
; i
++)
2785 { Argument
*arg1
= Argument::getNth(t1
->parameters
, i
);
2786 Argument
*arg2
= Argument::getNth(t2
->parameters
, i
);
2788 if (!arg1
->type
->equals(arg2
->type
))
2790 if (arg1
->storageClass
!= arg2
->storageClass
)
2794 else if (t1
->parameters
!= t2
->parameters
)
2797 // The argument lists match
2800 if (t1
->linkage
!= t2
->linkage
)
2803 Type
*t1n
= t1
->next
;
2804 Type
*t2n
= t2
->next
;
2806 if (t1n
->equals(t2n
))
2808 if (t1n
->ty
!= Tclass
|| t2n
->ty
!= Tclass
)
2811 // If t1n is forward referenced:
2812 ClassDeclaration
*cd
= ((TypeClass
*)t1n
)->sym
;
2813 if (!cd
->baseClass
&& cd
->baseclasses
.dim
&& !cd
->isInterfaceDeclaration())
2818 if (t1n
->implicitConvTo(t2n
))
2824 //printf("\tcovaraint: 1\n");
2828 //printf("\tcovaraint: 0\n");
2832 //printf("\tcovaraint: 2\n");
2836 void TypeFunction::toDecoBuffer(OutBuffer
*buf
)
2839 //printf("TypeFunction::toDecoBuffer() this = %p %s\n", this, toChars());
2840 //static int nest; if (++nest == 50) *(char*)0=0;
2842 { inuse
= 2; // flag error to caller
2848 case LINKd
: mc
= 'F'; break;
2849 case LINKc
: mc
= 'U'; break;
2850 case LINKwindows
: mc
= 'W'; break;
2851 case LINKpascal
: mc
= 'V'; break;
2852 case LINKcpp
: mc
= 'R'; break;
2857 // Write argument types
2858 Argument::argsToDecoBuffer(buf
, parameters
);
2859 //if (buf->data[buf->offset - 1] == '@') halt();
2860 buf
->writeByte('Z' - varargs
); // mark end of arg list
2861 next
->toDecoBuffer(buf
);
2865 void TypeFunction::toCBuffer(OutBuffer
*buf
, Identifier
*ident
, HdrGenState
*hgs
)
2870 { inuse
= 2; // flag error to caller
2874 if (next
&& (!ident
|| ident
->toHChars2() == ident
->toChars()))
2875 next
->toCBuffer2(buf
, hgs
, 0);
2880 case LINKd
: p
= NULL
; break;
2881 case LINKc
: p
= "C "; break;
2882 case LINKwindows
: p
= "Windows "; break;
2883 case LINKpascal
: p
= "Pascal "; break;
2884 case LINKcpp
: p
= "C++ "; break;
2890 if (!hgs
->hdrgen
&& p
)
2891 buf
->writestring(p
);
2893 { buf
->writeByte(' ');
2894 buf
->writestring(ident
->toHChars2());
2896 Argument::argsToCBuffer(buf
, hgs
, parameters
, varargs
);
2900 void TypeFunction::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2905 { inuse
= 2; // flag error to caller
2910 next
->toCBuffer2(buf
, hgs
, 0);
2915 case LINKd
: p
= NULL
; break;
2916 case LINKc
: p
= "C "; break;
2917 case LINKwindows
: p
= "Windows "; break;
2918 case LINKpascal
: p
= "Pascal "; break;
2919 case LINKcpp
: p
= "C++ "; break;
2925 if (!hgs
->hdrgen
&& p
)
2926 buf
->writestring(p
);
2927 buf
->writestring(" function");
2928 Argument::argsToCBuffer(buf
, hgs
, parameters
, varargs
);
2932 Type
*TypeFunction::semantic(Loc loc
, Scope
*sc
)
2934 if (deco
) // if semantic() already run
2936 //printf("already done\n");
2939 //printf("TypeFunction::semantic() this = %p\n", this);
2941 TypeFunction
*tf
= (TypeFunction
*)mem
.malloc(sizeof(TypeFunction
));
2942 memcpy(tf
, this, sizeof(TypeFunction
));
2944 { tf
->parameters
= (Arguments
*)parameters
->copy();
2945 for (size_t i
= 0; i
< parameters
->dim
; i
++)
2946 { Argument
*arg
= (Argument
*)parameters
->data
[i
];
2947 Argument
*cpy
= (Argument
*)mem
.malloc(sizeof(Argument
));
2948 memcpy(cpy
, arg
, sizeof(Argument
));
2949 tf
->parameters
->data
[i
] = (void *)cpy
;
2953 tf
->linkage
= sc
->linkage
;
2956 assert(global
.errors
);
2959 tf
->next
= tf
->next
->semantic(loc
,sc
);
2960 if (tf
->next
->toBasetype()->ty
== Tsarray
)
2961 { error(loc
, "functions cannot return static array %s", tf
->next
->toChars());
2962 tf
->next
= Type::terror
;
2964 if (tf
->next
->toBasetype()->ty
== Tfunction
)
2965 { error(loc
, "functions cannot return a function");
2966 tf
->next
= Type::terror
;
2968 if (tf
->next
->toBasetype()->ty
== Ttuple
)
2969 { error(loc
, "functions cannot return a tuple");
2970 tf
->next
= Type::terror
;
2972 if (tf
->next
->isauto() && !(sc
->flags
& SCOPEctor
))
2973 error(loc
, "functions cannot return auto %s", tf
->next
->toChars());
2976 { size_t dim
= Argument::dim(tf
->parameters
);
2978 for (size_t i
= 0; i
< dim
; i
++)
2979 { Argument
*arg
= Argument::getNth(tf
->parameters
, i
);
2983 arg
->type
= arg
->type
->semantic(loc
,sc
);
2984 if (tf
->inuse
== 1) tf
->inuse
--;
2985 t
= arg
->type
->toBasetype();
2987 if (arg
->storageClass
& (STCout
| STCref
| STClazy
))
2989 if (t
->ty
== Tsarray
)
2990 error(loc
, "cannot have out or ref parameter of type %s", t
->toChars());
2992 if (!(arg
->storageClass
& STClazy
) && t
->ty
== Tvoid
)
2993 error(loc
, "cannot have parameter of type %s", arg
->type
->toChars());
2995 if (arg
->defaultArg
)
2997 arg
->defaultArg
= arg
->defaultArg
->semantic(sc
);
2998 arg
->defaultArg
= resolveProperties(sc
, arg
->defaultArg
);
2999 arg
->defaultArg
= arg
->defaultArg
->implicitCastTo(sc
, arg
->type
);
3002 /* If arg turns out to be a tuple, the number of parameters may
3005 if (t
->ty
== Ttuple
)
3006 { dim
= Argument::dim(tf
->parameters
);
3011 tf
->deco
= tf
->merge()->deco
;
3014 { error(loc
, "recursive type");
3019 if (tf
->varargs
== 1 && tf
->linkage
!= LINKd
&& Argument::dim(tf
->parameters
) == 0)
3020 error(loc
, "variadic functions with non-D linkage must have at least one parameter");
3022 /* Don't return merge(), because arg identifiers and default args
3024 * even though the types match
3029 /********************************
3030 * 'args' are being matched to function 'this'
3031 * Determine match level.
3036 int TypeFunction::callMatch(Expressions
*args
)
3038 //printf("TypeFunction::callMatch()\n");
3039 int match
= MATCHexact
; // assume exact match
3041 size_t nparams
= Argument::dim(parameters
);
3042 size_t nargs
= args
? args
->dim
: 0;
3043 if (nparams
== nargs
)
3045 else if (nargs
> nparams
)
3048 goto Nomatch
; // too many args; no match
3049 match
= MATCHconvert
; // match ... with a "conversion" match level
3052 for (size_t u
= 0; u
< nparams
; u
++)
3056 // BUG: what about out and ref?
3058 Argument
*p
= Argument::getNth(parameters
, u
);
3064 if (varargs
== 2 && u
+ 1 == nparams
)
3066 goto Nomatch
; // not enough arguments
3068 arg
= (Expression
*)args
->data
[u
];
3070 if (p
->storageClass
& STClazy
&& p
->type
->ty
== Tvoid
&& arg
->type
->ty
!= Tvoid
)
3073 m
= arg
->implicitConvTo(p
->type
);
3074 //printf("\tm = %d\n", m);
3075 if (m
== MATCHnomatch
) // if no match
3078 if (varargs
== 2 && u
+ 1 == nparams
) // if last varargs param
3079 { Type
*tb
= p
->type
->toBasetype();
3086 tsa
= (TypeSArray
*)tb
;
3087 sz
= tsa
->dim
->toInteger();
3088 if (sz
!= nargs
- u
)
3091 for (; u
< nargs
; u
++)
3093 arg
= (Expression
*)args
->data
[u
];
3096 /* If lazy array of delegates,
3097 * convert arg(s) to delegate(s)
3099 Type
*tret
= p
->isLazyArray();
3102 if (tb
->next
->equals(arg
->type
))
3107 m
= arg
->implicitConvTo(tret
);
3108 if (m
== MATCHnomatch
)
3110 if (tret
->toBasetype()->ty
== Tvoid
)
3116 m
= arg
->implicitConvTo(tb
->next
);
3118 m
= arg
->implicitConvTo(tb
->next
);
3128 // Should see if there's a constructor match?
3129 // Or just leave it ambiguous?
3139 match
= m
; // pick worst match
3143 //printf("match = %d\n", match);
3147 //printf("no match\n");
3148 return MATCHnomatch
;
3151 Type
*TypeFunction::reliesOnTident()
3155 for (size_t i
= 0; i
< parameters
->dim
; i
++)
3156 { Argument
*arg
= (Argument
*)parameters
->data
[i
];
3157 Type
*t
= arg
->type
->reliesOnTident();
3162 return next
->reliesOnTident();
3165 /***************************** TypeDelegate *****************************/
3167 TypeDelegate::TypeDelegate(Type
*t
)
3168 : Type(Tfunction
, t
)
3173 Type
*TypeDelegate::syntaxCopy()
3175 Type
*t
= next
->syntaxCopy();
3179 t
= new TypeDelegate(t
);
3183 Type
*TypeDelegate::semantic(Loc loc
, Scope
*sc
)
3185 if (deco
) // if semantic() already run
3187 //printf("already done\n");
3190 next
= next
->semantic(loc
,sc
);
3194 d_uns64
TypeDelegate::size(Loc loc
)
3199 void TypeDelegate::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3201 if (mod
!= this->mod
)
3202 { toCBuffer3(buf
, hgs
, mod
);
3205 TypeFunction
*tf
= (TypeFunction
*)next
;
3207 tf
->next
->toCBuffer2(buf
, hgs
, 0);
3208 buf
->writestring(" delegate");
3209 Argument::argsToCBuffer(buf
, hgs
, tf
->parameters
, tf
->varargs
);
3212 Expression
*TypeDelegate::defaultInit(Loc loc
)
3215 printf("TypeDelegate::defaultInit() '%s'\n", toChars());
3218 e
= new NullExp(loc
);
3223 int TypeDelegate::isZeroInit()
3228 int TypeDelegate::checkBoolean()
3233 Expression
*TypeDelegate::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
3236 printf("TypeDelegate::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
3238 if (ident
== Id::ptr
)
3243 if (e
->op
== TOKdelegate
|| e
->op
== TOKcast
)
3244 e
= e
->castTo(sc
, tvoidptr
); // Not an lvalue
3247 e
= e
->addressOf(sc
);
3248 e
= e
->castTo(sc
, tvoidptr
->pointerTo());
3249 e
= new PtrExp(e
->loc
, e
);
3255 else if (ident
== Id::funcptr
)
3257 e
= e
->addressOf(sc
);
3259 e
= new AddExp(e
->loc
, e
, new IntegerExp(PTRSIZE
));
3261 e
= new PtrExp(e
->loc
, e
);
3262 e
->type
= next
->pointerTo();
3267 e
= Type::dotExp(sc
, e
, ident
);
3272 int TypeDelegate::hasPointers()
3279 /***************************** TypeQualified *****************************/
3281 TypeQualified::TypeQualified(TY ty
, Loc loc
)
3287 void TypeQualified::syntaxCopyHelper(TypeQualified
*t
)
3289 //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars());
3290 idents
.setDim(t
->idents
.dim
);
3291 for (int i
= 0; i
< idents
.dim
; i
++)
3293 Identifier
*id
= (Identifier
*)t
->idents
.data
[i
];
3294 if (id
->dyncast() == DYNCAST_DSYMBOL
)
3296 TemplateInstance
*ti
= (TemplateInstance
*)id
;
3298 ti
= (TemplateInstance
*)ti
->syntaxCopy(NULL
);
3299 id
= (Identifier
*)ti
;
3301 idents
.data
[i
] = id
;
3306 void TypeQualified::addIdent(Identifier
*ident
)
3311 void TypeQualified::toCBuffer2Helper(OutBuffer
*buf
, HdrGenState
*hgs
)
3315 for (i
= 0; i
< idents
.dim
; i
++)
3316 { Identifier
*id
= (Identifier
*)idents
.data
[i
];
3318 buf
->writeByte('.');
3320 if (id
->dyncast() == DYNCAST_DSYMBOL
)
3322 TemplateInstance
*ti
= (TemplateInstance
*)id
;
3323 ti
->toCBuffer(buf
, hgs
);
3326 buf
->writestring(id
->toChars());
3330 d_uns64
TypeQualified::size(Loc loc
)
3332 error(this->loc
, "size of type %s is not known", toChars());
3336 /*************************************
3337 * Takes an array of Identifiers and figures out if
3338 * it represents a Type or an Expression.
3340 * if expression, *pe is set
3341 * if type, *pt is set
3344 void TypeQualified::resolveHelper(Loc loc
, Scope
*sc
,
3345 Dsymbol
*s
, Dsymbol
*scopesym
,
3346 Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
3348 Identifier
*id
= NULL
;
3352 TupleDeclaration
*td
;
3357 printf("TypeQualified::resolveHelper(sc = %p, idents = '%s')\n", sc
, toChars());
3359 printf("\tscopesym = '%s'\n", scopesym
->toChars());
3366 //printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
3368 //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
3369 for (i
= 0; i
< idents
.dim
; i
++)
3372 id
= (Identifier
*)idents
.data
[i
];
3373 sm
= s
->searchX(loc
, sc
, id
);
3374 //printf("\t3: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
3375 //printf("getType = '%s'\n", s->getType()->toChars());
3378 v
= s
->isVarDeclaration();
3379 if (v
&& id
== Id::length
)
3381 if (v
->isConst() && v
->getExpInitializer())
3382 { e
= v
->getExpInitializer()->exp
;
3385 e
= new VarExp(loc
, v
);
3392 if (!t
&& s
->isDeclaration())
3393 t
= s
->isDeclaration()->type
;
3396 sm
= t
->toDsymbol(sc
);
3398 { sm
= sm
->search(loc
, id
, 0);
3402 //e = t->getProperty(loc, id);
3403 e
= new TypeExp(loc
, t
);
3404 e
= t
->dotExp(sc
, e
, id
);
3407 for (; i
< idents
.dim
; i
++)
3409 id
= (Identifier
*)idents
.data
[i
];
3410 //printf("e: '%s', id: '%s', type = %p\n", e->toChars(), id->toChars(), e->type);
3411 e
= e
->type
->dotExp(sc
, e
, id
);
3417 error(loc
, "identifier '%s' of '%s' is not defined", id
->toChars(), toChars());
3424 v
= s
->isVarDeclaration();
3427 // It's not a type, it's an expression
3428 if (v
->isConst() && v
->getExpInitializer())
3430 ExpInitializer
*ei
= v
->getExpInitializer();
3432 *pe
= ei
->exp
->copy(); // make copy so we can change loc
3438 WithScopeSymbol
*withsym
;
3439 if (scopesym
&& (withsym
= scopesym
->isWithScopeSymbol()) != NULL
)
3441 // Same as wthis.ident
3442 e
= new VarExp(loc
, withsym
->withstate
->wthis
);
3443 e
= new DotIdExp(loc
, e
, ident
);
3444 //assert(0); // BUG: should handle this
3448 *pe
= new VarExp(loc
, v
);
3452 em
= s
->isEnumMember();
3455 // It's not a type, it's an expression
3456 *pe
= em
->value
->copy();
3464 // If the symbol is an import, try looking inside the import
3470 s
= si
->search(loc
, s
->ident
, 0);
3478 if (t
->ty
== Tinstance
&& t
!= this && !t
->deco
)
3479 { error(loc
, "forward reference to '%s'", t
->toChars());
3485 if (t
->reliesOnTident())
3489 for (scx
= sc
; 1; scx
= scx
->enclosing
)
3492 { error(loc
, "forward reference to '%s'", t
->toChars());
3495 if (scx
->scopesym
== scopesym
)
3498 t
= t
->semantic(loc
, scx
);
3499 //((TypeIdentifier *)t)->resolve(loc, scx, pe, &t, ps);
3502 if (t
->ty
== Ttuple
)
3509 error(loc
, "identifier '%s' is not defined", toChars());
3513 /***************************** TypeIdentifier *****************************/
3515 TypeIdentifier::TypeIdentifier(Loc loc
, Identifier
*ident
)
3516 : TypeQualified(Tident
, loc
)
3518 this->ident
= ident
;
3522 Type
*TypeIdentifier::syntaxCopy()
3526 t
= new TypeIdentifier(loc
, ident
);
3527 t
->syntaxCopyHelper(this);
3531 void TypeIdentifier::toDecoBuffer(OutBuffer
*buf
)
3535 name
= ident
->toChars();
3537 buf
->printf("%c%d%s", mangleChar
[ty
], len
, name
);
3538 //buf->printf("%c%s", mangleChar[ty], name);
3541 void TypeIdentifier::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3543 if (mod
!= this->mod
)
3544 { toCBuffer3(buf
, hgs
, mod
);
3547 buf
->writestring(this->ident
->toChars());
3548 toCBuffer2Helper(buf
, hgs
);
3551 /*************************************
3552 * Takes an array of Identifiers and figures out if
3553 * it represents a Type or an Expression.
3555 * if expression, *pe is set
3556 * if type, *pt is set
3559 void TypeIdentifier::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
3563 //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars());
3564 s
= sc
->search(loc
, ident
, &scopesym
);
3565 resolveHelper(loc
, sc
, s
, scopesym
, pe
, pt
, ps
);
3568 /*****************************************
3569 * See if type resolves to a symbol, if so,
3570 * return that symbol.
3573 Dsymbol
*TypeIdentifier::toDsymbol(Scope
*sc
)
3575 //printf("TypeIdentifier::toDsymbol('%s')\n", toChars());
3578 //printf("ident = '%s'\n", ident->toChars());
3581 Dsymbol
*s
= sc
->search(loc
, ident
, &scopesym
);
3584 for (int i
= 0; i
< idents
.dim
; i
++)
3586 Identifier
*id
= (Identifier
*)idents
.data
[i
];
3587 s
= s
->searchX(loc
, sc
, id
);
3588 if (!s
) // failed to find a symbol
3589 { //printf("\tdidn't find a symbol\n");
3597 Type
*TypeIdentifier::semantic(Loc loc
, Scope
*sc
)
3603 //printf("TypeIdentifier::semantic(%s)\n", toChars());
3604 resolve(loc
, sc
, &e
, &t
, &s
);
3607 //printf("\tit's a type %d, %s, %s\n", t->ty, t->toChars(), t->deco);
3609 if (t
->ty
== Ttypedef
)
3610 { TypeTypedef
*tt
= (TypeTypedef
*)t
;
3612 if (tt
->sym
->sem
== 1)
3613 error(loc
, "circular reference of typedef %s", tt
->toChars());
3624 s
->error(loc
, "is used as a type");
3627 error(loc
, "%s is used as a type", toChars());
3634 Type
*TypeIdentifier::reliesOnTident()
3639 Expression
*TypeIdentifier::toExpression()
3641 Expression
*e
= new IdentifierExp(loc
, ident
);
3642 for (int i
= 0; i
< idents
.dim
; i
++)
3644 Identifier
*id
= (Identifier
*)idents
.data
[i
];
3645 e
= new DotIdExp(loc
, e
, id
);
3651 /***************************** TypeInstance *****************************/
3653 TypeInstance::TypeInstance(Loc loc
, TemplateInstance
*tempinst
)
3654 : TypeQualified(Tinstance
, loc
)
3656 this->tempinst
= tempinst
;
3659 Type
*TypeInstance::syntaxCopy()
3661 //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim);
3664 t
= new TypeInstance(loc
, (TemplateInstance
*)tempinst
->syntaxCopy(NULL
));
3665 t
->syntaxCopyHelper(this);
3670 void TypeInstance::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3672 if (mod
!= this->mod
)
3673 { toCBuffer3(buf
, hgs
, mod
);
3676 tempinst
->toCBuffer(buf
, hgs
);
3677 toCBuffer2Helper(buf
, hgs
);
3680 void TypeInstance::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
3682 // Note close similarity to TypeIdentifier::resolve()
3693 error(loc
, "template instance '%s' has no identifier", toChars());
3697 //id = (Identifier *)idents.data[0];
3698 //printf("TypeInstance::resolve(sc = %p, idents = '%s')\n", sc, id->toChars());
3702 resolveHelper(loc
, sc
, s
, NULL
, pe
, pt
, ps
);
3703 //printf("pt = '%s'\n", (*pt)->toChars());
3706 Type
*TypeInstance::semantic(Loc loc
, Scope
*sc
)
3712 //printf("TypeInstance::semantic(%s)\n", toChars());
3714 if (sc
->parameterSpecialization
)
3716 unsigned errors
= global
.errors
;
3719 resolve(loc
, sc
, &e
, &t
, &s
);
3722 if (errors
!= global
.errors
)
3723 { if (global
.gag
== 0)
3724 global
.errors
= errors
;
3729 resolve(loc
, sc
, &e
, &t
, &s
);
3736 error(loc
, "%s is used as a type", toChars());
3743 /***************************** TypeTypeof *****************************/
3745 TypeTypeof::TypeTypeof(Loc loc
, Expression
*exp
)
3746 : TypeQualified(Ttypeof
, loc
)
3751 Type
*TypeTypeof::syntaxCopy()
3755 t
= new TypeTypeof(loc
, exp
->syntaxCopy());
3756 t
->syntaxCopyHelper(this);
3760 Dsymbol
*TypeTypeof::toDsymbol(Scope
*sc
)
3764 t
= semantic(0, sc
);
3767 return t
->toDsymbol(sc
);
3770 void TypeTypeof::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3772 if (mod
!= this->mod
)
3773 { toCBuffer3(buf
, hgs
, mod
);
3776 buf
->writestring("typeof(");
3777 exp
->toCBuffer(buf
, hgs
);
3778 buf
->writeByte(')');
3779 toCBuffer2Helper(buf
, hgs
);
3782 Type
*TypeTypeof::semantic(Loc loc
, Scope
*sc
)
3786 //printf("TypeTypeof::semantic() %p\n", this);
3788 //static int nest; if (++nest == 50) *(char*)0=0;
3791 /* Special case for typeof(this) and typeof(super) since both
3792 * should work even if they are not inside a non-static member function
3794 if (exp
->op
== TOKthis
|| exp
->op
== TOKsuper
)
3796 // Find enclosing struct or class
3797 for (Dsymbol
*s
= sc
->parent
; 1; s
= s
->parent
)
3799 ClassDeclaration
*cd
;
3800 StructDeclaration
*sd
;
3804 error(loc
, "%s is not in a struct or class scope", exp
->toChars());
3807 cd
= s
->isClassDeclaration();
3810 if (exp
->op
== TOKsuper
)
3814 { error(loc
, "class %s has no 'super'", s
->toChars());
3821 sd
= s
->isStructDeclaration();
3824 if (exp
->op
== TOKsuper
)
3826 error(loc
, "struct %s has no 'super'", sd
->toChars());
3829 t
= sd
->type
->pointerTo();
3838 exp
= exp
->semantic(sc
);
3843 error(loc
, "expression (%s) has no type", exp
->toChars());
3850 Dsymbol
*s
= t
->toDsymbol(sc
);
3851 for (size_t i
= 0; i
< idents
.dim
; i
++)
3855 Identifier
*id
= (Identifier
*)idents
.data
[i
];
3856 s
= s
->searchX(loc
, sc
, id
);
3862 { error(loc
, "%s is not a type", s
->toChars());
3867 { error(loc
, "cannot resolve .property for %s", toChars());
3877 d_uns64
TypeTypeof::size(Loc loc
)
3880 return exp
->type
->size(loc
);
3882 return TypeQualified::size(loc
);
3887 /***************************** TypeEnum *****************************/
3889 TypeEnum::TypeEnum(EnumDeclaration
*sym
)
3895 char *TypeEnum::toChars()
3897 return sym
->toChars();
3900 Type
*TypeEnum::semantic(Loc loc
, Scope
*sc
)
3906 d_uns64
TypeEnum::size(Loc loc
)
3910 error(loc
, "enum %s is forward referenced", sym
->toChars());
3913 return sym
->memtype
->size(loc
);
3916 unsigned TypeEnum::alignsize()
3923 error(0, "enum %s is forward referenced", sym
->toChars());
3926 return sym
->memtype
->alignsize();
3929 Dsymbol
*TypeEnum::toDsymbol(Scope
*sc
)
3934 Type
*TypeEnum::toBasetype()
3941 error(sym
->loc
, "enum %s is forward referenced", sym
->toChars());
3944 return sym
->memtype
->toBasetype();
3947 void TypeEnum::toDecoBuffer(OutBuffer
*buf
)
3950 name
= sym
->mangle();
3951 // if (name[0] == '_' && name[1] == 'D')
3953 buf
->printf("%c%s", mangleChar
[ty
], name
);
3956 void TypeEnum::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3958 if (mod
!= this->mod
)
3959 { toCBuffer3(buf
, hgs
, mod
);
3962 buf
->writestring(sym
->toChars());
3965 Expression
*TypeEnum::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
3972 printf("TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\n", e
->toChars(), ident
->toChars(), toChars());
3976 s
= sym
->symtab
->lookup(ident
);
3979 return getProperty(e
->loc
, ident
);
3981 m
= s
->isEnumMember();
3982 em
= m
->value
->copy();
3987 error(e
->loc
, "forward reference of %s.%s", toChars(), ident
->toChars());
3988 return new IntegerExp(0, 0, this);
3991 Expression
*TypeEnum::getProperty(Loc loc
, Identifier
*ident
)
3994 if (ident
== Id::max
)
3998 e
= new IntegerExp(0, sym
->maxval
, this);
4000 else if (ident
== Id::min
)
4004 e
= new IntegerExp(0, sym
->minval
, this);
4006 else if (ident
== Id::init
)
4010 e
= defaultInit(loc
);
4016 e
= sym
->memtype
->getProperty(loc
, ident
);
4021 error(loc
, "forward reference of %s.%s", toChars(), ident
->toChars());
4022 return new IntegerExp(0, 0, this);
4025 int TypeEnum::isintegral()
4030 int TypeEnum::isfloating()
4035 int TypeEnum::isunsigned()
4037 return sym
->memtype
->isunsigned();
4040 int TypeEnum::isscalar()
4043 //return sym->memtype->isscalar();
4046 MATCH
TypeEnum::implicitConvTo(Type
*to
)
4049 //printf("TypeEnum::implicitConvTo()\n");
4050 if (this->equals(to
))
4051 m
= MATCHexact
; // exact match
4052 else if (sym
->memtype
->implicitConvTo(to
))
4053 m
= MATCHconvert
; // match with conversions
4055 m
= MATCHnomatch
; // no match
4059 Expression
*TypeEnum::defaultInit(Loc loc
)
4062 printf("TypeEnum::defaultInit() '%s'\n", toChars());
4064 // Initialize to first member of enum
4066 e
= new IntegerExp(loc
, sym
->defaultval
, this);
4070 int TypeEnum::isZeroInit()
4072 return (sym
->defaultval
== 0);
4075 int TypeEnum::hasPointers()
4077 return toBasetype()->hasPointers();
4080 /***************************** TypeTypedef *****************************/
4082 TypeTypedef::TypeTypedef(TypedefDeclaration
*sym
)
4083 : Type(Ttypedef
, NULL
)
4088 Type
*TypeTypedef::syntaxCopy()
4093 char *TypeTypedef::toChars()
4095 return sym
->toChars();
4098 Type
*TypeTypedef::semantic(Loc loc
, Scope
*sc
)
4100 //printf("TypeTypedef::semantic(%s), sem = %d\n", toChars(), sym->sem);
4105 d_uns64
TypeTypedef::size(Loc loc
)
4107 return sym
->basetype
->size(loc
);
4110 unsigned TypeTypedef::alignsize()
4112 return sym
->basetype
->alignsize();
4115 Dsymbol
*TypeTypedef::toDsymbol(Scope
*sc
)
4120 void TypeTypedef::toDecoBuffer(OutBuffer
*buf
)
4124 name
= sym
->mangle();
4125 // if (name[0] == '_' && name[1] == 'D')
4127 //len = strlen(name);
4128 //buf->printf("%c%d%s", mangleChar[ty], len, name);
4129 buf
->printf("%c%s", mangleChar
[ty
], name
);
4132 void TypeTypedef::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4134 //printf("TypeTypedef::toCBuffer2() '%s'\n", sym->toChars());
4135 if (mod
!= this->mod
)
4136 { toCBuffer3(buf
, hgs
, mod
);
4139 buf
->writestring(sym
->toChars());
4142 Expression
*TypeTypedef::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
4145 printf("TypeTypedef::dotExp(e = '%s', ident = '%s') '%s'\n", e
->toChars(), ident
->toChars(), toChars());
4147 if (ident
== Id::init
)
4149 return Type::dotExp(sc
, e
, ident
);
4151 return sym
->basetype
->dotExp(sc
, e
, ident
);
4154 Expression
*TypeTypedef::getProperty(Loc loc
, Identifier
*ident
)
4156 if (ident
== Id::init
)
4158 return Type::getProperty(loc
, ident
);
4160 return sym
->basetype
->getProperty(loc
, ident
);
4163 int TypeTypedef::isbit()
4165 return sym
->basetype
->isbit();
4168 int TypeTypedef::isintegral()
4170 //printf("TypeTypedef::isintegral()\n");
4171 //printf("sym = '%s'\n", sym->toChars());
4172 //printf("basetype = '%s'\n", sym->basetype->toChars());
4173 return sym
->basetype
->isintegral();
4176 int TypeTypedef::isfloating()
4178 return sym
->basetype
->isfloating();
4181 int TypeTypedef::isreal()
4183 return sym
->basetype
->isreal();
4186 int TypeTypedef::isimaginary()
4188 return sym
->basetype
->isimaginary();
4191 int TypeTypedef::iscomplex()
4193 return sym
->basetype
->iscomplex();
4196 int TypeTypedef::isunsigned()
4198 return sym
->basetype
->isunsigned();
4201 int TypeTypedef::isscalar()
4203 return sym
->basetype
->isscalar();
4206 int TypeTypedef::checkBoolean()
4208 return sym
->basetype
->checkBoolean();
4211 Type
*TypeTypedef::toBasetype()
4215 sym
->error("circular definition");
4216 sym
->basetype
= Type::terror
;
4217 return Type::terror
;
4220 Type
*t
= sym
->basetype
->toBasetype();
4225 MATCH
TypeTypedef::implicitConvTo(Type
*to
)
4228 //printf("TypeTypedef::implicitConvTo()\n");
4229 if (this->equals(to
))
4230 m
= MATCHexact
; // exact match
4231 else if (sym
->basetype
->implicitConvTo(to
))
4232 m
= MATCHconvert
; // match with conversions
4234 m
= MATCHnomatch
; // no match
4238 Expression
*TypeTypedef::defaultInit(Loc loc
)
4243 printf("TypeTypedef::defaultInit() '%s'\n", toChars());
4247 //sym->init->toExpression()->print();
4248 return sym
->init
->toExpression();
4251 e
= bt
->defaultInit(loc
);
4253 while (bt
->ty
== Tsarray
)
4256 bt
= bt
->next
->toBasetype();
4261 int TypeTypedef::isZeroInit()
4265 if (sym
->init
->isVoidInitializer())
4266 return 1; // initialize voids to 0
4267 Expression
*e
= sym
->init
->toExpression();
4268 if (e
&& e
->isBool(FALSE
))
4270 return 0; // assume not
4274 sym
->error("circular definition");
4275 sym
->basetype
= Type::terror
;
4278 int result
= sym
->basetype
->isZeroInit();
4283 int TypeTypedef::hasPointers()
4285 return toBasetype()->hasPointers();
4288 /***************************** TypeStruct *****************************/
4290 TypeStruct::TypeStruct(StructDeclaration
*sym
)
4291 : Type(Tstruct
, NULL
)
4296 char *TypeStruct::toChars()
4298 //printf("sym.parent: %s, deco = %s\n", sym->parent->toChars(), deco);
4299 TemplateInstance
*ti
= sym
->parent
->isTemplateInstance();
4300 if (ti
&& ti
->toAlias() == sym
)
4301 return ti
->toChars();
4302 return sym
->toChars();
4305 Type
*TypeStruct::syntaxCopy()
4310 Type
*TypeStruct::semantic(Loc loc
, Scope
*sc
)
4312 //printf("TypeStruct::semantic('%s')\n", sym->toChars());
4314 /* Cannot do semantic for sym because scope chain may not
4317 //sym->semantic(sc);
4322 d_uns64
TypeStruct::size(Loc loc
)
4324 return sym
->size(loc
);
4327 unsigned TypeStruct::alignsize()
4330 sym
->size(0); // give error for forward references
4331 sz
= sym
->alignsize
;
4332 if (sz
> sym
->structalign
)
4333 sz
= sym
->structalign
;
4337 Dsymbol
*TypeStruct::toDsymbol(Scope
*sc
)
4342 void TypeStruct::toDecoBuffer(OutBuffer
*buf
)
4346 name
= sym
->mangle();
4347 //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", toChars(), name);
4348 // if (name[0] == '_' && name[1] == 'D')
4350 //len = strlen(name);
4351 //buf->printf("%c%d%s", mangleChar[ty], len, name);
4352 buf
->printf("%c%s", mangleChar
[ty
], name
);
4355 void TypeStruct::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4357 if (mod
!= this->mod
)
4358 { toCBuffer3(buf
, hgs
, mod
);
4361 TemplateInstance
*ti
= sym
->parent
->isTemplateInstance();
4362 if (ti
&& ti
->toAlias() == sym
)
4363 buf
->writestring(ti
->toChars());
4365 buf
->writestring(sym
->toChars());
4368 Expression
*TypeStruct::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
4378 printf("TypeStruct::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
4382 error(e
->loc
, "struct %s is forward referenced", sym
->toChars());
4383 return new IntegerExp(e
->loc
, 0, Type::tint32
);
4386 if (ident
== Id::tupleof
)
4388 /* Create a TupleExp
4390 Expressions
*exps
= new Expressions
;
4391 exps
->reserve(sym
->fields
.dim
);
4392 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
4393 { VarDeclaration
*v
= (VarDeclaration
*)sym
->fields
.data
[i
];
4394 Expression
*fe
= new DotVarExp(e
->loc
, e
, v
);
4397 e
= new TupleExp(e
->loc
, exps
);
4398 e
= e
->semantic(sc
);
4402 if (e
->op
== TOKdotexp
)
4403 { DotExp
*de
= (DotExp
*)e
;
4405 if (de
->e1
->op
== TOKimport
)
4407 ScopeExp
*se
= (ScopeExp
*)de
->e1
;
4409 s
= se
->sds
->search(e
->loc
, ident
, 0);
4415 s
= sym
->search(e
->loc
, ident
, 0);
4419 //return getProperty(e->loc, ident);
4420 return Type::dotExp(sc
, e
, ident
);
4424 v
= s
->isVarDeclaration();
4425 if (v
&& v
->isConst())
4426 { ExpInitializer
*ei
= v
->getExpInitializer();
4429 { e
= ei
->exp
->copy(); // need to copy it if it's a StringExp
4430 e
= e
->semantic(sc
);
4437 //return new DotTypeExp(e->loc, e, s);
4438 return new TypeExp(e
->loc
, s
->getType());
4441 EnumMember
*em
= s
->isEnumMember();
4445 return em
->value
->copy();
4448 TemplateMixin
*tm
= s
->isTemplateMixin();
4452 de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, tm
));
4457 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
4460 e
= new DotTemplateExp(e
->loc
, e
, td
);
4465 TemplateInstance
*ti
= s
->isTemplateInstance();
4467 { if (!ti
->semanticdone
)
4469 s
= ti
->inst
->toAlias();
4470 if (!s
->isTemplateInstance())
4472 Expression
*de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, ti
));
4477 d
= s
->isDeclaration();
4480 printf("d = %s '%s'\n", s
->kind(), s
->toChars());
4484 if (e
->op
== TOKtype
)
4485 { FuncDeclaration
*fd
= sc
->func
;
4487 if (d
->needThis() && fd
&& fd
->vthis
)
4489 e
= new DotVarExp(e
->loc
, new ThisExp(e
->loc
), d
);
4490 e
= e
->semantic(sc
);
4493 if (d
->isTupleDeclaration())
4495 e
= new TupleExp(e
->loc
, d
->isTupleDeclaration());
4496 e
= e
->semantic(sc
);
4499 return new VarExp(e
->loc
, d
);
4507 accessCheck(e
->loc
, sc
, e
, d
);
4508 ve
= new VarExp(e
->loc
, d
);
4509 e
= new CommaExp(e
->loc
, e
, ve
);
4516 if (v
->toParent() != sym
)
4517 sym
->error(e
->loc
, "'%s' is not a member", v
->toChars());
4520 accessCheck(e
->loc
, sc
, e
, d
);
4521 b
= new AddrExp(e
->loc
, e
);
4522 b
->type
= e
->type
->pointerTo();
4523 b
= new AddExp(e
->loc
, b
, new IntegerExp(e
->loc
, v
->offset
, Type::tsize_t
));
4524 b
->type
= v
->type
->pointerTo();
4525 e
= new PtrExp(e
->loc
, b
);
4530 de
= new DotVarExp(e
->loc
, e
, d
);
4531 return de
->semantic(sc
);
4534 unsigned TypeStruct::memalign(unsigned salign
)
4536 sym
->size(0); // give error for forward references
4537 return sym
->structalign
;
4540 Expression
*TypeStruct::defaultInit(Loc loc
)
4545 printf("TypeStruct::defaultInit() '%s'\n", toChars());
4547 s
= sym
->toInitializer();
4548 d
= new SymbolDeclaration(sym
->loc
, s
, sym
);
4551 return new VarExp(sym
->loc
, d
);
4554 int TypeStruct::isZeroInit()
4556 return sym
->zeroInit
;
4559 int TypeStruct::checkBoolean()
4564 int TypeStruct::hasPointers()
4566 StructDeclaration
*s
= sym
;
4568 sym
->size(0); // give error for forward references
4571 for (size_t i
= 0; i
< s
->members
->dim
; i
++)
4573 Dsymbol
*sm
= (Dsymbol
*)s
->members
->data
[i
];
4574 if (sm
->hasPointers())
4582 /***************************** TypeClass *****************************/
4584 TypeClass::TypeClass(ClassDeclaration
*sym
)
4585 : Type(Tclass
, NULL
)
4590 char *TypeClass::toChars()
4592 return sym
->toPrettyChars();
4595 Type
*TypeClass::syntaxCopy()
4600 Type
*TypeClass::semantic(Loc loc
, Scope
*sc
)
4602 //printf("TypeClass::semantic(%s)\n", sym->toChars());
4604 sym
->semantic(sym
->scope
);
4608 d_uns64
TypeClass::size(Loc loc
)
4613 Dsymbol
*TypeClass::toDsymbol(Scope
*sc
)
4618 void TypeClass::toDecoBuffer(OutBuffer
*buf
)
4622 name
= sym
->mangle();
4623 // if (name[0] == '_' && name[1] == 'D')
4625 //printf("TypeClass::toDecoBuffer('%s') = '%s'\n", toChars(), name);
4626 //len = strlen(name);
4627 //buf->printf("%c%d%s", mangleChar[ty], len, name);
4628 buf
->printf("%c%s", mangleChar
[ty
], name
);
4631 void TypeClass::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4633 if (mod
!= this->mod
)
4634 { toCBuffer3(buf
, hgs
, mod
);
4637 buf
->writestring(sym
->toChars());
4640 Expression
*TypeClass::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
4650 printf("TypeClass::dotExp(e='%s', ident='%s')\n", e
->toChars(), ident
->toChars());
4653 if (e
->op
== TOKdotexp
)
4654 { DotExp
*de
= (DotExp
*)e
;
4656 if (de
->e1
->op
== TOKimport
)
4658 ScopeExp
*se
= (ScopeExp
*)de
->e1
;
4660 s
= se
->sds
->search(e
->loc
, ident
, 0);
4666 if (ident
== Id::tupleof
)
4668 /* Create a TupleExp
4670 Expressions
*exps
= new Expressions
;
4671 exps
->reserve(sym
->fields
.dim
);
4672 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
4673 { VarDeclaration
*v
= (VarDeclaration
*)sym
->fields
.data
[i
];
4674 Expression
*fe
= new DotVarExp(e
->loc
, e
, v
);
4677 e
= new TupleExp(e
->loc
, exps
);
4678 e
= e
->semantic(sc
);
4682 s
= sym
->search(e
->loc
, ident
, 0);
4686 // See if it's a base class
4687 ClassDeclaration
*cbase
;
4688 for (cbase
= sym
->baseClass
; cbase
; cbase
= cbase
->baseClass
)
4690 if (cbase
->ident
->equals(ident
))
4692 e
= new DotTypeExp(0, e
, cbase
);
4697 if (ident
== Id::classinfo
)
4701 assert(ClassDeclaration::classinfo
);
4702 t
= ClassDeclaration::classinfo
->type
;
4703 if (e
->op
== TOKtype
|| e
->op
== TOKdottype
)
4705 /* For type.classinfo, we know the classinfo
4708 if (!sym
->vclassinfo
)
4709 sym
->vclassinfo
= new ClassInfoDeclaration(sym
);
4710 e
= new VarExp(e
->loc
, sym
->vclassinfo
);
4711 e
= e
->addressOf(sc
);
4712 e
->type
= t
; // do this so we don't get redundant dereference
4715 { /* For class objects, the classinfo reference is the first
4716 * entry in the vtbl[]
4718 e
= new PtrExp(e
->loc
, e
);
4719 e
->type
= t
->pointerTo();
4720 if (sym
->isInterfaceDeclaration())
4722 if (sym
->isCOMinterface())
4723 { /* COM interface vtbl[]s are different in that the
4724 * first entry is always pointer to QueryInterface().
4725 * We can't get a .classinfo for it.
4727 error(e
->loc
, "no .classinfo for COM interface objects");
4729 /* For an interface, the first entry in the vtbl[]
4730 * is actually a pointer to an instance of struct Interface.
4731 * The first member of Interface is the .classinfo,
4732 * so add an extra pointer indirection.
4734 e
->type
= e
->type
->pointerTo();
4735 e
= new PtrExp(e
->loc
, e
);
4736 e
->type
= t
->pointerTo();
4738 e
= new PtrExp(e
->loc
, e
, t
);
4743 if (ident
== Id::typeinfo
)
4745 if (!global
.params
.useDeprecated
)
4746 error(e
->loc
, ".typeinfo deprecated, use typeid(type)");
4747 return getTypeInfo(sc
);
4749 if (ident
== Id::outer
&& sym
->vthis
)
4755 //return getProperty(e->loc, ident);
4756 return Type::dotExp(sc
, e
, ident
);
4760 v
= s
->isVarDeclaration();
4761 if (v
&& v
->isConst())
4762 { ExpInitializer
*ei
= v
->getExpInitializer();
4765 { e
= ei
->exp
->copy(); // need to copy it if it's a StringExp
4766 e
= e
->semantic(sc
);
4773 // if (e->op == TOKtype)
4774 return new TypeExp(e
->loc
, s
->getType());
4775 // return new DotTypeExp(e->loc, e, s);
4778 EnumMember
*em
= s
->isEnumMember();
4782 return em
->value
->copy();
4785 TemplateMixin
*tm
= s
->isTemplateMixin();
4789 de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, tm
));
4794 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
4797 e
= new DotTemplateExp(e
->loc
, e
, td
);
4802 TemplateInstance
*ti
= s
->isTemplateInstance();
4804 { if (!ti
->semanticdone
)
4806 s
= ti
->inst
->toAlias();
4807 if (!s
->isTemplateInstance())
4809 Expression
*de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, ti
));
4814 d
= s
->isDeclaration();
4817 e
->error("%s.%s is not a declaration", e
->toChars(), ident
->toChars());
4818 return new IntegerExp(e
->loc
, 1, Type::tint32
);
4821 if (e
->op
== TOKtype
)
4825 if (d
->needThis() && (hasThis(sc
) || !d
->isFuncDeclaration()))
4829 ClassDeclaration
*thiscd
;
4830 thiscd
= sc
->func
->toParent()->isClassDeclaration();
4834 ClassDeclaration
*cd
= e
->type
->isClassHandle();
4838 e
= new ThisExp(e
->loc
);
4839 e
= new DotTypeExp(e
->loc
, e
, cd
);
4840 de
= new DotVarExp(e
->loc
, e
, d
);
4841 e
= de
->semantic(sc
);
4844 else if ((!cd
|| !cd
->isBaseOf(thiscd
, NULL
)) &&
4845 !d
->isFuncDeclaration())
4846 e
->error("'this' is required, but %s is not a base class of %s", e
->type
->toChars(), thiscd
->toChars());
4850 de
= new DotVarExp(e
->loc
, new ThisExp(e
->loc
), d
);
4851 e
= de
->semantic(sc
);
4854 else if (d
->isTupleDeclaration())
4856 e
= new TupleExp(e
->loc
, d
->isTupleDeclaration());
4857 e
= e
->semantic(sc
);
4861 ve
= new VarExp(e
->loc
, d
);
4870 accessCheck(e
->loc
, sc
, e
, d
);
4871 ve
= new VarExp(e
->loc
, d
);
4872 e
= new CommaExp(e
->loc
, e
, ve
);
4877 if (d
->parent
&& d
->toParent()->isModule())
4882 ve
= new VarExp(e
->loc
, d
);
4883 e
= new CommaExp(e
->loc
, e
, ve
);
4888 de
= new DotVarExp(e
->loc
, e
, d
);
4889 return de
->semantic(sc
);
4892 ClassDeclaration
*TypeClass::isClassHandle()
4897 int TypeClass::isauto()
4902 int TypeClass::isBaseOf(Type
*t
, target_ptrdiff_t
*poffset
)
4904 if (t
->ty
== Tclass
)
4905 { ClassDeclaration
*cd
;
4907 cd
= ((TypeClass
*)t
)->sym
;
4908 if (sym
->isBaseOf(cd
, poffset
))
4914 MATCH
TypeClass::implicitConvTo(Type
*to
)
4916 //printf("TypeClass::implicitConvTo('%s')\n", to->toChars());
4918 // Can always convert a "Foo" to a "Foo?"
4919 if (to
->ty
== Tmaybe
&& to
->next
)
4925 ClassDeclaration
*cdto
= to
->isClassHandle();
4926 if (cdto
&& cdto
->isBaseOf(sym
, NULL
))
4927 { //printf("is base\n");
4928 return MATCHconvert
;
4931 if (global
.params
.Dversion
== 1)
4933 // Allow conversion to (void *)
4934 if (to
->ty
== Tpointer
&& to
->next
->ty
== Tvoid
)
4935 return MATCHconvert
;
4938 return MATCHnomatch
;
4941 Expression
*TypeClass::defaultInit(Loc loc
)
4944 printf("TypeClass::defaultInit() '%s'\n", toChars());
4947 e
= new NullExp(loc
);
4952 int TypeClass::isZeroInit()
4957 int TypeClass::checkBoolean()
4962 int TypeClass::hasPointers()
4967 /***************************** TypeTuple *****************************/
4969 TypeTuple::TypeTuple(Arguments
*arguments
)
4970 : Type(Ttuple
, NULL
)
4972 //printf("TypeTuple(this = %p)\n", this);
4973 this->arguments
= arguments
;
4977 for (size_t i
= 0; i
< arguments
->dim
; i
++)
4979 Argument
*arg
= (Argument
*)arguments
->data
[i
];
4980 assert(arg
&& arg
->type
);
4987 * Form TypeTuple from the types of the expressions.
4988 * Assume exps[] is already tuple expanded.
4991 TypeTuple::TypeTuple(Expressions
*exps
)
4992 : Type(Ttuple
, NULL
)
4994 Arguments
*arguments
= new Arguments
;
4997 arguments
->setDim(exps
->dim
);
4998 for (size_t i
= 0; i
< exps
->dim
; i
++)
4999 { Expression
*e
= (Expression
*)exps
->data
[i
];
5000 if (e
->type
->ty
== Ttuple
)
5001 e
->error("cannot form tuple of tuples");
5002 Argument
*arg
= new Argument(STCin
, e
->type
, NULL
, NULL
);
5003 arguments
->data
[i
] = (void *)arg
;
5006 this->arguments
= arguments
;
5009 Type
*TypeTuple::syntaxCopy()
5011 Arguments
*args
= Argument::arraySyntaxCopy(arguments
);
5012 Type
*t
= new TypeTuple(args
);
5016 Type
*TypeTuple::semantic(Loc loc
, Scope
*sc
)
5018 //printf("TypeTuple::semantic(this = %p)\n", this);
5020 deco
= merge()->deco
;
5022 /* Don't return merge(), because a tuple with one type has the
5023 * same deco as that type.
5028 int TypeTuple::equals(Object
*o
)
5032 //printf("TypeTuple::equals(%s, %s)\n", toChars(), t->toChars());
5037 if (t
->ty
== Ttuple
)
5038 { TypeTuple
*tt
= (TypeTuple
*)t
;
5040 if (arguments
->dim
== tt
->arguments
->dim
)
5042 for (size_t i
= 0; i
< tt
->arguments
->dim
; i
++)
5043 { Argument
*arg1
= (Argument
*)arguments
->data
[i
];
5044 Argument
*arg2
= (Argument
*)tt
->arguments
->data
[i
];
5046 if (!arg1
->type
->equals(arg2
->type
))
5055 Type
*TypeTuple::reliesOnTident()
5059 for (size_t i
= 0; i
< arguments
->dim
; i
++)
5061 Argument
*arg
= (Argument
*)arguments
->data
[i
];
5062 Type
*t
= arg
->type
->reliesOnTident();
5070 void TypeTuple::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
5072 Argument::argsToCBuffer(buf
, hgs
, arguments
, 0);
5075 void TypeTuple::toDecoBuffer(OutBuffer
*buf
)
5077 //printf("TypeTuple::toDecoBuffer() this = %p\n", this);
5079 Argument::argsToDecoBuffer(&buf2
, arguments
);
5080 unsigned len
= buf2
.offset
;
5082 // newlib bug as of 1.14.0
5083 char * p
= (char*) buf2
.extractData();
5084 buf
->printf("%c%d%.*s", mangleChar
[ty
], len
, len
, p
? p
: "");
5086 buf
->printf("%c%d%.*s", mangleChar
[ty
], len
, len
, (char *)buf2
.extractData());
5090 Expression
*TypeTuple::getProperty(Loc loc
, Identifier
*ident
)
5094 printf("TypeTuple::getProperty(type = '%s', ident = '%s')\n", toChars(), ident
->toChars());
5096 if (ident
== Id::length
)
5098 e
= new IntegerExp(loc
, arguments
->dim
, Type::tsize_t
);
5102 error(loc
, "no property '%s' for tuple '%s'", ident
->toChars(), toChars());
5103 e
= new IntegerExp(loc
, 1, Type::tint32
);
5108 /***************************** TypeSlice *****************************/
5110 /* This is so we can slice a TypeTuple */
5112 TypeSlice::TypeSlice(Type
*next
, Expression
*lwr
, Expression
*upr
)
5113 : Type(Tslice
, next
)
5115 //printf("TypeSlice[%s .. %s]\n", lwr->toChars(), upr->toChars());
5120 Type
*TypeSlice::syntaxCopy()
5122 Type
*t
= new TypeSlice(next
->syntaxCopy(), lwr
->syntaxCopy(), upr
->syntaxCopy());
5126 Type
*TypeSlice::semantic(Loc loc
, Scope
*sc
)
5128 //printf("TypeSlice::semantic() %s\n", toChars());
5129 next
= next
->semantic(loc
, sc
);
5130 //printf("next: %s\n", next->toChars());
5132 Type
*tbn
= next
->toBasetype();
5133 if (tbn
->ty
!= Ttuple
)
5134 { error(loc
, "can only slice tuple types, not %s", tbn
->toChars());
5135 return Type::terror
;
5137 TypeTuple
*tt
= (TypeTuple
*)tbn
;
5139 lwr
= semanticLength(sc
, tbn
, lwr
);
5140 lwr
= lwr
->optimize(WANTvalue
);
5141 uinteger_t i1
= lwr
->toUInteger();
5143 upr
= semanticLength(sc
, tbn
, upr
);
5144 upr
= upr
->optimize(WANTvalue
);
5145 uinteger_t i2
= upr
->toUInteger();
5147 if (!(i1
<= i2
&& i2
<= tt
->arguments
->dim
))
5148 { error(loc
, "slice [%"PRIuMAX
"..%"PRIuMAX
"] is out of range of [0..%u]", i1
, i2
, tt
->arguments
->dim
);
5149 return Type::terror
;
5152 Arguments
*args
= new Arguments
;
5153 args
->reserve(i2
- i1
);
5154 for (size_t i
= i1
; i
< i2
; i
++)
5155 { Argument
*arg
= (Argument
*)tt
->arguments
->data
[i
];
5159 return new TypeTuple(args
);
5162 void TypeSlice::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
5164 next
->resolve(loc
, sc
, pe
, pt
, ps
);
5166 { // It's really a slice expression
5168 e
= new SliceExp(loc
, *pe
, lwr
, upr
);
5173 TupleDeclaration
*td
= s
->isTupleDeclaration();
5176 /* It's a slice of a TupleDeclaration
5178 ScopeDsymbol
*sym
= new ArrayScopeSymbol(td
);
5179 sym
->parent
= sc
->scopesym
;
5182 lwr
= lwr
->semantic(sc
);
5183 lwr
= lwr
->optimize(WANTvalue
);
5184 uinteger_t i1
= lwr
->toUInteger();
5186 upr
= upr
->semantic(sc
);
5187 upr
= upr
->optimize(WANTvalue
);
5188 uinteger_t i2
= upr
->toUInteger();
5192 if (!(i1
<= i2
&& i2
<= td
->objects
->dim
))
5193 { error(loc
, "slice [%"PRIuMAX
"u..%"PRIuMAX
"u] is out of range of [0..%u]", i1
, i2
, td
->objects
->dim
);
5197 if (i1
== 0 && i2
== td
->objects
->dim
)
5203 /* Create a new TupleDeclaration which
5204 * is a slice [i1..i2] out of the old one.
5206 Objects
*objects
= new Objects
;
5207 objects
->setDim(i2
- i1
);
5208 for (size_t i
= 0; i
< objects
->dim
; i
++)
5210 objects
->data
[i
] = td
->objects
->data
[(size_t)i1
+ i
];
5213 TupleDeclaration
*tds
= new TupleDeclaration(loc
, td
->ident
, objects
);
5222 Type::resolve(loc
, sc
, pe
, pt
, ps
);
5226 void TypeSlice::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
5228 if (mod
!= this->mod
)
5229 { toCBuffer3(buf
, hgs
, mod
);
5232 next
->toCBuffer2(buf
, hgs
, this->mod
);
5234 buf
->printf("[%s .. ", lwr
->toChars());
5235 buf
->printf("%s]", upr
->toChars());
5238 /***************************** Argument *****************************/
5240 Argument::Argument(unsigned storageClass
, Type
*type
, Identifier
*ident
, Expression
*defaultArg
)
5243 this->ident
= ident
;
5244 this->storageClass
= storageClass
;
5245 this->defaultArg
= defaultArg
;
5248 Argument
*Argument::syntaxCopy()
5250 Argument
*a
= new Argument(storageClass
,
5251 type
? type
->syntaxCopy() : NULL
,
5253 defaultArg
? defaultArg
->syntaxCopy() : NULL
);
5257 Arguments
*Argument::arraySyntaxCopy(Arguments
*args
)
5258 { Arguments
*a
= NULL
;
5262 a
= new Arguments();
5263 a
->setDim(args
->dim
);
5264 for (size_t i
= 0; i
< a
->dim
; i
++)
5265 { Argument
*arg
= (Argument
*)args
->data
[i
];
5267 arg
= arg
->syntaxCopy();
5268 a
->data
[i
] = (void *)arg
;
5274 char *Argument::argsTypesToChars(Arguments
*args
, int varargs
)
5277 buf
= new OutBuffer();
5279 buf
->writeByte('(');
5285 for (i
= 0; i
< args
->dim
; i
++)
5289 buf
->writeByte(',');
5290 arg
= (Argument
*)args
->data
[i
];
5292 arg
->type
->toCBuffer2(&argbuf
, &hgs
, 0);
5293 buf
->write(&argbuf
);
5297 if (i
&& varargs
== 1)
5298 buf
->writeByte(',');
5299 buf
->writestring("...");
5302 buf
->writeByte(')');
5304 return buf
->toChars();
5307 void Argument::argsToCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
, Arguments
*arguments
, int varargs
)
5309 buf
->writeByte('(');
5314 for (i
= 0; i
< arguments
->dim
; i
++)
5318 buf
->writestring(", ");
5319 arg
= (Argument
*)arguments
->data
[i
];
5320 if (arg
->storageClass
& STCout
)
5321 buf
->writestring("out ");
5322 else if (arg
->storageClass
& STCref
)
5323 buf
->writestring((global
.params
.Dversion
== 1)
5324 ? (char *)"inout " : (char *)"ref ");
5325 else if (arg
->storageClass
& STClazy
)
5326 buf
->writestring("lazy ");
5328 arg
->type
->toCBuffer(&argbuf
, arg
->ident
, hgs
);
5329 if (arg
->defaultArg
)
5331 argbuf
.writestring(" = ");
5332 arg
->defaultArg
->toCBuffer(&argbuf
, hgs
);
5334 buf
->write(&argbuf
);
5338 if (i
&& varargs
== 1)
5339 buf
->writeByte(',');
5340 buf
->writestring("...");
5343 buf
->writeByte(')');
5347 void Argument::argsToDecoBuffer(OutBuffer
*buf
, Arguments
*arguments
)
5349 //printf("Argument::argsToDecoBuffer()\n");
5351 // Write argument types
5354 size_t dim
= Argument::dim(arguments
);
5355 for (size_t i
= 0; i
< dim
; i
++)
5357 Argument
*arg
= Argument::getNth(arguments
, i
);
5358 arg
->toDecoBuffer(buf
);
5363 /****************************************************
5364 * Determine if parameter is a lazy array of delegates.
5365 * If so, return the return type of those delegates.
5366 * If not, return NULL.
5369 Type
*Argument::isLazyArray()
5371 // if (inout == Lazy)
5373 Type
*tb
= type
->toBasetype();
5374 if (tb
->ty
== Tsarray
|| tb
->ty
== Tarray
)
5376 Type
*tel
= tb
->next
->toBasetype();
5377 if (tel
->ty
== Tdelegate
)
5379 TypeDelegate
*td
= (TypeDelegate
*)tel
;
5380 TypeFunction
*tf
= (TypeFunction
*)td
->next
;
5382 if (!tf
->varargs
&& Argument::dim(tf
->parameters
) == 0)
5384 return tf
->next
; // return type of delegate
5392 void Argument::toDecoBuffer(OutBuffer
*buf
)
5394 switch (storageClass
& (STCin
| STCout
| STCref
| STClazy
))
5399 buf
->writeByte('J');
5402 buf
->writeByte('K');
5405 buf
->writeByte('L');
5413 type
->toDecoBuffer(buf
);
5416 /***************************************
5417 * Determine number of arguments, folding in tuples.
5420 size_t Argument::dim(Arguments
*args
)
5425 for (size_t i
= 0; i
< args
->dim
; i
++)
5426 { Argument
*arg
= (Argument
*)args
->data
[i
];
5427 Type
*t
= arg
->type
->toBasetype();
5429 if (t
->ty
== Ttuple
)
5430 { TypeTuple
*tu
= (TypeTuple
*)t
;
5431 n
+= dim(tu
->arguments
);
5440 /***************************************
5441 * Get nth Argument, folding in tuples.
5443 * Argument* nth Argument
5444 * NULL not found, *pn gets incremented by the number
5448 Argument
*Argument::getNth(Arguments
*args
, size_t nth
, size_t *pn
)
5454 for (size_t i
= 0; i
< args
->dim
; i
++)
5455 { Argument
*arg
= (Argument
*)args
->data
[i
];
5456 Type
*t
= arg
->type
->toBasetype();
5458 if (t
->ty
== Ttuple
)
5459 { TypeTuple
*tu
= (TypeTuple
*)t
;
5460 arg
= getNth(tu
->arguments
, nth
- n
, &n
);