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 #define NOT_NULL_MANGLE 'Q'
195 mangleChar
[Tmaybe
] = '?';
196 mangleChar
[Treference
] = 'R';
197 mangleChar
[Tfunction
] = 'F';
198 mangleChar
[Tident
] = 'I';
199 mangleChar
[Tclass
] = 'C';
200 mangleChar
[Tstruct
] = 'S';
201 mangleChar
[Tenum
] = 'E';
202 mangleChar
[Ttypedef
] = 'T';
203 mangleChar
[Tdelegate
] = 'D';
205 mangleChar
[Tnone
] = 'n';
206 mangleChar
[Tvoid
] = 'v';
207 mangleChar
[Tint8
] = 'g';
208 mangleChar
[Tuns8
] = 'h';
209 mangleChar
[Tint16
] = 's';
210 mangleChar
[Tuns16
] = 't';
211 mangleChar
[Tint32
] = 'i';
212 mangleChar
[Tuns32
] = 'k';
213 mangleChar
[Tint64
] = 'l';
214 mangleChar
[Tuns64
] = 'm';
215 mangleChar
[Tfloat32
] = 'f';
216 mangleChar
[Tfloat64
] = 'd';
217 mangleChar
[Tfloat80
] = 'e';
219 mangleChar
[Timaginary32
] = 'o';
220 mangleChar
[Timaginary64
] = 'p';
221 mangleChar
[Timaginary80
] = 'j';
222 mangleChar
[Tcomplex32
] = 'q';
223 mangleChar
[Tcomplex64
] = 'r';
224 mangleChar
[Tcomplex80
] = 'c';
226 mangleChar
[Tbool
] = 'b';
227 mangleChar
[Tascii
] = 'a';
228 mangleChar
[Twchar
] = 'u';
229 mangleChar
[Tdchar
] = 'w';
231 mangleChar
[Tbit
] = '@';
232 mangleChar
[Tinstance
] = '@';
233 mangleChar
[Terror
] = '@';
234 mangleChar
[Ttypeof
] = '@';
235 mangleChar
[Ttuple
] = 'B';
236 mangleChar
[Tslice
] = '@';
238 for (i
= 0; i
< TMAX
; i
++)
239 { if (!mangleChar
[i
])
240 fprintf(stdmsg
, "ty = %d\n", i
);
241 assert(mangleChar
[i
]);
245 static TY basetab
[] =
246 { Tvoid
, Tint8
, Tuns8
, Tint16
, Tuns16
, Tint32
, Tuns32
, Tint64
, Tuns64
,
247 Tfloat32
, Tfloat64
, Tfloat80
,
248 Timaginary32
, Timaginary64
, Timaginary80
,
249 Tcomplex32
, Tcomplex64
, Tcomplex80
,
251 Tascii
, Twchar
, Tdchar
};
253 for (i
= 0; i
< sizeof(basetab
) / sizeof(basetab
[0]); i
++)
254 basic
[basetab
[i
]] = new TypeBasic(basetab
[i
]);
255 basic
[Terror
] = basic
[Tint32
];
257 tvoidptr
= tvoid
->pointerTo();
259 if (global
.params
.isX86_64
)
262 if (global
.params
.isLinux
)
283 CLASSINFO_SIZE
= 18 * PTRSIZE
;
291 d_uns64
Type::size(Loc loc
)
293 error(loc
, "no size for type %s", toChars());
297 unsigned Type::alignsize()
302 Type
*Type::semantic(Loc loc
, Scope
*sc
)
305 next
= next
->semantic(loc
,sc
);
314 t
= new TypeMaybe(this);
320 Type
*Type::pointerTo()
325 t
= new TypePointer(this);
331 Type
*Type::referenceTo()
336 t
= new TypeReference(this);
342 Type
*Type::arrayOf()
347 t
= new TypeDArray(this);
348 arrayof
= t
->merge();
353 Dsymbol
*Type::toDsymbol(Scope
*sc
)
358 /*******************************
359 * If this is a shell around another type,
360 * get that other type.
363 Type
*Type::toBasetype()
368 /********************************
372 void Type::toDecoBuffer(OutBuffer
*buf
)
374 buf
->writeByte(mangleChar
[ty
]);
377 assert(next
!= this);
378 //printf("this = %p, ty = %d, next = %p, ty = %d\n", this, this->ty, next, next->ty);
379 next
->toDecoBuffer(buf
);
383 /********************************
384 * For pretty-printing a type.
387 char *Type::toChars()
391 buf
= new OutBuffer();
392 toCBuffer(buf
, NULL
, &hgs
);
393 return buf
->toChars();
396 void Type::toCBuffer(OutBuffer
*buf
, Identifier
*ident
, HdrGenState
*hgs
)
398 toCBuffer2(buf
, hgs
, 0);
400 { buf
->writeByte(' ');
401 buf
->writestring(ident
->toChars());
405 void Type::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
407 if (mod
!= this->mod
)
408 { toCBuffer3(buf
, hgs
, mod
);
411 buf
->writestring(toChars());
414 void Type::toCBuffer3(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
416 if (mod
!= this->mod
)
422 toCBuffer2(buf
, hgs
, this->mod
);
429 L1
: buf
->writestring(p
);
430 toCBuffer2(buf
, hgs
, this->mod
);
440 /************************************
446 //printf("merge(%s)\n", toChars());
455 next
= next
->merge();
457 sv
= stringtable
.update((char *)buf
.data
, buf
.offset
);
459 { t
= (Type
*) sv
->ptrvalue
;
461 //printf("old value, deco = '%s' %p\n", t->deco, t->deco);
466 deco
= sv
->lstring
.string
;
467 //printf("new value, deco = '%s' %p\n", t->deco, t->deco);
478 int Type::isintegral()
483 int Type::isfloating()
493 int Type::isimaginary()
498 int Type::iscomplex()
508 int Type::isunsigned()
513 ClassDeclaration
*Type::isClassHandle()
528 int Type::checkBoolean()
533 /*********************************
534 * Check type to see if it is based on a deprecated symbol.
537 void Type::checkDeprecated(Loc loc
, Scope
*sc
)
542 for (t
= this; t
; t
= t
->next
)
544 s
= t
->toDsymbol(sc
);
546 s
->checkDeprecated(loc
, sc
);
551 Expression
*Type::defaultInit(Loc loc
)
554 printf("Type::defaultInit() '%s'\n", toChars());
559 int Type::isZeroInit()
561 return 0; // assume not
564 int Type::isBaseOf(Type
*t
, target_ptrdiff_t
*poffset
)
566 return 0; // assume not
569 /********************************
570 * Determine if 'this' can be implicitly converted
574 * 1 can convert using implicit conversions
575 * 2 this and to are the same type
578 MATCH
Type::implicitConvTo(Type
*to
)
580 //printf("Type::implicitConvTo(this=%p, to=%p)\n", this, to);
581 //printf("\tthis->next=%p, to->next=%p\n", this->next, to->next);
584 // if (to->ty == Tvoid)
589 Expression
*Type::getProperty(Loc loc
, Identifier
*ident
)
593 printf("Type::getProperty(type = '%s', ident = '%s')\n", toChars(), ident
->toChars());
595 if (ident
== Id::__sizeof
)
597 e
= new IntegerExp(loc
, size(loc
), Type::tsize_t
);
599 else if (ident
== Id::size
)
601 error(loc
, ".size property should be replaced with .sizeof");
602 e
= new IntegerExp(loc
, size(loc
), Type::tsize_t
);
604 else if (ident
== Id::alignof
)
606 e
= new IntegerExp(loc
, alignsize(), Type::tsize_t
);
608 else if (ident
== Id::typeinfo
)
610 if (!global
.params
.useDeprecated
)
611 error(loc
, ".typeinfo deprecated, use typeid(type)");
612 e
= getTypeInfo(NULL
);
614 else if (ident
== Id::init
)
617 error(loc
, "void does not have an initializer");
618 e
= defaultInit(loc
);
620 else if (ident
== Id::mangleof
)
623 e
= new StringExp(loc
, deco
, strlen(deco
), 'c');
625 e
= e
->semantic(&sc
);
627 else if (ident
== Id::stringof
)
628 { char *s
= toChars();
629 e
= new StringExp(loc
, s
, strlen(s
), 'c');
631 e
= e
->semantic(&sc
);
635 error(loc
, "no property '%s' for type '%s'", ident
->toChars(), toChars());
636 e
= new IntegerExp(loc
, 1, Type::tint32
);
641 Expression
*Type::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
642 { VarDeclaration
*v
= NULL
;
645 printf("Type::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
647 if (e
->op
== TOKdotvar
)
649 DotVarExp
*dv
= (DotVarExp
*)e
;
650 v
= dv
->var
->isVarDeclaration();
652 else if (e
->op
== TOKvar
)
654 VarExp
*ve
= (VarExp
*)e
;
655 v
= ve
->var
->isVarDeclaration();
659 if (ident
== Id::offset
)
661 if (!global
.params
.useDeprecated
)
662 error(e
->loc
, ".offset deprecated, use .offsetof");
665 else if (ident
== Id::offsetof
)
668 if (v
->storage_class
& STCfield
)
670 e
= new IntegerExp(e
->loc
, v
->offset
, Type::tsize_t
);
674 else if (ident
== Id::init
)
679 if (v
->init
->isVoidInitializer())
680 error(e
->loc
, "%s.init is void", v
->toChars());
683 e
= v
->init
->toExpression();
684 if (e
->op
== TOKassign
|| e
->op
== TOKconstruct
)
686 e
= ((AssignExp
*)e
)->e2
;
688 /* Take care of case where we used a 0
689 * to initialize the struct.
691 if (e
->type
== Type::tint32
&&
693 v
->type
->toBasetype()->ty
== Tstruct
)
695 e
= v
->type
->defaultInit(loc
);
698 e
= e
->optimize(WANTvalue
| WANTinterpret
);
699 // if (!e->isConst())
700 // error(loc, ".init cannot be evaluated at compile time");
705 Expression
*ex
= defaultInit(e
->loc
);
709 if (ident
== Id::typeinfo
)
711 if (!global
.params
.useDeprecated
)
712 error(e
->loc
, ".typeinfo deprecated, use typeid(type)");
716 if (ident
== Id::stringof
)
717 { char *s
= e
->toChars();
718 e
= new StringExp(e
->loc
, s
, strlen(s
), 'c');
720 e
= e
->semantic(&sc
);
723 return getProperty(e
->loc
, ident
);
726 unsigned Type::memalign(unsigned salign
)
731 void Type::error(Loc loc
, const char *format
, ...)
734 va_start(ap
, format
);
735 ::verror(loc
, format
, ap
);
739 Identifier
*Type::getTypeInfoIdent(int internal
)
741 // _init_10TypeInfo_%s
747 //toTypeInfoBuffer(&buf);
749 { buf
.writeByte(mangleChar
[ty
]);
751 buf
.writeByte(mangleChar
[next
->ty
]);
756 name
= (char *)alloca(19 + sizeof(len
) * 3 + len
+ 1);
758 sprintf(name
, "_D%dTypeInfo_%s6__initZ", 9 + len
, buf
.data
);
759 if (global
.params
.isWindows
)
760 name
++; // C mangling will add it back in
761 //printf("name = %s\n", name);
762 id
= Lexer::idPool(name
);
766 TypeBasic
*Type::isTypeBasic()
772 void Type::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
776 t
= semantic(loc
, sc
);
782 /*******************************
783 * If one of the subtypes of this type is a TypeIdentifier,
784 * i.e. it's an unresolved type, return that type.
787 Type
*Type::reliesOnTident()
792 return next
->reliesOnTident();
795 /********************************
796 * We've mistakenly parsed this as a type.
797 * Redo it as an Expression.
801 Expression
*Type::toExpression()
806 /***************************************
807 * Return !=0 if type has pointers that need to
808 * be scanned by the GC during a collection cycle.
811 int Type::hasPointers()
816 /* ============================= TypeBasic =========================== */
818 TypeBasic::TypeBasic(TY ty
)
824 #define TFLAGSintegral 1
825 #define TFLAGSfloating 2
826 #define TFLAGSunsigned 4
828 #define TFLAGSimaginary 0x10
829 #define TFLAGScomplex 0x20
834 case Tvoid
: d
= Token::toChars(TOKvoid
);
838 case Tint8
: d
= Token::toChars(TOKint8
);
840 flags
|= TFLAGSintegral
;
843 case Tuns8
: d
= Token::toChars(TOKuns8
);
845 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
848 case Tint16
: d
= Token::toChars(TOKint16
);
850 flags
|= TFLAGSintegral
;
853 case Tuns16
: d
= Token::toChars(TOKuns16
);
855 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
858 case Tint32
: d
= Token::toChars(TOKint32
);
860 flags
|= TFLAGSintegral
;
863 case Tuns32
: d
= Token::toChars(TOKuns32
);
865 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
868 case Tfloat32
: d
= Token::toChars(TOKfloat32
);
870 flags
|= TFLAGSfloating
| TFLAGSreal
;
873 case Tint64
: d
= Token::toChars(TOKint64
);
875 flags
|= TFLAGSintegral
;
878 case Tuns64
: d
= Token::toChars(TOKuns64
);
880 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
883 case Tfloat64
: d
= Token::toChars(TOKfloat64
);
885 flags
|= TFLAGSfloating
| TFLAGSreal
;
888 case Tfloat80
: d
= Token::toChars(TOKfloat80
);
890 flags
|= TFLAGSfloating
| TFLAGSreal
;
893 case Timaginary32
: d
= Token::toChars(TOKimaginary32
);
895 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
898 case Timaginary64
: d
= Token::toChars(TOKimaginary64
);
900 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
903 case Timaginary80
: d
= Token::toChars(TOKimaginary80
);
905 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
908 case Tcomplex32
: d
= Token::toChars(TOKcomplex32
);
910 flags
|= TFLAGSfloating
| TFLAGScomplex
;
913 case Tcomplex64
: d
= Token::toChars(TOKcomplex64
);
915 flags
|= TFLAGSfloating
| TFLAGScomplex
;
918 case Tcomplex80
: d
= Token::toChars(TOKcomplex80
);
920 flags
|= TFLAGSfloating
| TFLAGScomplex
;
924 case Tbit
: d
= Token::toChars(TOKbit
);
926 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
929 case Tbool
: d
= "bool";
931 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
934 case Tascii
: d
= Token::toChars(TOKchar
);
936 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
939 case Twchar
: d
= Token::toChars(TOKwchar
);
941 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
944 case Tdchar
: d
= Token::toChars(TOKdchar
);
946 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
957 Type
*TypeBasic::syntaxCopy()
959 // No semantic analysis done on basic types, no need to copy
964 char *TypeBasic::toChars()
969 void TypeBasic::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
971 //printf("TypeBasic::toCBuffer2(mod = %d, this->mod = %d)\n", mod, this->mod);
972 if (mod
!= this->mod
)
973 { toCBuffer3(buf
, hgs
, mod
);
976 buf
->writestring(dstring
);
979 d_uns64
TypeBasic::size(Loc loc
)
982 //printf("TypeBasic::size()\n");
986 case Tuns8
: size
= 1; break;
988 case Tuns16
: size
= 2; break;
1001 size
= REALSIZE
; break;
1007 size
= REALSIZE
* 2; break;
1010 //size = Type::size(); // error message
1014 case Tbit
: size
= 1; break;
1015 case Tbool
: size
= 1; break;
1016 case Tascii
: size
= 1; break;
1017 case Twchar
: size
= 2; break;
1018 case Tdchar
: size
= 4; break;
1024 //printf("TypeBasic::size() = %d\n", size);
1028 unsigned TypeBasic::alignsize()
1047 Expression
*TypeBasic::getProperty(Loc loc
, Identifier
*ident
)
1057 //printf("TypeBasic::getProperty('%s')\n", ident->toChars());
1058 if (ident
== Id::max
)
1062 case Tint8
: ivalue
= 0x7F; goto Livalue
;
1063 case Tuns8
: ivalue
= 0xFF; goto Livalue
;
1064 case Tint16
: ivalue
= 0x7FFFUL
; goto Livalue
;
1065 case Tuns16
: ivalue
= 0xFFFFUL
; goto Livalue
;
1066 case Tint32
: ivalue
= 0x7FFFFFFFUL
; goto Livalue
;
1067 case Tuns32
: ivalue
= 0xFFFFFFFFUL
; goto Livalue
;
1068 case Tint64
: ivalue
= 0x7FFFFFFFFFFFFFFFLL
; goto Livalue
;
1069 case Tuns64
: ivalue
= 0xFFFFFFFFFFFFFFFFULL
; goto Livalue
;
1070 case Tbit
: ivalue
= 1; goto Livalue
;
1071 case Tbool
: ivalue
= 1; goto Livalue
;
1072 case Tchar
: ivalue
= 0xFF; goto Livalue
;
1073 case Twchar
: ivalue
= 0xFFFFUL
; goto Livalue
;
1074 case Tdchar
: ivalue
= 0x10FFFFUL
; goto Livalue
;
1080 #define FLT_MAX real_t_properties[real_t::Float].maxval;
1081 #define DBL_MAX real_t_properties[real_t::Double].maxval;
1082 #define LDBL_MAX real_t_properties[real_t::LongDouble].maxval;
1083 #define FLT_MIN real_t_properties[real_t::Float].minval;
1084 #define DBL_MIN real_t_properties[real_t::Double].minval;
1085 #define LDBL_MIN real_t_properties[real_t::LongDouble].minval;
1086 #define FLT_DIG real_t_properties[real_t::Float].dig;
1087 #define DBL_DIG real_t_properties[real_t::Double].dig;
1088 #define LDBL_DIG real_t_properties[real_t::LongDouble].dig;
1089 #define FLT_MANT_DIG real_t_properties[real_t::Float].mant_dig;
1090 #define DBL_MANT_DIG real_t_properties[real_t::Double].mant_dig;
1091 #define LDBL_MANT_DIG real_t_properties[real_t::LongDouble].mant_dig;
1092 #define FLT_MAX_10_EXP real_t_properties[real_t::Float].max_10_exp;
1093 #define DBL_MAX_10_EXP real_t_properties[real_t::Double].max_10_exp;
1094 #define LDBL_MAX_10_EXP real_t_properties[real_t::LongDouble].max_10_exp;
1095 #define FLT_MIN_10_EXP real_t_properties[real_t::Float].min_10_exp;
1096 #define DBL_MIN_10_EXP real_t_properties[real_t::Double].min_10_exp;
1097 #define LDBL_MIN_10_EXP real_t_properties[real_t::LongDouble].min_10_exp;
1098 #define FLT_MAX_EXP real_t_properties[real_t::Float].max_exp;
1099 #define DBL_MAX_EXP real_t_properties[real_t::Double].max_exp;
1100 #define LDBL_MAX_EXP real_t_properties[real_t::LongDouble].max_exp;
1101 #define FLT_MIN_EXP real_t_properties[real_t::Float].min_exp;
1102 #define DBL_MIN_EXP real_t_properties[real_t::Double].min_exp;
1103 #define LDBL_MIN_EXP real_t_properties[real_t::LongDouble].min_exp;
1104 #define FLT_EPSILON real_t_properties[real_t::Float].epsilonval;
1105 #define DBL_EPSILON real_t_properties[real_t::Double].epsilonval;
1106 #define LDBL_EPSILON real_t_properties[real_t::LongDouble].epsilonval;
1110 case Tfloat32
: fvalue
= FLT_MAX
; goto Lfvalue
;
1113 case Tfloat64
: fvalue
= DBL_MAX
; goto Lfvalue
;
1116 case Tfloat80
: fvalue
= LDBL_MAX
; goto Lfvalue
;
1119 else if (ident
== Id::min
)
1123 case Tint8
: ivalue
= -128; goto Livalue
;
1124 case Tuns8
: ivalue
= 0; goto Livalue
;
1125 case Tint16
: ivalue
= -32768; goto Livalue
;
1126 case Tuns16
: ivalue
= 0; goto Livalue
;
1127 case Tint32
: ivalue
= -2147483647L - 1; goto Livalue
;
1128 case Tuns32
: ivalue
= 0; goto Livalue
;
1129 case Tint64
: ivalue
= (-9223372036854775807LL-1LL); goto Livalue
;
1130 case Tuns64
: ivalue
= 0; goto Livalue
;
1131 case Tbit
: ivalue
= 0; goto Livalue
;
1132 case Tbool
: ivalue
= 0; goto Livalue
;
1133 case Tchar
: ivalue
= 0; goto Livalue
;
1134 case Twchar
: ivalue
= 0; goto Livalue
;
1135 case Tdchar
: ivalue
= 0; goto Livalue
;
1139 case Tfloat32
: fvalue
= FLT_MIN
; goto Lfvalue
;
1142 case Tfloat64
: fvalue
= DBL_MIN
; goto Lfvalue
;
1145 case Tfloat80
: fvalue
= LDBL_MIN
; goto Lfvalue
;
1148 else if (ident
== Id::nan
)
1163 // mode doesn't matter, will be converted in RealExp anyway
1164 fvalue
= real_t::getnan(real_t::LongDouble
);
1166 // gcc nan's have the sign bit set by default, so turn it off
1167 // Need the volatile to prevent gcc from doing incorrect
1168 // constant folding.
1169 volatile d_float80 foo
;
1171 if (signbit(foo
)) // signbit sometimes, not always, set
1172 foo
= -foo
; // turn off sign bit
1175 unsigned long nan
[2]= { 0xFFFFFFFF, 0x7FFFFFFF };
1176 fvalue
= *(double*)nan
;
1184 else if (ident
== Id::infinity
)
1198 fvalue
= real_t::getinfinity();
1202 fvalue
= std::numeric_limits
<long double>::infinity();
1209 else if (ident
== Id::dig
)
1215 case Tfloat32
: ivalue
= FLT_DIG
; goto Lint
;
1218 case Tfloat64
: ivalue
= DBL_DIG
; goto Lint
;
1221 case Tfloat80
: ivalue
= LDBL_DIG
; goto Lint
;
1224 else if (ident
== Id::epsilon
)
1230 case Tfloat32
: fvalue
= FLT_EPSILON
; goto Lfvalue
;
1233 case Tfloat64
: fvalue
= DBL_EPSILON
; goto Lfvalue
;
1236 case Tfloat80
: fvalue
= LDBL_EPSILON
; goto Lfvalue
;
1239 else if (ident
== Id::mant_dig
)
1245 case Tfloat32
: ivalue
= FLT_MANT_DIG
; goto Lint
;
1248 case Tfloat64
: ivalue
= DBL_MANT_DIG
; goto Lint
;
1251 case Tfloat80
: ivalue
= LDBL_MANT_DIG
; goto Lint
;
1254 else if (ident
== Id::max_10_exp
)
1260 case Tfloat32
: ivalue
= FLT_MAX_10_EXP
; goto Lint
;
1263 case Tfloat64
: ivalue
= DBL_MAX_10_EXP
; goto Lint
;
1266 case Tfloat80
: ivalue
= LDBL_MAX_10_EXP
; goto Lint
;
1269 else if (ident
== Id::max_exp
)
1275 case Tfloat32
: ivalue
= FLT_MAX_EXP
; goto Lint
;
1278 case Tfloat64
: ivalue
= DBL_MAX_EXP
; goto Lint
;
1281 case Tfloat80
: ivalue
= LDBL_MAX_EXP
; goto Lint
;
1284 else if (ident
== Id::min_10_exp
)
1290 case Tfloat32
: ivalue
= FLT_MIN_10_EXP
; goto Lint
;
1293 case Tfloat64
: ivalue
= DBL_MIN_10_EXP
; goto Lint
;
1296 case Tfloat80
: ivalue
= LDBL_MIN_10_EXP
; goto Lint
;
1299 else if (ident
== Id::min_exp
)
1305 case Tfloat32
: ivalue
= FLT_MIN_EXP
; goto Lint
;
1308 case Tfloat64
: ivalue
= DBL_MIN_EXP
; goto Lint
;
1311 case Tfloat80
: ivalue
= LDBL_MIN_EXP
; goto Lint
;
1316 return Type::getProperty(loc
, ident
);
1319 e
= new IntegerExp(loc
, ivalue
, this);
1323 if (isreal() || isimaginary())
1324 e
= new RealExp(loc
, fvalue
, this);
1330 //((real_t *)&cvalue)[0] = fvalue;
1331 //((real_t *)&cvalue)[1] = fvalue;
1332 cvalue
= fvalue
+ fvalue
* I
;
1337 //for (int i = 0; i < 20; i++)
1338 // printf("%02x ", ((unsigned char *)&cvalue)[i]);
1340 e
= new ComplexExp(loc
, cvalue
, this);
1345 e
= new IntegerExp(loc
, ivalue
, Type::tint32
);
1349 Expression
*TypeBasic::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
1352 printf("TypeBasic::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
1356 if (ident
== Id::re
)
1360 case Tcomplex32
: t
= tfloat32
; goto L1
;
1361 case Tcomplex64
: t
= tfloat64
; goto L1
;
1362 case Tcomplex80
: t
= tfloat80
; goto L1
;
1364 e
= e
->castTo(sc
, t
);
1372 case Timaginary32
: t
= tfloat32
; goto L2
;
1373 case Timaginary64
: t
= tfloat64
; goto L2
;
1374 case Timaginary80
: t
= tfloat80
; goto L2
;
1376 e
= new RealExp(0, 0, t
);
1380 return Type::getProperty(e
->loc
, ident
);
1383 else if (ident
== Id::im
)
1388 case Tcomplex32
: t
= timaginary32
; t2
= tfloat32
; goto L3
;
1389 case Tcomplex64
: t
= timaginary64
; t2
= tfloat64
; goto L3
;
1390 case Tcomplex80
: t
= timaginary80
; t2
= tfloat80
; goto L3
;
1392 e
= e
->castTo(sc
, t
);
1396 case Timaginary32
: t
= tfloat32
; goto L4
;
1397 case Timaginary64
: t
= tfloat64
; goto L4
;
1398 case Timaginary80
: t
= tfloat80
; goto L4
;
1406 e
= new RealExp(0, 0, this);
1410 return Type::getProperty(e
->loc
, ident
);
1415 return Type::dotExp(sc
, e
, ident
);
1420 Expression
*TypeBasic::defaultInit(Loc loc
)
1421 { integer_t value
= 0;
1424 printf("TypeBasic::defaultInit() '%s'\n", toChars());
1446 return getProperty(loc
, Id::nan
);
1448 return new IntegerExp(loc
, value
, this);
1451 int TypeBasic::isZeroInit()
1472 int TypeBasic::isbit()
1474 return (ty
== Tbit
);
1477 int TypeBasic::isintegral()
1479 //printf("TypeBasic::isintegral('%s') x%x\n", toChars(), flags);
1480 return flags
& TFLAGSintegral
;
1483 int TypeBasic::isfloating()
1485 return flags
& TFLAGSfloating
;
1488 int TypeBasic::isreal()
1490 return flags
& TFLAGSreal
;
1493 int TypeBasic::isimaginary()
1495 return flags
& TFLAGSimaginary
;
1498 int TypeBasic::iscomplex()
1500 return flags
& TFLAGScomplex
;
1503 int TypeBasic::isunsigned()
1505 return flags
& TFLAGSunsigned
;
1508 int TypeBasic::isscalar()
1510 return flags
& (TFLAGSintegral
| TFLAGSfloating
);
1513 MATCH
TypeBasic::implicitConvTo(Type
*to
)
1515 //printf("TypeBasic::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
1519 if (ty
== Tvoid
|| to
->ty
== Tvoid
)
1520 return MATCHnomatch
;
1521 if (1 || global
.params
.Dversion
== 1)
1523 if (to
->ty
== Tbool
)
1524 return MATCHnomatch
;
1528 if (ty
== Tbool
|| to
->ty
== Tbool
)
1529 return MATCHnomatch
;
1531 if (!to
->isTypeBasic())
1532 return MATCHnomatch
;
1534 TypeBasic
*tob
= (TypeBasic
*)to
;
1535 if (flags
& TFLAGSintegral
)
1537 // Disallow implicit conversion of integers to imaginary or complex
1538 if (tob
->flags
& (TFLAGSimaginary
| TFLAGScomplex
))
1539 return MATCHnomatch
;
1541 // If converting to integral
1542 if (0 && global
.params
.Dversion
> 1 && tob
->flags
& TFLAGSintegral
)
1543 { d_uns64 sz
= size(0);
1544 d_uns64 tosz
= tob
->size(0);
1546 /* Can't convert to smaller size or, if same size, change sign
1549 return MATCHnomatch
;
1551 /*if (sz == tosz && (flags ^ tob->flags) & TFLAGSunsigned)
1552 return MATCHnomatch;*/
1555 else if (flags
& TFLAGSfloating
)
1557 // Disallow implicit conversion of floating point to integer
1558 if (tob
->flags
& TFLAGSintegral
)
1559 return MATCHnomatch
;
1561 assert(tob
->flags
& TFLAGSfloating
);
1563 // Disallow implicit conversion from complex to non-complex
1564 if (flags
& TFLAGScomplex
&& !(tob
->flags
& TFLAGScomplex
))
1565 return MATCHnomatch
;
1567 // Disallow implicit conversion of real or imaginary to complex
1568 if (flags
& (TFLAGSreal
| TFLAGSimaginary
) &&
1569 tob
->flags
& TFLAGScomplex
)
1570 return MATCHnomatch
;
1572 // Disallow implicit conversion to-from real and imaginary
1573 if ((flags
& (TFLAGSreal
| TFLAGSimaginary
)) !=
1574 (tob
->flags
& (TFLAGSreal
| TFLAGSimaginary
)))
1575 return MATCHnomatch
;
1577 return MATCHconvert
;
1580 TypeBasic
*TypeBasic::isTypeBasic()
1582 return (TypeBasic
*)this;
1585 /***************************** TypeArray *****************************/
1587 TypeArray::TypeArray(TY ty
, Type
*next
)
1592 Expression
*TypeArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
1594 Type
*n
= this->next
->toBasetype(); // uncover any typedef's
1597 printf("TypeArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
1599 if (ident
== Id::reverse
&& (n
->ty
== Tchar
|| n
->ty
== Twchar
))
1602 FuncDeclaration
*fd
;
1603 Expressions
*arguments
;
1605 static char *name
[2] = { "_adReverseChar", "_adReverseWchar" };
1607 nm
= name
[n
->ty
== Twchar
];
1608 fd
= FuncDeclaration::genCfunc(next
->arrayOf(), nm
, Type::tvoid
->arrayOf());
1609 ec
= new VarExp(0, fd
);
1610 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1611 arguments
= new Expressions();
1613 e
= new CallExp(e
->loc
, ec
, arguments
);
1614 e
->type
= next
->arrayOf();
1616 else if (ident
== Id::sort
&& (n
->ty
== Tchar
|| n
->ty
== Twchar
))
1619 FuncDeclaration
*fd
;
1620 Expressions
*arguments
;
1622 static char *name
[2] = { "_adSortChar", "_adSortWchar" };
1624 nm
= name
[n
->ty
== Twchar
];
1625 fd
= FuncDeclaration::genCfunc(next
->arrayOf(), nm
, Type::tvoid
->arrayOf());
1626 ec
= new VarExp(0, fd
);
1627 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1628 arguments
= new Expressions();
1630 e
= new CallExp(e
->loc
, ec
, arguments
);
1631 e
->type
= next
->arrayOf();
1633 else if (ident
== Id::reverse
|| ident
== Id::dup
)
1636 FuncDeclaration
*fd
;
1637 Expressions
*arguments
;
1638 target_size_t size
= next
->size(e
->loc
);
1642 dup
= (ident
== Id::dup
);
1644 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::adDup
,
1645 Type::typeinfo
->type
, Type::tvoid
->arrayOf());
1647 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::adReverse
,
1648 Type::tvoid
->arrayOf(), Type::tsize_t
);
1649 ec
= new VarExp(0, fd
);
1650 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1651 arguments
= new Expressions();
1653 arguments
->push(getTypeInfo(sc
));
1656 arguments
->push(new IntegerExp(0, size
, Type::tsize_t
));
1657 e
= new CallExp(e
->loc
, ec
, arguments
);
1658 e
->type
= next
->arrayOf();
1660 else if (ident
== Id::sort
)
1663 FuncDeclaration
*fd
;
1664 Expressions
*arguments
;
1666 fd
= FuncDeclaration::genCfunc(tint32
->arrayOf(),
1667 (char*)(n
->ty
== Tbit
? "_adSortBit" : "_adSort"),
1668 Type::tvoid
->arrayOf(),
1669 n
->ty
== Tbit
? NULL
: Type::tvoid
->pointerTo());
1670 ec
= new VarExp(0, fd
);
1671 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1672 arguments
= new Expressions();
1674 if (next
->ty
!= Tbit
)
1675 arguments
->push(n
->ty
== Tsarray
1676 ? n
->getTypeInfo(sc
) // don't convert to dynamic array
1677 : n
->getInternalTypeInfo(sc
));
1678 e
= new CallExp(e
->loc
, ec
, arguments
);
1679 e
->type
= next
->arrayOf();
1683 e
= Type::dotExp(sc
, e
, ident
);
1689 /***************************** TypeSArray *****************************/
1691 TypeSArray::TypeSArray(Type
*t
, Expression
*dim
)
1692 : TypeArray(Tsarray
, t
)
1694 //printf("TypeSArray(%s)\n", dim->toChars());
1698 Type
*TypeSArray::syntaxCopy()
1700 Type
*t
= next
->syntaxCopy();
1701 Expression
*e
= dim
->syntaxCopy();
1702 t
= new TypeSArray(t
, e
);
1706 d_uns64
TypeSArray::size(Loc loc
)
1710 return Type::size(loc
);
1711 sz
= dim
->toInteger();
1712 if (next
->toBasetype()->ty
== Tbit
) // if array of bits
1716 sz
= ((sz
+ 31) & ~31) / 8; // size in bytes, rounded up to 32 bit dwords
1723 if (n
&& (n2
/ n
) != sz
)
1730 error(loc
, "index %"PRIdMAX
" overflow for static array", sz
);
1734 unsigned TypeSArray::alignsize()
1736 return next
->alignsize();
1739 /**************************
1740 * This evaluates exp while setting length to be the number
1741 * of elements in the tuple t.
1743 Expression
*semanticLength(Scope
*sc
, Type
*t
, Expression
*exp
)
1745 if (t
->ty
== Ttuple
)
1746 { ScopeDsymbol
*sym
= new ArrayScopeSymbol((TypeTuple
*)t
);
1747 sym
->parent
= sc
->scopesym
;
1750 exp
= exp
->semantic(sc
);
1755 exp
= exp
->semantic(sc
);
1759 Expression
*semanticLength(Scope
*sc
, TupleDeclaration
*s
, Expression
*exp
)
1761 ScopeDsymbol
*sym
= new ArrayScopeSymbol(s
);
1762 sym
->parent
= sc
->scopesym
;
1765 exp
= exp
->semantic(sc
);
1771 void TypeSArray::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
1773 //printf("TypeSArray::resolve() %s\n", toChars());
1774 next
->resolve(loc
, sc
, pe
, pt
, ps
);
1775 //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
1777 { // It's really an index expression
1779 e
= new IndexExp(loc
, *pe
, dim
);
1784 TupleDeclaration
*td
= s
->isTupleDeclaration();
1787 ScopeDsymbol
*sym
= new ArrayScopeSymbol(td
);
1788 sym
->parent
= sc
->scopesym
;
1791 dim
= dim
->semantic(sc
);
1792 dim
= dim
->optimize(WANTvalue
| WANTinterpret
);
1793 uinteger_t d
= dim
->toUInteger();
1797 if (d
>= td
->objects
->dim
)
1798 { error(loc
, "tuple index %"PRIuMAX
" exceeds %u", d
, td
->objects
->dim
);
1801 Object
*o
= (Object
*)td
->objects
->data
[(size_t)d
];
1802 if (o
->dyncast() == DYNCAST_DSYMBOL
)
1807 if (o
->dyncast() == DYNCAST_EXPRESSION
)
1810 *pe
= (Expression
*)o
;
1814 /* Create a new TupleDeclaration which
1815 * is a slice [d..d+1] out of the old one.
1816 * Do it this way because TemplateInstance::semanticTiargs()
1817 * can handle unresolved Objects this way.
1819 Objects
*objects
= new Objects
;
1821 objects
->data
[0] = o
;
1823 TupleDeclaration
*tds
= new TupleDeclaration(loc
, td
->ident
, objects
);
1832 Type::resolve(loc
, sc
, pe
, pt
, ps
);
1836 Type
*TypeSArray::semantic(Loc loc
, Scope
*sc
)
1838 //printf("TypeSArray::semantic() %s\n", toChars());
1843 next
->resolve(loc
, sc
, &e
, &t
, &s
);
1844 if (dim
&& s
&& s
->isTupleDeclaration())
1845 { TupleDeclaration
*sd
= s
->isTupleDeclaration();
1847 dim
= semanticLength(sc
, sd
, dim
);
1848 dim
= dim
->optimize(WANTvalue
| WANTinterpret
);
1849 uinteger_t d
= dim
->toUInteger();
1851 if (d
>= sd
->objects
->dim
)
1852 { error(loc
, "tuple index %ju exceeds %u", d
, sd
->objects
->dim
);
1853 return Type::terror
;
1855 Object
*o
= (Object
*)sd
->objects
->data
[(size_t)d
];
1856 if (o
->dyncast() != DYNCAST_TYPE
)
1857 { error(loc
, "%s is not a type", toChars());
1858 return Type::terror
;
1864 next
= next
->semantic(loc
,sc
);
1865 Type
*tbn
= next
->toBasetype();
1870 dim
= semanticLength(sc
, tbn
, dim
);
1872 dim
= dim
->optimize(WANTvalue
| WANTinterpret
);
1873 if (sc
->parameterSpecialization
&& dim
->op
== TOKvar
&&
1874 ((VarExp
*)dim
)->var
->storage_class
& STCtemplateparameter
)
1876 /* It could be a template parameter N which has no value yet:
1877 * template Foo(T : T[N], size_t N);
1881 integer_t d1
= dim
->toInteger();
1882 dim
= dim
->castTo(sc
, tsize_t
);
1883 dim
= dim
->optimize(WANTvalue
);
1884 integer_t d2
= dim
->toInteger();
1889 if (tbn
->isintegral() ||
1890 tbn
->isfloating() ||
1891 tbn
->ty
== Tpointer
||
1892 tbn
->ty
== Tarray
||
1893 tbn
->ty
== Tsarray
||
1894 tbn
->ty
== Taarray
||
1897 /* Only do this for types that don't need to have semantic()
1898 * run on them for the size, since they may be forward referenced.
1904 if (n2
>= 0x1000000) // put a 'reasonable' limit on it
1906 if (n
&& n2
/ n
!= d2
)
1909 error(loc
, "index %"PRIdMAX
" overflow for static array", d1
);
1910 dim
= new IntegerExp(0, 1, tsize_t
);
1917 { // Index the tuple to get the type
1919 TypeTuple
*tt
= (TypeTuple
*)tbn
;
1920 uinteger_t d
= dim
->toUInteger();
1922 if (d
>= tt
->arguments
->dim
)
1923 { error(loc
, "tuple index %"PRIuMAX
" exceeds %u", d
, tt
->arguments
->dim
);
1924 return Type::terror
;
1926 Argument
*arg
= (Argument
*)tt
->arguments
->data
[(size_t)d
];
1931 error(loc
, "can't have array of %s", tbn
->toChars());
1932 tbn
= next
= tint32
;
1936 error(loc
, "cannot have array of auto %s", tbn
->toChars());
1940 void TypeSArray::toDecoBuffer(OutBuffer
*buf
)
1942 buf
->writeByte(mangleChar
[ty
]);
1944 buf
->printf("%"PRIuMAX
, dim
->toInteger());
1946 next
->toDecoBuffer(buf
);
1949 void TypeSArray::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
1951 if (mod
!= this->mod
)
1952 { toCBuffer3(buf
, hgs
, mod
);
1955 next
->toCBuffer2(buf
, hgs
, this->mod
);
1956 buf
->printf("[%s]", dim
->toChars());
1959 Expression
*TypeSArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
1962 printf("TypeSArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
1964 if (ident
== Id::length
)
1968 else if (ident
== Id::ptr
)
1970 e
= e
->castTo(sc
, next
->pointerTo());
1974 e
= TypeArray::dotExp(sc
, e
, ident
);
1979 int TypeSArray::isString()
1981 TY nty
= next
->toBasetype()->ty
;
1982 return nty
== Tchar
|| nty
== Twchar
|| nty
== Tdchar
;
1985 unsigned TypeSArray::memalign(unsigned salign
)
1987 return next
->memalign(salign
);
1990 MATCH
TypeSArray::implicitConvTo(Type
*to
)
1992 //printf("TypeSArray::implicitConvTo()\n");
1994 if (to
->ty
== Tmaybe
&& to
->next
)
1997 // Allow implicit conversion of static array to pointer or dynamic array
1998 if ((IMPLICIT_ARRAY_TO_PTR
&& to
->ty
== Tpointer
) &&
1999 (to
->next
->ty
== Tvoid
|| next
->equals(to
->next
)
2000 /*|| to->next->isBaseOf(next)*/))
2002 return MATCHconvert
;
2004 if (to
->ty
== Tarray
)
2005 { target_ptrdiff_t offset
= 0;
2007 if (next
->equals(to
->next
) ||
2008 (to
->next
->isBaseOf(next
, &offset
) && offset
== 0) ||
2009 to
->next
->ty
== Tvoid
)
2010 return MATCHconvert
;
2013 if (to
->ty
== Tsarray
)
2015 TypeSArray
*tsa
= (TypeSArray
*)to
;
2017 if (next
->equals(tsa
->next
) && dim
->equals(tsa
->dim
))
2019 return MATCHconvert
;
2023 return Type::implicitConvTo(to
);
2026 Expression
*TypeSArray::defaultInit(Loc loc
)
2029 printf("TypeSArray::defaultInit() '%s'\n", toChars());
2031 return next
->defaultInit(loc
);
2034 int TypeSArray::isZeroInit()
2036 return next
->isZeroInit();
2040 Expression
*TypeSArray::toExpression()
2042 Expression
*e
= next
->toExpression();
2044 { Expressions
*arguments
= new Expressions();
2045 arguments
->push(dim
);
2046 e
= new ArrayExp(dim
->loc
, e
, arguments
);
2051 int TypeSArray::hasPointers()
2053 return next
->hasPointers();
2056 /***************************** TypeDArray *****************************/
2058 TypeDArray::TypeDArray(Type
*t
)
2059 : TypeArray(Tarray
, t
)
2061 //printf("TypeDArray(t = %p)\n", t);
2064 Type
*TypeDArray::syntaxCopy()
2066 Type
*t
= next
->syntaxCopy();
2070 t
= new TypeDArray(t
);
2074 d_uns64
TypeDArray::size(Loc loc
)
2076 //printf("TypeDArray::size()\n");
2080 unsigned TypeDArray::alignsize()
2082 // A DArray consists of two ptr-sized values, so align it on pointer size
2087 Type
*TypeDArray::semantic(Loc loc
, Scope
*sc
)
2090 tn
= next
->semantic(loc
,sc
);
2091 Type
*tbn
= tn
->toBasetype();
2097 error(loc
, "can't have array of %s", tbn
->toChars());
2102 error(loc
, "cannot have array of auto %s", tn
->toChars());
2104 //deco = NULL; // redo
2105 return tn
->arrayOf();
2109 void TypeDArray::toDecoBuffer(OutBuffer
*buf
)
2111 buf
->writeByte(NOT_NULL_MANGLE
);
2112 buf
->writeByte(mangleChar
[ty
]);
2114 next
->toDecoBuffer(buf
);
2117 void TypeDArray::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2119 if (mod
!= this->mod
)
2120 { toCBuffer3(buf
, hgs
, mod
);
2123 next
->toCBuffer2(buf
, hgs
, this->mod
);
2124 buf
->writestring("[]");
2127 Expression
*TypeDArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2130 printf("TypeDArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
2132 if (ident
== Id::length
)
2134 if (e
->op
== TOKstring
)
2135 { StringExp
*se
= (StringExp
*)e
;
2137 return new IntegerExp(se
->loc
, se
->len
, Type::tindex
);
2139 e
= new ArrayLengthExp(e
->loc
, e
);
2140 e
->type
= Type::tsize_t
;
2143 else if (ident
== Id::ptr
)
2145 e
= e
->castTo(sc
, next
->pointerTo());
2150 e
= TypeArray::dotExp(sc
, e
, ident
);
2155 int TypeDArray::isString()
2157 TY nty
= next
->toBasetype()->ty
;
2158 return nty
== Tchar
|| nty
== Twchar
|| nty
== Tdchar
;
2161 MATCH
TypeDArray::implicitConvTo(Type
*to
)
2163 //printf("TypeDArray::implicitConvTo()\n");
2165 if (to
->ty
== Tmaybe
&& to
->next
)
2168 // Allow implicit conversion of array to pointer
2169 if (IMPLICIT_ARRAY_TO_PTR
&&
2170 to
->ty
== Tpointer
&&
2171 (to
->next
->ty
== Tvoid
|| next
->equals(to
->next
) /*|| to->next->isBaseOf(next)*/))
2173 return MATCHconvert
;
2176 if (to
->ty
== Tarray
)
2177 { target_ptrdiff_t offset
= 0;
2179 if ((to
->next
->isBaseOf(next
, &offset
) && offset
== 0) ||
2180 to
->next
->ty
== Tvoid
)
2181 return MATCHconvert
;
2183 return Type::implicitConvTo(to
);
2186 Expression
*TypeDArray::defaultInit(Loc loc
)
2189 printf("TypeDArray::defaultInit() '%s'\n", toChars());
2192 e
= new NullExp(loc
);
2197 int TypeDArray::isZeroInit()
2202 int TypeDArray::checkBoolean()
2207 int TypeDArray::hasPointers()
2212 /***************************** TypeAArray *****************************/
2214 TypeAArray::TypeAArray(Type
*t
, Type
*index
)
2215 : TypeArray(Taarray
, t
)
2217 this->index
= index
;
2221 Type
*TypeAArray::syntaxCopy()
2223 Type
*t
= next
->syntaxCopy();
2224 Type
*ti
= index
->syntaxCopy();
2225 if (t
== next
&& ti
== index
)
2228 t
= new TypeAArray(t
, ti
);
2232 d_uns64
TypeAArray::size(Loc loc
)
2234 return PTRSIZE
/* * 2*/;
2238 Type
*TypeAArray::semantic(Loc loc
, Scope
*sc
)
2240 //printf("TypeAArray::semantic() %s index->ty = %d\n", toChars(), index->ty);
2242 // Deal with the case where we thought the index was a type, but
2243 // in reality it was an expression.
2244 if (index
->ty
== Tident
|| index
->ty
== Tinstance
|| index
->ty
== Tsarray
)
2250 index
->resolve(loc
, sc
, &e
, &t
, &s
);
2252 { // It was an expression -
2253 // Rewrite as a static array
2256 tsa
= new TypeSArray(next
, e
);
2257 return tsa
->semantic(loc
,sc
);
2262 index
->error(loc
, "index is not a type or an expression");
2265 index
= index
->semantic(loc
,sc
);
2267 // Compute key type; the purpose of the key type is to
2268 // minimize the permutations of runtime library
2269 // routines as much as possible.
2270 key
= index
->toBasetype();
2284 // Convert to Tarray
2285 key
= key
->next
->arrayOf();
2293 error(loc
, "can't have associative array key of %s", key
->toChars());
2296 next
= next
->semantic(loc
,sc
);
2297 switch (next
->toBasetype()->ty
)
2301 error(loc
, "can't have associative array of %s", next
->toChars());
2305 error(loc
, "cannot have array of auto %s", next
->toChars());
2310 void TypeAArray::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
2312 //printf("TypeAArray::resolve() %s\n", toChars());
2314 // Deal with the case where we thought the index was a type, but
2315 // in reality it was an expression.
2316 if (index
->ty
== Tident
|| index
->ty
== Tinstance
|| index
->ty
== Tsarray
)
2322 index
->resolve(loc
, sc
, &e
, &t
, &s
);
2324 { // It was an expression -
2325 // Rewrite as a static array
2327 TypeSArray
*tsa
= new TypeSArray(next
, e
);
2328 return tsa
->resolve(loc
, sc
, pe
, pt
, ps
);
2333 index
->error(loc
, "index is not a type or an expression");
2335 Type::resolve(loc
, sc
, pe
, pt
, ps
);
2339 Expression
*TypeAArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2342 printf("TypeAArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
2344 if (ident
== Id::length
)
2347 FuncDeclaration
*fd
;
2348 Expressions
*arguments
;
2350 fd
= FuncDeclaration::genCfunc(Type::tsize_t
, Id::aaLen
, Type::tvoid
->arrayOf());
2351 ec
= new VarExp(0, fd
);
2352 arguments
= new Expressions();
2354 e
= new CallExp(e
->loc
, ec
, arguments
);
2355 e
->type
= fd
->type
->next
;
2357 else if (ident
== Id::keys
)
2360 FuncDeclaration
*fd
;
2361 Expressions
*arguments
;
2362 int size
= key
->size(e
->loc
);
2365 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::aaKeys
,
2366 Type::tvoid
->arrayOf(), Type::tsize_t
);
2367 ec
= new VarExp(0, fd
);
2368 arguments
= new Expressions();
2370 arguments
->push(new IntegerExp(0, size
, Type::tsize_t
));
2371 e
= new CallExp(e
->loc
, ec
, arguments
);
2372 e
->type
= index
->arrayOf();
2374 else if (ident
== Id::values
)
2377 FuncDeclaration
*fd
;
2378 Expressions
*arguments
;
2380 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::aaValues
,
2381 Type::tvoid
->arrayOf(), Type::tsize_t
, Type::tsize_t
);
2382 ec
= new VarExp(0, fd
);
2383 arguments
= new Expressions();
2385 size_t keysize
= key
->size(e
->loc
);
2386 keysize
= (keysize
+ (PTRSIZE
-1)) & ~(PTRSIZE
-1);
2387 arguments
->push(new IntegerExp(0, keysize
, Type::tsize_t
));
2388 arguments
->push(new IntegerExp(0, next
->size(e
->loc
), Type::tsize_t
));
2389 e
= new CallExp(e
->loc
, ec
, arguments
);
2390 e
->type
= next
->arrayOf();
2392 else if (ident
== Id::rehash
)
2395 FuncDeclaration
*fd
;
2396 Expressions
*arguments
;
2398 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::aaRehash
);
2399 ec
= new VarExp(0, fd
);
2400 arguments
= new Expressions();
2401 arguments
->push(e
->addressOf(sc
));
2402 arguments
->push(key
->getInternalTypeInfo(sc
));
2403 e
= new CallExp(e
->loc
, ec
, arguments
);
2408 e
= Type::dotExp(sc
, e
, ident
);
2413 void TypeAArray::toDecoBuffer(OutBuffer
*buf
)
2415 buf
->writeByte(mangleChar
[ty
]);
2416 index
->toDecoBuffer(buf
);
2417 next
->toDecoBuffer(buf
);
2420 void TypeAArray::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2422 if (mod
!= this->mod
)
2423 { toCBuffer3(buf
, hgs
, mod
);
2426 next
->toCBuffer2(buf
, hgs
, this->mod
);
2427 buf
->writeByte('[');
2428 index
->toCBuffer2(buf
, hgs
, 0);
2429 buf
->writeByte(']');
2432 Expression
*TypeAArray::defaultInit(Loc loc
)
2435 printf("TypeAArray::defaultInit() '%s'\n", toChars());
2438 e
= new NullExp(loc
);
2443 int TypeAArray::checkBoolean()
2448 int TypeAArray::hasPointers()
2453 /***************************** TypeMaybe *****************************/
2455 TypeMaybe::TypeMaybe(Type
*t
)
2460 void TypeMaybe::toDecoBuffer(OutBuffer
*buf
)
2462 int offset
= buf
->offset
;
2464 // Since all D types are TypeMaybe, adding a char here
2465 // would prevent linking to existing libraries.
2466 next
->toDecoBuffer(buf
);
2468 if (buf
->data
[offset
] == 'Q')
2469 buf
->remove(offset
, 1); // After semantic: remove not-null qualifier
2471 buf
->insert(offset
, "?", 1); // Before semantic: just make name unique
2474 Type
*TypeMaybe::syntaxCopy()
2476 Type
*t
= next
->syntaxCopy();
2480 t
= new TypeMaybe(t
);
2484 Type
*TypeMaybe::toBasetype()
2486 return next
->toBasetype();
2489 Expression
*TypeMaybe::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2491 e
->error("Attempt to access property '%s' for '%s' of type '%s', which may be null.",
2492 ident
->string
, e
->toChars(), toChars());
2493 return next
->dotExp(sc
, e
, ident
);
2496 Type
*TypeMaybe::semantic(Loc loc
, Scope
*sc
)
2498 //printf("TypeMaybe::semantic()\n");
2499 Type
*n
= next
->semantic(loc
, sc
);
2501 // For D source we don't know if it's a maybe type or not, so the parser
2502 // wraps everything in a TypeMaybe (including structs, etc, since it can't
2503 // tell). If the next type can't be null, we vanish here.
2511 //error(loc, "can't have maybe for %s of type %d", n->toChars(), n->toBasetype()->ty);
2520 d_uns64
TypeMaybe::size(Loc loc
)
2522 return next
->size();
2525 void TypeMaybe::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2527 //printf("TypeMaybe::toCBuffer2() next = %d\n", next->ty);
2528 if (mod
!= this->mod
)
2529 { toCBuffer3(buf
, hgs
, mod
);
2532 next
->toCBuffer2(buf
, hgs
, this->mod
);
2533 buf
->writeByte('?');
2536 MATCH
TypeMaybe::implicitConvTo(Type
*to
)
2538 //printf("TypeMaybe::implicitConvTo(%s)\n", to->toChars());
2543 if (to->ty == Tpointer && to->next)
2545 if (to->next->ty == Tvoid)
2546 return MATCHconvert;
2549 if (to->next->isBaseOf(next))
2550 return MATCHconvert;
2553 if (next->ty == Tfunction && to->next->ty == Tfunction)
2557 tf = (TypeFunction *)(next);
2558 tfto = (TypeFunction *)(to->next);
2559 return tfto->equals(tf) ? MATCHexact : MATCHnomatch;
2562 // if (to->ty == Tvoid)
2563 // return MATCHconvert;
2565 return MATCHnomatch
;
2568 int TypeMaybe::isscalar()
2570 return next
->isscalar();
2573 Expression
*TypeMaybe::defaultInit(Loc loc
)
2576 printf("TypeMaybe::defaultInit() '%s'\n", toChars());
2578 return next
->defaultInit();
2581 int TypeMaybe::isZeroInit()
2583 return next
->isZeroInit();
2586 int TypeMaybe::hasPointers()
2588 return next
->hasPointers();
2591 /***************************** TypePointer *****************************/
2593 TypePointer::TypePointer(Type
*t
)
2598 Type
*TypePointer::syntaxCopy()
2600 Type
*t
= next
->syntaxCopy();
2604 t
= new TypePointer(t
);
2608 Type
*TypePointer::semantic(Loc loc
, Scope
*sc
)
2610 //printf("TypePointer::semantic()\n");
2611 Type
*n
= next
->semantic(loc
, sc
);
2612 switch (n
->toBasetype()->ty
)
2615 error(loc
, "can't have pointer to %s", n
->toChars());
2626 d_uns64
TypePointer::size(Loc loc
)
2631 void TypePointer::toDecoBuffer(OutBuffer
*buf
)
2633 buf
->writeByte(NOT_NULL_MANGLE
);
2634 Type::toDecoBuffer(buf
);
2637 void TypePointer::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2639 //printf("TypePointer::toCBuffer2() next = %d\n", next->ty);
2640 if (mod
!= this->mod
)
2641 { toCBuffer3(buf
, hgs
, mod
);
2644 next
->toCBuffer2(buf
, hgs
, this->mod
);
2645 if (next
->ty
!= Tfunction
)
2646 buf
->writeByte('*');
2649 MATCH
TypePointer::implicitConvTo(Type
*to
)
2651 //printf("TypePointer::implicitConvTo()\n");
2655 if (to
->ty
== Tpointer
&& to
->next
)
2657 if (to
->next
->ty
== Tvoid
)
2658 return MATCHconvert
;
2661 if (to
->next
->isBaseOf(next
))
2662 return MATCHconvert
;
2665 if (next
->ty
== Tfunction
&& to
->next
->ty
== Tfunction
)
2669 tf
= (TypeFunction
*)(next
);
2670 tfto
= (TypeFunction
*)(to
->next
);
2671 return tfto
->equals(tf
) ? MATCHexact
: MATCHnomatch
;
2674 // if (to->ty == Tvoid)
2675 // return MATCHconvert;
2676 return MATCHnomatch
;
2679 int TypePointer::isscalar()
2684 Expression
*TypePointer::defaultInit(Loc loc
)
2687 printf("TypePointer::defaultInit() '%s'\n", toChars());
2690 e
= new NullExp(loc
);
2695 int TypePointer::isZeroInit()
2700 int TypePointer::hasPointers()
2706 /***************************** TypeReference *****************************/
2708 TypeReference::TypeReference(Type
*t
)
2709 : Type(Treference
, t
)
2712 error(0,"cannot make reference to a bit");
2713 // BUG: what about references to static arrays?
2716 Type
*TypeReference::syntaxCopy()
2718 Type
*t
= next
->syntaxCopy();
2722 t
= new TypeReference(t
);
2726 d_uns64
TypeReference::size(Loc loc
)
2731 void TypeReference::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2733 if (mod
!= this->mod
)
2734 { toCBuffer3(buf
, hgs
, mod
);
2737 next
->toCBuffer2(buf
, hgs
, this->mod
);
2738 buf
->writeByte('&');
2741 Expression
*TypeReference::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2744 printf("TypeReference::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
2747 // References just forward things along
2748 return next
->dotExp(sc
, e
, ident
);
2751 Expression
*TypeReference::defaultInit(Loc loc
)
2754 printf("TypeReference::defaultInit() '%s'\n", toChars());
2757 e
= new NullExp(loc
);
2762 int TypeReference::isZeroInit()
2768 /***************************** TypeFunction *****************************/
2770 TypeFunction::TypeFunction(Arguments
*parameters
, Type
*treturn
, int varargs
, enum LINK linkage
)
2771 : Type(Tfunction
, treturn
)
2773 //if (!treturn) *(char*)0=0;
2775 this->parameters
= parameters
;
2776 this->varargs
= varargs
;
2777 this->linkage
= linkage
;
2781 Type
*TypeFunction::syntaxCopy()
2783 Type
*treturn
= next
? next
->syntaxCopy() : NULL
;
2784 Arguments
*params
= Argument::arraySyntaxCopy(parameters
);
2785 Type
*t
= new TypeFunction(params
, treturn
, varargs
, linkage
);
2789 /*******************************
2791 * 0 types are distinct
2792 * 1 this is covariant with t
2793 * 2 arguments match as far as overloading goes,
2794 * but types are not covariant
2795 * 3 cannot determine covariance because of forward references
2798 int Type::covariant(Type
*t
)
2801 printf("Type::covariant(t = %s) %s\n", t
->toChars(), toChars());
2802 printf("deco = %p, %p\n", deco
, t
->deco
);
2803 printf("ty = %d\n", next
->ty
);
2806 int inoutmismatch
= 0;
2810 if (ty
!= Tfunction
|| t
->ty
!= Tfunction
)
2814 TypeFunction
*t1
= (TypeFunction
*)this;
2815 TypeFunction
*t2
= (TypeFunction
*)t
;
2817 if (t1
->varargs
!= t2
->varargs
)
2820 if (t1
->parameters
&& t2
->parameters
)
2822 size_t dim
= Argument::dim(t1
->parameters
);
2823 if (dim
!= Argument::dim(t2
->parameters
))
2826 for (size_t i
= 0; i
< dim
; i
++)
2827 { Argument
*arg1
= Argument::getNth(t1
->parameters
, i
);
2828 Argument
*arg2
= Argument::getNth(t2
->parameters
, i
);
2830 if (!arg1
->type
->equals(arg2
->type
))
2832 if (arg1
->storageClass
!= arg2
->storageClass
)
2836 else if (t1
->parameters
!= t2
->parameters
)
2839 // The argument lists match
2842 if (t1
->linkage
!= t2
->linkage
)
2845 Type
*t1n
= t1
->next
;
2846 Type
*t2n
= t2
->next
;
2848 if (t1n
->equals(t2n
))
2850 if (t1n
->ty
!= Tclass
|| t2n
->ty
!= Tclass
)
2853 // If t1n is forward referenced:
2854 ClassDeclaration
*cd
= ((TypeClass
*)t1n
)->sym
;
2855 if (!cd
->baseClass
&& cd
->baseclasses
.dim
&& !cd
->isInterfaceDeclaration())
2860 if (t1n
->implicitConvTo(t2n
))
2866 //printf("\tcovaraint: 1\n");
2870 //printf("\tcovaraint: 0\n");
2874 //printf("\tcovaraint: 2\n");
2878 void TypeFunction::toDecoBuffer(OutBuffer
*buf
)
2881 //printf("TypeFunction::toDecoBuffer() this = %p %s\n", this, toChars());
2882 //static int nest; if (++nest == 50) *(char*)0=0;
2884 { inuse
= 2; // flag error to caller
2890 case LINKd
: mc
= 'F'; break;
2891 case LINKc
: mc
= 'U'; break;
2892 case LINKwindows
: mc
= 'W'; break;
2893 case LINKpascal
: mc
= 'V'; break;
2894 case LINKcpp
: mc
= 'R'; break;
2899 // Write argument types
2900 Argument::argsToDecoBuffer(buf
, parameters
);
2901 //if (buf->data[buf->offset - 1] == '@') halt();
2902 buf
->writeByte('Z' - varargs
); // mark end of arg list
2903 next
->toDecoBuffer(buf
);
2907 void TypeFunction::toCBuffer(OutBuffer
*buf
, Identifier
*ident
, HdrGenState
*hgs
)
2912 { inuse
= 2; // flag error to caller
2916 if (next
&& (!ident
|| ident
->toHChars2() == ident
->toChars()))
2917 next
->toCBuffer2(buf
, hgs
, 0);
2922 case LINKd
: p
= NULL
; break;
2923 case LINKc
: p
= "C "; break;
2924 case LINKwindows
: p
= "Windows "; break;
2925 case LINKpascal
: p
= "Pascal "; break;
2926 case LINKcpp
: p
= "C++ "; break;
2932 if (!hgs
->hdrgen
&& p
)
2933 buf
->writestring(p
);
2935 { buf
->writeByte(' ');
2936 buf
->writestring(ident
->toHChars2());
2938 Argument::argsToCBuffer(buf
, hgs
, parameters
, varargs
);
2942 void TypeFunction::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2947 { inuse
= 2; // flag error to caller
2952 next
->toCBuffer2(buf
, hgs
, 0);
2957 case LINKd
: p
= NULL
; break;
2958 case LINKc
: p
= "C "; break;
2959 case LINKwindows
: p
= "Windows "; break;
2960 case LINKpascal
: p
= "Pascal "; break;
2961 case LINKcpp
: p
= "C++ "; break;
2967 if (!hgs
->hdrgen
&& p
)
2968 buf
->writestring(p
);
2969 buf
->writestring(" function");
2970 Argument::argsToCBuffer(buf
, hgs
, parameters
, varargs
);
2974 Type
*TypeFunction::semantic(Loc loc
, Scope
*sc
)
2976 if (deco
) // if semantic() already run
2978 //printf("already done\n");
2981 //printf("TypeFunction::semantic() this = %p\n", this);
2983 TypeFunction
*tf
= (TypeFunction
*)mem
.malloc(sizeof(TypeFunction
));
2984 memcpy(tf
, this, sizeof(TypeFunction
));
2986 { tf
->parameters
= (Arguments
*)parameters
->copy();
2987 for (size_t i
= 0; i
< parameters
->dim
; i
++)
2988 { Argument
*arg
= (Argument
*)parameters
->data
[i
];
2989 Argument
*cpy
= (Argument
*)mem
.malloc(sizeof(Argument
));
2990 memcpy(cpy
, arg
, sizeof(Argument
));
2991 tf
->parameters
->data
[i
] = (void *)cpy
;
2995 tf
->linkage
= sc
->linkage
;
2998 assert(global
.errors
);
3001 tf
->next
= tf
->next
->semantic(loc
,sc
);
3002 if (tf
->next
->toBasetype()->ty
== Tsarray
)
3003 { error(loc
, "functions cannot return static array %s", tf
->next
->toChars());
3004 tf
->next
= Type::terror
;
3006 if (tf
->next
->toBasetype()->ty
== Tfunction
)
3007 { error(loc
, "functions cannot return a function");
3008 tf
->next
= Type::terror
;
3010 if (tf
->next
->toBasetype()->ty
== Ttuple
)
3011 { error(loc
, "functions cannot return a tuple");
3012 tf
->next
= Type::terror
;
3014 if (tf
->next
->isauto() && !(sc
->flags
& SCOPEctor
))
3015 error(loc
, "functions cannot return auto %s", tf
->next
->toChars());
3018 { size_t dim
= Argument::dim(tf
->parameters
);
3020 for (size_t i
= 0; i
< dim
; i
++)
3021 { Argument
*arg
= Argument::getNth(tf
->parameters
, i
);
3025 arg
->type
= arg
->type
->semantic(loc
,sc
);
3026 if (tf
->inuse
== 1) tf
->inuse
--;
3027 t
= arg
->type
->toBasetype();
3029 if (arg
->storageClass
& (STCout
| STCref
| STClazy
))
3031 if (t
->ty
== Tsarray
)
3032 error(loc
, "cannot have out or ref parameter of type %s", t
->toChars());
3034 if (!(arg
->storageClass
& STClazy
) && t
->ty
== Tvoid
)
3035 error(loc
, "cannot have parameter of type %s", arg
->type
->toChars());
3037 if (arg
->defaultArg
)
3039 arg
->defaultArg
= arg
->defaultArg
->semantic(sc
);
3040 arg
->defaultArg
= resolveProperties(sc
, arg
->defaultArg
);
3041 arg
->defaultArg
= arg
->defaultArg
->implicitCastTo(sc
, arg
->type
);
3044 /* If arg turns out to be a tuple, the number of parameters may
3047 if (t
->ty
== Ttuple
)
3048 { dim
= Argument::dim(tf
->parameters
);
3053 tf
->deco
= tf
->merge()->deco
;
3056 { error(loc
, "recursive type");
3061 if (tf
->varargs
== 1 && tf
->linkage
!= LINKd
&& Argument::dim(tf
->parameters
) == 0)
3062 error(loc
, "variadic functions with non-D linkage must have at least one parameter");
3064 /* Don't return merge(), because arg identifiers and default args
3066 * even though the types match
3071 /********************************
3072 * 'args' are being matched to function 'this'
3073 * Determine match level.
3078 int TypeFunction::callMatch(Expressions
*args
)
3080 //printf("TypeFunction::callMatch()\n");
3081 int match
= MATCHexact
; // assume exact match
3083 size_t nparams
= Argument::dim(parameters
);
3084 size_t nargs
= args
? args
->dim
: 0;
3085 if (nparams
== nargs
)
3087 else if (nargs
> nparams
)
3090 goto Nomatch
; // too many args; no match
3091 match
= MATCHconvert
; // match ... with a "conversion" match level
3094 for (size_t u
= 0; u
< nparams
; u
++)
3098 // BUG: what about out and ref?
3100 Argument
*p
= Argument::getNth(parameters
, u
);
3106 if (varargs
== 2 && u
+ 1 == nparams
)
3108 goto Nomatch
; // not enough arguments
3110 arg
= (Expression
*)args
->data
[u
];
3112 if (p
->storageClass
& STClazy
&& p
->type
->ty
== Tvoid
&& arg
->type
->ty
!= Tvoid
)
3115 m
= arg
->implicitConvTo(p
->type
);
3116 //printf("\tm = %d\n", m);
3117 if (m
== MATCHnomatch
) // if no match
3120 if (varargs
== 2 && u
+ 1 == nparams
) // if last varargs param
3121 { Type
*tb
= p
->type
->toBasetype();
3128 tsa
= (TypeSArray
*)tb
;
3129 sz
= tsa
->dim
->toInteger();
3130 if (sz
!= nargs
- u
)
3133 for (; u
< nargs
; u
++)
3135 arg
= (Expression
*)args
->data
[u
];
3138 /* If lazy array of delegates,
3139 * convert arg(s) to delegate(s)
3141 Type
*tret
= p
->isLazyArray();
3144 if (tb
->next
->equals(arg
->type
))
3149 m
= arg
->implicitConvTo(tret
);
3150 if (m
== MATCHnomatch
)
3152 if (tret
->toBasetype()->ty
== Tvoid
)
3158 m
= arg
->implicitConvTo(tb
->next
);
3160 m
= arg
->implicitConvTo(tb
->next
);
3170 // Should see if there's a constructor match?
3171 // Or just leave it ambiguous?
3181 match
= m
; // pick worst match
3185 //printf("match = %d\n", match);
3189 //printf("no match\n");
3190 return MATCHnomatch
;
3193 Type
*TypeFunction::reliesOnTident()
3197 for (size_t i
= 0; i
< parameters
->dim
; i
++)
3198 { Argument
*arg
= (Argument
*)parameters
->data
[i
];
3199 Type
*t
= arg
->type
->reliesOnTident();
3204 return next
->reliesOnTident();
3207 /***************************** TypeDelegate *****************************/
3209 TypeDelegate::TypeDelegate(Type
*t
)
3210 : Type(Tfunction
, t
)
3215 Type
*TypeDelegate::syntaxCopy()
3217 Type
*t
= next
->syntaxCopy();
3221 t
= new TypeDelegate(t
);
3225 Type
*TypeDelegate::semantic(Loc loc
, Scope
*sc
)
3227 if (deco
) // if semantic() already run
3229 //printf("already done\n");
3232 next
= next
->semantic(loc
,sc
);
3236 d_uns64
TypeDelegate::size(Loc loc
)
3241 void TypeDelegate::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3243 if (mod
!= this->mod
)
3244 { toCBuffer3(buf
, hgs
, mod
);
3247 TypeFunction
*tf
= (TypeFunction
*)next
;
3249 tf
->next
->toCBuffer2(buf
, hgs
, 0);
3250 buf
->writestring(" delegate");
3251 Argument::argsToCBuffer(buf
, hgs
, tf
->parameters
, tf
->varargs
);
3254 Expression
*TypeDelegate::defaultInit(Loc loc
)
3257 printf("TypeDelegate::defaultInit() '%s'\n", toChars());
3260 e
= new NullExp(loc
);
3265 int TypeDelegate::isZeroInit()
3270 int TypeDelegate::checkBoolean()
3275 Expression
*TypeDelegate::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
3278 printf("TypeDelegate::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
3280 if (ident
== Id::ptr
)
3285 if (e
->op
== TOKdelegate
|| e
->op
== TOKcast
)
3286 e
= e
->castTo(sc
, tvoidptr
); // Not an lvalue
3289 e
= e
->addressOf(sc
);
3290 e
= e
->castTo(sc
, tvoidptr
->pointerTo());
3291 e
= new PtrExp(e
->loc
, e
);
3297 else if (ident
== Id::funcptr
)
3299 e
= e
->addressOf(sc
);
3301 e
= new AddExp(e
->loc
, e
, new IntegerExp(PTRSIZE
));
3303 e
= new PtrExp(e
->loc
, e
);
3304 e
->type
= next
->pointerTo();
3309 e
= Type::dotExp(sc
, e
, ident
);
3314 int TypeDelegate::hasPointers()
3321 /***************************** TypeQualified *****************************/
3323 TypeQualified::TypeQualified(TY ty
, Loc loc
)
3329 void TypeQualified::syntaxCopyHelper(TypeQualified
*t
)
3331 //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars());
3332 idents
.setDim(t
->idents
.dim
);
3333 for (int i
= 0; i
< idents
.dim
; i
++)
3335 Identifier
*id
= (Identifier
*)t
->idents
.data
[i
];
3336 if (id
->dyncast() == DYNCAST_DSYMBOL
)
3338 TemplateInstance
*ti
= (TemplateInstance
*)id
;
3340 ti
= (TemplateInstance
*)ti
->syntaxCopy(NULL
);
3341 id
= (Identifier
*)ti
;
3343 idents
.data
[i
] = id
;
3348 void TypeQualified::addIdent(Identifier
*ident
)
3353 void TypeQualified::toCBuffer2Helper(OutBuffer
*buf
, HdrGenState
*hgs
)
3357 for (i
= 0; i
< idents
.dim
; i
++)
3358 { Identifier
*id
= (Identifier
*)idents
.data
[i
];
3360 buf
->writeByte('.');
3362 if (id
->dyncast() == DYNCAST_DSYMBOL
)
3364 TemplateInstance
*ti
= (TemplateInstance
*)id
;
3365 ti
->toCBuffer(buf
, hgs
);
3368 buf
->writestring(id
->toChars());
3372 d_uns64
TypeQualified::size(Loc loc
)
3374 error(this->loc
, "size of type %s is not known", toChars());
3378 /*************************************
3379 * Takes an array of Identifiers and figures out if
3380 * it represents a Type or an Expression.
3382 * if expression, *pe is set
3383 * if type, *pt is set
3386 void TypeQualified::resolveHelper(Loc loc
, Scope
*sc
,
3387 Dsymbol
*s
, Dsymbol
*scopesym
,
3388 Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
3390 Identifier
*id
= NULL
;
3394 TupleDeclaration
*td
;
3399 printf("TypeQualified::resolveHelper(sc = %p, idents = '%s')\n", sc
, toChars());
3401 printf("\tscopesym = '%s'\n", scopesym
->toChars());
3408 //printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
3410 //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
3411 for (i
= 0; i
< idents
.dim
; i
++)
3414 id
= (Identifier
*)idents
.data
[i
];
3415 sm
= s
->searchX(loc
, sc
, id
);
3416 //printf("\t3: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
3417 //printf("getType = '%s'\n", s->getType()->toChars());
3420 v
= s
->isVarDeclaration();
3421 if (v
&& id
== Id::length
)
3423 if (v
->isConst() && v
->getExpInitializer())
3424 { e
= v
->getExpInitializer()->exp
;
3427 e
= new VarExp(loc
, v
);
3434 if (!t
&& s
->isDeclaration())
3435 t
= s
->isDeclaration()->type
;
3438 sm
= t
->toDsymbol(sc
);
3440 { sm
= sm
->search(loc
, id
, 0);
3444 //e = t->getProperty(loc, id);
3445 e
= new TypeExp(loc
, t
);
3446 e
= t
->dotExp(sc
, e
, id
);
3449 for (; i
< idents
.dim
; i
++)
3451 id
= (Identifier
*)idents
.data
[i
];
3452 //printf("e: '%s', id: '%s', type = %p\n", e->toChars(), id->toChars(), e->type);
3453 e
= e
->type
->dotExp(sc
, e
, id
);
3459 error(loc
, "identifier '%s' of '%s' is not defined", id
->toChars(), toChars());
3466 v
= s
->isVarDeclaration();
3469 // It's not a type, it's an expression
3470 if (v
->isConst() && v
->getExpInitializer())
3472 ExpInitializer
*ei
= v
->getExpInitializer();
3474 *pe
= ei
->exp
->copy(); // make copy so we can change loc
3480 WithScopeSymbol
*withsym
;
3481 if (scopesym
&& (withsym
= scopesym
->isWithScopeSymbol()) != NULL
)
3483 // Same as wthis.ident
3484 e
= new VarExp(loc
, withsym
->withstate
->wthis
);
3485 e
= new DotIdExp(loc
, e
, ident
);
3486 //assert(0); // BUG: should handle this
3490 *pe
= new VarExp(loc
, v
);
3494 em
= s
->isEnumMember();
3497 // It's not a type, it's an expression
3498 *pe
= em
->value
->copy();
3506 // If the symbol is an import, try looking inside the import
3512 s
= si
->search(loc
, s
->ident
, 0);
3520 if (t
->ty
== Tinstance
&& t
!= this && !t
->deco
)
3521 { error(loc
, "forward reference to '%s'", t
->toChars());
3527 if (t
->reliesOnTident())
3531 for (scx
= sc
; 1; scx
= scx
->enclosing
)
3534 { error(loc
, "forward reference to '%s'", t
->toChars());
3537 if (scx
->scopesym
== scopesym
)
3540 t
= t
->semantic(loc
, scx
);
3541 //((TypeIdentifier *)t)->resolve(loc, scx, pe, &t, ps);
3544 if (t
->ty
== Ttuple
)
3551 error(loc
, "identifier '%s' is not defined", toChars());
3555 /***************************** TypeIdentifier *****************************/
3557 TypeIdentifier::TypeIdentifier(Loc loc
, Identifier
*ident
)
3558 : TypeQualified(Tident
, loc
)
3560 this->ident
= ident
;
3564 Type
*TypeIdentifier::syntaxCopy()
3568 t
= new TypeIdentifier(loc
, ident
);
3569 t
->syntaxCopyHelper(this);
3573 void TypeIdentifier::toDecoBuffer(OutBuffer
*buf
)
3577 name
= ident
->toChars();
3579 buf
->printf("%c%d%s", mangleChar
[ty
], len
, name
);
3580 //buf->printf("%c%s", mangleChar[ty], name);
3583 void TypeIdentifier::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3585 if (mod
!= this->mod
)
3586 { toCBuffer3(buf
, hgs
, mod
);
3589 buf
->writestring(this->ident
->toChars());
3590 toCBuffer2Helper(buf
, hgs
);
3593 /*************************************
3594 * Takes an array of Identifiers and figures out if
3595 * it represents a Type or an Expression.
3597 * if expression, *pe is set
3598 * if type, *pt is set
3601 void TypeIdentifier::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
3605 //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars());
3606 s
= sc
->search(loc
, ident
, &scopesym
);
3607 resolveHelper(loc
, sc
, s
, scopesym
, pe
, pt
, ps
);
3610 /*****************************************
3611 * See if type resolves to a symbol, if so,
3612 * return that symbol.
3615 Dsymbol
*TypeIdentifier::toDsymbol(Scope
*sc
)
3617 //printf("TypeIdentifier::toDsymbol('%s')\n", toChars());
3620 //printf("ident = '%s'\n", ident->toChars());
3623 Dsymbol
*s
= sc
->search(loc
, ident
, &scopesym
);
3626 for (int i
= 0; i
< idents
.dim
; i
++)
3628 Identifier
*id
= (Identifier
*)idents
.data
[i
];
3629 s
= s
->searchX(loc
, sc
, id
);
3630 if (!s
) // failed to find a symbol
3631 { //printf("\tdidn't find a symbol\n");
3639 Type
*TypeIdentifier::semantic(Loc loc
, Scope
*sc
)
3645 //printf("TypeIdentifier::semantic(%s)\n", toChars());
3646 resolve(loc
, sc
, &e
, &t
, &s
);
3649 //printf("\tit's a type %d, %s, %s\n", t->ty, t->toChars(), t->deco);
3651 if (t
->ty
== Ttypedef
)
3652 { TypeTypedef
*tt
= (TypeTypedef
*)t
;
3654 if (tt
->sym
->sem
== 1)
3655 error(loc
, "circular reference of typedef %s", tt
->toChars());
3666 s
->error(loc
, "is used as a type");
3669 error(loc
, "%s is used as a type", toChars());
3676 Type
*TypeIdentifier::reliesOnTident()
3681 Expression
*TypeIdentifier::toExpression()
3683 Expression
*e
= new IdentifierExp(loc
, ident
);
3684 for (int i
= 0; i
< idents
.dim
; i
++)
3686 Identifier
*id
= (Identifier
*)idents
.data
[i
];
3687 e
= new DotIdExp(loc
, e
, id
);
3693 /***************************** TypeInstance *****************************/
3695 TypeInstance::TypeInstance(Loc loc
, TemplateInstance
*tempinst
)
3696 : TypeQualified(Tinstance
, loc
)
3698 this->tempinst
= tempinst
;
3701 Type
*TypeInstance::syntaxCopy()
3703 //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim);
3706 t
= new TypeInstance(loc
, (TemplateInstance
*)tempinst
->syntaxCopy(NULL
));
3707 t
->syntaxCopyHelper(this);
3712 void TypeInstance::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3714 if (mod
!= this->mod
)
3715 { toCBuffer3(buf
, hgs
, mod
);
3718 tempinst
->toCBuffer(buf
, hgs
);
3719 toCBuffer2Helper(buf
, hgs
);
3722 void TypeInstance::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
3724 // Note close similarity to TypeIdentifier::resolve()
3735 error(loc
, "template instance '%s' has no identifier", toChars());
3739 //id = (Identifier *)idents.data[0];
3740 //printf("TypeInstance::resolve(sc = %p, idents = '%s')\n", sc, id->toChars());
3744 resolveHelper(loc
, sc
, s
, NULL
, pe
, pt
, ps
);
3745 //printf("pt = '%s'\n", (*pt)->toChars());
3748 Type
*TypeInstance::semantic(Loc loc
, Scope
*sc
)
3754 //printf("TypeInstance::semantic(%s)\n", toChars());
3756 if (sc
->parameterSpecialization
)
3758 unsigned errors
= global
.errors
;
3761 resolve(loc
, sc
, &e
, &t
, &s
);
3764 if (errors
!= global
.errors
)
3765 { if (global
.gag
== 0)
3766 global
.errors
= errors
;
3771 resolve(loc
, sc
, &e
, &t
, &s
);
3778 error(loc
, "%s is used as a type", toChars());
3785 /***************************** TypeTypeof *****************************/
3787 TypeTypeof::TypeTypeof(Loc loc
, Expression
*exp
)
3788 : TypeQualified(Ttypeof
, loc
)
3793 Type
*TypeTypeof::syntaxCopy()
3797 t
= new TypeTypeof(loc
, exp
->syntaxCopy());
3798 t
->syntaxCopyHelper(this);
3802 Dsymbol
*TypeTypeof::toDsymbol(Scope
*sc
)
3806 t
= semantic(0, sc
);
3809 return t
->toDsymbol(sc
);
3812 void TypeTypeof::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3814 if (mod
!= this->mod
)
3815 { toCBuffer3(buf
, hgs
, mod
);
3818 buf
->writestring("typeof(");
3819 exp
->toCBuffer(buf
, hgs
);
3820 buf
->writeByte(')');
3821 toCBuffer2Helper(buf
, hgs
);
3824 Type
*TypeTypeof::semantic(Loc loc
, Scope
*sc
)
3828 //printf("TypeTypeof::semantic() %p\n", this);
3830 //static int nest; if (++nest == 50) *(char*)0=0;
3833 /* Special case for typeof(this) and typeof(super) since both
3834 * should work even if they are not inside a non-static member function
3836 if (exp
->op
== TOKthis
|| exp
->op
== TOKsuper
)
3838 // Find enclosing struct or class
3839 for (Dsymbol
*s
= sc
->parent
; 1; s
= s
->parent
)
3841 ClassDeclaration
*cd
;
3842 StructDeclaration
*sd
;
3846 error(loc
, "%s is not in a struct or class scope", exp
->toChars());
3849 cd
= s
->isClassDeclaration();
3852 if (exp
->op
== TOKsuper
)
3856 { error(loc
, "class %s has no 'super'", s
->toChars());
3863 sd
= s
->isStructDeclaration();
3866 if (exp
->op
== TOKsuper
)
3868 error(loc
, "struct %s has no 'super'", sd
->toChars());
3871 t
= sd
->type
->pointerTo();
3880 exp
= exp
->semantic(sc
);
3885 error(loc
, "expression (%s) has no type", exp
->toChars());
3892 Dsymbol
*s
= t
->toDsymbol(sc
);
3893 for (size_t i
= 0; i
< idents
.dim
; i
++)
3897 Identifier
*id
= (Identifier
*)idents
.data
[i
];
3898 s
= s
->searchX(loc
, sc
, id
);
3904 { error(loc
, "%s is not a type", s
->toChars());
3909 { error(loc
, "cannot resolve .property for %s", toChars());
3919 d_uns64
TypeTypeof::size(Loc loc
)
3922 return exp
->type
->size(loc
);
3924 return TypeQualified::size(loc
);
3929 /***************************** TypeEnum *****************************/
3931 TypeEnum::TypeEnum(EnumDeclaration
*sym
)
3937 char *TypeEnum::toChars()
3939 return sym
->toChars();
3942 Type
*TypeEnum::semantic(Loc loc
, Scope
*sc
)
3948 d_uns64
TypeEnum::size(Loc loc
)
3952 error(loc
, "enum %s is forward referenced", sym
->toChars());
3955 return sym
->memtype
->size(loc
);
3958 unsigned TypeEnum::alignsize()
3965 error(0, "enum %s is forward referenced", sym
->toChars());
3968 return sym
->memtype
->alignsize();
3971 Dsymbol
*TypeEnum::toDsymbol(Scope
*sc
)
3976 Type
*TypeEnum::toBasetype()
3983 error(sym
->loc
, "enum %s is forward referenced", sym
->toChars());
3986 return sym
->memtype
->toBasetype();
3989 void TypeEnum::toDecoBuffer(OutBuffer
*buf
)
3992 name
= sym
->mangle();
3993 // if (name[0] == '_' && name[1] == 'D')
3995 buf
->printf("%c%s", mangleChar
[ty
], name
);
3998 void TypeEnum::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4000 if (mod
!= this->mod
)
4001 { toCBuffer3(buf
, hgs
, mod
);
4004 buf
->writestring(sym
->toChars());
4007 Expression
*TypeEnum::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
4014 printf("TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\n", e
->toChars(), ident
->toChars(), toChars());
4018 s
= sym
->symtab
->lookup(ident
);
4021 return getProperty(e
->loc
, ident
);
4023 m
= s
->isEnumMember();
4024 em
= m
->value
->copy();
4029 error(e
->loc
, "forward reference of %s.%s", toChars(), ident
->toChars());
4030 return new IntegerExp(0, 0, this);
4033 Expression
*TypeEnum::getProperty(Loc loc
, Identifier
*ident
)
4036 if (ident
== Id::max
)
4040 e
= new IntegerExp(0, sym
->maxval
, this);
4042 else if (ident
== Id::min
)
4046 e
= new IntegerExp(0, sym
->minval
, this);
4048 else if (ident
== Id::init
)
4052 e
= defaultInit(loc
);
4058 e
= sym
->memtype
->getProperty(loc
, ident
);
4063 error(loc
, "forward reference of %s.%s", toChars(), ident
->toChars());
4064 return new IntegerExp(0, 0, this);
4067 int TypeEnum::isintegral()
4072 int TypeEnum::isfloating()
4077 int TypeEnum::isunsigned()
4079 return sym
->memtype
->isunsigned();
4082 int TypeEnum::isscalar()
4085 //return sym->memtype->isscalar();
4088 MATCH
TypeEnum::implicitConvTo(Type
*to
)
4091 //printf("TypeEnum::implicitConvTo()\n");
4092 if (this->equals(to
))
4093 m
= MATCHexact
; // exact match
4094 else if (sym
->memtype
->implicitConvTo(to
))
4095 m
= MATCHconvert
; // match with conversions
4097 m
= MATCHnomatch
; // no match
4101 Expression
*TypeEnum::defaultInit(Loc loc
)
4104 printf("TypeEnum::defaultInit() '%s'\n", toChars());
4106 // Initialize to first member of enum
4108 e
= new IntegerExp(loc
, sym
->defaultval
, this);
4112 int TypeEnum::isZeroInit()
4114 return (sym
->defaultval
== 0);
4117 int TypeEnum::hasPointers()
4119 return toBasetype()->hasPointers();
4122 /***************************** TypeTypedef *****************************/
4124 TypeTypedef::TypeTypedef(TypedefDeclaration
*sym
)
4125 : Type(Ttypedef
, NULL
)
4130 Type
*TypeTypedef::syntaxCopy()
4135 char *TypeTypedef::toChars()
4137 return sym
->toChars();
4140 Type
*TypeTypedef::semantic(Loc loc
, Scope
*sc
)
4142 //printf("TypeTypedef::semantic(%s), sem = %d\n", toChars(), sym->sem);
4147 d_uns64
TypeTypedef::size(Loc loc
)
4149 return sym
->basetype
->size(loc
);
4152 unsigned TypeTypedef::alignsize()
4154 return sym
->basetype
->alignsize();
4157 Dsymbol
*TypeTypedef::toDsymbol(Scope
*sc
)
4162 void TypeTypedef::toDecoBuffer(OutBuffer
*buf
)
4166 name
= sym
->mangle();
4167 // if (name[0] == '_' && name[1] == 'D')
4169 //len = strlen(name);
4170 //buf->printf("%c%d%s", mangleChar[ty], len, name);
4171 buf
->printf("%c%s", mangleChar
[ty
], name
);
4174 void TypeTypedef::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4176 //printf("TypeTypedef::toCBuffer2() '%s'\n", sym->toChars());
4177 if (mod
!= this->mod
)
4178 { toCBuffer3(buf
, hgs
, mod
);
4181 buf
->writestring(sym
->toChars());
4184 Expression
*TypeTypedef::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
4187 printf("TypeTypedef::dotExp(e = '%s', ident = '%s') '%s'\n", e
->toChars(), ident
->toChars(), toChars());
4189 if (ident
== Id::init
)
4191 return Type::dotExp(sc
, e
, ident
);
4193 return sym
->basetype
->dotExp(sc
, e
, ident
);
4196 Expression
*TypeTypedef::getProperty(Loc loc
, Identifier
*ident
)
4198 if (ident
== Id::init
)
4200 return Type::getProperty(loc
, ident
);
4202 return sym
->basetype
->getProperty(loc
, ident
);
4205 int TypeTypedef::isbit()
4207 return sym
->basetype
->isbit();
4210 int TypeTypedef::isintegral()
4212 //printf("TypeTypedef::isintegral()\n");
4213 //printf("sym = '%s'\n", sym->toChars());
4214 //printf("basetype = '%s'\n", sym->basetype->toChars());
4215 return sym
->basetype
->isintegral();
4218 int TypeTypedef::isfloating()
4220 return sym
->basetype
->isfloating();
4223 int TypeTypedef::isreal()
4225 return sym
->basetype
->isreal();
4228 int TypeTypedef::isimaginary()
4230 return sym
->basetype
->isimaginary();
4233 int TypeTypedef::iscomplex()
4235 return sym
->basetype
->iscomplex();
4238 int TypeTypedef::isunsigned()
4240 return sym
->basetype
->isunsigned();
4243 int TypeTypedef::isscalar()
4245 return sym
->basetype
->isscalar();
4248 int TypeTypedef::checkBoolean()
4250 return sym
->basetype
->checkBoolean();
4253 Type
*TypeTypedef::toBasetype()
4257 sym
->error("circular definition");
4258 sym
->basetype
= Type::terror
;
4259 return Type::terror
;
4262 Type
*t
= sym
->basetype
->toBasetype();
4267 MATCH
TypeTypedef::implicitConvTo(Type
*to
)
4270 //printf("TypeTypedef::implicitConvTo()\n");
4271 if (this->equals(to
))
4272 m
= MATCHexact
; // exact match
4273 else if (sym
->basetype
->implicitConvTo(to
))
4274 m
= MATCHconvert
; // match with conversions
4276 m
= MATCHnomatch
; // no match
4280 Expression
*TypeTypedef::defaultInit(Loc loc
)
4285 printf("TypeTypedef::defaultInit() '%s'\n", toChars());
4289 //sym->init->toExpression()->print();
4290 return sym
->init
->toExpression();
4293 e
= bt
->defaultInit(loc
);
4295 while (bt
->ty
== Tsarray
)
4298 bt
= bt
->next
->toBasetype();
4303 int TypeTypedef::isZeroInit()
4307 if (sym
->init
->isVoidInitializer())
4308 return 1; // initialize voids to 0
4309 Expression
*e
= sym
->init
->toExpression();
4310 if (e
&& e
->isBool(FALSE
))
4312 return 0; // assume not
4316 sym
->error("circular definition");
4317 sym
->basetype
= Type::terror
;
4320 int result
= sym
->basetype
->isZeroInit();
4325 int TypeTypedef::hasPointers()
4327 return toBasetype()->hasPointers();
4330 /***************************** TypeStruct *****************************/
4332 TypeStruct::TypeStruct(StructDeclaration
*sym
)
4333 : Type(Tstruct
, NULL
)
4338 char *TypeStruct::toChars()
4340 //printf("sym.parent: %s, deco = %s\n", sym->parent->toChars(), deco);
4341 TemplateInstance
*ti
= sym
->parent
->isTemplateInstance();
4342 if (ti
&& ti
->toAlias() == sym
)
4343 return ti
->toChars();
4344 return sym
->toChars();
4347 Type
*TypeStruct::syntaxCopy()
4352 Type
*TypeStruct::semantic(Loc loc
, Scope
*sc
)
4354 //printf("TypeStruct::semantic('%s')\n", sym->toChars());
4356 /* Cannot do semantic for sym because scope chain may not
4359 //sym->semantic(sc);
4364 d_uns64
TypeStruct::size(Loc loc
)
4366 return sym
->size(loc
);
4369 unsigned TypeStruct::alignsize()
4372 sym
->size(0); // give error for forward references
4373 sz
= sym
->alignsize
;
4374 if (sz
> sym
->structalign
)
4375 sz
= sym
->structalign
;
4379 Dsymbol
*TypeStruct::toDsymbol(Scope
*sc
)
4384 void TypeStruct::toDecoBuffer(OutBuffer
*buf
)
4388 name
= sym
->mangle();
4389 //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", toChars(), name);
4390 // if (name[0] == '_' && name[1] == 'D')
4392 //len = strlen(name);
4393 //buf->printf("%c%d%s", mangleChar[ty], len, name);
4394 buf
->printf("%c%s", mangleChar
[ty
], name
);
4397 void TypeStruct::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4399 if (mod
!= this->mod
)
4400 { toCBuffer3(buf
, hgs
, mod
);
4403 TemplateInstance
*ti
= sym
->parent
->isTemplateInstance();
4404 if (ti
&& ti
->toAlias() == sym
)
4405 buf
->writestring(ti
->toChars());
4407 buf
->writestring(sym
->toChars());
4410 Expression
*TypeStruct::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
4420 printf("TypeStruct::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
4424 error(e
->loc
, "struct %s is forward referenced", sym
->toChars());
4425 return new IntegerExp(e
->loc
, 0, Type::tint32
);
4428 if (ident
== Id::tupleof
)
4430 /* Create a TupleExp
4432 Expressions
*exps
= new Expressions
;
4433 exps
->reserve(sym
->fields
.dim
);
4434 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
4435 { VarDeclaration
*v
= (VarDeclaration
*)sym
->fields
.data
[i
];
4436 Expression
*fe
= new DotVarExp(e
->loc
, e
, v
);
4439 e
= new TupleExp(e
->loc
, exps
);
4440 e
= e
->semantic(sc
);
4444 if (e
->op
== TOKdotexp
)
4445 { DotExp
*de
= (DotExp
*)e
;
4447 if (de
->e1
->op
== TOKimport
)
4449 ScopeExp
*se
= (ScopeExp
*)de
->e1
;
4451 s
= se
->sds
->search(e
->loc
, ident
, 0);
4457 s
= sym
->search(e
->loc
, ident
, 0);
4461 //return getProperty(e->loc, ident);
4462 return Type::dotExp(sc
, e
, ident
);
4466 v
= s
->isVarDeclaration();
4467 if (v
&& v
->isConst())
4468 { ExpInitializer
*ei
= v
->getExpInitializer();
4471 { e
= ei
->exp
->copy(); // need to copy it if it's a StringExp
4472 e
= e
->semantic(sc
);
4479 //return new DotTypeExp(e->loc, e, s);
4480 return new TypeExp(e
->loc
, s
->getType());
4483 EnumMember
*em
= s
->isEnumMember();
4487 return em
->value
->copy();
4490 TemplateMixin
*tm
= s
->isTemplateMixin();
4494 de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, tm
));
4499 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
4502 e
= new DotTemplateExp(e
->loc
, e
, td
);
4507 TemplateInstance
*ti
= s
->isTemplateInstance();
4509 { if (!ti
->semanticdone
)
4511 s
= ti
->inst
->toAlias();
4512 if (!s
->isTemplateInstance())
4514 Expression
*de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, ti
));
4519 d
= s
->isDeclaration();
4522 printf("d = %s '%s'\n", s
->kind(), s
->toChars());
4526 if (e
->op
== TOKtype
)
4527 { FuncDeclaration
*fd
= sc
->func
;
4529 if (d
->needThis() && fd
&& fd
->vthis
)
4531 e
= new DotVarExp(e
->loc
, new ThisExp(e
->loc
), d
);
4532 e
= e
->semantic(sc
);
4535 if (d
->isTupleDeclaration())
4537 e
= new TupleExp(e
->loc
, d
->isTupleDeclaration());
4538 e
= e
->semantic(sc
);
4541 return new VarExp(e
->loc
, d
);
4549 accessCheck(e
->loc
, sc
, e
, d
);
4550 ve
= new VarExp(e
->loc
, d
);
4551 e
= new CommaExp(e
->loc
, e
, ve
);
4558 if (v
->toParent() != sym
)
4559 sym
->error(e
->loc
, "'%s' is not a member", v
->toChars());
4562 accessCheck(e
->loc
, sc
, e
, d
);
4563 b
= new AddrExp(e
->loc
, e
);
4564 b
->type
= e
->type
->pointerTo();
4565 b
= new AddExp(e
->loc
, b
, new IntegerExp(e
->loc
, v
->offset
, Type::tsize_t
));
4566 b
->type
= v
->type
->pointerTo();
4567 e
= new PtrExp(e
->loc
, b
);
4572 de
= new DotVarExp(e
->loc
, e
, d
);
4573 return de
->semantic(sc
);
4576 unsigned TypeStruct::memalign(unsigned salign
)
4578 sym
->size(0); // give error for forward references
4579 return sym
->structalign
;
4582 Expression
*TypeStruct::defaultInit(Loc loc
)
4587 printf("TypeStruct::defaultInit() '%s'\n", toChars());
4589 s
= sym
->toInitializer();
4590 d
= new SymbolDeclaration(sym
->loc
, s
, sym
);
4593 return new VarExp(sym
->loc
, d
);
4596 int TypeStruct::isZeroInit()
4598 return sym
->zeroInit
;
4601 int TypeStruct::checkBoolean()
4606 int TypeStruct::hasPointers()
4608 StructDeclaration
*s
= sym
;
4610 sym
->size(0); // give error for forward references
4613 for (size_t i
= 0; i
< s
->members
->dim
; i
++)
4615 Dsymbol
*sm
= (Dsymbol
*)s
->members
->data
[i
];
4616 if (sm
->hasPointers())
4624 /***************************** TypeClass *****************************/
4626 TypeClass::TypeClass(ClassDeclaration
*sym
)
4627 : Type(Tclass
, NULL
)
4632 char *TypeClass::toChars()
4634 return sym
->toPrettyChars();
4637 Type
*TypeClass::syntaxCopy()
4642 Type
*TypeClass::semantic(Loc loc
, Scope
*sc
)
4644 //printf("TypeClass::semantic(%s)\n", sym->toChars());
4646 sym
->semantic(sym
->scope
);
4650 d_uns64
TypeClass::size(Loc loc
)
4655 Dsymbol
*TypeClass::toDsymbol(Scope
*sc
)
4660 void TypeClass::toDecoBuffer(OutBuffer
*buf
)
4664 name
= sym
->mangle();
4665 // if (name[0] == '_' && name[1] == 'D')
4667 //printf("TypeClass::toDecoBuffer('%s') = '%s'\n", toChars(), name);
4668 //len = strlen(name);
4669 //buf->printf("%c%d%s", mangleChar[ty], len, name);
4670 buf
->printf("Q%c%s", mangleChar
[ty
], name
);
4673 void TypeClass::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4675 if (mod
!= this->mod
)
4676 { toCBuffer3(buf
, hgs
, mod
);
4679 buf
->writestring(sym
->toChars());
4682 Expression
*TypeClass::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
4692 printf("TypeClass::dotExp(e='%s', ident='%s')\n", e
->toChars(), ident
->toChars());
4695 if (e
->op
== TOKdotexp
)
4696 { DotExp
*de
= (DotExp
*)e
;
4698 if (de
->e1
->op
== TOKimport
)
4700 ScopeExp
*se
= (ScopeExp
*)de
->e1
;
4702 s
= se
->sds
->search(e
->loc
, ident
, 0);
4708 if (ident
== Id::tupleof
)
4710 /* Create a TupleExp
4712 Expressions
*exps
= new Expressions
;
4713 exps
->reserve(sym
->fields
.dim
);
4714 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
4715 { VarDeclaration
*v
= (VarDeclaration
*)sym
->fields
.data
[i
];
4716 Expression
*fe
= new DotVarExp(e
->loc
, e
, v
);
4719 e
= new TupleExp(e
->loc
, exps
);
4720 e
= e
->semantic(sc
);
4724 s
= sym
->search(e
->loc
, ident
, 0);
4728 // See if it's a base class
4729 ClassDeclaration
*cbase
;
4730 for (cbase
= sym
->baseClass
; cbase
; cbase
= cbase
->baseClass
)
4732 if (cbase
->ident
->equals(ident
))
4734 e
= new DotTypeExp(0, e
, cbase
);
4739 if (ident
== Id::classinfo
)
4743 assert(ClassDeclaration::classinfo
);
4744 t
= ClassDeclaration::classinfo
->type
;
4745 if (e
->op
== TOKtype
|| e
->op
== TOKdottype
)
4747 /* For type.classinfo, we know the classinfo
4750 if (!sym
->vclassinfo
)
4751 sym
->vclassinfo
= new ClassInfoDeclaration(sym
);
4752 e
= new VarExp(e
->loc
, sym
->vclassinfo
);
4753 e
= e
->addressOf(sc
);
4754 e
->type
= t
; // do this so we don't get redundant dereference
4757 { /* For class objects, the classinfo reference is the first
4758 * entry in the vtbl[]
4760 e
= new PtrExp(e
->loc
, e
);
4761 e
->type
= t
->pointerTo();
4762 if (sym
->isInterfaceDeclaration())
4764 if (sym
->isCOMinterface())
4765 { /* COM interface vtbl[]s are different in that the
4766 * first entry is always pointer to QueryInterface().
4767 * We can't get a .classinfo for it.
4769 error(e
->loc
, "no .classinfo for COM interface objects");
4771 /* For an interface, the first entry in the vtbl[]
4772 * is actually a pointer to an instance of struct Interface.
4773 * The first member of Interface is the .classinfo,
4774 * so add an extra pointer indirection.
4776 e
->type
= e
->type
->pointerTo();
4777 e
= new PtrExp(e
->loc
, e
);
4778 e
->type
= t
->pointerTo();
4780 e
= new PtrExp(e
->loc
, e
, t
);
4785 if (ident
== Id::typeinfo
)
4787 if (!global
.params
.useDeprecated
)
4788 error(e
->loc
, ".typeinfo deprecated, use typeid(type)");
4789 return getTypeInfo(sc
);
4791 if (ident
== Id::outer
&& sym
->vthis
)
4797 //return getProperty(e->loc, ident);
4798 return Type::dotExp(sc
, e
, ident
);
4802 v
= s
->isVarDeclaration();
4803 if (v
&& v
->isConst())
4804 { ExpInitializer
*ei
= v
->getExpInitializer();
4807 { e
= ei
->exp
->copy(); // need to copy it if it's a StringExp
4808 e
= e
->semantic(sc
);
4815 // if (e->op == TOKtype)
4816 return new TypeExp(e
->loc
, s
->getType());
4817 // return new DotTypeExp(e->loc, e, s);
4820 EnumMember
*em
= s
->isEnumMember();
4824 return em
->value
->copy();
4827 TemplateMixin
*tm
= s
->isTemplateMixin();
4831 de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, tm
));
4836 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
4839 e
= new DotTemplateExp(e
->loc
, e
, td
);
4844 TemplateInstance
*ti
= s
->isTemplateInstance();
4846 { if (!ti
->semanticdone
)
4848 s
= ti
->inst
->toAlias();
4849 if (!s
->isTemplateInstance())
4851 Expression
*de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, ti
));
4856 d
= s
->isDeclaration();
4859 e
->error("%s.%s is not a declaration", e
->toChars(), ident
->toChars());
4860 return new IntegerExp(e
->loc
, 1, Type::tint32
);
4863 if (e
->op
== TOKtype
)
4867 if (d
->needThis() && (hasThis(sc
) || !d
->isFuncDeclaration()))
4871 ClassDeclaration
*thiscd
;
4872 thiscd
= sc
->func
->toParent()->isClassDeclaration();
4876 ClassDeclaration
*cd
= e
->type
->isClassHandle();
4880 e
= new ThisExp(e
->loc
);
4881 e
= new DotTypeExp(e
->loc
, e
, cd
);
4882 de
= new DotVarExp(e
->loc
, e
, d
);
4883 e
= de
->semantic(sc
);
4886 else if ((!cd
|| !cd
->isBaseOf(thiscd
, NULL
)) &&
4887 !d
->isFuncDeclaration())
4888 e
->error("'this' is required, but %s is not a base class of %s", e
->type
->toChars(), thiscd
->toChars());
4892 de
= new DotVarExp(e
->loc
, new ThisExp(e
->loc
), d
);
4893 e
= de
->semantic(sc
);
4896 else if (d
->isTupleDeclaration())
4898 e
= new TupleExp(e
->loc
, d
->isTupleDeclaration());
4899 e
= e
->semantic(sc
);
4903 ve
= new VarExp(e
->loc
, d
);
4912 accessCheck(e
->loc
, sc
, e
, d
);
4913 ve
= new VarExp(e
->loc
, d
);
4914 e
= new CommaExp(e
->loc
, e
, ve
);
4919 if (d
->parent
&& d
->toParent()->isModule())
4924 ve
= new VarExp(e
->loc
, d
);
4925 e
= new CommaExp(e
->loc
, e
, ve
);
4930 de
= new DotVarExp(e
->loc
, e
, d
);
4931 return de
->semantic(sc
);
4934 ClassDeclaration
*TypeClass::isClassHandle()
4939 int TypeClass::isauto()
4944 int TypeClass::isBaseOf(Type
*t
, target_ptrdiff_t
*poffset
)
4946 if (t
->ty
== Tclass
)
4947 { ClassDeclaration
*cd
;
4949 cd
= ((TypeClass
*)t
)->sym
;
4950 if (sym
->isBaseOf(cd
, poffset
))
4956 MATCH
TypeClass::implicitConvTo(Type
*to
)
4958 //printf("TypeClass::implicitConvTo('%s')\n", to->toChars());
4960 // Can always convert a "Foo" to a "Foo?"
4961 if (to
->ty
== Tmaybe
&& to
->next
)
4967 ClassDeclaration
*cdto
= to
->isClassHandle();
4968 if (cdto
&& cdto
->isBaseOf(sym
, NULL
))
4969 { //printf("is base\n");
4970 return MATCHconvert
;
4973 if (global
.params
.Dversion
== 1)
4975 // Allow conversion to (void *)
4976 if (to
->ty
== Tpointer
&& to
->next
->ty
== Tvoid
)
4977 return MATCHconvert
;
4980 return MATCHnomatch
;
4983 Expression
*TypeClass::defaultInit(Loc loc
)
4986 printf("TypeClass::defaultInit() '%s'\n", toChars());
4989 e
= new NullExp(loc
);
4994 int TypeClass::isZeroInit()
4999 int TypeClass::checkBoolean()
5004 int TypeClass::hasPointers()
5009 /***************************** TypeTuple *****************************/
5011 TypeTuple::TypeTuple(Arguments
*arguments
)
5012 : Type(Ttuple
, NULL
)
5014 //printf("TypeTuple(this = %p)\n", this);
5015 this->arguments
= arguments
;
5019 for (size_t i
= 0; i
< arguments
->dim
; i
++)
5021 Argument
*arg
= (Argument
*)arguments
->data
[i
];
5022 assert(arg
&& arg
->type
);
5029 * Form TypeTuple from the types of the expressions.
5030 * Assume exps[] is already tuple expanded.
5033 TypeTuple::TypeTuple(Expressions
*exps
)
5034 : Type(Ttuple
, NULL
)
5036 Arguments
*arguments
= new Arguments
;
5039 arguments
->setDim(exps
->dim
);
5040 for (size_t i
= 0; i
< exps
->dim
; i
++)
5041 { Expression
*e
= (Expression
*)exps
->data
[i
];
5042 if (e
->type
->ty
== Ttuple
)
5043 e
->error("cannot form tuple of tuples");
5044 Argument
*arg
= new Argument(STCin
, e
->type
, NULL
, NULL
);
5045 arguments
->data
[i
] = (void *)arg
;
5048 this->arguments
= arguments
;
5051 Type
*TypeTuple::syntaxCopy()
5053 Arguments
*args
= Argument::arraySyntaxCopy(arguments
);
5054 Type
*t
= new TypeTuple(args
);
5058 Type
*TypeTuple::semantic(Loc loc
, Scope
*sc
)
5060 //printf("TypeTuple::semantic(this = %p)\n", this);
5062 deco
= merge()->deco
;
5064 /* Don't return merge(), because a tuple with one type has the
5065 * same deco as that type.
5070 int TypeTuple::equals(Object
*o
)
5074 //printf("TypeTuple::equals(%s, %s)\n", toChars(), t->toChars());
5079 if (t
->ty
== Ttuple
)
5080 { TypeTuple
*tt
= (TypeTuple
*)t
;
5082 if (arguments
->dim
== tt
->arguments
->dim
)
5084 for (size_t i
= 0; i
< tt
->arguments
->dim
; i
++)
5085 { Argument
*arg1
= (Argument
*)arguments
->data
[i
];
5086 Argument
*arg2
= (Argument
*)tt
->arguments
->data
[i
];
5088 if (!arg1
->type
->equals(arg2
->type
))
5097 Type
*TypeTuple::reliesOnTident()
5101 for (size_t i
= 0; i
< arguments
->dim
; i
++)
5103 Argument
*arg
= (Argument
*)arguments
->data
[i
];
5104 Type
*t
= arg
->type
->reliesOnTident();
5112 void TypeTuple::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
5114 Argument::argsToCBuffer(buf
, hgs
, arguments
, 0);
5117 void TypeTuple::toDecoBuffer(OutBuffer
*buf
)
5119 //printf("TypeTuple::toDecoBuffer() this = %p\n", this);
5121 Argument::argsToDecoBuffer(&buf2
, arguments
);
5122 unsigned len
= buf2
.offset
;
5124 // newlib bug as of 1.14.0
5125 char * p
= (char*) buf2
.extractData();
5126 buf
->printf("%c%d%.*s", mangleChar
[ty
], len
, len
, p
? p
: "");
5128 buf
->printf("%c%d%.*s", mangleChar
[ty
], len
, len
, (char *)buf2
.extractData());
5132 Expression
*TypeTuple::getProperty(Loc loc
, Identifier
*ident
)
5136 printf("TypeTuple::getProperty(type = '%s', ident = '%s')\n", toChars(), ident
->toChars());
5138 if (ident
== Id::length
)
5140 e
= new IntegerExp(loc
, arguments
->dim
, Type::tsize_t
);
5144 error(loc
, "no property '%s' for tuple '%s'", ident
->toChars(), toChars());
5145 e
= new IntegerExp(loc
, 1, Type::tint32
);
5150 /***************************** TypeSlice *****************************/
5152 /* This is so we can slice a TypeTuple */
5154 TypeSlice::TypeSlice(Type
*next
, Expression
*lwr
, Expression
*upr
)
5155 : Type(Tslice
, next
)
5157 //printf("TypeSlice[%s .. %s]\n", lwr->toChars(), upr->toChars());
5162 Type
*TypeSlice::syntaxCopy()
5164 Type
*t
= new TypeSlice(next
->syntaxCopy(), lwr
->syntaxCopy(), upr
->syntaxCopy());
5168 Type
*TypeSlice::semantic(Loc loc
, Scope
*sc
)
5170 //printf("TypeSlice::semantic() %s\n", toChars());
5171 next
= next
->semantic(loc
, sc
);
5172 //printf("next: %s\n", next->toChars());
5174 Type
*tbn
= next
->toBasetype();
5175 if (tbn
->ty
!= Ttuple
)
5176 { error(loc
, "can only slice tuple types, not %s", tbn
->toChars());
5177 return Type::terror
;
5179 TypeTuple
*tt
= (TypeTuple
*)tbn
;
5181 lwr
= semanticLength(sc
, tbn
, lwr
);
5182 lwr
= lwr
->optimize(WANTvalue
);
5183 uinteger_t i1
= lwr
->toUInteger();
5185 upr
= semanticLength(sc
, tbn
, upr
);
5186 upr
= upr
->optimize(WANTvalue
);
5187 uinteger_t i2
= upr
->toUInteger();
5189 if (!(i1
<= i2
&& i2
<= tt
->arguments
->dim
))
5190 { error(loc
, "slice [%"PRIuMAX
"..%"PRIuMAX
"] is out of range of [0..%u]", i1
, i2
, tt
->arguments
->dim
);
5191 return Type::terror
;
5194 Arguments
*args
= new Arguments
;
5195 args
->reserve(i2
- i1
);
5196 for (size_t i
= i1
; i
< i2
; i
++)
5197 { Argument
*arg
= (Argument
*)tt
->arguments
->data
[i
];
5201 return new TypeTuple(args
);
5204 void TypeSlice::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
5206 next
->resolve(loc
, sc
, pe
, pt
, ps
);
5208 { // It's really a slice expression
5210 e
= new SliceExp(loc
, *pe
, lwr
, upr
);
5215 TupleDeclaration
*td
= s
->isTupleDeclaration();
5218 /* It's a slice of a TupleDeclaration
5220 ScopeDsymbol
*sym
= new ArrayScopeSymbol(td
);
5221 sym
->parent
= sc
->scopesym
;
5224 lwr
= lwr
->semantic(sc
);
5225 lwr
= lwr
->optimize(WANTvalue
);
5226 uinteger_t i1
= lwr
->toUInteger();
5228 upr
= upr
->semantic(sc
);
5229 upr
= upr
->optimize(WANTvalue
);
5230 uinteger_t i2
= upr
->toUInteger();
5234 if (!(i1
<= i2
&& i2
<= td
->objects
->dim
))
5235 { error(loc
, "slice [%"PRIuMAX
"u..%"PRIuMAX
"u] is out of range of [0..%u]", i1
, i2
, td
->objects
->dim
);
5239 if (i1
== 0 && i2
== td
->objects
->dim
)
5245 /* Create a new TupleDeclaration which
5246 * is a slice [i1..i2] out of the old one.
5248 Objects
*objects
= new Objects
;
5249 objects
->setDim(i2
- i1
);
5250 for (size_t i
= 0; i
< objects
->dim
; i
++)
5252 objects
->data
[i
] = td
->objects
->data
[(size_t)i1
+ i
];
5255 TupleDeclaration
*tds
= new TupleDeclaration(loc
, td
->ident
, objects
);
5264 Type::resolve(loc
, sc
, pe
, pt
, ps
);
5268 void TypeSlice::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
5270 if (mod
!= this->mod
)
5271 { toCBuffer3(buf
, hgs
, mod
);
5274 next
->toCBuffer2(buf
, hgs
, this->mod
);
5276 buf
->printf("[%s .. ", lwr
->toChars());
5277 buf
->printf("%s]", upr
->toChars());
5280 /***************************** Argument *****************************/
5282 Argument::Argument(unsigned storageClass
, Type
*type
, Identifier
*ident
, Expression
*defaultArg
)
5285 this->ident
= ident
;
5286 this->storageClass
= storageClass
;
5287 this->defaultArg
= defaultArg
;
5290 Argument
*Argument::syntaxCopy()
5292 Argument
*a
= new Argument(storageClass
,
5293 type
? type
->syntaxCopy() : NULL
,
5295 defaultArg
? defaultArg
->syntaxCopy() : NULL
);
5299 Arguments
*Argument::arraySyntaxCopy(Arguments
*args
)
5300 { Arguments
*a
= NULL
;
5304 a
= new Arguments();
5305 a
->setDim(args
->dim
);
5306 for (size_t i
= 0; i
< a
->dim
; i
++)
5307 { Argument
*arg
= (Argument
*)args
->data
[i
];
5309 arg
= arg
->syntaxCopy();
5310 a
->data
[i
] = (void *)arg
;
5316 char *Argument::argsTypesToChars(Arguments
*args
, int varargs
)
5319 buf
= new OutBuffer();
5321 buf
->writeByte('(');
5327 for (i
= 0; i
< args
->dim
; i
++)
5331 buf
->writeByte(',');
5332 arg
= (Argument
*)args
->data
[i
];
5334 arg
->type
->toCBuffer2(&argbuf
, &hgs
, 0);
5335 buf
->write(&argbuf
);
5339 if (i
&& varargs
== 1)
5340 buf
->writeByte(',');
5341 buf
->writestring("...");
5344 buf
->writeByte(')');
5346 return buf
->toChars();
5349 void Argument::argsToCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
, Arguments
*arguments
, int varargs
)
5351 buf
->writeByte('(');
5356 for (i
= 0; i
< arguments
->dim
; i
++)
5360 buf
->writestring(", ");
5361 arg
= (Argument
*)arguments
->data
[i
];
5362 if (arg
->storageClass
& STCout
)
5363 buf
->writestring("out ");
5364 else if (arg
->storageClass
& STCref
)
5365 buf
->writestring((global
.params
.Dversion
== 1)
5366 ? (char *)"inout " : (char *)"ref ");
5367 else if (arg
->storageClass
& STClazy
)
5368 buf
->writestring("lazy ");
5370 arg
->type
->toCBuffer(&argbuf
, arg
->ident
, hgs
);
5371 if (arg
->defaultArg
)
5373 argbuf
.writestring(" = ");
5374 arg
->defaultArg
->toCBuffer(&argbuf
, hgs
);
5376 buf
->write(&argbuf
);
5380 if (i
&& varargs
== 1)
5381 buf
->writeByte(',');
5382 buf
->writestring("...");
5385 buf
->writeByte(')');
5389 void Argument::argsToDecoBuffer(OutBuffer
*buf
, Arguments
*arguments
)
5391 //printf("Argument::argsToDecoBuffer()\n");
5393 // Write argument types
5396 size_t dim
= Argument::dim(arguments
);
5397 for (size_t i
= 0; i
< dim
; i
++)
5399 Argument
*arg
= Argument::getNth(arguments
, i
);
5400 arg
->toDecoBuffer(buf
);
5405 /****************************************************
5406 * Determine if parameter is a lazy array of delegates.
5407 * If so, return the return type of those delegates.
5408 * If not, return NULL.
5411 Type
*Argument::isLazyArray()
5413 // if (inout == Lazy)
5415 Type
*tb
= type
->toBasetype();
5416 if (tb
->ty
== Tsarray
|| tb
->ty
== Tarray
)
5418 Type
*tel
= tb
->next
->toBasetype();
5419 if (tel
->ty
== Tdelegate
)
5421 TypeDelegate
*td
= (TypeDelegate
*)tel
;
5422 TypeFunction
*tf
= (TypeFunction
*)td
->next
;
5424 if (!tf
->varargs
&& Argument::dim(tf
->parameters
) == 0)
5426 return tf
->next
; // return type of delegate
5434 void Argument::toDecoBuffer(OutBuffer
*buf
)
5436 switch (storageClass
& (STCin
| STCout
| STCref
| STClazy
))
5441 buf
->writeByte('J');
5444 buf
->writeByte('K');
5447 buf
->writeByte('L');
5455 type
->toDecoBuffer(buf
);
5458 /***************************************
5459 * Determine number of arguments, folding in tuples.
5462 size_t Argument::dim(Arguments
*args
)
5467 for (size_t i
= 0; i
< args
->dim
; i
++)
5468 { Argument
*arg
= (Argument
*)args
->data
[i
];
5469 Type
*t
= arg
->type
->toBasetype();
5471 if (t
->ty
== Ttuple
)
5472 { TypeTuple
*tu
= (TypeTuple
*)t
;
5473 n
+= dim(tu
->arguments
);
5482 /***************************************
5483 * Get nth Argument, folding in tuples.
5485 * Argument* nth Argument
5486 * NULL not found, *pn gets incremented by the number
5490 Argument
*Argument::getNth(Arguments
*args
, size_t nth
, size_t *pn
)
5496 for (size_t i
= 0; i
< args
->dim
; i
++)
5497 { Argument
*arg
= (Argument
*)args
->data
[i
];
5498 Type
*t
= arg
->type
->toBasetype();
5500 if (t
->ty
== Ttuple
)
5501 { TypeTuple
*tu
= (TypeTuple
*)t
;
5502 arg
= getNth(tu
->arguments
, nth
- n
, &n
);