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 '?'
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
);
309 // If this type can be null, wrap it in TypeMaybe.
310 // Otherwise just, returns itself. This is so that
311 // we can try wrapping everything in D source easily.
316 printf("maybe maybe\n");
320 // For some reason, "void*?" causes problems.
321 // Since it's not type safe anyway, don't worry about it.
322 if (ty
== Tpointer
&& next
->ty
== Tvoid
)
325 if (ty
!= Tpointer
&& ty
!= Tclass
&& ty
!= Tident
)
326 return this; // Can't be null
331 t
= new TypeMaybe(this);
332 if (t
->reliesOnTident())
340 Type
*Type::pointerTo()
345 t
= new TypePointer(this);
351 Type
*Type::referenceTo()
356 t
= new TypeReference(this);
362 Type
*Type::arrayOf()
367 t
= new TypeDArray(this);
368 arrayof
= t
->merge();
373 Dsymbol
*Type::toDsymbol(Scope
*sc
)
378 /*******************************
379 * If this is a shell around another type,
380 * get that other type.
383 Type
*Type::toBasetype()
388 /********************************
392 void Type::toDecoBuffer(OutBuffer
*buf
)
394 buf
->writeByte(mangleChar
[ty
]);
397 assert(next
!= this);
398 //printf("this = %p, ty = %d, next = %p, ty = %d\n", this, this->ty, next, next->ty);
399 next
->toDecoBuffer(buf
);
403 /********************************
404 * For pretty-printing a type.
407 char *Type::toChars()
411 buf
= new OutBuffer();
412 toCBuffer(buf
, NULL
, &hgs
);
413 return buf
->toChars();
416 void Type::toCBuffer(OutBuffer
*buf
, Identifier
*ident
, HdrGenState
*hgs
)
418 toCBuffer2(buf
, hgs
, 0);
420 { buf
->writeByte(' ');
421 buf
->writestring(ident
->toChars());
425 void Type::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
427 if (mod
!= this->mod
)
428 { toCBuffer3(buf
, hgs
, mod
);
431 buf
->writestring(toChars());
434 void Type::toCBuffer3(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
436 if (mod
!= this->mod
)
442 toCBuffer2(buf
, hgs
, this->mod
);
449 L1
: buf
->writestring(p
);
450 toCBuffer2(buf
, hgs
, this->mod
);
460 /************************************
466 //printf("merge(%s)\n", toChars());
475 next
= next
->merge();
477 sv
= stringtable
.update((char *)buf
.data
, buf
.offset
);
479 { t
= (Type
*) sv
->ptrvalue
;
481 //printf("old value, deco = '%s' %p\n", t->deco, t->deco);
486 deco
= sv
->lstring
.string
;
487 //printf("new value, deco = '%s' %p\n", t->deco, t->deco);
498 int Type::isintegral()
503 int Type::isfloating()
513 int Type::isimaginary()
518 int Type::iscomplex()
528 int Type::isunsigned()
533 ClassDeclaration
*Type::isClassHandle()
548 int Type::checkBoolean()
553 /*********************************
554 * Check type to see if it is based on a deprecated symbol.
557 void Type::checkDeprecated(Loc loc
, Scope
*sc
)
562 for (t
= this; t
; t
= t
->next
)
564 s
= t
->toDsymbol(sc
);
566 s
->checkDeprecated(loc
, sc
);
571 Expression
*Type::defaultInit(Loc loc
)
574 printf("Type::defaultInit() '%s'\n", toChars());
579 int Type::isZeroInit()
581 return 0; // assume not
584 int Type::isBaseOf(Type
*t
, target_ptrdiff_t
*poffset
)
586 return 0; // assume not
589 /********************************
590 * Determine if 'this' can be implicitly converted
594 * 1 can convert using implicit conversions
595 * 2 this and to are the same type
598 MATCH
Type::implicitConvTo(Type
*to
)
600 //printf("Type::implicitConvTo(this=%p, to=%p)\n", this, to);
601 //printf("\tthis->next=%p, to->next=%p\n", this->next, to->next);
604 // if (to->ty == Tvoid)
609 Expression
*Type::getProperty(Loc loc
, Identifier
*ident
)
613 printf("Type::getProperty(type = '%s', ident = '%s')\n", toChars(), ident
->toChars());
615 if (ident
== Id::__sizeof
)
617 e
= new IntegerExp(loc
, size(loc
), Type::tsize_t
);
619 else if (ident
== Id::size
)
621 error(loc
, ".size property should be replaced with .sizeof");
622 e
= new IntegerExp(loc
, size(loc
), Type::tsize_t
);
624 else if (ident
== Id::alignof
)
626 e
= new IntegerExp(loc
, alignsize(), Type::tsize_t
);
628 else if (ident
== Id::typeinfo
)
630 if (!global
.params
.useDeprecated
)
631 error(loc
, ".typeinfo deprecated, use typeid(type)");
632 e
= getTypeInfo(NULL
);
634 else if (ident
== Id::init
)
637 error(loc
, "void does not have an initializer");
638 e
= defaultInit(loc
);
640 else if (ident
== Id::mangleof
)
643 e
= new StringExp(loc
, deco
, strlen(deco
), 'c');
645 e
= e
->semantic(&sc
);
647 else if (ident
== Id::stringof
)
648 { char *s
= toChars();
649 e
= new StringExp(loc
, s
, strlen(s
), 'c');
651 e
= e
->semantic(&sc
);
655 error(loc
, "no property '%s' for type '%s'", ident
->toChars(), toChars());
656 e
= new IntegerExp(loc
, 1, Type::tint32
);
661 Expression
*Type::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
662 { VarDeclaration
*v
= NULL
;
665 printf("Type::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
667 if (e
->op
== TOKdotvar
)
669 DotVarExp
*dv
= (DotVarExp
*)e
;
670 v
= dv
->var
->isVarDeclaration();
672 else if (e
->op
== TOKvar
)
674 VarExp
*ve
= (VarExp
*)e
;
675 v
= ve
->var
->isVarDeclaration();
679 if (ident
== Id::offset
)
681 if (!global
.params
.useDeprecated
)
682 error(e
->loc
, ".offset deprecated, use .offsetof");
685 else if (ident
== Id::offsetof
)
688 if (v
->storage_class
& STCfield
)
690 e
= new IntegerExp(e
->loc
, v
->offset
, Type::tsize_t
);
694 else if (ident
== Id::init
)
699 if (v
->init
->isVoidInitializer())
700 error(e
->loc
, "%s.init is void", v
->toChars());
703 e
= v
->init
->toExpression();
704 if (e
->op
== TOKassign
|| e
->op
== TOKconstruct
)
706 e
= ((AssignExp
*)e
)->e2
;
708 /* Take care of case where we used a 0
709 * to initialize the struct.
711 if (e
->type
== Type::tint32
&&
713 v
->type
->toBasetype()->ty
== Tstruct
)
715 e
= v
->type
->defaultInit(loc
);
718 e
= e
->optimize(WANTvalue
| WANTinterpret
);
719 // if (!e->isConst())
720 // error(loc, ".init cannot be evaluated at compile time");
725 Expression
*ex
= defaultInit(e
->loc
);
729 if (ident
== Id::typeinfo
)
731 if (!global
.params
.useDeprecated
)
732 error(e
->loc
, ".typeinfo deprecated, use typeid(type)");
736 if (ident
== Id::stringof
)
737 { char *s
= e
->toChars();
738 e
= new StringExp(e
->loc
, s
, strlen(s
), 'c');
740 e
= e
->semantic(&sc
);
743 return getProperty(e
->loc
, ident
);
746 unsigned Type::memalign(unsigned salign
)
751 void Type::error(Loc loc
, const char *format
, ...)
754 va_start(ap
, format
);
755 ::verror(loc
, format
, ap
);
759 Identifier
*Type::getTypeInfoIdent(int internal
)
761 // _init_10TypeInfo_%s
767 //toTypeInfoBuffer(&buf);
769 { buf
.writeByte(mangleChar
[ty
]);
771 buf
.writeByte(mangleChar
[next
->ty
]);
776 // Because these are in the D library, they are maybe types
777 if (buf
.data
[0] == NOT_NULL_MANGLE
)
781 name
= (char *)alloca(19 + sizeof(len
) * 3 + len
+ 1);
783 sprintf(name
, "_D%dTypeInfo_%s6__initZ", 9 + len
, buf
.data
);
784 if (global
.params
.isWindows
)
785 name
++; // C mangling will add it back in
786 //printf("name = %s\n", name);
787 id
= Lexer::idPool(name
);
791 TypeBasic
*Type::isTypeBasic()
797 void Type::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
801 t
= semantic(loc
, sc
);
807 /*******************************
808 * If one of the subtypes of this type is a TypeIdentifier,
809 * i.e. it's an unresolved type, return that type.
812 Type
*Type::reliesOnTident()
817 return next
->reliesOnTident();
820 /********************************
821 * We've mistakenly parsed this as a type.
822 * Redo it as an Expression.
826 Expression
*Type::toExpression()
831 /***************************************
832 * Return !=0 if type has pointers that need to
833 * be scanned by the GC during a collection cycle.
836 int Type::hasPointers()
841 /* ============================= TypeBasic =========================== */
843 TypeBasic::TypeBasic(TY ty
)
849 #define TFLAGSintegral 1
850 #define TFLAGSfloating 2
851 #define TFLAGSunsigned 4
853 #define TFLAGSimaginary 0x10
854 #define TFLAGScomplex 0x20
859 case Tvoid
: d
= Token::toChars(TOKvoid
);
863 case Tint8
: d
= Token::toChars(TOKint8
);
865 flags
|= TFLAGSintegral
;
868 case Tuns8
: d
= Token::toChars(TOKuns8
);
870 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
873 case Tint16
: d
= Token::toChars(TOKint16
);
875 flags
|= TFLAGSintegral
;
878 case Tuns16
: d
= Token::toChars(TOKuns16
);
880 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
883 case Tint32
: d
= Token::toChars(TOKint32
);
885 flags
|= TFLAGSintegral
;
888 case Tuns32
: d
= Token::toChars(TOKuns32
);
890 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
893 case Tfloat32
: d
= Token::toChars(TOKfloat32
);
895 flags
|= TFLAGSfloating
| TFLAGSreal
;
898 case Tint64
: d
= Token::toChars(TOKint64
);
900 flags
|= TFLAGSintegral
;
903 case Tuns64
: d
= Token::toChars(TOKuns64
);
905 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
908 case Tfloat64
: d
= Token::toChars(TOKfloat64
);
910 flags
|= TFLAGSfloating
| TFLAGSreal
;
913 case Tfloat80
: d
= Token::toChars(TOKfloat80
);
915 flags
|= TFLAGSfloating
| TFLAGSreal
;
918 case Timaginary32
: d
= Token::toChars(TOKimaginary32
);
920 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
923 case Timaginary64
: d
= Token::toChars(TOKimaginary64
);
925 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
928 case Timaginary80
: d
= Token::toChars(TOKimaginary80
);
930 flags
|= TFLAGSfloating
| TFLAGSimaginary
;
933 case Tcomplex32
: d
= Token::toChars(TOKcomplex32
);
935 flags
|= TFLAGSfloating
| TFLAGScomplex
;
938 case Tcomplex64
: d
= Token::toChars(TOKcomplex64
);
940 flags
|= TFLAGSfloating
| TFLAGScomplex
;
943 case Tcomplex80
: d
= Token::toChars(TOKcomplex80
);
945 flags
|= TFLAGSfloating
| TFLAGScomplex
;
949 case Tbit
: d
= Token::toChars(TOKbit
);
951 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
954 case Tbool
: d
= "bool";
956 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
959 case Tascii
: d
= Token::toChars(TOKchar
);
961 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
964 case Twchar
: d
= Token::toChars(TOKwchar
);
966 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
969 case Tdchar
: d
= Token::toChars(TOKdchar
);
971 flags
|= TFLAGSintegral
| TFLAGSunsigned
;
982 Type
*TypeBasic::syntaxCopy()
984 // No semantic analysis done on basic types, no need to copy
989 char *TypeBasic::toChars()
994 void TypeBasic::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
996 //printf("TypeBasic::toCBuffer2(mod = %d, this->mod = %d)\n", mod, this->mod);
997 if (mod
!= this->mod
)
998 { toCBuffer3(buf
, hgs
, mod
);
1001 buf
->writestring(dstring
);
1004 d_uns64
TypeBasic::size(Loc loc
)
1007 //printf("TypeBasic::size()\n");
1011 case Tuns8
: size
= 1; break;
1013 case Tuns16
: size
= 2; break;
1026 size
= REALSIZE
; break;
1032 size
= REALSIZE
* 2; break;
1035 //size = Type::size(); // error message
1039 case Tbit
: size
= 1; break;
1040 case Tbool
: size
= 1; break;
1041 case Tascii
: size
= 1; break;
1042 case Twchar
: size
= 2; break;
1043 case Tdchar
: size
= 4; break;
1049 //printf("TypeBasic::size() = %d\n", size);
1053 unsigned TypeBasic::alignsize()
1072 Expression
*TypeBasic::getProperty(Loc loc
, Identifier
*ident
)
1082 //printf("TypeBasic::getProperty('%s')\n", ident->toChars());
1083 if (ident
== Id::max
)
1087 case Tint8
: ivalue
= 0x7F; goto Livalue
;
1088 case Tuns8
: ivalue
= 0xFF; goto Livalue
;
1089 case Tint16
: ivalue
= 0x7FFFUL
; goto Livalue
;
1090 case Tuns16
: ivalue
= 0xFFFFUL
; goto Livalue
;
1091 case Tint32
: ivalue
= 0x7FFFFFFFUL
; goto Livalue
;
1092 case Tuns32
: ivalue
= 0xFFFFFFFFUL
; goto Livalue
;
1093 case Tint64
: ivalue
= 0x7FFFFFFFFFFFFFFFLL
; goto Livalue
;
1094 case Tuns64
: ivalue
= 0xFFFFFFFFFFFFFFFFULL
; goto Livalue
;
1095 case Tbit
: ivalue
= 1; goto Livalue
;
1096 case Tbool
: ivalue
= 1; goto Livalue
;
1097 case Tchar
: ivalue
= 0xFF; goto Livalue
;
1098 case Twchar
: ivalue
= 0xFFFFUL
; goto Livalue
;
1099 case Tdchar
: ivalue
= 0x10FFFFUL
; goto Livalue
;
1105 #define FLT_MAX real_t_properties[real_t::Float].maxval;
1106 #define DBL_MAX real_t_properties[real_t::Double].maxval;
1107 #define LDBL_MAX real_t_properties[real_t::LongDouble].maxval;
1108 #define FLT_MIN real_t_properties[real_t::Float].minval;
1109 #define DBL_MIN real_t_properties[real_t::Double].minval;
1110 #define LDBL_MIN real_t_properties[real_t::LongDouble].minval;
1111 #define FLT_DIG real_t_properties[real_t::Float].dig;
1112 #define DBL_DIG real_t_properties[real_t::Double].dig;
1113 #define LDBL_DIG real_t_properties[real_t::LongDouble].dig;
1114 #define FLT_MANT_DIG real_t_properties[real_t::Float].mant_dig;
1115 #define DBL_MANT_DIG real_t_properties[real_t::Double].mant_dig;
1116 #define LDBL_MANT_DIG real_t_properties[real_t::LongDouble].mant_dig;
1117 #define FLT_MAX_10_EXP real_t_properties[real_t::Float].max_10_exp;
1118 #define DBL_MAX_10_EXP real_t_properties[real_t::Double].max_10_exp;
1119 #define LDBL_MAX_10_EXP real_t_properties[real_t::LongDouble].max_10_exp;
1120 #define FLT_MIN_10_EXP real_t_properties[real_t::Float].min_10_exp;
1121 #define DBL_MIN_10_EXP real_t_properties[real_t::Double].min_10_exp;
1122 #define LDBL_MIN_10_EXP real_t_properties[real_t::LongDouble].min_10_exp;
1123 #define FLT_MAX_EXP real_t_properties[real_t::Float].max_exp;
1124 #define DBL_MAX_EXP real_t_properties[real_t::Double].max_exp;
1125 #define LDBL_MAX_EXP real_t_properties[real_t::LongDouble].max_exp;
1126 #define FLT_MIN_EXP real_t_properties[real_t::Float].min_exp;
1127 #define DBL_MIN_EXP real_t_properties[real_t::Double].min_exp;
1128 #define LDBL_MIN_EXP real_t_properties[real_t::LongDouble].min_exp;
1129 #define FLT_EPSILON real_t_properties[real_t::Float].epsilonval;
1130 #define DBL_EPSILON real_t_properties[real_t::Double].epsilonval;
1131 #define LDBL_EPSILON real_t_properties[real_t::LongDouble].epsilonval;
1135 case Tfloat32
: fvalue
= FLT_MAX
; goto Lfvalue
;
1138 case Tfloat64
: fvalue
= DBL_MAX
; goto Lfvalue
;
1141 case Tfloat80
: fvalue
= LDBL_MAX
; goto Lfvalue
;
1144 else if (ident
== Id::min
)
1148 case Tint8
: ivalue
= -128; goto Livalue
;
1149 case Tuns8
: ivalue
= 0; goto Livalue
;
1150 case Tint16
: ivalue
= -32768; goto Livalue
;
1151 case Tuns16
: ivalue
= 0; goto Livalue
;
1152 case Tint32
: ivalue
= -2147483647L - 1; goto Livalue
;
1153 case Tuns32
: ivalue
= 0; goto Livalue
;
1154 case Tint64
: ivalue
= (-9223372036854775807LL-1LL); goto Livalue
;
1155 case Tuns64
: ivalue
= 0; goto Livalue
;
1156 case Tbit
: ivalue
= 0; goto Livalue
;
1157 case Tbool
: ivalue
= 0; goto Livalue
;
1158 case Tchar
: ivalue
= 0; goto Livalue
;
1159 case Twchar
: ivalue
= 0; goto Livalue
;
1160 case Tdchar
: ivalue
= 0; goto Livalue
;
1164 case Tfloat32
: fvalue
= FLT_MIN
; goto Lfvalue
;
1167 case Tfloat64
: fvalue
= DBL_MIN
; goto Lfvalue
;
1170 case Tfloat80
: fvalue
= LDBL_MIN
; goto Lfvalue
;
1173 else if (ident
== Id::nan
)
1188 // mode doesn't matter, will be converted in RealExp anyway
1189 fvalue
= real_t::getnan(real_t::LongDouble
);
1191 // gcc nan's have the sign bit set by default, so turn it off
1192 // Need the volatile to prevent gcc from doing incorrect
1193 // constant folding.
1194 volatile d_float80 foo
;
1196 if (signbit(foo
)) // signbit sometimes, not always, set
1197 foo
= -foo
; // turn off sign bit
1200 unsigned long nan
[2]= { 0xFFFFFFFF, 0x7FFFFFFF };
1201 fvalue
= *(double*)nan
;
1209 else if (ident
== Id::infinity
)
1223 fvalue
= real_t::getinfinity();
1227 fvalue
= std::numeric_limits
<long double>::infinity();
1234 else if (ident
== Id::dig
)
1240 case Tfloat32
: ivalue
= FLT_DIG
; goto Lint
;
1243 case Tfloat64
: ivalue
= DBL_DIG
; goto Lint
;
1246 case Tfloat80
: ivalue
= LDBL_DIG
; goto Lint
;
1249 else if (ident
== Id::epsilon
)
1255 case Tfloat32
: fvalue
= FLT_EPSILON
; goto Lfvalue
;
1258 case Tfloat64
: fvalue
= DBL_EPSILON
; goto Lfvalue
;
1261 case Tfloat80
: fvalue
= LDBL_EPSILON
; goto Lfvalue
;
1264 else if (ident
== Id::mant_dig
)
1270 case Tfloat32
: ivalue
= FLT_MANT_DIG
; goto Lint
;
1273 case Tfloat64
: ivalue
= DBL_MANT_DIG
; goto Lint
;
1276 case Tfloat80
: ivalue
= LDBL_MANT_DIG
; goto Lint
;
1279 else if (ident
== Id::max_10_exp
)
1285 case Tfloat32
: ivalue
= FLT_MAX_10_EXP
; goto Lint
;
1288 case Tfloat64
: ivalue
= DBL_MAX_10_EXP
; goto Lint
;
1291 case Tfloat80
: ivalue
= LDBL_MAX_10_EXP
; goto Lint
;
1294 else if (ident
== Id::max_exp
)
1300 case Tfloat32
: ivalue
= FLT_MAX_EXP
; goto Lint
;
1303 case Tfloat64
: ivalue
= DBL_MAX_EXP
; goto Lint
;
1306 case Tfloat80
: ivalue
= LDBL_MAX_EXP
; goto Lint
;
1309 else if (ident
== Id::min_10_exp
)
1315 case Tfloat32
: ivalue
= FLT_MIN_10_EXP
; goto Lint
;
1318 case Tfloat64
: ivalue
= DBL_MIN_10_EXP
; goto Lint
;
1321 case Tfloat80
: ivalue
= LDBL_MIN_10_EXP
; goto Lint
;
1324 else if (ident
== Id::min_exp
)
1330 case Tfloat32
: ivalue
= FLT_MIN_EXP
; goto Lint
;
1333 case Tfloat64
: ivalue
= DBL_MIN_EXP
; goto Lint
;
1336 case Tfloat80
: ivalue
= LDBL_MIN_EXP
; goto Lint
;
1341 return Type::getProperty(loc
, ident
);
1344 e
= new IntegerExp(loc
, ivalue
, this);
1348 if (isreal() || isimaginary())
1349 e
= new RealExp(loc
, fvalue
, this);
1355 //((real_t *)&cvalue)[0] = fvalue;
1356 //((real_t *)&cvalue)[1] = fvalue;
1357 cvalue
= fvalue
+ fvalue
* I
;
1362 //for (int i = 0; i < 20; i++)
1363 // printf("%02x ", ((unsigned char *)&cvalue)[i]);
1365 e
= new ComplexExp(loc
, cvalue
, this);
1370 e
= new IntegerExp(loc
, ivalue
, Type::tint32
);
1374 Expression
*TypeBasic::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
1377 printf("TypeBasic::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
1381 if (ident
== Id::re
)
1385 case Tcomplex32
: t
= tfloat32
; goto L1
;
1386 case Tcomplex64
: t
= tfloat64
; goto L1
;
1387 case Tcomplex80
: t
= tfloat80
; goto L1
;
1389 e
= e
->castTo(sc
, t
);
1397 case Timaginary32
: t
= tfloat32
; goto L2
;
1398 case Timaginary64
: t
= tfloat64
; goto L2
;
1399 case Timaginary80
: t
= tfloat80
; goto L2
;
1401 e
= new RealExp(0, 0, t
);
1405 return Type::getProperty(e
->loc
, ident
);
1408 else if (ident
== Id::im
)
1413 case Tcomplex32
: t
= timaginary32
; t2
= tfloat32
; goto L3
;
1414 case Tcomplex64
: t
= timaginary64
; t2
= tfloat64
; goto L3
;
1415 case Tcomplex80
: t
= timaginary80
; t2
= tfloat80
; goto L3
;
1417 e
= e
->castTo(sc
, t
);
1421 case Timaginary32
: t
= tfloat32
; goto L4
;
1422 case Timaginary64
: t
= tfloat64
; goto L4
;
1423 case Timaginary80
: t
= tfloat80
; goto L4
;
1431 e
= new RealExp(0, 0, this);
1435 return Type::getProperty(e
->loc
, ident
);
1440 return Type::dotExp(sc
, e
, ident
);
1445 Expression
*TypeBasic::defaultInit(Loc loc
)
1446 { integer_t value
= 0;
1449 printf("TypeBasic::defaultInit() '%s'\n", toChars());
1471 return getProperty(loc
, Id::nan
);
1473 return new IntegerExp(loc
, value
, this);
1476 int TypeBasic::isZeroInit()
1497 int TypeBasic::isbit()
1499 return (ty
== Tbit
);
1502 int TypeBasic::isintegral()
1504 //printf("TypeBasic::isintegral('%s') x%x\n", toChars(), flags);
1505 return flags
& TFLAGSintegral
;
1508 int TypeBasic::isfloating()
1510 return flags
& TFLAGSfloating
;
1513 int TypeBasic::isreal()
1515 return flags
& TFLAGSreal
;
1518 int TypeBasic::isimaginary()
1520 return flags
& TFLAGSimaginary
;
1523 int TypeBasic::iscomplex()
1525 return flags
& TFLAGScomplex
;
1528 int TypeBasic::isunsigned()
1530 return flags
& TFLAGSunsigned
;
1533 int TypeBasic::isscalar()
1535 return flags
& (TFLAGSintegral
| TFLAGSfloating
);
1538 MATCH
TypeBasic::implicitConvTo(Type
*to
)
1540 //printf("TypeBasic::implicitConvTo(%s) from %s\n", to->toChars(), toChars());
1544 if (ty
== Tvoid
|| to
->ty
== Tvoid
)
1545 return MATCHnomatch
;
1546 if (1 || global
.params
.Dversion
== 1)
1548 if (to
->ty
== Tbool
)
1549 return MATCHnomatch
;
1553 if (ty
== Tbool
|| to
->ty
== Tbool
)
1554 return MATCHnomatch
;
1556 if (!to
->isTypeBasic())
1557 return MATCHnomatch
;
1559 TypeBasic
*tob
= (TypeBasic
*)to
;
1560 if (flags
& TFLAGSintegral
)
1562 // Disallow implicit conversion of integers to imaginary or complex
1563 if (tob
->flags
& (TFLAGSimaginary
| TFLAGScomplex
))
1564 return MATCHnomatch
;
1566 // If converting to integral
1567 if (0 && global
.params
.Dversion
> 1 && tob
->flags
& TFLAGSintegral
)
1568 { d_uns64 sz
= size(0);
1569 d_uns64 tosz
= tob
->size(0);
1571 /* Can't convert to smaller size or, if same size, change sign
1574 return MATCHnomatch
;
1576 /*if (sz == tosz && (flags ^ tob->flags) & TFLAGSunsigned)
1577 return MATCHnomatch;*/
1580 else if (flags
& TFLAGSfloating
)
1582 // Disallow implicit conversion of floating point to integer
1583 if (tob
->flags
& TFLAGSintegral
)
1584 return MATCHnomatch
;
1586 assert(tob
->flags
& TFLAGSfloating
);
1588 // Disallow implicit conversion from complex to non-complex
1589 if (flags
& TFLAGScomplex
&& !(tob
->flags
& TFLAGScomplex
))
1590 return MATCHnomatch
;
1592 // Disallow implicit conversion of real or imaginary to complex
1593 if (flags
& (TFLAGSreal
| TFLAGSimaginary
) &&
1594 tob
->flags
& TFLAGScomplex
)
1595 return MATCHnomatch
;
1597 // Disallow implicit conversion to-from real and imaginary
1598 if ((flags
& (TFLAGSreal
| TFLAGSimaginary
)) !=
1599 (tob
->flags
& (TFLAGSreal
| TFLAGSimaginary
)))
1600 return MATCHnomatch
;
1602 return MATCHconvert
;
1605 TypeBasic
*TypeBasic::isTypeBasic()
1607 return (TypeBasic
*)this;
1610 /***************************** TypeArray *****************************/
1612 TypeArray::TypeArray(TY ty
, Type
*next
)
1617 Expression
*TypeArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
1619 Type
*n
= this->next
->toBasetype(); // uncover any typedef's
1622 printf("TypeArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
1624 if (ident
== Id::reverse
&& (n
->ty
== Tchar
|| n
->ty
== Twchar
))
1627 FuncDeclaration
*fd
;
1628 Expressions
*arguments
;
1630 static char *name
[2] = { "_adReverseChar", "_adReverseWchar" };
1632 nm
= name
[n
->ty
== Twchar
];
1633 fd
= FuncDeclaration::genCfunc(next
->arrayOf(), nm
, Type::tvoid
->arrayOf());
1634 ec
= new VarExp(0, fd
);
1635 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1636 arguments
= new Expressions();
1638 e
= new CallExp(e
->loc
, ec
, arguments
);
1639 e
->type
= next
->arrayOf();
1641 else if (ident
== Id::sort
&& (n
->ty
== Tchar
|| n
->ty
== Twchar
))
1644 FuncDeclaration
*fd
;
1645 Expressions
*arguments
;
1647 static char *name
[2] = { "_adSortChar", "_adSortWchar" };
1649 nm
= name
[n
->ty
== Twchar
];
1650 fd
= FuncDeclaration::genCfunc(next
->arrayOf(), nm
, Type::tvoid
->arrayOf());
1651 ec
= new VarExp(0, fd
);
1652 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1653 arguments
= new Expressions();
1655 e
= new CallExp(e
->loc
, ec
, arguments
);
1656 e
->type
= next
->arrayOf();
1658 else if (ident
== Id::reverse
|| ident
== Id::dup
)
1661 FuncDeclaration
*fd
;
1662 Expressions
*arguments
;
1663 target_size_t size
= next
->size(e
->loc
);
1667 dup
= (ident
== Id::dup
);
1669 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::adDup
,
1670 Type::typeinfo
->type
, Type::tvoid
->arrayOf());
1672 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::adReverse
,
1673 Type::tvoid
->arrayOf(), Type::tsize_t
);
1674 ec
= new VarExp(0, fd
);
1675 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1676 arguments
= new Expressions();
1678 arguments
->push(getTypeInfo(sc
));
1681 arguments
->push(new IntegerExp(0, size
, Type::tsize_t
));
1682 e
= new CallExp(e
->loc
, ec
, arguments
);
1683 e
->type
= next
->arrayOf();
1685 else if (ident
== Id::sort
)
1688 FuncDeclaration
*fd
;
1689 Expressions
*arguments
;
1691 fd
= FuncDeclaration::genCfunc(tint32
->arrayOf(),
1692 (char*)(n
->ty
== Tbit
? "_adSortBit" : "_adSort"),
1693 Type::tvoid
->arrayOf(),
1694 n
->ty
== Tbit
? NULL
: Type::tvoid
->pointerTo());
1695 ec
= new VarExp(0, fd
);
1696 e
= e
->castTo(sc
, n
->arrayOf()); // convert to dynamic array
1697 arguments
= new Expressions();
1699 if (next
->ty
!= Tbit
)
1700 arguments
->push(n
->ty
== Tsarray
1701 ? n
->getTypeInfo(sc
) // don't convert to dynamic array
1702 : n
->getInternalTypeInfo(sc
));
1703 e
= new CallExp(e
->loc
, ec
, arguments
);
1704 e
->type
= next
->arrayOf();
1708 e
= Type::dotExp(sc
, e
, ident
);
1714 /***************************** TypeSArray *****************************/
1716 TypeSArray::TypeSArray(Type
*t
, Expression
*dim
)
1717 : TypeArray(Tsarray
, t
)
1719 //printf("TypeSArray(%s)\n", dim->toChars());
1723 Type
*TypeSArray::syntaxCopy()
1725 Type
*t
= next
->syntaxCopy();
1726 Expression
*e
= dim
->syntaxCopy();
1727 t
= new TypeSArray(t
, e
);
1731 d_uns64
TypeSArray::size(Loc loc
)
1735 return Type::size(loc
);
1736 sz
= dim
->toInteger();
1737 if (next
->toBasetype()->ty
== Tbit
) // if array of bits
1741 sz
= ((sz
+ 31) & ~31) / 8; // size in bytes, rounded up to 32 bit dwords
1748 if (n
&& (n2
/ n
) != sz
)
1755 error(loc
, "index %"PRIdMAX
" overflow for static array", sz
);
1759 unsigned TypeSArray::alignsize()
1761 return next
->alignsize();
1764 /**************************
1765 * This evaluates exp while setting length to be the number
1766 * of elements in the tuple t.
1768 Expression
*semanticLength(Scope
*sc
, Type
*t
, Expression
*exp
)
1770 if (t
->ty
== Ttuple
)
1771 { ScopeDsymbol
*sym
= new ArrayScopeSymbol((TypeTuple
*)t
);
1772 sym
->parent
= sc
->scopesym
;
1775 exp
= exp
->semantic(sc
);
1780 exp
= exp
->semantic(sc
);
1784 Expression
*semanticLength(Scope
*sc
, TupleDeclaration
*s
, Expression
*exp
)
1786 ScopeDsymbol
*sym
= new ArrayScopeSymbol(s
);
1787 sym
->parent
= sc
->scopesym
;
1790 exp
= exp
->semantic(sc
);
1796 void TypeSArray::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
1798 //printf("TypeSArray::resolve() %s\n", toChars());
1799 next
->resolve(loc
, sc
, pe
, pt
, ps
);
1800 //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt);
1802 { // It's really an index expression
1804 e
= new IndexExp(loc
, *pe
, dim
);
1809 TupleDeclaration
*td
= s
->isTupleDeclaration();
1812 ScopeDsymbol
*sym
= new ArrayScopeSymbol(td
);
1813 sym
->parent
= sc
->scopesym
;
1816 dim
= dim
->semantic(sc
);
1817 dim
= dim
->optimize(WANTvalue
| WANTinterpret
);
1818 uinteger_t d
= dim
->toUInteger();
1822 if (d
>= td
->objects
->dim
)
1823 { error(loc
, "tuple index %"PRIuMAX
" exceeds %u", d
, td
->objects
->dim
);
1826 Object
*o
= (Object
*)td
->objects
->data
[(size_t)d
];
1827 if (o
->dyncast() == DYNCAST_DSYMBOL
)
1832 if (o
->dyncast() == DYNCAST_EXPRESSION
)
1835 *pe
= (Expression
*)o
;
1839 /* Create a new TupleDeclaration which
1840 * is a slice [d..d+1] out of the old one.
1841 * Do it this way because TemplateInstance::semanticTiargs()
1842 * can handle unresolved Objects this way.
1844 Objects
*objects
= new Objects
;
1846 objects
->data
[0] = o
;
1848 TupleDeclaration
*tds
= new TupleDeclaration(loc
, td
->ident
, objects
);
1857 Type::resolve(loc
, sc
, pe
, pt
, ps
);
1861 Type
*TypeSArray::semantic(Loc loc
, Scope
*sc
)
1863 //printf("TypeSArray::semantic() %s\n", toChars());
1868 next
->resolve(loc
, sc
, &e
, &t
, &s
);
1869 if (dim
&& s
&& s
->isTupleDeclaration())
1870 { TupleDeclaration
*sd
= s
->isTupleDeclaration();
1872 dim
= semanticLength(sc
, sd
, dim
);
1873 dim
= dim
->optimize(WANTvalue
| WANTinterpret
);
1874 uinteger_t d
= dim
->toUInteger();
1876 if (d
>= sd
->objects
->dim
)
1877 { error(loc
, "tuple index %ju exceeds %u", d
, sd
->objects
->dim
);
1878 return Type::terror
;
1880 Object
*o
= (Object
*)sd
->objects
->data
[(size_t)d
];
1881 if (o
->dyncast() != DYNCAST_TYPE
)
1882 { error(loc
, "%s is not a type", toChars());
1883 return Type::terror
;
1889 next
= next
->semantic(loc
,sc
);
1890 Type
*tbn
= next
->toBasetype();
1895 dim
= semanticLength(sc
, tbn
, dim
);
1897 dim
= dim
->optimize(WANTvalue
| WANTinterpret
);
1898 if (sc
->parameterSpecialization
&& dim
->op
== TOKvar
&&
1899 ((VarExp
*)dim
)->var
->storage_class
& STCtemplateparameter
)
1901 /* It could be a template parameter N which has no value yet:
1902 * template Foo(T : T[N], size_t N);
1906 integer_t d1
= dim
->toInteger();
1907 dim
= dim
->castTo(sc
, tsize_t
);
1908 dim
= dim
->optimize(WANTvalue
);
1909 integer_t d2
= dim
->toInteger();
1914 if (tbn
->isintegral() ||
1915 tbn
->isfloating() ||
1916 tbn
->ty
== Tpointer
||
1917 tbn
->ty
== Tarray
||
1918 tbn
->ty
== Tsarray
||
1919 tbn
->ty
== Taarray
||
1922 /* Only do this for types that don't need to have semantic()
1923 * run on them for the size, since they may be forward referenced.
1929 if (n2
>= 0x1000000) // put a 'reasonable' limit on it
1931 if (n
&& n2
/ n
!= d2
)
1934 error(loc
, "index %"PRIdMAX
" overflow for static array", d1
);
1935 dim
= new IntegerExp(0, 1, tsize_t
);
1942 { // Index the tuple to get the type
1944 TypeTuple
*tt
= (TypeTuple
*)tbn
;
1945 uinteger_t d
= dim
->toUInteger();
1947 if (d
>= tt
->arguments
->dim
)
1948 { error(loc
, "tuple index %"PRIuMAX
" exceeds %u", d
, tt
->arguments
->dim
);
1949 return Type::terror
;
1951 Argument
*arg
= (Argument
*)tt
->arguments
->data
[(size_t)d
];
1956 error(loc
, "can't have array of %s", tbn
->toChars());
1957 tbn
= next
= tint32
;
1961 error(loc
, "cannot have array of auto %s", tbn
->toChars());
1965 void TypeSArray::toDecoBuffer(OutBuffer
*buf
)
1967 buf
->writeByte(mangleChar
[ty
]);
1969 buf
->printf("%"PRIuMAX
, dim
->toInteger());
1971 next
->toDecoBuffer(buf
);
1974 void TypeSArray::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
1976 if (mod
!= this->mod
)
1977 { toCBuffer3(buf
, hgs
, mod
);
1980 next
->toCBuffer2(buf
, hgs
, this->mod
);
1981 buf
->printf("[%s]", dim
->toChars());
1984 Expression
*TypeSArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
1987 printf("TypeSArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
1989 if (ident
== Id::length
)
1993 else if (ident
== Id::ptr
)
1995 e
= e
->castTo(sc
, next
->pointerTo());
1999 e
= TypeArray::dotExp(sc
, e
, ident
);
2004 int TypeSArray::isString()
2006 TY nty
= next
->toBasetype()->ty
;
2007 return nty
== Tchar
|| nty
== Twchar
|| nty
== Tdchar
;
2010 unsigned TypeSArray::memalign(unsigned salign
)
2012 return next
->memalign(salign
);
2015 MATCH
TypeSArray::implicitConvTo(Type
*to
)
2017 //printf("TypeSArray::implicitConvTo()\n");
2019 if (to
->ty
== Tmaybe
&& to
->next
)
2022 // Allow implicit conversion of static array to pointer or dynamic array
2023 if ((IMPLICIT_ARRAY_TO_PTR
&& to
->ty
== Tpointer
) &&
2024 (to
->next
->ty
== Tvoid
|| next
->equals(to
->next
)
2025 /*|| to->next->isBaseOf(next)*/))
2027 return MATCHconvert
;
2029 if (to
->ty
== Tarray
)
2030 { target_ptrdiff_t offset
= 0;
2032 if (next
->equals(to
->next
) ||
2033 (to
->next
->isBaseOf(next
, &offset
) && offset
== 0) ||
2034 to
->next
->ty
== Tvoid
)
2035 return MATCHconvert
;
2038 if (to
->ty
== Tsarray
)
2040 TypeSArray
*tsa
= (TypeSArray
*)to
;
2042 if (next
->equals(tsa
->next
) && dim
->equals(tsa
->dim
))
2044 return MATCHconvert
;
2048 return Type::implicitConvTo(to
);
2051 Expression
*TypeSArray::defaultInit(Loc loc
)
2054 printf("TypeSArray::defaultInit() '%s'\n", toChars());
2056 return next
->defaultInit(loc
);
2059 int TypeSArray::isZeroInit()
2061 return next
->isZeroInit();
2065 Expression
*TypeSArray::toExpression()
2067 Expression
*e
= next
->toExpression();
2069 { Expressions
*arguments
= new Expressions();
2070 arguments
->push(dim
);
2071 e
= new ArrayExp(dim
->loc
, e
, arguments
);
2076 int TypeSArray::hasPointers()
2078 return next
->hasPointers();
2081 /***************************** TypeDArray *****************************/
2083 TypeDArray::TypeDArray(Type
*t
)
2084 : TypeArray(Tarray
, t
)
2086 //printf("TypeDArray(t = %p)\n", t);
2089 Type
*TypeDArray::syntaxCopy()
2091 Type
*t
= next
->syntaxCopy();
2095 t
= new TypeDArray(t
);
2099 d_uns64
TypeDArray::size(Loc loc
)
2101 //printf("TypeDArray::size()\n");
2105 unsigned TypeDArray::alignsize()
2107 // A DArray consists of two ptr-sized values, so align it on pointer size
2112 Type
*TypeDArray::semantic(Loc loc
, Scope
*sc
)
2115 tn
= next
->semantic(loc
,sc
);
2116 Type
*tbn
= tn
->toBasetype();
2122 error(loc
, "can't have array of %s", tbn
->toChars());
2127 error(loc
, "cannot have array of auto %s", tn
->toChars());
2129 //deco = NULL; // redo
2130 return tn
->arrayOf();
2134 void TypeDArray::toDecoBuffer(OutBuffer
*buf
)
2136 buf
->writeByte(mangleChar
[ty
]);
2138 next
->toDecoBuffer(buf
);
2141 void TypeDArray::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2143 if (mod
!= this->mod
)
2144 { toCBuffer3(buf
, hgs
, mod
);
2147 next
->toCBuffer2(buf
, hgs
, this->mod
);
2148 buf
->writestring("[]");
2151 Expression
*TypeDArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2154 printf("TypeDArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
2156 if (ident
== Id::length
)
2158 if (e
->op
== TOKstring
)
2159 { StringExp
*se
= (StringExp
*)e
;
2161 return new IntegerExp(se
->loc
, se
->len
, Type::tindex
);
2163 e
= new ArrayLengthExp(e
->loc
, e
);
2164 e
->type
= Type::tsize_t
;
2167 else if (ident
== Id::ptr
)
2169 e
= e
->castTo(sc
, next
->pointerTo()->maybe());
2174 e
= TypeArray::dotExp(sc
, e
, ident
);
2179 int TypeDArray::isString()
2181 TY nty
= next
->toBasetype()->ty
;
2182 return nty
== Tchar
|| nty
== Twchar
|| nty
== Tdchar
;
2185 MATCH
TypeDArray::implicitConvTo(Type
*to
)
2187 //printf("TypeDArray::implicitConvTo()\n");
2189 if (to
->ty
== Tmaybe
&& to
->next
)
2192 // Allow implicit conversion of array to pointer
2193 if (IMPLICIT_ARRAY_TO_PTR
&&
2194 to
->ty
== Tpointer
&&
2195 (to
->next
->ty
== Tvoid
|| next
->equals(to
->next
) /*|| to->next->isBaseOf(next)*/))
2197 return MATCHconvert
;
2200 if (to
->ty
== Tarray
)
2201 { target_ptrdiff_t offset
= 0;
2203 if ((to
->next
->isBaseOf(next
, &offset
) && offset
== 0) ||
2204 to
->next
->ty
== Tvoid
)
2205 return MATCHconvert
;
2207 return Type::implicitConvTo(to
);
2210 Expression
*TypeDArray::defaultInit(Loc loc
)
2213 printf("TypeDArray::defaultInit() '%s'\n", toChars());
2216 e
= new NullExp(loc
);
2221 int TypeDArray::isZeroInit()
2226 int TypeDArray::checkBoolean()
2231 int TypeDArray::hasPointers()
2236 /***************************** TypeAArray *****************************/
2238 TypeAArray::TypeAArray(Type
*t
, Type
*index
)
2239 : TypeArray(Taarray
, t
)
2241 this->index
= index
;
2245 Type
*TypeAArray::syntaxCopy()
2247 Type
*t
= next
->syntaxCopy();
2248 Type
*ti
= index
->syntaxCopy();
2249 if (t
== next
&& ti
== index
)
2252 t
= new TypeAArray(t
, ti
);
2256 d_uns64
TypeAArray::size(Loc loc
)
2258 return PTRSIZE
/* * 2*/;
2262 Type
*TypeAArray::semantic(Loc loc
, Scope
*sc
)
2264 //printf("TypeAArray::semantic() %s index->ty = %d\n", toChars(), index->ty);
2266 // Deal with the case where we thought the index was a type, but
2267 // in reality it was an expression.
2268 if (index
->ty
== Tident
|| index
->ty
== Tinstance
|| index
->ty
== Tsarray
)
2274 index
->resolve(loc
, sc
, &e
, &t
, &s
);
2276 { // It was an expression -
2277 // Rewrite as a static array
2280 tsa
= new TypeSArray(next
, e
);
2281 return tsa
->semantic(loc
,sc
);
2286 index
->error(loc
, "index is not a type or an expression");
2289 index
= index
->semantic(loc
,sc
);
2291 // Compute key type; the purpose of the key type is to
2292 // minimize the permutations of runtime library
2293 // routines as much as possible.
2294 key
= index
->toBasetype();
2308 // Convert to Tarray
2309 key
= key
->next
->arrayOf();
2317 error(loc
, "can't have associative array key of %s", key
->toChars());
2320 next
= next
->semantic(loc
,sc
);
2321 switch (next
->toBasetype()->ty
)
2325 error(loc
, "can't have associative array of %s", next
->toChars());
2329 error(loc
, "cannot have array of auto %s", next
->toChars());
2334 void TypeAArray::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
2336 //printf("TypeAArray::resolve() %s\n", toChars());
2338 // Deal with the case where we thought the index was a type, but
2339 // in reality it was an expression.
2340 if (index
->ty
== Tident
|| index
->ty
== Tinstance
|| index
->ty
== Tsarray
)
2346 index
->resolve(loc
, sc
, &e
, &t
, &s
);
2348 { // It was an expression -
2349 // Rewrite as a static array
2351 TypeSArray
*tsa
= new TypeSArray(next
, e
);
2352 return tsa
->resolve(loc
, sc
, pe
, pt
, ps
);
2357 index
->error(loc
, "index is not a type or an expression");
2359 Type::resolve(loc
, sc
, pe
, pt
, ps
);
2363 Expression
*TypeAArray::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2366 printf("TypeAArray::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
2368 if (ident
== Id::length
)
2371 FuncDeclaration
*fd
;
2372 Expressions
*arguments
;
2374 fd
= FuncDeclaration::genCfunc(Type::tsize_t
, Id::aaLen
, Type::tvoid
->arrayOf());
2375 ec
= new VarExp(0, fd
);
2376 arguments
= new Expressions();
2378 e
= new CallExp(e
->loc
, ec
, arguments
);
2379 e
->type
= fd
->type
->next
;
2381 else if (ident
== Id::keys
)
2384 FuncDeclaration
*fd
;
2385 Expressions
*arguments
;
2386 int size
= key
->size(e
->loc
);
2389 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::aaKeys
,
2390 Type::tvoid
->arrayOf(), Type::tsize_t
);
2391 ec
= new VarExp(0, fd
);
2392 arguments
= new Expressions();
2394 arguments
->push(new IntegerExp(0, size
, Type::tsize_t
));
2395 e
= new CallExp(e
->loc
, ec
, arguments
);
2396 e
->type
= index
->arrayOf();
2398 else if (ident
== Id::values
)
2401 FuncDeclaration
*fd
;
2402 Expressions
*arguments
;
2404 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::aaValues
,
2405 Type::tvoid
->arrayOf(), Type::tsize_t
, Type::tsize_t
);
2406 ec
= new VarExp(0, fd
);
2407 arguments
= new Expressions();
2409 size_t keysize
= key
->size(e
->loc
);
2410 keysize
= (keysize
+ (PTRSIZE
-1)) & ~(PTRSIZE
-1);
2411 arguments
->push(new IntegerExp(0, keysize
, Type::tsize_t
));
2412 arguments
->push(new IntegerExp(0, next
->size(e
->loc
), Type::tsize_t
));
2413 e
= new CallExp(e
->loc
, ec
, arguments
);
2414 e
->type
= next
->arrayOf();
2416 else if (ident
== Id::rehash
)
2419 FuncDeclaration
*fd
;
2420 Expressions
*arguments
;
2422 fd
= FuncDeclaration::genCfunc(Type::tvoid
->arrayOf(), Id::aaRehash
);
2423 ec
= new VarExp(0, fd
);
2424 arguments
= new Expressions();
2425 arguments
->push(e
->addressOf(sc
));
2426 arguments
->push(key
->getInternalTypeInfo(sc
));
2427 e
= new CallExp(e
->loc
, ec
, arguments
);
2432 e
= Type::dotExp(sc
, e
, ident
);
2437 void TypeAArray::toDecoBuffer(OutBuffer
*buf
)
2439 buf
->writeByte(mangleChar
[ty
]);
2440 index
->toDecoBuffer(buf
);
2441 next
->toDecoBuffer(buf
);
2444 void TypeAArray::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2446 if (mod
!= this->mod
)
2447 { toCBuffer3(buf
, hgs
, mod
);
2450 next
->toCBuffer2(buf
, hgs
, this->mod
);
2451 buf
->writeByte('[');
2452 index
->toCBuffer2(buf
, hgs
, 0);
2453 buf
->writeByte(']');
2456 Expression
*TypeAArray::defaultInit(Loc loc
)
2459 printf("TypeAArray::defaultInit() '%s'\n", toChars());
2462 e
= new NullExp(loc
);
2467 int TypeAArray::checkBoolean()
2472 int TypeAArray::hasPointers()
2477 /***************************** TypeMaybe *****************************/
2479 TypeMaybe::TypeMaybe(Type
*t
)
2484 void TypeMaybe::toDecoBuffer(OutBuffer
*buf
)
2486 int offset
= buf
->offset
;
2488 // Since all D types are TypeMaybe, adding a char here
2489 // would prevent linking to existing libraries.
2490 next
->toDecoBuffer(buf
);
2492 if (buf
->data
[offset
] == NOT_NULL_MANGLE
)
2493 buf
->remove(offset
, 1); // After semantic: remove not-null qualifier
2495 buf
->insert(offset
, "?", 1); // Before semantic: just make name unique
2498 Type
*TypeMaybe::syntaxCopy()
2500 Type
*t
= next
->syntaxCopy();
2504 t
= new TypeMaybe(t
);
2508 Type
*TypeMaybe::toBasetype()
2510 return next
->toBasetype();
2513 Expression
*TypeMaybe::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2515 if (sc
->module
->isDltFile
)
2516 e
->error("Attempt to access property '%s' for '%s' of type '%s', which may be null.",
2517 ident
->string
, e
->toChars(), toChars());
2518 // else it came from D - ignore any problems since we can't check
2519 return next
->dotExp(sc
, e
, ident
);
2522 Type
*TypeMaybe::semantic(Loc loc
, Scope
*sc
)
2524 //printf("TypeMaybe::semantic()\n");
2525 Type
*n
= next
->semantic(loc
, sc
);
2527 // For D source we don't know if it's a maybe type or not, so the parser
2528 // wraps everything in a TypeMaybe (including structs, etc, since it can't
2529 // tell). If the next type can't be null, we vanish here.
2533 if (n
->next
->ty
== Tvoid
)
2539 error(loc
, "can't have maybe for %s of type %d", n
->toChars(), n
->toBasetype()->ty
);
2548 d_uns64
TypeMaybe::size(Loc loc
)
2550 return next
->size();
2553 void TypeMaybe::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2555 //printf("TypeMaybe::toCBuffer2() next = %d\n", next->ty);
2556 if (mod
!= this->mod
)
2557 { toCBuffer3(buf
, hgs
, mod
);
2560 next
->toCBuffer2(buf
, hgs
, this->mod
);
2561 buf
->writeByte('?');
2564 MATCH
TypeMaybe::implicitConvTo(Type
*to
)
2566 //printf("TypeMaybe::implicitConvTo(%s)\n", to->toChars());
2571 return MATCHnomatch
;
2574 int TypeMaybe::isscalar()
2576 return next
->isscalar();
2579 Expression
*TypeMaybe::defaultInit(Loc loc
)
2582 printf("TypeMaybe::defaultInit() '%s'\n", toChars());
2584 return next
->defaultInit();
2587 int TypeMaybe::isZeroInit()
2589 return next
->isZeroInit();
2592 int TypeMaybe::hasPointers()
2594 return next
->hasPointers();
2597 /***************************** TypePointer *****************************/
2599 TypePointer::TypePointer(Type
*t
)
2604 Type
*TypePointer::syntaxCopy()
2606 Type
*t
= next
->syntaxCopy();
2610 t
= new TypePointer(t
);
2614 Type
*TypePointer::semantic(Loc loc
, Scope
*sc
)
2616 //printf("TypePointer::semantic()\n");
2617 Type
*n
= next
->semantic(loc
, sc
);
2618 switch (n
->toBasetype()->ty
)
2621 error(loc
, "can't have pointer to %s", n
->toChars());
2632 d_uns64
TypePointer::size(Loc loc
)
2637 void TypePointer::toDecoBuffer(OutBuffer
*buf
)
2639 buf
->writeByte(NOT_NULL_MANGLE
);
2640 Type::toDecoBuffer(buf
);
2643 void TypePointer::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2645 //printf("TypePointer::toCBuffer2() next = %d\n", next->ty);
2646 if (mod
!= this->mod
)
2647 { toCBuffer3(buf
, hgs
, mod
);
2650 next
->toCBuffer2(buf
, hgs
, this->mod
);
2651 if (next
->ty
!= Tfunction
)
2652 buf
->writeByte('*');
2655 MATCH
TypePointer::implicitConvTo(Type
*to
)
2657 //printf("TypePointer::implicitConvTo()\n");
2659 // Can always convert a "Foo*" to a "Foo*?"
2660 if (to
->ty
== Tmaybe
&& to
->next
)
2665 if (to
->ty
== Tpointer
&& to
->next
)
2667 if (to
->next
->ty
== Tvoid
)
2668 return MATCHconvert
;
2671 if (to
->next
->isBaseOf(next
))
2672 return MATCHconvert
;
2675 if (next
->ty
== Tfunction
&& to
->next
->ty
== Tfunction
)
2679 tf
= (TypeFunction
*)(next
);
2680 tfto
= (TypeFunction
*)(to
->next
);
2681 return tfto
->equals(tf
) ? MATCHexact
: MATCHnomatch
;
2684 // if (to->ty == Tvoid)
2685 // return MATCHconvert;
2686 return MATCHnomatch
;
2689 int TypePointer::isscalar()
2694 Expression
*TypePointer::defaultInit(Loc loc
)
2697 printf("TypePointer::defaultInit() '%s'\n", toChars());
2700 e
= new NullExp(loc
);
2705 int TypePointer::isZeroInit()
2710 int TypePointer::hasPointers()
2716 /***************************** TypeReference *****************************/
2718 TypeReference::TypeReference(Type
*t
)
2719 : Type(Treference
, t
)
2722 error(0,"cannot make reference to a bit");
2723 // BUG: what about references to static arrays?
2726 Type
*TypeReference::syntaxCopy()
2728 Type
*t
= next
->syntaxCopy();
2732 t
= new TypeReference(t
);
2736 d_uns64
TypeReference::size(Loc loc
)
2741 void TypeReference::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2743 if (mod
!= this->mod
)
2744 { toCBuffer3(buf
, hgs
, mod
);
2747 next
->toCBuffer2(buf
, hgs
, this->mod
);
2748 buf
->writeByte('&');
2751 Expression
*TypeReference::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
2754 printf("TypeReference::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
2757 // References just forward things along
2758 return next
->dotExp(sc
, e
, ident
);
2761 Expression
*TypeReference::defaultInit(Loc loc
)
2764 printf("TypeReference::defaultInit() '%s'\n", toChars());
2767 e
= new NullExp(loc
);
2772 int TypeReference::isZeroInit()
2778 /***************************** TypeFunction *****************************/
2780 TypeFunction::TypeFunction(Arguments
*parameters
, Type
*treturn
, int varargs
, enum LINK linkage
)
2781 : Type(Tfunction
, treturn
)
2783 //if (!treturn) *(char*)0=0;
2785 this->parameters
= parameters
;
2786 this->varargs
= varargs
;
2787 this->linkage
= linkage
;
2791 Type
*TypeFunction::syntaxCopy()
2793 Type
*treturn
= next
? next
->syntaxCopy() : NULL
;
2794 Arguments
*params
= Argument::arraySyntaxCopy(parameters
);
2795 Type
*t
= new TypeFunction(params
, treturn
, varargs
, linkage
);
2799 /*******************************
2801 * 0 types are distinct
2802 * 1 this is covariant with t
2803 * 2 arguments match as far as overloading goes,
2804 * but types are not covariant
2805 * 3 cannot determine covariance because of forward references
2808 int Type::covariant(Type
*t
)
2811 printf("Type::covariant(t = %s) %s\n", t
->toChars(), toChars());
2812 printf("deco = %p, %p\n", deco
, t
->deco
);
2813 printf("ty = %d\n", next
->ty
);
2816 int inoutmismatch
= 0;
2820 if (ty
!= Tfunction
|| t
->ty
!= Tfunction
)
2824 TypeFunction
*t1
= (TypeFunction
*)this;
2825 TypeFunction
*t2
= (TypeFunction
*)t
;
2827 if (t1
->varargs
!= t2
->varargs
)
2830 if (t1
->parameters
&& t2
->parameters
)
2832 size_t dim
= Argument::dim(t1
->parameters
);
2833 if (dim
!= Argument::dim(t2
->parameters
))
2836 for (size_t i
= 0; i
< dim
; i
++)
2837 { Argument
*arg1
= Argument::getNth(t1
->parameters
, i
);
2838 Argument
*arg2
= Argument::getNth(t2
->parameters
, i
);
2840 if (!arg1
->type
->equals(arg2
->type
))
2842 if (arg1
->storageClass
!= arg2
->storageClass
)
2846 else if (t1
->parameters
!= t2
->parameters
)
2849 // The argument lists match
2852 if (t1
->linkage
!= t2
->linkage
)
2855 Type
*t1n
= t1
->next
;
2856 Type
*t2n
= t2
->next
;
2858 if (t1n
->equals(t2n
))
2860 if (t1n
->ty
!= Tclass
|| t2n
->ty
!= Tclass
)
2863 // If t1n is forward referenced:
2864 ClassDeclaration
*cd
= ((TypeClass
*)t1n
)->sym
;
2865 if (!cd
->baseClass
&& cd
->baseclasses
.dim
&& !cd
->isInterfaceDeclaration())
2870 if (t1n
->implicitConvTo(t2n
))
2876 //printf("\tcovaraint: 1\n");
2880 //printf("\tcovaraint: 0\n");
2884 //printf("\tcovaraint: 2\n");
2888 void TypeFunction::toDecoBuffer(OutBuffer
*buf
)
2891 //printf("TypeFunction::toDecoBuffer() this = %p %s\n", this, toChars());
2892 //static int nest; if (++nest == 50) *(char*)0=0;
2894 { inuse
= 2; // flag error to caller
2900 case LINKd
: mc
= 'F'; break;
2901 case LINKc
: mc
= 'U'; break;
2902 case LINKwindows
: mc
= 'W'; break;
2903 case LINKpascal
: mc
= 'V'; break;
2904 case LINKcpp
: mc
= 'R'; break;
2909 // Write argument types
2910 Argument::argsToDecoBuffer(buf
, parameters
);
2911 //if (buf->data[buf->offset - 1] == '@') halt();
2912 buf
->writeByte('Z' - varargs
); // mark end of arg list
2913 next
->toDecoBuffer(buf
);
2917 void TypeFunction::toCBuffer(OutBuffer
*buf
, Identifier
*ident
, HdrGenState
*hgs
)
2922 { inuse
= 2; // flag error to caller
2926 if (next
&& (!ident
|| ident
->toHChars2() == ident
->toChars()))
2927 next
->toCBuffer2(buf
, hgs
, 0);
2932 case LINKd
: p
= NULL
; break;
2933 case LINKc
: p
= "C "; break;
2934 case LINKwindows
: p
= "Windows "; break;
2935 case LINKpascal
: p
= "Pascal "; break;
2936 case LINKcpp
: p
= "C++ "; break;
2942 if (!hgs
->hdrgen
&& p
)
2943 buf
->writestring(p
);
2945 { buf
->writeByte(' ');
2946 buf
->writestring(ident
->toHChars2());
2948 Argument::argsToCBuffer(buf
, hgs
, parameters
, varargs
);
2952 void TypeFunction::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
2957 { inuse
= 2; // flag error to caller
2962 next
->toCBuffer2(buf
, hgs
, 0);
2967 case LINKd
: p
= NULL
; break;
2968 case LINKc
: p
= "C "; break;
2969 case LINKwindows
: p
= "Windows "; break;
2970 case LINKpascal
: p
= "Pascal "; break;
2971 case LINKcpp
: p
= "C++ "; break;
2977 if (!hgs
->hdrgen
&& p
)
2978 buf
->writestring(p
);
2979 buf
->writestring(" function");
2980 Argument::argsToCBuffer(buf
, hgs
, parameters
, varargs
);
2984 Type
*TypeFunction::semantic(Loc loc
, Scope
*sc
)
2986 if (deco
) // if semantic() already run
2988 //printf("already done\n");
2991 //printf("TypeFunction::semantic() this = %p\n", this);
2993 TypeFunction
*tf
= (TypeFunction
*)mem
.malloc(sizeof(TypeFunction
));
2994 memcpy(tf
, this, sizeof(TypeFunction
));
2996 { tf
->parameters
= (Arguments
*)parameters
->copy();
2997 for (size_t i
= 0; i
< parameters
->dim
; i
++)
2998 { Argument
*arg
= (Argument
*)parameters
->data
[i
];
2999 Argument
*cpy
= (Argument
*)mem
.malloc(sizeof(Argument
));
3000 memcpy(cpy
, arg
, sizeof(Argument
));
3001 tf
->parameters
->data
[i
] = (void *)cpy
;
3005 tf
->linkage
= sc
->linkage
;
3008 assert(global
.errors
);
3011 tf
->next
= tf
->next
->semantic(loc
,sc
);
3012 if (tf
->next
->toBasetype()->ty
== Tsarray
)
3013 { error(loc
, "functions cannot return static array %s", tf
->next
->toChars());
3014 tf
->next
= Type::terror
;
3016 if (tf
->next
->toBasetype()->ty
== Tfunction
)
3017 { error(loc
, "functions cannot return a function");
3018 tf
->next
= Type::terror
;
3020 if (tf
->next
->toBasetype()->ty
== Ttuple
)
3021 { error(loc
, "functions cannot return a tuple");
3022 tf
->next
= Type::terror
;
3024 if (tf
->next
->isauto() && !(sc
->flags
& SCOPEctor
))
3025 error(loc
, "functions cannot return auto %s", tf
->next
->toChars());
3028 { size_t dim
= Argument::dim(tf
->parameters
);
3030 for (size_t i
= 0; i
< dim
; i
++)
3031 { Argument
*arg
= Argument::getNth(tf
->parameters
, i
);
3035 arg
->type
= arg
->type
->semantic(loc
,sc
);
3036 if (tf
->inuse
== 1) tf
->inuse
--;
3037 t
= arg
->type
->toBasetype();
3039 if (arg
->storageClass
& (STCout
| STCref
| STClazy
))
3041 if (t
->ty
== Tsarray
)
3042 error(loc
, "cannot have out or ref parameter of type %s", t
->toChars());
3044 if (!(arg
->storageClass
& STClazy
) && t
->ty
== Tvoid
)
3045 error(loc
, "cannot have parameter of type %s", arg
->type
->toChars());
3047 if (arg
->defaultArg
)
3049 arg
->defaultArg
= arg
->defaultArg
->semantic(sc
);
3050 arg
->defaultArg
= resolveProperties(sc
, arg
->defaultArg
);
3051 arg
->defaultArg
= arg
->defaultArg
->implicitCastTo(sc
, arg
->type
);
3054 /* If arg turns out to be a tuple, the number of parameters may
3057 if (t
->ty
== Ttuple
)
3058 { dim
= Argument::dim(tf
->parameters
);
3063 tf
->deco
= tf
->merge()->deco
;
3066 { error(loc
, "recursive type");
3071 if (tf
->varargs
== 1 && tf
->linkage
!= LINKd
&& Argument::dim(tf
->parameters
) == 0)
3072 error(loc
, "variadic functions with non-D linkage must have at least one parameter");
3074 /* Don't return merge(), because arg identifiers and default args
3076 * even though the types match
3081 /********************************
3082 * 'args' are being matched to function 'this'
3083 * Determine match level.
3088 int TypeFunction::callMatch(Expressions
*args
)
3090 //printf("TypeFunction::callMatch()\n");
3091 int match
= MATCHexact
; // assume exact match
3093 size_t nparams
= Argument::dim(parameters
);
3094 size_t nargs
= args
? args
->dim
: 0;
3095 if (nparams
== nargs
)
3097 else if (nargs
> nparams
)
3100 goto Nomatch
; // too many args; no match
3101 match
= MATCHconvert
; // match ... with a "conversion" match level
3104 for (size_t u
= 0; u
< nparams
; u
++)
3108 // BUG: what about out and ref?
3110 Argument
*p
= Argument::getNth(parameters
, u
);
3116 if (varargs
== 2 && u
+ 1 == nparams
)
3118 goto Nomatch
; // not enough arguments
3120 arg
= (Expression
*)args
->data
[u
];
3122 if (p
->storageClass
& STClazy
&& p
->type
->ty
== Tvoid
&& arg
->type
->ty
!= Tvoid
)
3125 m
= arg
->implicitConvTo(p
->type
);
3126 //printf("\tm = %d\n", m);
3127 if (m
== MATCHnomatch
) // if no match
3130 if (varargs
== 2 && u
+ 1 == nparams
) // if last varargs param
3131 { Type
*tb
= p
->type
->toBasetype();
3138 tsa
= (TypeSArray
*)tb
;
3139 sz
= tsa
->dim
->toInteger();
3140 if (sz
!= nargs
- u
)
3143 for (; u
< nargs
; u
++)
3145 arg
= (Expression
*)args
->data
[u
];
3148 /* If lazy array of delegates,
3149 * convert arg(s) to delegate(s)
3151 Type
*tret
= p
->isLazyArray();
3154 if (tb
->next
->equals(arg
->type
))
3159 m
= arg
->implicitConvTo(tret
);
3160 if (m
== MATCHnomatch
)
3162 if (tret
->toBasetype()->ty
== Tvoid
)
3168 m
= arg
->implicitConvTo(tb
->next
);
3170 m
= arg
->implicitConvTo(tb
->next
);
3180 // Should see if there's a constructor match?
3181 // Or just leave it ambiguous?
3191 match
= m
; // pick worst match
3195 //printf("match = %d\n", match);
3199 //printf("no match\n");
3200 return MATCHnomatch
;
3203 Type
*TypeFunction::reliesOnTident()
3207 for (size_t i
= 0; i
< parameters
->dim
; i
++)
3208 { Argument
*arg
= (Argument
*)parameters
->data
[i
];
3209 Type
*t
= arg
->type
->reliesOnTident();
3214 return next
->reliesOnTident();
3217 /***************************** TypeDelegate *****************************/
3219 TypeDelegate::TypeDelegate(Type
*t
)
3220 : Type(Tfunction
, t
)
3225 Type
*TypeDelegate::syntaxCopy()
3227 Type
*t
= next
->syntaxCopy();
3231 t
= new TypeDelegate(t
);
3235 Type
*TypeDelegate::semantic(Loc loc
, Scope
*sc
)
3237 if (deco
) // if semantic() already run
3239 //printf("already done\n");
3242 next
= next
->semantic(loc
,sc
);
3246 d_uns64
TypeDelegate::size(Loc loc
)
3251 void TypeDelegate::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3253 if (mod
!= this->mod
)
3254 { toCBuffer3(buf
, hgs
, mod
);
3257 TypeFunction
*tf
= (TypeFunction
*)next
;
3259 tf
->next
->toCBuffer2(buf
, hgs
, 0);
3260 buf
->writestring(" delegate");
3261 Argument::argsToCBuffer(buf
, hgs
, tf
->parameters
, tf
->varargs
);
3264 Expression
*TypeDelegate::defaultInit(Loc loc
)
3267 printf("TypeDelegate::defaultInit() '%s'\n", toChars());
3270 e
= new NullExp(loc
);
3275 int TypeDelegate::isZeroInit()
3280 int TypeDelegate::checkBoolean()
3285 Expression
*TypeDelegate::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
3288 printf("TypeDelegate::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
3290 if (ident
== Id::ptr
)
3295 if (e
->op
== TOKdelegate
|| e
->op
== TOKcast
)
3296 e
= e
->castTo(sc
, tvoidptr
); // Not an lvalue
3299 e
= e
->addressOf(sc
);
3300 e
= e
->castTo(sc
, tvoidptr
->pointerTo());
3301 e
= new PtrExp(e
->loc
, e
);
3307 else if (ident
== Id::funcptr
)
3309 e
= e
->addressOf(sc
);
3311 e
= new AddExp(e
->loc
, e
, new IntegerExp(PTRSIZE
));
3313 e
= new PtrExp(e
->loc
, e
);
3314 e
->type
= next
->pointerTo();
3319 e
= Type::dotExp(sc
, e
, ident
);
3324 int TypeDelegate::hasPointers()
3331 /***************************** TypeQualified *****************************/
3333 TypeQualified::TypeQualified(TY ty
, Loc loc
)
3339 void TypeQualified::syntaxCopyHelper(TypeQualified
*t
)
3341 //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars());
3342 idents
.setDim(t
->idents
.dim
);
3343 for (int i
= 0; i
< idents
.dim
; i
++)
3345 Identifier
*id
= (Identifier
*)t
->idents
.data
[i
];
3346 if (id
->dyncast() == DYNCAST_DSYMBOL
)
3348 TemplateInstance
*ti
= (TemplateInstance
*)id
;
3350 ti
= (TemplateInstance
*)ti
->syntaxCopy(NULL
);
3351 id
= (Identifier
*)ti
;
3353 idents
.data
[i
] = id
;
3358 void TypeQualified::addIdent(Identifier
*ident
)
3363 void TypeQualified::toCBuffer2Helper(OutBuffer
*buf
, HdrGenState
*hgs
)
3367 for (i
= 0; i
< idents
.dim
; i
++)
3368 { Identifier
*id
= (Identifier
*)idents
.data
[i
];
3370 buf
->writeByte('.');
3372 if (id
->dyncast() == DYNCAST_DSYMBOL
)
3374 TemplateInstance
*ti
= (TemplateInstance
*)id
;
3375 ti
->toCBuffer(buf
, hgs
);
3378 buf
->writestring(id
->toChars());
3382 d_uns64
TypeQualified::size(Loc loc
)
3384 error(this->loc
, "size of type %s is not known", toChars());
3388 /*************************************
3389 * Takes an array of Identifiers and figures out if
3390 * it represents a Type or an Expression.
3392 * if expression, *pe is set
3393 * if type, *pt is set
3396 void TypeQualified::resolveHelper(Loc loc
, Scope
*sc
,
3397 Dsymbol
*s
, Dsymbol
*scopesym
,
3398 Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
3400 Identifier
*id
= NULL
;
3404 TupleDeclaration
*td
;
3409 printf("TypeQualified::resolveHelper(sc = %p, idents = '%s')\n", sc
, toChars());
3411 printf("\tscopesym = '%s'\n", scopesym
->toChars());
3418 //printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
3420 //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
3421 for (i
= 0; i
< idents
.dim
; i
++)
3424 id
= (Identifier
*)idents
.data
[i
];
3425 sm
= s
->searchX(loc
, sc
, id
);
3426 //printf("\t3: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
3427 //printf("getType = '%s'\n", s->getType()->toChars());
3430 v
= s
->isVarDeclaration();
3431 if (v
&& id
== Id::length
)
3433 if (v
->isConst() && v
->getExpInitializer())
3434 { e
= v
->getExpInitializer()->exp
;
3437 e
= new VarExp(loc
, v
);
3444 if (!t
&& s
->isDeclaration())
3445 t
= s
->isDeclaration()->type
;
3448 sm
= t
->toDsymbol(sc
);
3450 { sm
= sm
->search(loc
, id
, 0);
3454 //e = t->getProperty(loc, id);
3455 e
= new TypeExp(loc
, t
);
3456 e
= t
->dotExp(sc
, e
, id
);
3459 for (; i
< idents
.dim
; i
++)
3461 id
= (Identifier
*)idents
.data
[i
];
3462 //printf("e: '%s', id: '%s', type = %p\n", e->toChars(), id->toChars(), e->type);
3463 e
= e
->type
->dotExp(sc
, e
, id
);
3469 error(loc
, "identifier '%s' of '%s' is not defined", id
->toChars(), toChars());
3476 v
= s
->isVarDeclaration();
3479 // It's not a type, it's an expression
3480 if (v
->isConst() && v
->getExpInitializer())
3482 ExpInitializer
*ei
= v
->getExpInitializer();
3484 *pe
= ei
->exp
->copy(); // make copy so we can change loc
3490 WithScopeSymbol
*withsym
;
3491 if (scopesym
&& (withsym
= scopesym
->isWithScopeSymbol()) != NULL
)
3493 // Same as wthis.ident
3494 e
= new VarExp(loc
, withsym
->withstate
->wthis
);
3495 e
= new DotIdExp(loc
, e
, ident
);
3496 //assert(0); // BUG: should handle this
3500 *pe
= new VarExp(loc
, v
);
3504 em
= s
->isEnumMember();
3507 // It's not a type, it's an expression
3508 *pe
= em
->value
->copy();
3516 // If the symbol is an import, try looking inside the import
3522 s
= si
->search(loc
, s
->ident
, 0);
3530 if (t
->ty
== Tinstance
&& t
!= this && !t
->deco
)
3531 { error(loc
, "forward reference to '%s'", t
->toChars());
3537 if (t
->reliesOnTident())
3541 for (scx
= sc
; 1; scx
= scx
->enclosing
)
3544 { error(loc
, "forward reference to '%s'", t
->toChars());
3547 if (scx
->scopesym
== scopesym
)
3550 t
= t
->semantic(loc
, scx
);
3551 //((TypeIdentifier *)t)->resolve(loc, scx, pe, &t, ps);
3554 if (t
->ty
== Ttuple
)
3561 error(loc
, "identifier '%s' is not defined", toChars());
3565 /***************************** TypeIdentifier *****************************/
3567 TypeIdentifier::TypeIdentifier(Loc loc
, Identifier
*ident
)
3568 : TypeQualified(Tident
, loc
)
3570 this->ident
= ident
;
3575 Type
*TypeIdentifier::syntaxCopy()
3579 t
= new TypeIdentifier(loc
, ident
);
3580 t
->syntaxCopyHelper(this);
3584 void TypeIdentifier::toDecoBuffer(OutBuffer
*buf
)
3588 name
= ident
->toChars();
3590 buf
->printf("%c%d%s", mangleChar
[ty
], len
, name
);
3591 //buf->printf("%c%s", mangleChar[ty], name);
3594 void TypeIdentifier::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3596 if (mod
!= this->mod
)
3597 { toCBuffer3(buf
, hgs
, mod
);
3600 buf
->writestring(this->ident
->toChars());
3601 toCBuffer2Helper(buf
, hgs
);
3604 /*************************************
3605 * Takes an array of Identifiers and figures out if
3606 * it represents a Type or an Expression.
3608 * if expression, *pe is set
3609 * if type, *pt is set
3612 void TypeIdentifier::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
3616 //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars());
3617 s
= sc
->search(loc
, ident
, &scopesym
);
3618 resolveHelper(loc
, sc
, s
, scopesym
, pe
, pt
, ps
);
3621 /*****************************************
3622 * See if type resolves to a symbol, if so,
3623 * return that symbol.
3626 Dsymbol
*TypeIdentifier::toDsymbol(Scope
*sc
)
3628 //printf("TypeIdentifier::toDsymbol('%s')\n", toChars());
3631 //printf("ident = '%s'\n", ident->toChars());
3634 Dsymbol
*s
= sc
->search(loc
, ident
, &scopesym
);
3637 for (int i
= 0; i
< idents
.dim
; i
++)
3639 Identifier
*id
= (Identifier
*)idents
.data
[i
];
3640 s
= s
->searchX(loc
, sc
, id
);
3641 if (!s
) // failed to find a symbol
3642 { //printf("\tdidn't find a symbol\n");
3650 Type
*TypeIdentifier::semantic(Loc loc
, Scope
*sc
)
3656 //printf("TypeIdentifier::semantic(%s)\n", toChars());
3657 resolve(loc
, sc
, &e
, &t
, &s
);
3660 //printf("\tit's a type %d, %s, %s\n", t->ty, t->toChars(), t->deco);
3662 if (t
->ty
== Ttypedef
)
3663 { TypeTypedef
*tt
= (TypeTypedef
*)t
;
3665 if (tt
->sym
->sem
== 1)
3666 error(loc
, "circular reference of typedef %s", tt
->toChars());
3668 // Do the delayed wrapping now we're sure it's a type
3670 return t
->maybe()->semantic(loc
, sc
);
3681 s
->error(loc
, "is used as a type");
3684 error(loc
, "%s is used as a type", toChars());
3691 Type
*TypeIdentifier::reliesOnTident()
3696 Expression
*TypeIdentifier::toExpression()
3698 Expression
*e
= new IdentifierExp(loc
, ident
);
3699 for (int i
= 0; i
< idents
.dim
; i
++)
3701 Identifier
*id
= (Identifier
*)idents
.data
[i
];
3702 e
= new DotIdExp(loc
, e
, id
);
3708 /***************************** TypeInstance *****************************/
3710 TypeInstance::TypeInstance(Loc loc
, TemplateInstance
*tempinst
)
3711 : TypeQualified(Tinstance
, loc
)
3713 this->tempinst
= tempinst
;
3716 Type
*TypeInstance::syntaxCopy()
3718 //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim);
3721 t
= new TypeInstance(loc
, (TemplateInstance
*)tempinst
->syntaxCopy(NULL
));
3722 t
->syntaxCopyHelper(this);
3727 void TypeInstance::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3729 if (mod
!= this->mod
)
3730 { toCBuffer3(buf
, hgs
, mod
);
3733 tempinst
->toCBuffer(buf
, hgs
);
3734 toCBuffer2Helper(buf
, hgs
);
3737 void TypeInstance::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
3739 // Note close similarity to TypeIdentifier::resolve()
3750 error(loc
, "template instance '%s' has no identifier", toChars());
3754 //id = (Identifier *)idents.data[0];
3755 //printf("TypeInstance::resolve(sc = %p, idents = '%s')\n", sc, id->toChars());
3759 resolveHelper(loc
, sc
, s
, NULL
, pe
, pt
, ps
);
3760 //printf("pt = '%s'\n", (*pt)->toChars());
3763 Type
*TypeInstance::semantic(Loc loc
, Scope
*sc
)
3769 //printf("TypeInstance::semantic(%s)\n", toChars());
3771 if (sc
->parameterSpecialization
)
3773 unsigned errors
= global
.errors
;
3776 resolve(loc
, sc
, &e
, &t
, &s
);
3779 if (errors
!= global
.errors
)
3780 { if (global
.gag
== 0)
3781 global
.errors
= errors
;
3786 resolve(loc
, sc
, &e
, &t
, &s
);
3793 error(loc
, "%s is used as a type", toChars());
3800 /***************************** TypeTypeof *****************************/
3802 TypeTypeof::TypeTypeof(Loc loc
, Expression
*exp
)
3803 : TypeQualified(Ttypeof
, loc
)
3808 Type
*TypeTypeof::syntaxCopy()
3812 t
= new TypeTypeof(loc
, exp
->syntaxCopy());
3813 t
->syntaxCopyHelper(this);
3817 Dsymbol
*TypeTypeof::toDsymbol(Scope
*sc
)
3821 t
= semantic(0, sc
);
3824 return t
->toDsymbol(sc
);
3827 void TypeTypeof::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
3829 if (mod
!= this->mod
)
3830 { toCBuffer3(buf
, hgs
, mod
);
3833 buf
->writestring("typeof(");
3834 exp
->toCBuffer(buf
, hgs
);
3835 buf
->writeByte(')');
3836 toCBuffer2Helper(buf
, hgs
);
3839 Type
*TypeTypeof::semantic(Loc loc
, Scope
*sc
)
3843 //printf("TypeTypeof::semantic() %p\n", this);
3845 //static int nest; if (++nest == 50) *(char*)0=0;
3848 /* Special case for typeof(this) and typeof(super) since both
3849 * should work even if they are not inside a non-static member function
3851 if (exp
->op
== TOKthis
|| exp
->op
== TOKsuper
)
3853 // Find enclosing struct or class
3854 for (Dsymbol
*s
= sc
->parent
; 1; s
= s
->parent
)
3856 ClassDeclaration
*cd
;
3857 StructDeclaration
*sd
;
3861 error(loc
, "%s is not in a struct or class scope", exp
->toChars());
3864 cd
= s
->isClassDeclaration();
3867 if (exp
->op
== TOKsuper
)
3871 { error(loc
, "class %s has no 'super'", s
->toChars());
3878 sd
= s
->isStructDeclaration();
3881 if (exp
->op
== TOKsuper
)
3883 error(loc
, "struct %s has no 'super'", sd
->toChars());
3886 t
= sd
->type
->pointerTo();
3895 exp
= exp
->semantic(sc
);
3900 error(loc
, "expression (%s) has no type", exp
->toChars());
3907 Dsymbol
*s
= t
->toDsymbol(sc
);
3908 for (size_t i
= 0; i
< idents
.dim
; i
++)
3912 Identifier
*id
= (Identifier
*)idents
.data
[i
];
3913 s
= s
->searchX(loc
, sc
, id
);
3919 { error(loc
, "%s is not a type", s
->toChars());
3924 { error(loc
, "cannot resolve .property for %s", toChars());
3934 d_uns64
TypeTypeof::size(Loc loc
)
3937 return exp
->type
->size(loc
);
3939 return TypeQualified::size(loc
);
3944 /***************************** TypeEnum *****************************/
3946 TypeEnum::TypeEnum(EnumDeclaration
*sym
)
3952 char *TypeEnum::toChars()
3954 return sym
->toChars();
3957 Type
*TypeEnum::semantic(Loc loc
, Scope
*sc
)
3963 d_uns64
TypeEnum::size(Loc loc
)
3967 error(loc
, "enum %s is forward referenced", sym
->toChars());
3970 return sym
->memtype
->size(loc
);
3973 unsigned TypeEnum::alignsize()
3980 error(0, "enum %s is forward referenced", sym
->toChars());
3983 return sym
->memtype
->alignsize();
3986 Dsymbol
*TypeEnum::toDsymbol(Scope
*sc
)
3991 Type
*TypeEnum::toBasetype()
3998 error(sym
->loc
, "enum %s is forward referenced", sym
->toChars());
4001 return sym
->memtype
->toBasetype();
4004 void TypeEnum::toDecoBuffer(OutBuffer
*buf
)
4007 name
= sym
->mangle();
4008 // if (name[0] == '_' && name[1] == 'D')
4010 buf
->printf("%c%s", mangleChar
[ty
], name
);
4013 void TypeEnum::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4015 if (mod
!= this->mod
)
4016 { toCBuffer3(buf
, hgs
, mod
);
4019 buf
->writestring(sym
->toChars());
4022 Expression
*TypeEnum::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
4029 printf("TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\n", e
->toChars(), ident
->toChars(), toChars());
4033 s
= sym
->symtab
->lookup(ident
);
4036 return getProperty(e
->loc
, ident
);
4038 m
= s
->isEnumMember();
4039 em
= m
->value
->copy();
4044 error(e
->loc
, "forward reference of %s.%s", toChars(), ident
->toChars());
4045 return new IntegerExp(0, 0, this);
4048 Expression
*TypeEnum::getProperty(Loc loc
, Identifier
*ident
)
4051 if (ident
== Id::max
)
4055 e
= new IntegerExp(0, sym
->maxval
, this);
4057 else if (ident
== Id::min
)
4061 e
= new IntegerExp(0, sym
->minval
, this);
4063 else if (ident
== Id::init
)
4067 e
= defaultInit(loc
);
4073 e
= sym
->memtype
->getProperty(loc
, ident
);
4078 error(loc
, "forward reference of %s.%s", toChars(), ident
->toChars());
4079 return new IntegerExp(0, 0, this);
4082 int TypeEnum::isintegral()
4087 int TypeEnum::isfloating()
4092 int TypeEnum::isunsigned()
4094 return sym
->memtype
->isunsigned();
4097 int TypeEnum::isscalar()
4100 //return sym->memtype->isscalar();
4103 MATCH
TypeEnum::implicitConvTo(Type
*to
)
4106 //printf("TypeEnum::implicitConvTo()\n");
4107 if (this->equals(to
))
4108 m
= MATCHexact
; // exact match
4109 else if (sym
->memtype
->implicitConvTo(to
))
4110 m
= MATCHconvert
; // match with conversions
4112 m
= MATCHnomatch
; // no match
4116 Expression
*TypeEnum::defaultInit(Loc loc
)
4119 printf("TypeEnum::defaultInit() '%s'\n", toChars());
4121 // Initialize to first member of enum
4123 e
= new IntegerExp(loc
, sym
->defaultval
, this);
4127 int TypeEnum::isZeroInit()
4129 return (sym
->defaultval
== 0);
4132 int TypeEnum::hasPointers()
4134 return toBasetype()->hasPointers();
4137 /***************************** TypeTypedef *****************************/
4139 TypeTypedef::TypeTypedef(TypedefDeclaration
*sym
)
4140 : Type(Ttypedef
, NULL
)
4145 Type
*TypeTypedef::syntaxCopy()
4150 char *TypeTypedef::toChars()
4152 return sym
->toChars();
4155 Type
*TypeTypedef::semantic(Loc loc
, Scope
*sc
)
4157 //printf("TypeTypedef::semantic(%s), sem = %d\n", toChars(), sym->sem);
4162 d_uns64
TypeTypedef::size(Loc loc
)
4164 return sym
->basetype
->size(loc
);
4167 unsigned TypeTypedef::alignsize()
4169 return sym
->basetype
->alignsize();
4172 Dsymbol
*TypeTypedef::toDsymbol(Scope
*sc
)
4177 void TypeTypedef::toDecoBuffer(OutBuffer
*buf
)
4181 name
= sym
->mangle();
4182 // if (name[0] == '_' && name[1] == 'D')
4184 //len = strlen(name);
4185 //buf->printf("%c%d%s", mangleChar[ty], len, name);
4186 buf
->printf("%c%s", mangleChar
[ty
], name
);
4189 void TypeTypedef::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4191 //printf("TypeTypedef::toCBuffer2() '%s'\n", sym->toChars());
4192 if (mod
!= this->mod
)
4193 { toCBuffer3(buf
, hgs
, mod
);
4196 buf
->writestring(sym
->toChars());
4199 Expression
*TypeTypedef::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
4202 printf("TypeTypedef::dotExp(e = '%s', ident = '%s') '%s'\n", e
->toChars(), ident
->toChars(), toChars());
4204 if (ident
== Id::init
)
4206 return Type::dotExp(sc
, e
, ident
);
4208 return sym
->basetype
->dotExp(sc
, e
, ident
);
4211 Expression
*TypeTypedef::getProperty(Loc loc
, Identifier
*ident
)
4213 if (ident
== Id::init
)
4215 return Type::getProperty(loc
, ident
);
4217 return sym
->basetype
->getProperty(loc
, ident
);
4220 int TypeTypedef::isbit()
4222 return sym
->basetype
->isbit();
4225 int TypeTypedef::isintegral()
4227 //printf("TypeTypedef::isintegral()\n");
4228 //printf("sym = '%s'\n", sym->toChars());
4229 //printf("basetype = '%s'\n", sym->basetype->toChars());
4230 return sym
->basetype
->isintegral();
4233 int TypeTypedef::isfloating()
4235 return sym
->basetype
->isfloating();
4238 int TypeTypedef::isreal()
4240 return sym
->basetype
->isreal();
4243 int TypeTypedef::isimaginary()
4245 return sym
->basetype
->isimaginary();
4248 int TypeTypedef::iscomplex()
4250 return sym
->basetype
->iscomplex();
4253 int TypeTypedef::isunsigned()
4255 return sym
->basetype
->isunsigned();
4258 int TypeTypedef::isscalar()
4260 return sym
->basetype
->isscalar();
4263 int TypeTypedef::checkBoolean()
4265 return sym
->basetype
->checkBoolean();
4268 Type
*TypeTypedef::toBasetype()
4272 sym
->error("circular definition");
4273 sym
->basetype
= Type::terror
;
4274 return Type::terror
;
4277 Type
*t
= sym
->basetype
->toBasetype();
4282 MATCH
TypeTypedef::implicitConvTo(Type
*to
)
4285 //printf("TypeTypedef::implicitConvTo()\n");
4286 if (this->equals(to
))
4287 m
= MATCHexact
; // exact match
4288 else if (sym
->basetype
->implicitConvTo(to
))
4289 m
= MATCHconvert
; // match with conversions
4291 m
= MATCHnomatch
; // no match
4295 Expression
*TypeTypedef::defaultInit(Loc loc
)
4300 printf("TypeTypedef::defaultInit() '%s'\n", toChars());
4304 //sym->init->toExpression()->print();
4305 return sym
->init
->toExpression();
4308 e
= bt
->defaultInit(loc
);
4310 while (bt
->ty
== Tsarray
)
4313 bt
= bt
->next
->toBasetype();
4318 int TypeTypedef::isZeroInit()
4322 if (sym
->init
->isVoidInitializer())
4323 return 1; // initialize voids to 0
4324 Expression
*e
= sym
->init
->toExpression();
4325 if (e
&& e
->isBool(FALSE
))
4327 return 0; // assume not
4331 sym
->error("circular definition");
4332 sym
->basetype
= Type::terror
;
4335 int result
= sym
->basetype
->isZeroInit();
4340 int TypeTypedef::hasPointers()
4342 return toBasetype()->hasPointers();
4345 /***************************** TypeStruct *****************************/
4347 TypeStruct::TypeStruct(StructDeclaration
*sym
)
4348 : Type(Tstruct
, NULL
)
4353 char *TypeStruct::toChars()
4355 //printf("sym.parent: %s, deco = %s\n", sym->parent->toChars(), deco);
4356 TemplateInstance
*ti
= sym
->parent
->isTemplateInstance();
4357 if (ti
&& ti
->toAlias() == sym
)
4358 return ti
->toChars();
4359 return sym
->toChars();
4362 Type
*TypeStruct::syntaxCopy()
4367 Type
*TypeStruct::semantic(Loc loc
, Scope
*sc
)
4369 //printf("TypeStruct::semantic('%s')\n", sym->toChars());
4371 /* Cannot do semantic for sym because scope chain may not
4374 //sym->semantic(sc);
4379 d_uns64
TypeStruct::size(Loc loc
)
4381 return sym
->size(loc
);
4384 unsigned TypeStruct::alignsize()
4387 sym
->size(0); // give error for forward references
4388 sz
= sym
->alignsize
;
4389 if (sz
> sym
->structalign
)
4390 sz
= sym
->structalign
;
4394 Dsymbol
*TypeStruct::toDsymbol(Scope
*sc
)
4399 void TypeStruct::toDecoBuffer(OutBuffer
*buf
)
4403 name
= sym
->mangle();
4404 //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", toChars(), name);
4405 // if (name[0] == '_' && name[1] == 'D')
4407 //len = strlen(name);
4408 //buf->printf("%c%d%s", mangleChar[ty], len, name);
4409 buf
->printf("%c%s", mangleChar
[ty
], name
);
4412 void TypeStruct::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4414 if (mod
!= this->mod
)
4415 { toCBuffer3(buf
, hgs
, mod
);
4418 TemplateInstance
*ti
= sym
->parent
->isTemplateInstance();
4419 if (ti
&& ti
->toAlias() == sym
)
4420 buf
->writestring(ti
->toChars());
4422 buf
->writestring(sym
->toChars());
4425 Expression
*TypeStruct::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
4435 printf("TypeStruct::dotExp(e = '%s', ident = '%s')\n", e
->toChars(), ident
->toChars());
4439 error(e
->loc
, "struct %s is forward referenced", sym
->toChars());
4440 return new IntegerExp(e
->loc
, 0, Type::tint32
);
4443 if (ident
== Id::tupleof
)
4445 /* Create a TupleExp
4447 Expressions
*exps
= new Expressions
;
4448 exps
->reserve(sym
->fields
.dim
);
4449 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
4450 { VarDeclaration
*v
= (VarDeclaration
*)sym
->fields
.data
[i
];
4451 Expression
*fe
= new DotVarExp(e
->loc
, e
, v
);
4454 e
= new TupleExp(e
->loc
, exps
);
4455 e
= e
->semantic(sc
);
4459 if (e
->op
== TOKdotexp
)
4460 { DotExp
*de
= (DotExp
*)e
;
4462 if (de
->e1
->op
== TOKimport
)
4464 ScopeExp
*se
= (ScopeExp
*)de
->e1
;
4466 s
= se
->sds
->search(e
->loc
, ident
, 0);
4472 s
= sym
->search(e
->loc
, ident
, 0);
4476 //return getProperty(e->loc, ident);
4477 return Type::dotExp(sc
, e
, ident
);
4481 v
= s
->isVarDeclaration();
4482 if (v
&& v
->isConst())
4483 { ExpInitializer
*ei
= v
->getExpInitializer();
4486 { e
= ei
->exp
->copy(); // need to copy it if it's a StringExp
4487 e
= e
->semantic(sc
);
4494 //return new DotTypeExp(e->loc, e, s);
4495 return new TypeExp(e
->loc
, s
->getType());
4498 EnumMember
*em
= s
->isEnumMember();
4502 return em
->value
->copy();
4505 TemplateMixin
*tm
= s
->isTemplateMixin();
4509 de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, tm
));
4514 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
4517 e
= new DotTemplateExp(e
->loc
, e
, td
);
4522 TemplateInstance
*ti
= s
->isTemplateInstance();
4524 { if (!ti
->semanticdone
)
4526 s
= ti
->inst
->toAlias();
4527 if (!s
->isTemplateInstance())
4529 Expression
*de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, ti
));
4534 d
= s
->isDeclaration();
4537 printf("d = %s '%s'\n", s
->kind(), s
->toChars());
4541 if (e
->op
== TOKtype
)
4542 { FuncDeclaration
*fd
= sc
->func
;
4544 if (d
->needThis() && fd
&& fd
->vthis
)
4546 e
= new DotVarExp(e
->loc
, new ThisExp(e
->loc
), d
);
4547 e
= e
->semantic(sc
);
4550 if (d
->isTupleDeclaration())
4552 e
= new TupleExp(e
->loc
, d
->isTupleDeclaration());
4553 e
= e
->semantic(sc
);
4556 return new VarExp(e
->loc
, d
);
4564 accessCheck(e
->loc
, sc
, e
, d
);
4565 ve
= new VarExp(e
->loc
, d
);
4566 e
= new CommaExp(e
->loc
, e
, ve
);
4573 if (v
->toParent() != sym
)
4574 sym
->error(e
->loc
, "'%s' is not a member", v
->toChars());
4577 accessCheck(e
->loc
, sc
, e
, d
);
4578 b
= new AddrExp(e
->loc
, e
);
4579 b
->type
= e
->type
->pointerTo();
4580 b
= new AddExp(e
->loc
, b
, new IntegerExp(e
->loc
, v
->offset
, Type::tsize_t
));
4581 b
->type
= v
->type
->pointerTo();
4582 e
= new PtrExp(e
->loc
, b
);
4587 de
= new DotVarExp(e
->loc
, e
, d
);
4588 return de
->semantic(sc
);
4591 unsigned TypeStruct::memalign(unsigned salign
)
4593 sym
->size(0); // give error for forward references
4594 return sym
->structalign
;
4597 Expression
*TypeStruct::defaultInit(Loc loc
)
4602 printf("TypeStruct::defaultInit() '%s'\n", toChars());
4604 s
= sym
->toInitializer();
4605 d
= new SymbolDeclaration(sym
->loc
, s
, sym
);
4608 return new VarExp(sym
->loc
, d
);
4611 int TypeStruct::isZeroInit()
4613 return sym
->zeroInit
;
4616 int TypeStruct::checkBoolean()
4621 int TypeStruct::hasPointers()
4623 StructDeclaration
*s
= sym
;
4625 sym
->size(0); // give error for forward references
4628 for (size_t i
= 0; i
< s
->members
->dim
; i
++)
4630 Dsymbol
*sm
= (Dsymbol
*)s
->members
->data
[i
];
4631 if (sm
->hasPointers())
4639 /***************************** TypeClass *****************************/
4641 TypeClass::TypeClass(ClassDeclaration
*sym
)
4642 : Type(Tclass
, NULL
)
4647 char *TypeClass::toChars()
4649 return sym
->toPrettyChars();
4652 Type
*TypeClass::syntaxCopy()
4657 Type
*TypeClass::semantic(Loc loc
, Scope
*sc
)
4659 //printf("TypeClass::semantic(%s)\n", sym->toChars());
4661 sym
->semantic(sym
->scope
);
4665 d_uns64
TypeClass::size(Loc loc
)
4670 Dsymbol
*TypeClass::toDsymbol(Scope
*sc
)
4675 void TypeClass::toDecoBuffer(OutBuffer
*buf
)
4679 name
= sym
->mangle();
4680 // if (name[0] == '_' && name[1] == 'D')
4682 //printf("TypeClass::toDecoBuffer('%s') = '%s'\n", toChars(), name);
4683 //len = strlen(name);
4684 //buf->printf("%c%d%s", mangleChar[ty], len, name);
4685 buf
->writebyte(NOT_NULL_MANGLE
);
4686 buf
->printf("%c%s", mangleChar
[ty
], name
);
4689 void TypeClass::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
4691 if (mod
!= this->mod
)
4692 { toCBuffer3(buf
, hgs
, mod
);
4695 buf
->writestring(sym
->toChars());
4698 Expression
*TypeClass::dotExp(Scope
*sc
, Expression
*e
, Identifier
*ident
)
4708 printf("TypeClass::dotExp(e='%s', ident='%s')\n", e
->toChars(), ident
->toChars());
4711 if (e
->op
== TOKdotexp
)
4712 { DotExp
*de
= (DotExp
*)e
;
4714 if (de
->e1
->op
== TOKimport
)
4716 ScopeExp
*se
= (ScopeExp
*)de
->e1
;
4718 s
= se
->sds
->search(e
->loc
, ident
, 0);
4724 if (ident
== Id::tupleof
)
4726 /* Create a TupleExp
4728 Expressions
*exps
= new Expressions
;
4729 exps
->reserve(sym
->fields
.dim
);
4730 for (size_t i
= 0; i
< sym
->fields
.dim
; i
++)
4731 { VarDeclaration
*v
= (VarDeclaration
*)sym
->fields
.data
[i
];
4732 Expression
*fe
= new DotVarExp(e
->loc
, e
, v
);
4735 e
= new TupleExp(e
->loc
, exps
);
4736 e
= e
->semantic(sc
);
4740 s
= sym
->search(e
->loc
, ident
, 0);
4744 // See if it's a base class
4745 ClassDeclaration
*cbase
;
4746 for (cbase
= sym
->baseClass
; cbase
; cbase
= cbase
->baseClass
)
4748 if (cbase
->ident
->equals(ident
))
4750 e
= new DotTypeExp(0, e
, cbase
);
4755 if (ident
== Id::classinfo
)
4759 assert(ClassDeclaration::classinfo
);
4760 t
= ClassDeclaration::classinfo
->type
;
4761 if (e
->op
== TOKtype
|| e
->op
== TOKdottype
)
4763 /* For type.classinfo, we know the classinfo
4766 if (!sym
->vclassinfo
)
4767 sym
->vclassinfo
= new ClassInfoDeclaration(sym
);
4768 e
= new VarExp(e
->loc
, sym
->vclassinfo
);
4769 e
= e
->addressOf(sc
);
4770 e
->type
= t
; // do this so we don't get redundant dereference
4773 { /* For class objects, the classinfo reference is the first
4774 * entry in the vtbl[]
4776 e
= new PtrExp(e
->loc
, e
);
4777 e
->type
= t
->pointerTo();
4778 if (sym
->isInterfaceDeclaration())
4780 if (sym
->isCOMinterface())
4781 { /* COM interface vtbl[]s are different in that the
4782 * first entry is always pointer to QueryInterface().
4783 * We can't get a .classinfo for it.
4785 error(e
->loc
, "no .classinfo for COM interface objects");
4787 /* For an interface, the first entry in the vtbl[]
4788 * is actually a pointer to an instance of struct Interface.
4789 * The first member of Interface is the .classinfo,
4790 * so add an extra pointer indirection.
4792 e
->type
= e
->type
->pointerTo();
4793 e
= new PtrExp(e
->loc
, e
);
4794 e
->type
= t
->pointerTo();
4796 e
= new PtrExp(e
->loc
, e
, t
);
4801 if (ident
== Id::typeinfo
)
4803 if (!global
.params
.useDeprecated
)
4804 error(e
->loc
, ".typeinfo deprecated, use typeid(type)");
4805 return getTypeInfo(sc
);
4807 if (ident
== Id::outer
&& sym
->vthis
)
4813 //return getProperty(e->loc, ident);
4814 return Type::dotExp(sc
, e
, ident
);
4818 v
= s
->isVarDeclaration();
4819 if (v
&& v
->isConst())
4820 { ExpInitializer
*ei
= v
->getExpInitializer();
4823 { e
= ei
->exp
->copy(); // need to copy it if it's a StringExp
4824 e
= e
->semantic(sc
);
4831 // if (e->op == TOKtype)
4832 return new TypeExp(e
->loc
, s
->getType());
4833 // return new DotTypeExp(e->loc, e, s);
4836 EnumMember
*em
= s
->isEnumMember();
4840 return em
->value
->copy();
4843 TemplateMixin
*tm
= s
->isTemplateMixin();
4847 de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, tm
));
4852 TemplateDeclaration
*td
= s
->isTemplateDeclaration();
4855 e
= new DotTemplateExp(e
->loc
, e
, td
);
4860 TemplateInstance
*ti
= s
->isTemplateInstance();
4862 { if (!ti
->semanticdone
)
4864 s
= ti
->inst
->toAlias();
4865 if (!s
->isTemplateInstance())
4867 Expression
*de
= new DotExp(e
->loc
, e
, new ScopeExp(e
->loc
, ti
));
4872 d
= s
->isDeclaration();
4875 e
->error("%s.%s is not a declaration", e
->toChars(), ident
->toChars());
4876 return new IntegerExp(e
->loc
, 1, Type::tint32
);
4879 if (e
->op
== TOKtype
)
4883 if (d
->needThis() && (hasThis(sc
) || !d
->isFuncDeclaration()))
4887 ClassDeclaration
*thiscd
;
4888 thiscd
= sc
->func
->toParent()->isClassDeclaration();
4892 ClassDeclaration
*cd
= e
->type
->isClassHandle();
4896 e
= new ThisExp(e
->loc
);
4897 e
= new DotTypeExp(e
->loc
, e
, cd
);
4898 de
= new DotVarExp(e
->loc
, e
, d
);
4899 e
= de
->semantic(sc
);
4902 else if ((!cd
|| !cd
->isBaseOf(thiscd
, NULL
)) &&
4903 !d
->isFuncDeclaration())
4904 e
->error("'this' is required, but %s is not a base class of %s", e
->type
->toChars(), thiscd
->toChars());
4908 de
= new DotVarExp(e
->loc
, new ThisExp(e
->loc
), d
);
4909 e
= de
->semantic(sc
);
4912 else if (d
->isTupleDeclaration())
4914 e
= new TupleExp(e
->loc
, d
->isTupleDeclaration());
4915 e
= e
->semantic(sc
);
4919 ve
= new VarExp(e
->loc
, d
);
4928 accessCheck(e
->loc
, sc
, e
, d
);
4929 ve
= new VarExp(e
->loc
, d
);
4930 e
= new CommaExp(e
->loc
, e
, ve
);
4935 if (d
->parent
&& d
->toParent()->isModule())
4940 ve
= new VarExp(e
->loc
, d
);
4941 e
= new CommaExp(e
->loc
, e
, ve
);
4946 de
= new DotVarExp(e
->loc
, e
, d
);
4947 return de
->semantic(sc
);
4950 ClassDeclaration
*TypeClass::isClassHandle()
4955 int TypeClass::isauto()
4960 int TypeClass::isBaseOf(Type
*t
, target_ptrdiff_t
*poffset
)
4962 if (t
->ty
== Tclass
)
4963 { ClassDeclaration
*cd
;
4965 cd
= ((TypeClass
*)t
)->sym
;
4966 if (sym
->isBaseOf(cd
, poffset
))
4972 MATCH
TypeClass::implicitConvTo(Type
*to
)
4974 //printf("TypeClass::implicitConvTo('%s')\n", to->toChars());
4976 // Can always convert a "Foo" to a "Foo?"
4977 if (to
->ty
== Tmaybe
&& to
->next
)
4983 ClassDeclaration
*cdto
= to
->isClassHandle();
4984 if (cdto
&& cdto
->isBaseOf(sym
, NULL
))
4985 { //printf("is base\n");
4986 return MATCHconvert
;
4989 if (global
.params
.Dversion
== 1)
4991 // Allow conversion to (void *)
4992 if (to
->ty
== Tpointer
&& to
->next
->ty
== Tvoid
)
4993 return MATCHconvert
;
4996 return MATCHnomatch
;
4999 Expression
*TypeClass::defaultInit(Loc loc
)
5002 printf("TypeClass::defaultInit() '%s'\n", toChars());
5005 e
= new NullExp(loc
);
5010 int TypeClass::isZeroInit()
5015 int TypeClass::checkBoolean()
5020 int TypeClass::hasPointers()
5025 /***************************** TypeTuple *****************************/
5027 TypeTuple::TypeTuple(Arguments
*arguments
)
5028 : Type(Ttuple
, NULL
)
5030 //printf("TypeTuple(this = %p)\n", this);
5031 this->arguments
= arguments
;
5035 for (size_t i
= 0; i
< arguments
->dim
; i
++)
5037 Argument
*arg
= (Argument
*)arguments
->data
[i
];
5038 assert(arg
&& arg
->type
);
5045 * Form TypeTuple from the types of the expressions.
5046 * Assume exps[] is already tuple expanded.
5049 TypeTuple::TypeTuple(Expressions
*exps
)
5050 : Type(Ttuple
, NULL
)
5052 Arguments
*arguments
= new Arguments
;
5055 arguments
->setDim(exps
->dim
);
5056 for (size_t i
= 0; i
< exps
->dim
; i
++)
5057 { Expression
*e
= (Expression
*)exps
->data
[i
];
5058 if (e
->type
->ty
== Ttuple
)
5059 e
->error("cannot form tuple of tuples");
5060 Argument
*arg
= new Argument(STCin
, e
->type
, NULL
, NULL
);
5061 arguments
->data
[i
] = (void *)arg
;
5064 this->arguments
= arguments
;
5067 Type
*TypeTuple::syntaxCopy()
5069 Arguments
*args
= Argument::arraySyntaxCopy(arguments
);
5070 Type
*t
= new TypeTuple(args
);
5074 Type
*TypeTuple::semantic(Loc loc
, Scope
*sc
)
5076 //printf("TypeTuple::semantic(this = %p)\n", this);
5078 deco
= merge()->deco
;
5080 /* Don't return merge(), because a tuple with one type has the
5081 * same deco as that type.
5086 int TypeTuple::equals(Object
*o
)
5090 //printf("TypeTuple::equals(%s, %s)\n", toChars(), t->toChars());
5095 if (t
->ty
== Ttuple
)
5096 { TypeTuple
*tt
= (TypeTuple
*)t
;
5098 if (arguments
->dim
== tt
->arguments
->dim
)
5100 for (size_t i
= 0; i
< tt
->arguments
->dim
; i
++)
5101 { Argument
*arg1
= (Argument
*)arguments
->data
[i
];
5102 Argument
*arg2
= (Argument
*)tt
->arguments
->data
[i
];
5104 if (!arg1
->type
->equals(arg2
->type
))
5113 Type
*TypeTuple::reliesOnTident()
5117 for (size_t i
= 0; i
< arguments
->dim
; i
++)
5119 Argument
*arg
= (Argument
*)arguments
->data
[i
];
5120 Type
*t
= arg
->type
->reliesOnTident();
5128 void TypeTuple::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
5130 Argument::argsToCBuffer(buf
, hgs
, arguments
, 0);
5133 void TypeTuple::toDecoBuffer(OutBuffer
*buf
)
5135 //printf("TypeTuple::toDecoBuffer() this = %p\n", this);
5137 Argument::argsToDecoBuffer(&buf2
, arguments
);
5138 unsigned len
= buf2
.offset
;
5140 // newlib bug as of 1.14.0
5141 char * p
= (char*) buf2
.extractData();
5142 buf
->printf("%c%d%.*s", mangleChar
[ty
], len
, len
, p
? p
: "");
5144 buf
->printf("%c%d%.*s", mangleChar
[ty
], len
, len
, (char *)buf2
.extractData());
5148 Expression
*TypeTuple::getProperty(Loc loc
, Identifier
*ident
)
5152 printf("TypeTuple::getProperty(type = '%s', ident = '%s')\n", toChars(), ident
->toChars());
5154 if (ident
== Id::length
)
5156 e
= new IntegerExp(loc
, arguments
->dim
, Type::tsize_t
);
5160 error(loc
, "no property '%s' for tuple '%s'", ident
->toChars(), toChars());
5161 e
= new IntegerExp(loc
, 1, Type::tint32
);
5166 /***************************** TypeSlice *****************************/
5168 /* This is so we can slice a TypeTuple */
5170 TypeSlice::TypeSlice(Type
*next
, Expression
*lwr
, Expression
*upr
)
5171 : Type(Tslice
, next
)
5173 //printf("TypeSlice[%s .. %s]\n", lwr->toChars(), upr->toChars());
5178 Type
*TypeSlice::syntaxCopy()
5180 Type
*t
= new TypeSlice(next
->syntaxCopy(), lwr
->syntaxCopy(), upr
->syntaxCopy());
5184 Type
*TypeSlice::semantic(Loc loc
, Scope
*sc
)
5186 //printf("TypeSlice::semantic() %s\n", toChars());
5187 next
= next
->semantic(loc
, sc
);
5188 //printf("next: %s\n", next->toChars());
5190 Type
*tbn
= next
->toBasetype();
5191 if (tbn
->ty
!= Ttuple
)
5192 { error(loc
, "can only slice tuple types, not %s", tbn
->toChars());
5193 return Type::terror
;
5195 TypeTuple
*tt
= (TypeTuple
*)tbn
;
5197 lwr
= semanticLength(sc
, tbn
, lwr
);
5198 lwr
= lwr
->optimize(WANTvalue
);
5199 uinteger_t i1
= lwr
->toUInteger();
5201 upr
= semanticLength(sc
, tbn
, upr
);
5202 upr
= upr
->optimize(WANTvalue
);
5203 uinteger_t i2
= upr
->toUInteger();
5205 if (!(i1
<= i2
&& i2
<= tt
->arguments
->dim
))
5206 { error(loc
, "slice [%"PRIuMAX
"..%"PRIuMAX
"] is out of range of [0..%u]", i1
, i2
, tt
->arguments
->dim
);
5207 return Type::terror
;
5210 Arguments
*args
= new Arguments
;
5211 args
->reserve(i2
- i1
);
5212 for (size_t i
= i1
; i
< i2
; i
++)
5213 { Argument
*arg
= (Argument
*)tt
->arguments
->data
[i
];
5217 return new TypeTuple(args
);
5220 void TypeSlice::resolve(Loc loc
, Scope
*sc
, Expression
**pe
, Type
**pt
, Dsymbol
**ps
)
5222 next
->resolve(loc
, sc
, pe
, pt
, ps
);
5224 { // It's really a slice expression
5226 e
= new SliceExp(loc
, *pe
, lwr
, upr
);
5231 TupleDeclaration
*td
= s
->isTupleDeclaration();
5234 /* It's a slice of a TupleDeclaration
5236 ScopeDsymbol
*sym
= new ArrayScopeSymbol(td
);
5237 sym
->parent
= sc
->scopesym
;
5240 lwr
= lwr
->semantic(sc
);
5241 lwr
= lwr
->optimize(WANTvalue
);
5242 uinteger_t i1
= lwr
->toUInteger();
5244 upr
= upr
->semantic(sc
);
5245 upr
= upr
->optimize(WANTvalue
);
5246 uinteger_t i2
= upr
->toUInteger();
5250 if (!(i1
<= i2
&& i2
<= td
->objects
->dim
))
5251 { error(loc
, "slice [%"PRIuMAX
"u..%"PRIuMAX
"u] is out of range of [0..%u]", i1
, i2
, td
->objects
->dim
);
5255 if (i1
== 0 && i2
== td
->objects
->dim
)
5261 /* Create a new TupleDeclaration which
5262 * is a slice [i1..i2] out of the old one.
5264 Objects
*objects
= new Objects
;
5265 objects
->setDim(i2
- i1
);
5266 for (size_t i
= 0; i
< objects
->dim
; i
++)
5268 objects
->data
[i
] = td
->objects
->data
[(size_t)i1
+ i
];
5271 TupleDeclaration
*tds
= new TupleDeclaration(loc
, td
->ident
, objects
);
5280 Type::resolve(loc
, sc
, pe
, pt
, ps
);
5284 void TypeSlice::toCBuffer2(OutBuffer
*buf
, HdrGenState
*hgs
, int mod
)
5286 if (mod
!= this->mod
)
5287 { toCBuffer3(buf
, hgs
, mod
);
5290 next
->toCBuffer2(buf
, hgs
, this->mod
);
5292 buf
->printf("[%s .. ", lwr
->toChars());
5293 buf
->printf("%s]", upr
->toChars());
5296 /***************************** Argument *****************************/
5298 Argument::Argument(unsigned storageClass
, Type
*type
, Identifier
*ident
, Expression
*defaultArg
)
5301 this->ident
= ident
;
5302 this->storageClass
= storageClass
;
5303 this->defaultArg
= defaultArg
;
5306 Argument
*Argument::syntaxCopy()
5308 Argument
*a
= new Argument(storageClass
,
5309 type
? type
->syntaxCopy() : NULL
,
5311 defaultArg
? defaultArg
->syntaxCopy() : NULL
);
5315 Arguments
*Argument::arraySyntaxCopy(Arguments
*args
)
5316 { Arguments
*a
= NULL
;
5320 a
= new Arguments();
5321 a
->setDim(args
->dim
);
5322 for (size_t i
= 0; i
< a
->dim
; i
++)
5323 { Argument
*arg
= (Argument
*)args
->data
[i
];
5325 arg
= arg
->syntaxCopy();
5326 a
->data
[i
] = (void *)arg
;
5332 char *Argument::argsTypesToChars(Arguments
*args
, int varargs
)
5335 buf
= new OutBuffer();
5337 buf
->writeByte('(');
5343 for (i
= 0; i
< args
->dim
; i
++)
5347 buf
->writeByte(',');
5348 arg
= (Argument
*)args
->data
[i
];
5350 arg
->type
->toCBuffer2(&argbuf
, &hgs
, 0);
5351 buf
->write(&argbuf
);
5355 if (i
&& varargs
== 1)
5356 buf
->writeByte(',');
5357 buf
->writestring("...");
5360 buf
->writeByte(')');
5362 return buf
->toChars();
5365 void Argument::argsToCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
, Arguments
*arguments
, int varargs
)
5367 buf
->writeByte('(');
5372 for (i
= 0; i
< arguments
->dim
; i
++)
5376 buf
->writestring(", ");
5377 arg
= (Argument
*)arguments
->data
[i
];
5378 if (arg
->storageClass
& STCout
)
5379 buf
->writestring("out ");
5380 else if (arg
->storageClass
& STCref
)
5381 buf
->writestring((global
.params
.Dversion
== 1)
5382 ? (char *)"inout " : (char *)"ref ");
5383 else if (arg
->storageClass
& STClazy
)
5384 buf
->writestring("lazy ");
5386 arg
->type
->toCBuffer(&argbuf
, arg
->ident
, hgs
);
5387 if (arg
->defaultArg
)
5389 argbuf
.writestring(" = ");
5390 arg
->defaultArg
->toCBuffer(&argbuf
, hgs
);
5392 buf
->write(&argbuf
);
5396 if (i
&& varargs
== 1)
5397 buf
->writeByte(',');
5398 buf
->writestring("...");
5401 buf
->writeByte(')');
5405 void Argument::argsToDecoBuffer(OutBuffer
*buf
, Arguments
*arguments
)
5407 //printf("Argument::argsToDecoBuffer()\n");
5409 // Write argument types
5412 size_t dim
= Argument::dim(arguments
);
5413 for (size_t i
= 0; i
< dim
; i
++)
5415 Argument
*arg
= Argument::getNth(arguments
, i
);
5416 arg
->toDecoBuffer(buf
);
5421 /****************************************************
5422 * Determine if parameter is a lazy array of delegates.
5423 * If so, return the return type of those delegates.
5424 * If not, return NULL.
5427 Type
*Argument::isLazyArray()
5429 // if (inout == Lazy)
5431 Type
*tb
= type
->toBasetype();
5432 if (tb
->ty
== Tsarray
|| tb
->ty
== Tarray
)
5434 Type
*tel
= tb
->next
->toBasetype();
5435 if (tel
->ty
== Tdelegate
)
5437 TypeDelegate
*td
= (TypeDelegate
*)tel
;
5438 TypeFunction
*tf
= (TypeFunction
*)td
->next
;
5440 if (!tf
->varargs
&& Argument::dim(tf
->parameters
) == 0)
5442 return tf
->next
; // return type of delegate
5450 void Argument::toDecoBuffer(OutBuffer
*buf
)
5452 switch (storageClass
& (STCin
| STCout
| STCref
| STClazy
))
5457 buf
->writeByte('J');
5460 buf
->writeByte('K');
5463 buf
->writeByte('L');
5471 type
->toDecoBuffer(buf
);
5474 /***************************************
5475 * Determine number of arguments, folding in tuples.
5478 size_t Argument::dim(Arguments
*args
)
5483 for (size_t i
= 0; i
< args
->dim
; i
++)
5484 { Argument
*arg
= (Argument
*)args
->data
[i
];
5485 Type
*t
= arg
->type
->toBasetype();
5487 if (t
->ty
== Ttuple
)
5488 { TypeTuple
*tu
= (TypeTuple
*)t
;
5489 n
+= dim(tu
->arguments
);
5498 /***************************************
5499 * Get nth Argument, folding in tuples.
5501 * Argument* nth Argument
5502 * NULL not found, *pn gets incremented by the number
5506 Argument
*Argument::getNth(Arguments
*args
, size_t nth
, size_t *pn
)
5512 for (size_t i
= 0; i
< args
->dim
; i
++)
5513 { Argument
*arg
= (Argument
*)args
->data
[i
];
5514 Type
*t
= arg
->type
->toBasetype();
5516 if (t
->ty
== Ttuple
)
5517 { TypeTuple
*tu
= (TypeTuple
*)t
;
5518 arg
= getNth(tu
->arguments
, nth
- n
, &n
);