Mercurial > projects > ldc
annotate dmd/mtype.c @ 1351:8d501abecd24
Initial (but disabled) fix for ticket #294 , the actual part that fixes the bug is in a #if 0 block as I'm afraid it will cause regressions. I'm most likely not going to be around tonight, and maybe not tomorrow as well, so I'm pushing it in case someone wants to run some serious testing/investigate the problem noted in llvmhelpers.cpp : realignOffset .
author | Tomas Lindquist Olsen <tomas.l.olsen gmail com> |
---|---|
date | Thu, 14 May 2009 17:20:17 +0200 |
parents | 680b4df0ea36 |
children | 8026319762be |
rev | line source |
---|---|
159 | 1 |
2 // Compiler implementation of the D programming language | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
3 // Copyright (c) 1999-2009 by Digital Mars |
159 | 4 // All Rights Reserved |
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. | |
10 | |
872
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
846
diff
changeset
|
11 #define __C99FEATURES__ 1 // Needed on Solaris for NaN and more |
159 | 12 #define __USE_ISOC99 1 // so signbit() gets defined |
872
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
846
diff
changeset
|
13 |
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
846
diff
changeset
|
14 #if (defined (__SVR4) && defined (__sun)) |
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
846
diff
changeset
|
15 #include <alloca.h> |
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
846
diff
changeset
|
16 #endif |
aa953cc960b6
Apply BlueZeniX's patch for OpenSolaris compatibility. Fixes #158.
Christian Kamm <kamm incasoftware de>
parents:
846
diff
changeset
|
17 |
1147
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
18 #ifdef __DMC__ |
1133
eeb8b95ea92e
Cleanup DMD 1.041 merge.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1124
diff
changeset
|
19 #include <math.h> |
1147
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
20 #else |
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
21 #include <cmath> |
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
22 #endif |
159 | 23 |
24 #include <stdio.h> | |
25 #include <assert.h> | |
26 #include <float.h> | |
27 | |
28 #if _MSC_VER | |
29 #include <malloc.h> | |
30 #include <complex> | |
31 #include <limits> | |
32 #elif __DMC__ | |
33 #include <complex.h> | |
285
297690b5d4a5
[svn r306] Fixed: it's now possible to compile and link llvmdc with MinGW32 and msys on Win32 :D I tried it myself ;) Building the runtime still needs some work, but it's a step in the right direction.
lindquist
parents:
270
diff
changeset
|
34 #elif __MINGW32__ |
297690b5d4a5
[svn r306] Fixed: it's now possible to compile and link llvmdc with MinGW32 and msys on Win32 :D I tried it myself ;) Building the runtime still needs some work, but it's a step in the right direction.
lindquist
parents:
270
diff
changeset
|
35 #include <malloc.h> |
159 | 36 #endif |
37 | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
38 #include "rmem.h" |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
39 #include "port.h" |
159 | 40 |
41 #include "dsymbol.h" | |
42 #include "mtype.h" | |
43 #include "scope.h" | |
44 #include "init.h" | |
45 #include "expression.h" | |
46 #include "attrib.h" | |
47 #include "declaration.h" | |
48 #include "template.h" | |
49 #include "id.h" | |
50 #include "enum.h" | |
51 #include "import.h" | |
52 #include "aggregate.h" | |
53 #include "hdrgen.h" | |
54 | |
1147
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
55 #if IN_LLVM |
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
56 //#include "gen/tollvm.h" |
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
57 Ir* Type::sir = NULL; |
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
58 unsigned GetTypeAlignment(Ir* ir, Type* t); |
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
59 #endif |
1009
b1b23a64ad8c
Use LLVM alignment data instead of hand-picked.
Frits van Bommel <fvbommel wxs.nl>
parents:
1008
diff
changeset
|
60 |
159 | 61 FuncDeclaration *hasThis(Scope *sc); |
62 | |
63 | |
64 #define LOGDOTEXP 0 // log ::dotExp() | |
65 #define LOGDEFAULTINIT 0 // log ::defaultInit() | |
66 | |
67 // Allow implicit conversion of T[] to T* | |
68 #define IMPLICIT_ARRAY_TO_PTR global.params.useDeprecated | |
69 | |
70 /* These have default values for 32 bit code, they get | |
71 * adjusted for 64 bit code. | |
72 */ | |
73 | |
74 int PTRSIZE = 4; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
75 #if TARGET_OSX |
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
76 int REALSIZE = 16; |
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
77 int REALPAD = 6; |
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
78 int REALALIGNSIZE = 16; |
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
79 #elif TARGET_LINUX || TARGET_FREEBSD |
159 | 80 int REALSIZE = 12; |
81 int REALPAD = 2; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
82 int REALALIGNSIZE = 4; |
159 | 83 #else |
84 int REALSIZE = 10; | |
85 int REALPAD = 0; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
86 int REALALIGNSIZE = 2; |
159 | 87 #endif |
88 int Tsize_t = Tuns32; | |
89 int Tptrdiff_t = Tint32; | |
90 | |
1257
7af860e4f403
Changes for mingw to compile properly
Kelly Wilson <wilsonk cpsc.ucalgary.ca>
parents:
1245
diff
changeset
|
91 #if _WIN32 |
7af860e4f403
Changes for mingw to compile properly
Kelly Wilson <wilsonk cpsc.ucalgary.ca>
parents:
1245
diff
changeset
|
92 static double zero = 0; |
7af860e4f403
Changes for mingw to compile properly
Kelly Wilson <wilsonk cpsc.ucalgary.ca>
parents:
1245
diff
changeset
|
93 double Port::nan = NAN; |
7af860e4f403
Changes for mingw to compile properly
Kelly Wilson <wilsonk cpsc.ucalgary.ca>
parents:
1245
diff
changeset
|
94 double Port::infinity = 1/zero; |
7af860e4f403
Changes for mingw to compile properly
Kelly Wilson <wilsonk cpsc.ucalgary.ca>
parents:
1245
diff
changeset
|
95 #endif |
7af860e4f403
Changes for mingw to compile properly
Kelly Wilson <wilsonk cpsc.ucalgary.ca>
parents:
1245
diff
changeset
|
96 |
159 | 97 /***************************** Type *****************************/ |
98 | |
99 ClassDeclaration *Type::typeinfo; | |
100 ClassDeclaration *Type::typeinfoclass; | |
101 ClassDeclaration *Type::typeinfointerface; | |
102 ClassDeclaration *Type::typeinfostruct; | |
103 ClassDeclaration *Type::typeinfotypedef; | |
104 ClassDeclaration *Type::typeinfopointer; | |
105 ClassDeclaration *Type::typeinfoarray; | |
106 ClassDeclaration *Type::typeinfostaticarray; | |
107 ClassDeclaration *Type::typeinfoassociativearray; | |
108 ClassDeclaration *Type::typeinfoenum; | |
109 ClassDeclaration *Type::typeinfofunction; | |
110 ClassDeclaration *Type::typeinfodelegate; | |
111 ClassDeclaration *Type::typeinfotypelist; | |
112 | |
113 Type *Type::tvoidptr; | |
114 Type *Type::basic[TMAX]; | |
115 unsigned char Type::mangleChar[TMAX]; | |
116 StringTable Type::stringtable; | |
117 | |
1245
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
118 #if IN_LLVM |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
119 StringTable Type::deco_stringtable; |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
120 #endif |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
121 |
159 | 122 |
123 Type::Type(TY ty, Type *next) | |
124 { | |
125 this->ty = ty; | |
126 this->mod = 0; | |
127 this->next = next; | |
128 this->deco = NULL; | |
336 | 129 #if DMDV2 |
159 | 130 this->cto = NULL; |
131 this->ito = NULL; | |
132 #endif | |
133 this->pto = NULL; | |
134 this->rto = NULL; | |
135 this->arrayof = NULL; | |
136 this->vtinfo = NULL; | |
1146
1860414bf3b7
* Moved ir/irsymbol.cpp/h into ir/irdsymbol.cpp/h.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1133
diff
changeset
|
137 #if IN_DMD |
159 | 138 this->ctype = NULL; |
1146
1860414bf3b7
* Moved ir/irsymbol.cpp/h into ir/irdsymbol.cpp/h.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1133
diff
changeset
|
139 #endif |
1192
3251ce06c820
Started seperating type resolution from the rest of codegen again, the merge had too many regressions.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1188
diff
changeset
|
140 |
3251ce06c820
Started seperating type resolution from the rest of codegen again, the merge had too many regressions.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1188
diff
changeset
|
141 #if IN_LLVM |
3251ce06c820
Started seperating type resolution from the rest of codegen again, the merge had too many regressions.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1188
diff
changeset
|
142 this->irtype = NULL; |
3251ce06c820
Started seperating type resolution from the rest of codegen again, the merge had too many regressions.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1188
diff
changeset
|
143 #endif |
159 | 144 } |
145 | |
146 Type *Type::syntaxCopy() | |
147 { | |
148 print(); | |
149 fprintf(stdmsg, "ty = %d\n", ty); | |
150 assert(0); | |
151 return this; | |
152 } | |
153 | |
154 int Type::equals(Object *o) | |
155 { Type *t; | |
156 | |
157 t = (Type *)o; | |
158 //printf("Type::equals(%s, %s)\n", toChars(), t->toChars()); | |
159 if (this == o || | |
160 (t && deco == t->deco) && // deco strings are unique | |
161 deco != NULL) // and semantic() has been run | |
162 { | |
163 //printf("deco = '%s', t->deco = '%s'\n", deco, t->deco); | |
164 return 1; | |
165 } | |
166 //if (deco && t && t->deco) printf("deco = '%s', t->deco = '%s'\n", deco, t->deco); | |
167 return 0; | |
168 } | |
169 | |
170 char Type::needThisPrefix() | |
171 { | |
172 return 'M'; // name mangling prefix for functions needing 'this' | |
173 } | |
174 | |
1147
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
175 #if IN_LLVM |
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
176 void Type::init(Ir* _sir) |
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
177 #else |
159 | 178 void Type::init() |
1147
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
179 #endif |
159 | 180 { int i; |
181 int j; | |
182 | |
183 Lexer::initKeywords(); | |
184 | |
185 mangleChar[Tarray] = 'A'; | |
186 mangleChar[Tsarray] = 'G'; | |
187 mangleChar[Taarray] = 'H'; | |
188 mangleChar[Tpointer] = 'P'; | |
189 mangleChar[Treference] = 'R'; | |
190 mangleChar[Tfunction] = 'F'; | |
191 mangleChar[Tident] = 'I'; | |
192 mangleChar[Tclass] = 'C'; | |
193 mangleChar[Tstruct] = 'S'; | |
194 mangleChar[Tenum] = 'E'; | |
195 mangleChar[Ttypedef] = 'T'; | |
196 mangleChar[Tdelegate] = 'D'; | |
197 | |
198 mangleChar[Tnone] = 'n'; | |
199 mangleChar[Tvoid] = 'v'; | |
200 mangleChar[Tint8] = 'g'; | |
201 mangleChar[Tuns8] = 'h'; | |
202 mangleChar[Tint16] = 's'; | |
203 mangleChar[Tuns16] = 't'; | |
204 mangleChar[Tint32] = 'i'; | |
205 mangleChar[Tuns32] = 'k'; | |
206 mangleChar[Tint64] = 'l'; | |
207 mangleChar[Tuns64] = 'm'; | |
208 mangleChar[Tfloat32] = 'f'; | |
209 mangleChar[Tfloat64] = 'd'; | |
210 mangleChar[Tfloat80] = 'e'; | |
211 | |
212 mangleChar[Timaginary32] = 'o'; | |
213 mangleChar[Timaginary64] = 'p'; | |
214 mangleChar[Timaginary80] = 'j'; | |
215 mangleChar[Tcomplex32] = 'q'; | |
216 mangleChar[Tcomplex64] = 'r'; | |
217 mangleChar[Tcomplex80] = 'c'; | |
218 | |
219 mangleChar[Tbool] = 'b'; | |
220 mangleChar[Tascii] = 'a'; | |
221 mangleChar[Twchar] = 'u'; | |
222 mangleChar[Tdchar] = 'w'; | |
223 | |
224 mangleChar[Tbit] = '@'; | |
225 mangleChar[Tinstance] = '@'; | |
226 mangleChar[Terror] = '@'; | |
227 mangleChar[Ttypeof] = '@'; | |
228 mangleChar[Ttuple] = 'B'; | |
229 mangleChar[Tslice] = '@'; | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
230 mangleChar[Treturn] = '@'; |
159 | 231 |
232 for (i = 0; i < TMAX; i++) | |
233 { if (!mangleChar[i]) | |
234 fprintf(stdmsg, "ty = %d\n", i); | |
235 assert(mangleChar[i]); | |
236 } | |
237 | |
238 // Set basic types | |
239 static TY basetab[] = | |
240 { Tvoid, Tint8, Tuns8, Tint16, Tuns16, Tint32, Tuns32, Tint64, Tuns64, | |
241 Tfloat32, Tfloat64, Tfloat80, | |
242 Timaginary32, Timaginary64, Timaginary80, | |
243 Tcomplex32, Tcomplex64, Tcomplex80, | |
244 Tbit, Tbool, | |
245 Tascii, Twchar, Tdchar }; | |
246 | |
247 for (i = 0; i < sizeof(basetab) / sizeof(basetab[0]); i++) | |
248 basic[basetab[i]] = new TypeBasic(basetab[i]); | |
249 basic[Terror] = basic[Tint32]; | |
250 | |
251 tvoidptr = tvoid->pointerTo(); | |
252 | |
1147
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
253 // LDC |
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
254 sir = _sir; |
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
255 |
270
d9d5d59873d8
[svn r291] Fixed a bunch of the old Phobos tests to work with Tango.
lindquist
parents:
243
diff
changeset
|
256 // set size_t / ptrdiff_t types and pointer size |
159 | 257 if (global.params.is64bit) |
258 { | |
742
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
259 Tsize_t = Tuns64; |
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
260 Tptrdiff_t = Tint64; |
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
261 PTRSIZE = 8; |
159 | 262 } |
263 else | |
264 { | |
742
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
265 Tsize_t = Tuns32; |
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
266 Tptrdiff_t = Tint32; |
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
267 PTRSIZE = 4; |
243
4d006f7b2ada
[svn r260] Changed some of the LLVMDC specific code in the Tango core and did some minor cleanups.
lindquist
parents:
217
diff
changeset
|
268 } |
4d006f7b2ada
[svn r260] Changed some of the LLVMDC specific code in the Tango core and did some minor cleanups.
lindquist
parents:
217
diff
changeset
|
269 |
4d006f7b2ada
[svn r260] Changed some of the LLVMDC specific code in the Tango core and did some minor cleanups.
lindquist
parents:
217
diff
changeset
|
270 // set real size and padding |
445
cc40db549aea
Changed the handling of variadic intrinsics a bit.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
389
diff
changeset
|
271 if (global.params.cpu == ARCHx86) |
243
4d006f7b2ada
[svn r260] Changed some of the LLVMDC specific code in the Tango core and did some minor cleanups.
lindquist
parents:
217
diff
changeset
|
272 { |
742
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
273 REALSIZE = 12; |
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
274 REALPAD = 2; |
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
275 } |
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
276 else if (global.params.cpu == ARCHx86_64) |
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
277 { |
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
278 REALSIZE = 16; |
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
279 REALPAD = 6; |
243
4d006f7b2ada
[svn r260] Changed some of the LLVMDC specific code in the Tango core and did some minor cleanups.
lindquist
parents:
217
diff
changeset
|
280 } |
4d006f7b2ada
[svn r260] Changed some of the LLVMDC specific code in the Tango core and did some minor cleanups.
lindquist
parents:
217
diff
changeset
|
281 else |
4d006f7b2ada
[svn r260] Changed some of the LLVMDC specific code in the Tango core and did some minor cleanups.
lindquist
parents:
217
diff
changeset
|
282 { |
742
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
283 REALSIZE = 8; |
05e7657a7811
Fix REALSIZE, REALPAD and alignment of double and real for x86-64.
Christian Kamm <kamm incasoftware de>
parents:
739
diff
changeset
|
284 REALPAD = 0; |
159 | 285 } |
286 } | |
287 | |
288 d_uns64 Type::size() | |
289 { | |
290 return size(0); | |
291 } | |
292 | |
293 d_uns64 Type::size(Loc loc) | |
294 { | |
295 error(loc, "no size for type %s", toChars()); | |
296 return 1; | |
297 } | |
298 | |
299 unsigned Type::alignsize() | |
300 { | |
301 return size(0); | |
302 } | |
303 | |
304 Type *Type::semantic(Loc loc, Scope *sc) | |
305 { | |
306 if (next) | |
307 next = next->semantic(loc,sc); | |
308 return merge(); | |
309 } | |
310 | |
311 Type *Type::pointerTo() | |
312 { | |
313 if (!pto) | |
314 { Type *t; | |
315 | |
316 t = new TypePointer(this); | |
317 pto = t->merge(); | |
318 } | |
319 return pto; | |
320 } | |
321 | |
322 Type *Type::referenceTo() | |
323 { | |
324 if (!rto) | |
325 { Type *t; | |
326 | |
327 t = new TypeReference(this); | |
328 rto = t->merge(); | |
329 } | |
330 return rto; | |
331 } | |
332 | |
333 Type *Type::arrayOf() | |
334 { | |
335 if (!arrayof) | |
336 { Type *t; | |
337 | |
338 t = new TypeDArray(this); | |
339 arrayof = t->merge(); | |
340 } | |
341 return arrayof; | |
342 } | |
343 | |
344 Dsymbol *Type::toDsymbol(Scope *sc) | |
345 { | |
346 return NULL; | |
347 } | |
348 | |
349 /******************************* | |
350 * If this is a shell around another type, | |
351 * get that other type. | |
352 */ | |
353 | |
354 Type *Type::toBasetype() | |
355 { | |
356 return this; | |
357 } | |
358 | |
359 /******************************** | |
360 * Name mangling. | |
361 */ | |
362 | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
363 void Type::toDecoBuffer(OutBuffer *buf, bool mangle) |
159 | 364 { |
365 buf->writeByte(mangleChar[ty]); | |
366 if (next) | |
367 { | |
368 assert(next != this); | |
369 //printf("this = %p, ty = %d, next = %p, ty = %d\n", this, this->ty, next, next->ty); | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
370 next->toDecoBuffer(buf, mangle); |
159 | 371 } |
372 } | |
373 | |
374 /******************************** | |
375 * For pretty-printing a type. | |
376 */ | |
377 | |
378 char *Type::toChars() | |
379 { OutBuffer *buf; | |
380 HdrGenState hgs; | |
381 | |
382 buf = new OutBuffer(); | |
383 toCBuffer(buf, NULL, &hgs); | |
384 return buf->toChars(); | |
385 } | |
386 | |
387 void Type::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs) | |
388 { | |
389 toCBuffer2(buf, hgs, 0); | |
390 if (ident) | |
391 { buf->writeByte(' '); | |
392 buf->writestring(ident->toChars()); | |
393 } | |
394 } | |
395 | |
396 void Type::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
397 { | |
398 if (mod != this->mod) | |
399 { toCBuffer3(buf, hgs, mod); | |
400 return; | |
401 } | |
402 buf->writestring(toChars()); | |
403 } | |
404 | |
405 void Type::toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod) | |
406 { | |
407 if (mod != this->mod) | |
408 { char *p; | |
409 | |
410 switch (this->mod) | |
411 { | |
412 case 0: | |
413 toCBuffer2(buf, hgs, this->mod); | |
414 break; | |
415 case MODconst: | |
416 p = "const("; | |
417 goto L1; | |
418 case MODinvariant: | |
419 p = "invariant("; | |
420 L1: buf->writestring(p); | |
421 toCBuffer2(buf, hgs, this->mod); | |
422 buf->writeByte(')'); | |
423 break; | |
424 default: | |
425 assert(0); | |
426 } | |
427 } | |
428 } | |
429 | |
430 | |
431 /************************************ | |
432 */ | |
433 | |
434 Type *Type::merge() | |
435 { Type *t; | |
436 | |
437 //printf("merge(%s)\n", toChars()); | |
438 t = this; | |
439 assert(t); | |
440 if (!deco) | |
441 { | |
442 OutBuffer buf; | |
443 StringValue *sv; | |
444 | |
445 if (next) | |
446 next = next->merge(); | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
447 toDecoBuffer(&buf, false); |
159 | 448 sv = stringtable.update((char *)buf.data, buf.offset); |
449 if (sv->ptrvalue) | |
450 { t = (Type *) sv->ptrvalue; | |
451 assert(t->deco); | |
452 //printf("old value, deco = '%s' %p\n", t->deco, t->deco); | |
453 } | |
454 else | |
455 { | |
456 sv->ptrvalue = this; | |
1245
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
457 |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
458 // we still need deco strings to be unique |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
459 // or Type::equals fails, which breaks a bunch of stuff, |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
460 // like covariant member function overloads. |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
461 OutBuffer mangle; |
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
462 toDecoBuffer(&mangle, true); |
1245
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
463 StringValue* sv2 = deco_stringtable.update((char *)mangle.data, mangle.offset); |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
464 if (sv2->ptrvalue) |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
465 { Type* t2 = (Type *) sv2->ptrvalue; |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
466 assert(t2->deco); |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
467 deco = t2->deco; |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
468 } |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
469 else |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
470 { |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
471 sv2->ptrvalue = this; |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
472 deco = (char *)sv2->lstring.string; |
465a77c904d4
Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1228
diff
changeset
|
473 } |
159 | 474 //printf("new value, deco = '%s' %p\n", t->deco, t->deco); |
475 } | |
476 } | |
477 return t; | |
478 } | |
479 | |
480 int Type::isbit() | |
481 { | |
482 return FALSE; | |
483 } | |
484 | |
485 int Type::isintegral() | |
486 { | |
487 return FALSE; | |
488 } | |
489 | |
490 int Type::isfloating() | |
491 { | |
492 return FALSE; | |
493 } | |
494 | |
495 int Type::isreal() | |
496 { | |
497 return FALSE; | |
498 } | |
499 | |
500 int Type::isimaginary() | |
501 { | |
502 return FALSE; | |
503 } | |
504 | |
505 int Type::iscomplex() | |
506 { | |
507 return FALSE; | |
508 } | |
509 | |
510 int Type::isscalar() | |
511 { | |
512 return FALSE; | |
513 } | |
514 | |
515 int Type::isunsigned() | |
516 { | |
517 return FALSE; | |
518 } | |
519 | |
520 ClassDeclaration *Type::isClassHandle() | |
521 { | |
522 return NULL; | |
523 } | |
524 | |
525 int Type::isauto() | |
526 { | |
527 return FALSE; | |
528 } | |
529 | |
530 int Type::isString() | |
531 { | |
532 return FALSE; | |
533 } | |
534 | |
535 int Type::checkBoolean() | |
536 { | |
537 return isscalar(); | |
538 } | |
539 | |
540 /********************************* | |
541 * Check type to see if it is based on a deprecated symbol. | |
542 */ | |
543 | |
544 void Type::checkDeprecated(Loc loc, Scope *sc) | |
545 { | |
546 Type *t; | |
547 Dsymbol *s; | |
548 | |
549 for (t = this; t; t = t->next) | |
550 { | |
551 s = t->toDsymbol(sc); | |
552 if (s) | |
553 s->checkDeprecated(loc, sc); | |
554 } | |
555 } | |
556 | |
557 | |
558 Expression *Type::defaultInit(Loc loc) | |
559 { | |
560 #if LOGDEFAULTINIT | |
561 printf("Type::defaultInit() '%s'\n", toChars()); | |
562 #endif | |
563 return NULL; | |
564 } | |
565 | |
566 int Type::isZeroInit() | |
567 { | |
568 return 0; // assume not | |
569 } | |
570 | |
571 int Type::isBaseOf(Type *t, int *poffset) | |
572 { | |
573 return 0; // assume not | |
574 } | |
575 | |
576 /******************************** | |
577 * Determine if 'this' can be implicitly converted | |
578 * to type 'to'. | |
579 * Returns: | |
580 * 0 can't convert | |
581 * 1 can convert using implicit conversions | |
582 * 2 this and to are the same type | |
583 */ | |
584 | |
585 MATCH Type::implicitConvTo(Type *to) | |
586 { | |
587 //printf("Type::implicitConvTo(this=%p, to=%p)\n", this, to); | |
588 //printf("\tthis->next=%p, to->next=%p\n", this->next, to->next); | |
589 if (this == to) | |
590 return MATCHexact; | |
591 // if (to->ty == Tvoid) | |
592 // return 1; | |
593 return MATCHnomatch; | |
594 } | |
595 | |
596 Expression *Type::getProperty(Loc loc, Identifier *ident) | |
597 { Expression *e; | |
598 | |
599 #if LOGDOTEXP | |
600 printf("Type::getProperty(type = '%s', ident = '%s')\n", toChars(), ident->toChars()); | |
601 #endif | |
602 if (ident == Id::__sizeof) | |
603 { | |
604 e = new IntegerExp(loc, size(loc), Type::tsize_t); | |
605 } | |
606 else if (ident == Id::size) | |
607 { | |
608 error(loc, ".size property should be replaced with .sizeof"); | |
609 e = new IntegerExp(loc, size(loc), Type::tsize_t); | |
610 } | |
611 else if (ident == Id::alignof) | |
612 { | |
613 e = new IntegerExp(loc, alignsize(), Type::tsize_t); | |
614 } | |
615 else if (ident == Id::typeinfo) | |
616 { | |
617 if (!global.params.useDeprecated) | |
618 error(loc, ".typeinfo deprecated, use typeid(type)"); | |
619 e = getTypeInfo(NULL); | |
620 } | |
621 else if (ident == Id::init) | |
622 { | |
623 if (ty == Tvoid) | |
624 error(loc, "void does not have an initializer"); | |
625 e = defaultInit(loc); | |
626 } | |
627 else if (ident == Id::mangleof) | |
628 { | |
629 assert(deco); | |
630 e = new StringExp(loc, deco, strlen(deco), 'c'); | |
631 Scope sc; | |
632 e = e->semantic(&sc); | |
633 } | |
634 else if (ident == Id::stringof) | |
635 { char *s = toChars(); | |
636 e = new StringExp(loc, s, strlen(s), 'c'); | |
637 Scope sc; | |
638 e = e->semantic(&sc); | |
639 } | |
640 else | |
641 { | |
642 error(loc, "no property '%s' for type '%s'", ident->toChars(), toChars()); | |
643 e = new IntegerExp(loc, 1, Type::tint32); | |
644 } | |
645 return e; | |
646 } | |
647 | |
648 Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident) | |
649 { VarDeclaration *v = NULL; | |
650 | |
651 #if LOGDOTEXP | |
652 printf("Type::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); | |
653 #endif | |
654 if (e->op == TOKdotvar) | |
655 { | |
656 DotVarExp *dv = (DotVarExp *)e; | |
657 v = dv->var->isVarDeclaration(); | |
658 } | |
659 else if (e->op == TOKvar) | |
660 { | |
661 VarExp *ve = (VarExp *)e; | |
662 v = ve->var->isVarDeclaration(); | |
663 } | |
664 if (v) | |
665 { | |
666 if (ident == Id::offset) | |
667 { | |
668 if (!global.params.useDeprecated) | |
669 error(e->loc, ".offset deprecated, use .offsetof"); | |
670 goto Loffset; | |
671 } | |
672 else if (ident == Id::offsetof) | |
673 { | |
674 Loffset: | |
675 if (v->storage_class & STCfield) | |
676 { | |
677 e = new IntegerExp(e->loc, v->offset, Type::tsize_t); | |
678 return e; | |
679 } | |
680 } | |
681 else if (ident == Id::init) | |
682 { | |
683 #if 0 | |
684 if (v->init) | |
685 { | |
686 if (v->init->isVoidInitializer()) | |
687 error(e->loc, "%s.init is void", v->toChars()); | |
688 else | |
689 { Loc loc = e->loc; | |
690 e = v->init->toExpression(); | |
691 if (e->op == TOKassign || e->op == TOKconstruct) | |
692 { | |
693 e = ((AssignExp *)e)->e2; | |
694 | |
695 /* Take care of case where we used a 0 | |
696 * to initialize the struct. | |
697 */ | |
698 if (e->type == Type::tint32 && | |
699 e->isBool(0) && | |
700 v->type->toBasetype()->ty == Tstruct) | |
701 { | |
702 e = v->type->defaultInit(loc); | |
703 } | |
704 } | |
705 e = e->optimize(WANTvalue | WANTinterpret); | |
706 // if (!e->isConst()) | |
707 // error(loc, ".init cannot be evaluated at compile time"); | |
708 } | |
709 return e; | |
710 } | |
711 #endif | |
712 Expression *ex = defaultInit(e->loc); | |
713 return ex; | |
714 } | |
715 } | |
716 if (ident == Id::typeinfo) | |
717 { | |
718 if (!global.params.useDeprecated) | |
719 error(e->loc, ".typeinfo deprecated, use typeid(type)"); | |
720 e = getTypeInfo(sc); | |
721 return e; | |
722 } | |
723 if (ident == Id::stringof) | |
724 { char *s = e->toChars(); | |
725 e = new StringExp(e->loc, s, strlen(s), 'c'); | |
726 Scope sc; | |
727 e = e->semantic(&sc); | |
728 return e; | |
729 } | |
730 return getProperty(e->loc, ident); | |
731 } | |
732 | |
733 unsigned Type::memalign(unsigned salign) | |
734 { | |
735 return salign; | |
736 } | |
737 | |
738 void Type::error(Loc loc, const char *format, ...) | |
739 { | |
740 va_list ap; | |
741 va_start(ap, format); | |
742 ::verror(loc, format, ap); | |
743 va_end( ap ); | |
744 } | |
745 | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
746 void Type::warning(Loc loc, const char *format, ...) |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
747 { |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
748 if (global.params.warnings && !global.gag) |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
749 { |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
750 va_list ap; |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
751 va_start(ap, format); |
1124
e7f0c2b48047
Fix a bug where ::warning() was called with a va_list argument instead of an
Frits van Bommel <fvbommel wxs.nl>
parents:
1103
diff
changeset
|
752 ::vwarning(loc, format, ap); |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
753 va_end( ap ); |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
754 } |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
755 } |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
756 |
159 | 757 Identifier *Type::getTypeInfoIdent(int internal) |
758 { | |
759 // _init_10TypeInfo_%s | |
760 OutBuffer buf; | |
761 Identifier *id; | |
762 char *name; | |
763 int len; | |
764 | |
765 //toTypeInfoBuffer(&buf); | |
766 if (internal) | |
767 { buf.writeByte(mangleChar[ty]); | |
768 if (ty == Tarray) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
769 buf.writeByte(mangleChar[((TypeArray *)this)->next->ty]); |
159 | 770 } |
771 else | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
772 toDecoBuffer(&buf, true); |
159 | 773 len = buf.offset; |
774 name = (char *)alloca(19 + sizeof(len) * 3 + len + 1); | |
775 buf.writeByte(0); | |
776 sprintf(name, "_D%dTypeInfo_%s6__initZ", 9 + len, buf.data); | |
664
eef8ac26c66c
Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents:
658
diff
changeset
|
777 // LDC |
375
3c4460b988bd
Do not strip the leading underscore for typeinfo mangles on Windows.
Christian Kamm <kamm incasoftware de>
parents:
336
diff
changeset
|
778 // it is not clear where the underscore that's stripped here is added back in |
3c4460b988bd
Do not strip the leading underscore for typeinfo mangles on Windows.
Christian Kamm <kamm incasoftware de>
parents:
336
diff
changeset
|
779 // if (global.params.isWindows) |
3c4460b988bd
Do not strip the leading underscore for typeinfo mangles on Windows.
Christian Kamm <kamm incasoftware de>
parents:
336
diff
changeset
|
780 // name++; // C mangling will add it back in |
159 | 781 //printf("name = %s\n", name); |
782 id = Lexer::idPool(name); | |
783 return id; | |
784 } | |
785 | |
786 TypeBasic *Type::isTypeBasic() | |
787 { | |
788 return NULL; | |
789 } | |
790 | |
791 | |
792 void Type::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) | |
793 { | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
794 //printf("Type::resolve() %s, %d\n", toChars(), ty); |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
795 Type *t = semantic(loc, sc); |
159 | 796 *pt = t; |
797 *pe = NULL; | |
798 *ps = NULL; | |
799 } | |
800 | |
801 /******************************* | |
802 * If one of the subtypes of this type is a TypeIdentifier, | |
803 * i.e. it's an unresolved type, return that type. | |
804 */ | |
805 | |
806 Type *Type::reliesOnTident() | |
807 { | |
808 if (!next) | |
809 return NULL; | |
810 else | |
811 return next->reliesOnTident(); | |
812 } | |
813 | |
814 /******************************** | |
815 * We've mistakenly parsed this as a type. | |
816 * Redo it as an Expression. | |
817 * NULL if cannot. | |
818 */ | |
819 | |
820 Expression *Type::toExpression() | |
821 { | |
822 return NULL; | |
823 } | |
824 | |
825 /*************************************** | |
826 * Return !=0 if type has pointers that need to | |
827 * be scanned by the GC during a collection cycle. | |
828 */ | |
829 | |
830 int Type::hasPointers() | |
831 { | |
832 return FALSE; | |
833 } | |
834 | |
835 /* ============================= TypeBasic =========================== */ | |
836 | |
837 TypeBasic::TypeBasic(TY ty) | |
838 : Type(ty, NULL) | |
658
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
642
diff
changeset
|
839 { const char *c; |
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
642
diff
changeset
|
840 const char *d; |
159 | 841 unsigned flags; |
842 | |
843 #define TFLAGSintegral 1 | |
844 #define TFLAGSfloating 2 | |
845 #define TFLAGSunsigned 4 | |
846 #define TFLAGSreal 8 | |
847 #define TFLAGSimaginary 0x10 | |
848 #define TFLAGScomplex 0x20 | |
849 | |
850 flags = 0; | |
851 switch (ty) | |
852 { | |
853 case Tvoid: d = Token::toChars(TOKvoid); | |
854 c = "void"; | |
855 break; | |
856 | |
857 case Tint8: d = Token::toChars(TOKint8); | |
858 c = "byte"; | |
859 flags |= TFLAGSintegral; | |
860 break; | |
861 | |
862 case Tuns8: d = Token::toChars(TOKuns8); | |
863 c = "ubyte"; | |
864 flags |= TFLAGSintegral | TFLAGSunsigned; | |
865 break; | |
866 | |
867 case Tint16: d = Token::toChars(TOKint16); | |
868 c = "short"; | |
869 flags |= TFLAGSintegral; | |
870 break; | |
871 | |
872 case Tuns16: d = Token::toChars(TOKuns16); | |
873 c = "ushort"; | |
874 flags |= TFLAGSintegral | TFLAGSunsigned; | |
875 break; | |
876 | |
877 case Tint32: d = Token::toChars(TOKint32); | |
878 c = "int"; | |
879 flags |= TFLAGSintegral; | |
880 break; | |
881 | |
882 case Tuns32: d = Token::toChars(TOKuns32); | |
883 c = "uint"; | |
884 flags |= TFLAGSintegral | TFLAGSunsigned; | |
885 break; | |
886 | |
887 case Tfloat32: d = Token::toChars(TOKfloat32); | |
888 c = "float"; | |
889 flags |= TFLAGSfloating | TFLAGSreal; | |
890 break; | |
891 | |
892 case Tint64: d = Token::toChars(TOKint64); | |
893 c = "long"; | |
894 flags |= TFLAGSintegral; | |
895 break; | |
896 | |
897 case Tuns64: d = Token::toChars(TOKuns64); | |
898 c = "ulong"; | |
899 flags |= TFLAGSintegral | TFLAGSunsigned; | |
900 break; | |
901 | |
902 case Tfloat64: d = Token::toChars(TOKfloat64); | |
903 c = "double"; | |
904 flags |= TFLAGSfloating | TFLAGSreal; | |
905 break; | |
906 | |
907 case Tfloat80: d = Token::toChars(TOKfloat80); | |
908 c = "real"; | |
909 flags |= TFLAGSfloating | TFLAGSreal; | |
910 break; | |
911 | |
912 case Timaginary32: d = Token::toChars(TOKimaginary32); | |
913 c = "ifloat"; | |
914 flags |= TFLAGSfloating | TFLAGSimaginary; | |
915 break; | |
916 | |
917 case Timaginary64: d = Token::toChars(TOKimaginary64); | |
918 c = "idouble"; | |
919 flags |= TFLAGSfloating | TFLAGSimaginary; | |
920 break; | |
921 | |
922 case Timaginary80: d = Token::toChars(TOKimaginary80); | |
923 c = "ireal"; | |
924 flags |= TFLAGSfloating | TFLAGSimaginary; | |
925 break; | |
926 | |
927 case Tcomplex32: d = Token::toChars(TOKcomplex32); | |
928 c = "cfloat"; | |
929 flags |= TFLAGSfloating | TFLAGScomplex; | |
930 break; | |
931 | |
932 case Tcomplex64: d = Token::toChars(TOKcomplex64); | |
933 c = "cdouble"; | |
934 flags |= TFLAGSfloating | TFLAGScomplex; | |
935 break; | |
936 | |
937 case Tcomplex80: d = Token::toChars(TOKcomplex80); | |
938 c = "creal"; | |
939 flags |= TFLAGSfloating | TFLAGScomplex; | |
940 break; | |
941 | |
942 | |
943 case Tbit: d = Token::toChars(TOKbit); | |
944 c = "bit"; | |
945 flags |= TFLAGSintegral | TFLAGSunsigned; | |
946 break; | |
947 | |
948 case Tbool: d = "bool"; | |
949 c = d; | |
950 flags |= TFLAGSintegral | TFLAGSunsigned; | |
951 break; | |
952 | |
953 case Tascii: d = Token::toChars(TOKchar); | |
954 c = "char"; | |
955 flags |= TFLAGSintegral | TFLAGSunsigned; | |
956 break; | |
957 | |
958 case Twchar: d = Token::toChars(TOKwchar); | |
959 c = "wchar"; | |
960 flags |= TFLAGSintegral | TFLAGSunsigned; | |
961 break; | |
962 | |
963 case Tdchar: d = Token::toChars(TOKdchar); | |
964 c = "dchar"; | |
965 flags |= TFLAGSintegral | TFLAGSunsigned; | |
966 break; | |
967 | |
968 default: assert(0); | |
969 } | |
970 this->dstring = d; | |
971 this->cstring = c; | |
972 this->flags = flags; | |
973 merge(); | |
974 } | |
975 | |
976 Type *TypeBasic::syntaxCopy() | |
977 { | |
978 // No semantic analysis done on basic types, no need to copy | |
979 return this; | |
980 } | |
981 | |
982 | |
983 char *TypeBasic::toChars() | |
984 { | |
658
50383e476c7e
Upgraded frontend to DMD 1.035
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
642
diff
changeset
|
985 return (char *)dstring; |
159 | 986 } |
987 | |
988 void TypeBasic::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
989 { | |
990 //printf("TypeBasic::toCBuffer2(mod = %d, this->mod = %d)\n", mod, this->mod); | |
991 if (mod != this->mod) | |
992 { toCBuffer3(buf, hgs, mod); | |
993 return; | |
994 } | |
995 buf->writestring(dstring); | |
996 } | |
997 | |
998 d_uns64 TypeBasic::size(Loc loc) | |
999 { unsigned size; | |
1000 | |
1001 //printf("TypeBasic::size()\n"); | |
1002 switch (ty) | |
1003 { | |
1004 case Tint8: | |
1005 case Tuns8: size = 1; break; | |
1006 case Tint16: | |
1007 case Tuns16: size = 2; break; | |
1008 case Tint32: | |
1009 case Tuns32: | |
1010 case Tfloat32: | |
1011 case Timaginary32: | |
1012 size = 4; break; | |
1013 case Tint64: | |
1014 case Tuns64: | |
1015 case Tfloat64: | |
1016 case Timaginary64: | |
1017 size = 8; break; | |
1018 case Tfloat80: | |
1019 case Timaginary80: | |
1020 size = REALSIZE; break; | |
1021 case Tcomplex32: | |
1022 size = 8; break; | |
1023 case Tcomplex64: | |
1024 size = 16; break; | |
1025 case Tcomplex80: | |
1026 size = REALSIZE * 2; break; | |
1027 | |
1028 case Tvoid: | |
1029 //size = Type::size(); // error message | |
1030 size = 1; | |
1031 break; | |
1032 | |
1033 case Tbit: size = 1; break; | |
1034 case Tbool: size = 1; break; | |
1035 case Tascii: size = 1; break; | |
1036 case Twchar: size = 2; break; | |
1037 case Tdchar: size = 4; break; | |
1038 | |
1039 default: | |
1040 assert(0); | |
1041 break; | |
1042 } | |
1043 //printf("TypeBasic::size() = %d\n", size); | |
1044 return size; | |
1045 } | |
1046 | |
1047 unsigned TypeBasic::alignsize() | |
1009
b1b23a64ad8c
Use LLVM alignment data instead of hand-picked.
Frits van Bommel <fvbommel wxs.nl>
parents:
1008
diff
changeset
|
1048 { |
1014
47f8b54f90b3
Fixed alignsize for void types. (it's one byte)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
1009
diff
changeset
|
1049 if (ty == Tvoid) |
47f8b54f90b3
Fixed alignsize for void types. (it's one byte)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
1009
diff
changeset
|
1050 return 1; |
1147
dbe4af57b240
Changed use of toObjFile to a new codegen method.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1146
diff
changeset
|
1051 return GetTypeAlignment(sir, this); |
159 | 1052 } |
1053 | |
1054 | |
1055 Expression *TypeBasic::getProperty(Loc loc, Identifier *ident) | |
1056 { | |
1057 Expression *e; | |
1058 d_int64 ivalue; | |
1059 #ifdef IN_GCC | |
1060 real_t fvalue; | |
1061 #else | |
1062 d_float80 fvalue; | |
1063 #endif | |
1064 | |
1065 //printf("TypeBasic::getProperty('%s')\n", ident->toChars()); | |
1066 if (ident == Id::max) | |
1067 { | |
1068 switch (ty) | |
1069 { | |
1070 case Tint8: ivalue = 0x7F; goto Livalue; | |
1071 case Tuns8: ivalue = 0xFF; goto Livalue; | |
1072 case Tint16: ivalue = 0x7FFFUL; goto Livalue; | |
1073 case Tuns16: ivalue = 0xFFFFUL; goto Livalue; | |
1074 case Tint32: ivalue = 0x7FFFFFFFUL; goto Livalue; | |
1075 case Tuns32: ivalue = 0xFFFFFFFFUL; goto Livalue; | |
1076 case Tint64: ivalue = 0x7FFFFFFFFFFFFFFFLL; goto Livalue; | |
1077 case Tuns64: ivalue = 0xFFFFFFFFFFFFFFFFULL; goto Livalue; | |
1078 case Tbit: ivalue = 1; goto Livalue; | |
1079 case Tbool: ivalue = 1; goto Livalue; | |
1080 case Tchar: ivalue = 0xFF; goto Livalue; | |
1081 case Twchar: ivalue = 0xFFFFUL; goto Livalue; | |
1082 case Tdchar: ivalue = 0x10FFFFUL; goto Livalue; | |
1083 | |
1084 case Tcomplex32: | |
1085 case Timaginary32: | |
1086 case Tfloat32: fvalue = FLT_MAX; goto Lfvalue; | |
1087 case Tcomplex64: | |
1088 case Timaginary64: | |
1089 case Tfloat64: fvalue = DBL_MAX; goto Lfvalue; | |
1090 case Tcomplex80: | |
1091 case Timaginary80: | |
1092 case Tfloat80: fvalue = LDBL_MAX; goto Lfvalue; | |
1093 } | |
1094 } | |
1095 else if (ident == Id::min) | |
1096 { | |
1097 switch (ty) | |
1098 { | |
1099 case Tint8: ivalue = -128; goto Livalue; | |
1100 case Tuns8: ivalue = 0; goto Livalue; | |
1101 case Tint16: ivalue = -32768; goto Livalue; | |
1102 case Tuns16: ivalue = 0; goto Livalue; | |
1103 case Tint32: ivalue = -2147483647L - 1; goto Livalue; | |
1104 case Tuns32: ivalue = 0; goto Livalue; | |
1105 case Tint64: ivalue = (-9223372036854775807LL-1LL); goto Livalue; | |
1106 case Tuns64: ivalue = 0; goto Livalue; | |
1107 case Tbit: ivalue = 0; goto Livalue; | |
1108 case Tbool: ivalue = 0; goto Livalue; | |
1109 case Tchar: ivalue = 0; goto Livalue; | |
1110 case Twchar: ivalue = 0; goto Livalue; | |
1111 case Tdchar: ivalue = 0; goto Livalue; | |
1112 | |
1113 case Tcomplex32: | |
1114 case Timaginary32: | |
1115 case Tfloat32: fvalue = FLT_MIN; goto Lfvalue; | |
1116 case Tcomplex64: | |
1117 case Timaginary64: | |
1118 case Tfloat64: fvalue = DBL_MIN; goto Lfvalue; | |
1119 case Tcomplex80: | |
1120 case Timaginary80: | |
1121 case Tfloat80: fvalue = LDBL_MIN; goto Lfvalue; | |
1122 } | |
1123 } | |
1124 else if (ident == Id::nan) | |
1125 { | |
1126 switch (ty) | |
1127 { | |
1128 case Tcomplex32: | |
1129 case Tcomplex64: | |
1130 case Tcomplex80: | |
1131 case Timaginary32: | |
1132 case Timaginary64: | |
1133 case Timaginary80: | |
1134 case Tfloat32: | |
1135 case Tfloat64: | |
1136 case Tfloat80: | |
1137 { | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
1138 fvalue = Port::nan; |
159 | 1139 goto Lfvalue; |
1140 } | |
1141 } | |
1142 } | |
1143 else if (ident == Id::infinity) | |
1144 { | |
1145 switch (ty) | |
1146 { | |
1147 case Tcomplex32: | |
1148 case Tcomplex64: | |
1149 case Tcomplex80: | |
1150 case Timaginary32: | |
1151 case Timaginary64: | |
1152 case Timaginary80: | |
1153 case Tfloat32: | |
1154 case Tfloat64: | |
1155 case Tfloat80: | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
1156 fvalue = Port::infinity; |
159 | 1157 goto Lfvalue; |
1158 } | |
1159 } | |
1160 else if (ident == Id::dig) | |
1161 { | |
1162 switch (ty) | |
1163 { | |
1164 case Tcomplex32: | |
1165 case Timaginary32: | |
1166 case Tfloat32: ivalue = FLT_DIG; goto Lint; | |
1167 case Tcomplex64: | |
1168 case Timaginary64: | |
1169 case Tfloat64: ivalue = DBL_DIG; goto Lint; | |
1170 case Tcomplex80: | |
1171 case Timaginary80: | |
1172 case Tfloat80: ivalue = LDBL_DIG; goto Lint; | |
1173 } | |
1174 } | |
1175 else if (ident == Id::epsilon) | |
1176 { | |
1177 switch (ty) | |
1178 { | |
1179 case Tcomplex32: | |
1180 case Timaginary32: | |
1181 case Tfloat32: fvalue = FLT_EPSILON; goto Lfvalue; | |
1182 case Tcomplex64: | |
1183 case Timaginary64: | |
1184 case Tfloat64: fvalue = DBL_EPSILON; goto Lfvalue; | |
1185 case Tcomplex80: | |
1186 case Timaginary80: | |
1187 case Tfloat80: fvalue = LDBL_EPSILON; goto Lfvalue; | |
1188 } | |
1189 } | |
1190 else if (ident == Id::mant_dig) | |
1191 { | |
1192 switch (ty) | |
1193 { | |
1194 case Tcomplex32: | |
1195 case Timaginary32: | |
1196 case Tfloat32: ivalue = FLT_MANT_DIG; goto Lint; | |
1197 case Tcomplex64: | |
1198 case Timaginary64: | |
1199 case Tfloat64: ivalue = DBL_MANT_DIG; goto Lint; | |
1200 case Tcomplex80: | |
1201 case Timaginary80: | |
1202 case Tfloat80: ivalue = LDBL_MANT_DIG; goto Lint; | |
1203 } | |
1204 } | |
1205 else if (ident == Id::max_10_exp) | |
1206 { | |
1207 switch (ty) | |
1208 { | |
1209 case Tcomplex32: | |
1210 case Timaginary32: | |
1211 case Tfloat32: ivalue = FLT_MAX_10_EXP; goto Lint; | |
1212 case Tcomplex64: | |
1213 case Timaginary64: | |
1214 case Tfloat64: ivalue = DBL_MAX_10_EXP; goto Lint; | |
1215 case Tcomplex80: | |
1216 case Timaginary80: | |
1217 case Tfloat80: ivalue = LDBL_MAX_10_EXP; goto Lint; | |
1218 } | |
1219 } | |
1220 else if (ident == Id::max_exp) | |
1221 { | |
1222 switch (ty) | |
1223 { | |
1224 case Tcomplex32: | |
1225 case Timaginary32: | |
1226 case Tfloat32: ivalue = FLT_MAX_EXP; goto Lint; | |
1227 case Tcomplex64: | |
1228 case Timaginary64: | |
1229 case Tfloat64: ivalue = DBL_MAX_EXP; goto Lint; | |
1230 case Tcomplex80: | |
1231 case Timaginary80: | |
1232 case Tfloat80: ivalue = LDBL_MAX_EXP; goto Lint; | |
1233 } | |
1234 } | |
1235 else if (ident == Id::min_10_exp) | |
1236 { | |
1237 switch (ty) | |
1238 { | |
1239 case Tcomplex32: | |
1240 case Timaginary32: | |
1241 case Tfloat32: ivalue = FLT_MIN_10_EXP; goto Lint; | |
1242 case Tcomplex64: | |
1243 case Timaginary64: | |
1244 case Tfloat64: ivalue = DBL_MIN_10_EXP; goto Lint; | |
1245 case Tcomplex80: | |
1246 case Timaginary80: | |
1247 case Tfloat80: ivalue = LDBL_MIN_10_EXP; goto Lint; | |
1248 } | |
1249 } | |
1250 else if (ident == Id::min_exp) | |
1251 { | |
1252 switch (ty) | |
1253 { | |
1254 case Tcomplex32: | |
1255 case Timaginary32: | |
1256 case Tfloat32: ivalue = FLT_MIN_EXP; goto Lint; | |
1257 case Tcomplex64: | |
1258 case Timaginary64: | |
1259 case Tfloat64: ivalue = DBL_MIN_EXP; goto Lint; | |
1260 case Tcomplex80: | |
1261 case Timaginary80: | |
1262 case Tfloat80: ivalue = LDBL_MIN_EXP; goto Lint; | |
1263 } | |
1264 } | |
1265 | |
1266 Ldefault: | |
1267 return Type::getProperty(loc, ident); | |
1268 | |
1269 Livalue: | |
1270 e = new IntegerExp(loc, ivalue, this); | |
1271 return e; | |
1272 | |
1273 Lfvalue: | |
1274 if (isreal() || isimaginary()) | |
1275 e = new RealExp(loc, fvalue, this); | |
1276 else | |
1277 { | |
1278 complex_t cvalue; | |
1279 | |
1280 #if __DMC__ | |
1281 //((real_t *)&cvalue)[0] = fvalue; | |
1282 //((real_t *)&cvalue)[1] = fvalue; | |
1283 cvalue = fvalue + fvalue * I; | |
1284 #else | |
1285 cvalue.re = fvalue; | |
1286 cvalue.im = fvalue; | |
1287 #endif | |
1288 //for (int i = 0; i < 20; i++) | |
1289 // printf("%02x ", ((unsigned char *)&cvalue)[i]); | |
1290 //printf("\n"); | |
1291 e = new ComplexExp(loc, cvalue, this); | |
1292 } | |
1293 return e; | |
1294 | |
1295 Lint: | |
1296 e = new IntegerExp(loc, ivalue, Type::tint32); | |
1297 return e; | |
1298 } | |
1299 | |
1300 Expression *TypeBasic::dotExp(Scope *sc, Expression *e, Identifier *ident) | |
1301 { | |
1302 #if LOGDOTEXP | |
1303 printf("TypeBasic::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); | |
1304 #endif | |
1305 Type *t; | |
1306 | |
1307 if (ident == Id::re) | |
1308 { | |
1309 switch (ty) | |
1310 { | |
1311 case Tcomplex32: t = tfloat32; goto L1; | |
1312 case Tcomplex64: t = tfloat64; goto L1; | |
1313 case Tcomplex80: t = tfloat80; goto L1; | |
1314 L1: | |
1315 e = e->castTo(sc, t); | |
1316 break; | |
1317 | |
1318 case Tfloat32: | |
1319 case Tfloat64: | |
1320 case Tfloat80: | |
1321 break; | |
1322 | |
1323 case Timaginary32: t = tfloat32; goto L2; | |
1324 case Timaginary64: t = tfloat64; goto L2; | |
1325 case Timaginary80: t = tfloat80; goto L2; | |
1326 L2: | |
1327 e = new RealExp(0, 0.0, t); | |
1328 break; | |
1329 | |
1330 default: | |
1331 return Type::getProperty(e->loc, ident); | |
1332 } | |
1333 } | |
1334 else if (ident == Id::im) | |
1335 { Type *t2; | |
1336 | |
1337 switch (ty) | |
1338 { | |
1339 case Tcomplex32: t = timaginary32; t2 = tfloat32; goto L3; | |
1340 case Tcomplex64: t = timaginary64; t2 = tfloat64; goto L3; | |
1341 case Tcomplex80: t = timaginary80; t2 = tfloat80; goto L3; | |
1342 L3: | |
1343 e = e->castTo(sc, t); | |
1344 e->type = t2; | |
1345 break; | |
1346 | |
1347 case Timaginary32: t = tfloat32; goto L4; | |
1348 case Timaginary64: t = tfloat64; goto L4; | |
1349 case Timaginary80: t = tfloat80; goto L4; | |
1350 L4: | |
1351 e->type = t; | |
1352 break; | |
1353 | |
1354 case Tfloat32: | |
1355 case Tfloat64: | |
1356 case Tfloat80: | |
1357 e = new RealExp(0, 0.0, this); | |
1358 break; | |
1359 | |
1360 default: | |
1361 return Type::getProperty(e->loc, ident); | |
1362 } | |
1363 } | |
1364 else | |
1365 { | |
1366 return Type::dotExp(sc, e, ident); | |
1367 } | |
1368 return e; | |
1369 } | |
1370 | |
1371 Expression *TypeBasic::defaultInit(Loc loc) | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
1372 { dinteger_t value = 0; |
159 | 1373 |
1374 #if LOGDEFAULTINIT | |
1375 printf("TypeBasic::defaultInit() '%s'\n", toChars()); | |
1376 #endif | |
1377 switch (ty) | |
1378 { | |
591
e6bcc4d9e5ff
Add _d_newarrayvT and _d_newarraymvT to create arrays without initialization.
Christian Kamm <kamm incasoftware de>
parents:
585
diff
changeset
|
1379 case Tvoid: |
e6bcc4d9e5ff
Add _d_newarrayvT and _d_newarraymvT to create arrays without initialization.
Christian Kamm <kamm incasoftware de>
parents:
585
diff
changeset
|
1380 return new IntegerExp(loc, value, Type::tbool); |
e6bcc4d9e5ff
Add _d_newarrayvT and _d_newarraymvT to create arrays without initialization.
Christian Kamm <kamm incasoftware de>
parents:
585
diff
changeset
|
1381 |
159 | 1382 case Tchar: |
1383 value = 0xFF; | |
1384 break; | |
1385 | |
1386 case Twchar: | |
1387 case Tdchar: | |
1388 value = 0xFFFF; | |
1389 break; | |
1390 | |
1391 case Timaginary32: | |
1392 case Timaginary64: | |
1393 case Timaginary80: | |
1394 case Tfloat32: | |
1395 case Tfloat64: | |
1396 case Tfloat80: | |
1397 case Tcomplex32: | |
1398 case Tcomplex64: | |
1399 case Tcomplex80: | |
1400 return getProperty(loc, Id::nan); | |
1401 } | |
1402 return new IntegerExp(loc, value, this); | |
1403 } | |
1404 | |
1405 int TypeBasic::isZeroInit() | |
1406 { | |
1407 switch (ty) | |
1408 { | |
1409 case Tchar: | |
1410 case Twchar: | |
1411 case Tdchar: | |
1412 case Timaginary32: | |
1413 case Timaginary64: | |
1414 case Timaginary80: | |
1415 case Tfloat32: | |
1416 case Tfloat64: | |
1417 case Tfloat80: | |
1418 case Tcomplex32: | |
1419 case Tcomplex64: | |
1420 case Tcomplex80: | |
1421 return 0; // no | |
1422 } | |
1423 return 1; // yes | |
1424 } | |
1425 | |
1426 int TypeBasic::isbit() | |
1427 { | |
1428 return (ty == Tbit); | |
1429 } | |
1430 | |
1431 int TypeBasic::isintegral() | |
1432 { | |
1433 //printf("TypeBasic::isintegral('%s') x%x\n", toChars(), flags); | |
1434 return flags & TFLAGSintegral; | |
1435 } | |
1436 | |
1437 int TypeBasic::isfloating() | |
1438 { | |
1439 return flags & TFLAGSfloating; | |
1440 } | |
1441 | |
1442 int TypeBasic::isreal() | |
1443 { | |
1444 return flags & TFLAGSreal; | |
1445 } | |
1446 | |
1447 int TypeBasic::isimaginary() | |
1448 { | |
1449 return flags & TFLAGSimaginary; | |
1450 } | |
1451 | |
1452 int TypeBasic::iscomplex() | |
1453 { | |
1454 return flags & TFLAGScomplex; | |
1455 } | |
1456 | |
1457 int TypeBasic::isunsigned() | |
1458 { | |
1459 return flags & TFLAGSunsigned; | |
1460 } | |
1461 | |
1462 int TypeBasic::isscalar() | |
1463 { | |
1464 return flags & (TFLAGSintegral | TFLAGSfloating); | |
1465 } | |
1466 | |
1467 MATCH TypeBasic::implicitConvTo(Type *to) | |
1468 { | |
1469 //printf("TypeBasic::implicitConvTo(%s) from %s\n", to->toChars(), toChars()); | |
1470 if (this == to) | |
1471 return MATCHexact; | |
1472 | |
1473 if (ty == Tvoid || to->ty == Tvoid) | |
1474 return MATCHnomatch; | |
1475 if (1 || global.params.Dversion == 1) | |
1476 { | |
1477 if (to->ty == Tbool) | |
1478 return MATCHnomatch; | |
1479 } | |
1480 else | |
1481 { | |
1482 if (ty == Tbool || to->ty == Tbool) | |
1483 return MATCHnomatch; | |
1484 } | |
1485 if (!to->isTypeBasic()) | |
1486 return MATCHnomatch; | |
1487 | |
1488 TypeBasic *tob = (TypeBasic *)to; | |
1489 if (flags & TFLAGSintegral) | |
1490 { | |
1491 // Disallow implicit conversion of integers to imaginary or complex | |
1492 if (tob->flags & (TFLAGSimaginary | TFLAGScomplex)) | |
1493 return MATCHnomatch; | |
1494 | |
1495 // If converting to integral | |
1496 if (0 && global.params.Dversion > 1 && tob->flags & TFLAGSintegral) | |
1497 { d_uns64 sz = size(0); | |
1498 d_uns64 tosz = tob->size(0); | |
1499 | |
1500 /* Can't convert to smaller size or, if same size, change sign | |
1501 */ | |
1502 if (sz > tosz) | |
1503 return MATCHnomatch; | |
1504 | |
1505 /*if (sz == tosz && (flags ^ tob->flags) & TFLAGSunsigned) | |
1506 return MATCHnomatch;*/ | |
1507 } | |
1508 } | |
1509 else if (flags & TFLAGSfloating) | |
1510 { | |
1511 // Disallow implicit conversion of floating point to integer | |
1512 if (tob->flags & TFLAGSintegral) | |
1513 return MATCHnomatch; | |
1514 | |
1515 assert(tob->flags & TFLAGSfloating); | |
1516 | |
1517 // Disallow implicit conversion from complex to non-complex | |
1518 if (flags & TFLAGScomplex && !(tob->flags & TFLAGScomplex)) | |
1519 return MATCHnomatch; | |
1520 | |
1521 // Disallow implicit conversion of real or imaginary to complex | |
1522 if (flags & (TFLAGSreal | TFLAGSimaginary) && | |
1523 tob->flags & TFLAGScomplex) | |
1524 return MATCHnomatch; | |
1525 | |
1526 // Disallow implicit conversion to-from real and imaginary | |
1527 if ((flags & (TFLAGSreal | TFLAGSimaginary)) != | |
1528 (tob->flags & (TFLAGSreal | TFLAGSimaginary))) | |
1529 return MATCHnomatch; | |
1530 } | |
1531 return MATCHconvert; | |
1532 } | |
1533 | |
1534 TypeBasic *TypeBasic::isTypeBasic() | |
1535 { | |
1536 return (TypeBasic *)this; | |
1537 } | |
1538 | |
1539 /***************************** TypeArray *****************************/ | |
1540 | |
1541 TypeArray::TypeArray(TY ty, Type *next) | |
1542 : Type(ty, next) | |
1543 { | |
1544 } | |
1545 | |
1546 Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident) | |
1547 { | |
1548 Type *n = this->next->toBasetype(); // uncover any typedef's | |
1549 | |
1550 #if LOGDOTEXP | |
1551 printf("TypeArray::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); | |
1552 #endif | |
1553 if (ident == Id::reverse && (n->ty == Tchar || n->ty == Twchar)) | |
1554 { | |
1555 Expression *ec; | |
1556 Expressions *arguments; | |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1557 |
664
eef8ac26c66c
Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents:
658
diff
changeset
|
1558 //LDC: Build arguments. |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1559 static FuncDeclaration *adReverseChar_fd = NULL; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1560 if(!adReverseChar_fd) { |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1561 Arguments* args = new Arguments; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1562 Type* arrty = Type::tchar->arrayOf(); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1563 args->push(new Argument(STCin, arrty, NULL, NULL)); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1564 adReverseChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseChar"); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1565 } |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1566 static FuncDeclaration *adReverseWchar_fd = NULL; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1567 if(!adReverseWchar_fd) { |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1568 Arguments* args = new Arguments; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1569 Type* arrty = Type::twchar->arrayOf(); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1570 args->push(new Argument(STCin, arrty, NULL, NULL)); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1571 adReverseWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseWchar"); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1572 } |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1573 |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1574 if(n->ty == Twchar) |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1575 ec = new VarExp(0, adReverseWchar_fd); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1576 else |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1577 ec = new VarExp(0, adReverseChar_fd); |
159 | 1578 e = e->castTo(sc, n->arrayOf()); // convert to dynamic array |
1579 arguments = new Expressions(); | |
1580 arguments->push(e); | |
1581 e = new CallExp(e->loc, ec, arguments); | |
1582 e->type = next->arrayOf(); | |
1583 } | |
1584 else if (ident == Id::sort && (n->ty == Tchar || n->ty == Twchar)) | |
1585 { | |
1586 Expression *ec; | |
1587 Expressions *arguments; | |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1588 |
664
eef8ac26c66c
Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents:
658
diff
changeset
|
1589 //LDC: Build arguments. |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1590 static FuncDeclaration *adSortChar_fd = NULL; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1591 if(!adSortChar_fd) { |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1592 Arguments* args = new Arguments; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1593 Type* arrty = Type::tchar->arrayOf(); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1594 args->push(new Argument(STCin, arrty, NULL, NULL)); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1595 adSortChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortChar"); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1596 } |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1597 static FuncDeclaration *adSortWchar_fd = NULL; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1598 if(!adSortWchar_fd) { |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1599 Arguments* args = new Arguments; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1600 Type* arrty = Type::twchar->arrayOf(); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1601 args->push(new Argument(STCin, arrty, NULL, NULL)); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1602 adSortWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortWchar"); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1603 } |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1604 |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1605 if(n->ty == Twchar) |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1606 ec = new VarExp(0, adSortWchar_fd); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1607 else |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1608 ec = new VarExp(0, adSortChar_fd); |
159 | 1609 e = e->castTo(sc, n->arrayOf()); // convert to dynamic array |
1610 arguments = new Expressions(); | |
1611 arguments->push(e); | |
1612 e = new CallExp(e->loc, ec, arguments); | |
1613 e->type = next->arrayOf(); | |
1614 } | |
1615 else if (ident == Id::reverse || ident == Id::dup) | |
1616 { | |
1617 Expression *ec; | |
1618 Expressions *arguments; | |
1619 int size = next->size(e->loc); | |
1620 int dup; | |
1621 | |
1622 assert(size); | |
1623 dup = (ident == Id::dup); | |
664
eef8ac26c66c
Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents:
658
diff
changeset
|
1624 //LDC: Build arguments. |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1625 static FuncDeclaration *adDup_fd = NULL; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1626 if(!adDup_fd) { |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1627 Arguments* args = new Arguments; |
378
d8234836b40f
Get rid of runTimeHack and instead add proper argument info to the frontend
Christian Kamm <kamm incasoftware de>
parents:
375
diff
changeset
|
1628 args->push(new Argument(STCin, Type::typeinfo->type, NULL, NULL)); |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1629 args->push(new Argument(STCin, Type::tvoid->arrayOf(), NULL, NULL)); |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1630 adDup_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adDup); |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1631 } |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1632 static FuncDeclaration *adReverse_fd = NULL; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1633 if(!adReverse_fd) { |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1634 Arguments* args = new Arguments; |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1635 args->push(new Argument(STCin, Type::tvoid->arrayOf(), NULL, NULL)); |
378
d8234836b40f
Get rid of runTimeHack and instead add proper argument info to the frontend
Christian Kamm <kamm incasoftware de>
parents:
375
diff
changeset
|
1636 args->push(new Argument(STCin, Type::tsize_t, NULL, NULL)); |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1637 adReverse_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adReverse); |
378
d8234836b40f
Get rid of runTimeHack and instead add proper argument info to the frontend
Christian Kamm <kamm incasoftware de>
parents:
375
diff
changeset
|
1638 } |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1639 |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1640 if(dup) |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1641 ec = new VarExp(0, adDup_fd); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1642 else |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1643 ec = new VarExp(0, adReverse_fd); |
159 | 1644 e = e->castTo(sc, n->arrayOf()); // convert to dynamic array |
1645 arguments = new Expressions(); | |
1646 if (dup) | |
1647 arguments->push(getTypeInfo(sc)); | |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1648 |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1649 // LDC repaint array type to void[] |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1650 if (n->ty != Tvoid) { |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1651 e = new CastExp(e->loc, e, e->type); |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1652 e->type = Type::tvoid->arrayOf(); |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1653 } |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1654 arguments->push(e); |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1655 |
159 | 1656 if (!dup) |
881
1c2faa8325d1
Fixed 64bit problem in mtype.c with _adReverse runtime call, fixes #161 .
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
875
diff
changeset
|
1657 arguments->push(new IntegerExp(0, size, Type::tsize_t)); |
159 | 1658 e = new CallExp(e->loc, ec, arguments); |
1659 e->type = next->arrayOf(); | |
1660 } | |
1661 else if (ident == Id::sort) | |
1662 { | |
1663 Expression *ec; | |
1664 Expressions *arguments; | |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1665 bool isBit = (n->ty == Tbit); |
159 | 1666 |
664
eef8ac26c66c
Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents:
658
diff
changeset
|
1667 //LDC: Build arguments. |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1668 static FuncDeclaration *adSort_fd = NULL; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1669 if(!adSort_fd) { |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1670 Arguments* args = new Arguments; |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1671 args->push(new Argument(STCin, Type::tvoid->arrayOf(), NULL, NULL)); |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1672 args->push(new Argument(STCin, Type::typeinfo->type, NULL, NULL)); |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1673 adSort_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSort"); |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1674 } |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1675 static FuncDeclaration *adSortBit_fd = NULL; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1676 if(!adSortBit_fd) { |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1677 Arguments* args = new Arguments; |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1678 args->push(new Argument(STCin, Type::tvoid->arrayOf(), NULL, NULL)); |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1679 args->push(new Argument(STCin, Type::typeinfo->type, NULL, NULL)); |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1680 adSortBit_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSortBit"); |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1681 } |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1682 |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1683 if(isBit) |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1684 ec = new VarExp(0, adSortBit_fd); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1685 else |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
1686 ec = new VarExp(0, adSort_fd); |
159 | 1687 e = e->castTo(sc, n->arrayOf()); // convert to dynamic array |
1688 arguments = new Expressions(); | |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1689 |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1690 // LDC repaint array type to void[] |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1691 if (n->ty != Tvoid) { |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1692 e = new CastExp(e->loc, e, e->type); |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1693 e->type = Type::tvoid->arrayOf(); |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1694 } |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1695 arguments->push(e); |
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
1696 |
509
337554fd34f1
Fixed mini/missingti.d
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
489
diff
changeset
|
1697 if (next->ty != Tbit) |
664
eef8ac26c66c
Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents:
658
diff
changeset
|
1698 arguments->push(n->getTypeInfo(sc)); // LDC, we don't support the getInternalTypeInfo |
509
337554fd34f1
Fixed mini/missingti.d
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
489
diff
changeset
|
1699 // optimization arbitrarily, not yet at least... |
159 | 1700 e = new CallExp(e->loc, ec, arguments); |
1701 e->type = next->arrayOf(); | |
1702 } | |
1703 else | |
1704 { | |
1705 e = Type::dotExp(sc, e, ident); | |
1706 } | |
1707 return e; | |
1708 } | |
1709 | |
1710 | |
1711 /***************************** TypeSArray *****************************/ | |
1712 | |
1713 TypeSArray::TypeSArray(Type *t, Expression *dim) | |
1714 : TypeArray(Tsarray, t) | |
1715 { | |
1716 //printf("TypeSArray(%s)\n", dim->toChars()); | |
1717 this->dim = dim; | |
1718 } | |
1719 | |
1720 Type *TypeSArray::syntaxCopy() | |
1721 { | |
1722 Type *t = next->syntaxCopy(); | |
1723 Expression *e = dim->syntaxCopy(); | |
1724 t = new TypeSArray(t, e); | |
1725 return t; | |
1726 } | |
1727 | |
1728 d_uns64 TypeSArray::size(Loc loc) | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
1729 { dinteger_t sz; |
159 | 1730 |
1731 if (!dim) | |
1732 return Type::size(loc); | |
1733 sz = dim->toInteger(); | |
1734 if (next->toBasetype()->ty == Tbit) // if array of bits | |
1735 { | |
1736 if (sz + 31 < sz) | |
1737 goto Loverflow; | |
1738 sz = ((sz + 31) & ~31) / 8; // size in bytes, rounded up to 32 bit dwords | |
1739 } | |
1740 else | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
1741 { dinteger_t n, n2; |
159 | 1742 |
1743 n = next->size(); | |
1744 n2 = n * sz; | |
1745 if (n && (n2 / n) != sz) | |
1746 goto Loverflow; | |
1747 sz = n2; | |
1748 } | |
1749 return sz; | |
1750 | |
1751 Loverflow: | |
1133
eeb8b95ea92e
Cleanup DMD 1.041 merge.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1124
diff
changeset
|
1752 error(loc, "index %jd overflow for static array", sz); |
159 | 1753 return 1; |
1754 } | |
1755 | |
1756 unsigned TypeSArray::alignsize() | |
1757 { | |
1758 return next->alignsize(); | |
1759 } | |
1760 | |
1761 /************************** | |
1762 * This evaluates exp while setting length to be the number | |
1763 * of elements in the tuple t. | |
1764 */ | |
1765 Expression *semanticLength(Scope *sc, Type *t, Expression *exp) | |
1766 { | |
1767 if (t->ty == Ttuple) | |
1768 { ScopeDsymbol *sym = new ArrayScopeSymbol((TypeTuple *)t); | |
1769 sym->parent = sc->scopesym; | |
1770 sc = sc->push(sym); | |
1771 | |
1772 exp = exp->semantic(sc); | |
1773 | |
1774 sc->pop(); | |
1775 } | |
1776 else | |
1777 exp = exp->semantic(sc); | |
1778 return exp; | |
1779 } | |
1780 | |
1781 Expression *semanticLength(Scope *sc, TupleDeclaration *s, Expression *exp) | |
1782 { | |
1783 ScopeDsymbol *sym = new ArrayScopeSymbol(s); | |
1784 sym->parent = sc->scopesym; | |
1785 sc = sc->push(sym); | |
1786 | |
1787 exp = exp->semantic(sc); | |
1788 | |
1789 sc->pop(); | |
1790 return exp; | |
1791 } | |
1792 | |
1793 void TypeSArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) | |
1794 { | |
1795 //printf("TypeSArray::resolve() %s\n", toChars()); | |
1796 next->resolve(loc, sc, pe, pt, ps); | |
1797 //printf("s = %p, e = %p, t = %p\n", *ps, *pe, *pt); | |
1798 if (*pe) | |
1799 { // It's really an index expression | |
1800 Expression *e; | |
1801 e = new IndexExp(loc, *pe, dim); | |
1802 *pe = e; | |
1803 } | |
1804 else if (*ps) | |
1805 { Dsymbol *s = *ps; | |
1806 TupleDeclaration *td = s->isTupleDeclaration(); | |
1807 if (td) | |
1808 { | |
1809 ScopeDsymbol *sym = new ArrayScopeSymbol(td); | |
1810 sym->parent = sc->scopesym; | |
1811 sc = sc->push(sym); | |
1812 | |
1813 dim = dim->semantic(sc); | |
1814 dim = dim->optimize(WANTvalue | WANTinterpret); | |
1815 uinteger_t d = dim->toUInteger(); | |
1816 | |
1817 sc = sc->pop(); | |
1818 | |
1819 if (d >= td->objects->dim) | |
1133
eeb8b95ea92e
Cleanup DMD 1.041 merge.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1124
diff
changeset
|
1820 { error(loc, "tuple index %ju exceeds %u", d, td->objects->dim); |
159 | 1821 goto Ldefault; |
1822 } | |
1823 Object *o = (Object *)td->objects->data[(size_t)d]; | |
1824 if (o->dyncast() == DYNCAST_DSYMBOL) | |
1825 { | |
1826 *ps = (Dsymbol *)o; | |
1827 return; | |
1828 } | |
1829 if (o->dyncast() == DYNCAST_EXPRESSION) | |
1830 { | |
1831 *ps = NULL; | |
1832 *pe = (Expression *)o; | |
1833 return; | |
1834 } | |
1835 | |
1836 /* Create a new TupleDeclaration which | |
1837 * is a slice [d..d+1] out of the old one. | |
1838 * Do it this way because TemplateInstance::semanticTiargs() | |
1839 * can handle unresolved Objects this way. | |
1840 */ | |
1841 Objects *objects = new Objects; | |
1842 objects->setDim(1); | |
1843 objects->data[0] = o; | |
1844 | |
1845 TupleDeclaration *tds = new TupleDeclaration(loc, td->ident, objects); | |
1846 *ps = tds; | |
1847 } | |
1848 else | |
1849 goto Ldefault; | |
1850 } | |
1851 else | |
1852 { | |
1853 Ldefault: | |
1854 Type::resolve(loc, sc, pe, pt, ps); | |
1855 } | |
1856 } | |
1857 | |
1858 Type *TypeSArray::semantic(Loc loc, Scope *sc) | |
1859 { | |
1860 //printf("TypeSArray::semantic() %s\n", toChars()); | |
1861 | |
1862 Type *t; | |
1863 Expression *e; | |
1864 Dsymbol *s; | |
1865 next->resolve(loc, sc, &e, &t, &s); | |
1866 if (dim && s && s->isTupleDeclaration()) | |
1867 { TupleDeclaration *sd = s->isTupleDeclaration(); | |
1868 | |
1869 dim = semanticLength(sc, sd, dim); | |
1870 dim = dim->optimize(WANTvalue | WANTinterpret); | |
1871 uinteger_t d = dim->toUInteger(); | |
1872 | |
1873 if (d >= sd->objects->dim) | |
1133
eeb8b95ea92e
Cleanup DMD 1.041 merge.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1124
diff
changeset
|
1874 { error(loc, "tuple index %ju exceeds %u", d, sd->objects->dim); |
159 | 1875 return Type::terror; |
1876 } | |
1877 Object *o = (Object *)sd->objects->data[(size_t)d]; | |
1878 if (o->dyncast() != DYNCAST_TYPE) | |
1879 { error(loc, "%s is not a type", toChars()); | |
1880 return Type::terror; | |
1881 } | |
1882 t = (Type *)o; | |
1883 return t; | |
1884 } | |
1885 | |
1886 next = next->semantic(loc,sc); | |
1887 Type *tbn = next->toBasetype(); | |
1888 | |
1889 if (dim) | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
1890 { dinteger_t n, n2; |
159 | 1891 |
1892 dim = semanticLength(sc, tbn, dim); | |
1893 | |
1894 dim = dim->optimize(WANTvalue | WANTinterpret); | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
1895 if (sc && sc->parameterSpecialization && dim->op == TOKvar && |
159 | 1896 ((VarExp *)dim)->var->storage_class & STCtemplateparameter) |
1897 { | |
1898 /* It could be a template parameter N which has no value yet: | |
1899 * template Foo(T : T[N], size_t N); | |
1900 */ | |
1901 return this; | |
1902 } | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
1903 dinteger_t d1 = dim->toInteger(); |
159 | 1904 dim = dim->castTo(sc, tsize_t); |
1905 dim = dim->optimize(WANTvalue); | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
1906 dinteger_t d2 = dim->toInteger(); |
159 | 1907 |
1908 if (d1 != d2) | |
1909 goto Loverflow; | |
1910 | |
1911 if (tbn->isintegral() || | |
1912 tbn->isfloating() || | |
1913 tbn->ty == Tpointer || | |
1914 tbn->ty == Tarray || | |
1915 tbn->ty == Tsarray || | |
1916 tbn->ty == Taarray || | |
1917 tbn->ty == Tclass) | |
1918 { | |
1919 /* Only do this for types that don't need to have semantic() | |
1920 * run on them for the size, since they may be forward referenced. | |
1921 */ | |
1922 n = tbn->size(loc); | |
1923 n2 = n * d2; | |
1924 if ((int)n2 < 0) | |
1925 goto Loverflow; | |
1926 if (n2 >= 0x1000000) // put a 'reasonable' limit on it | |
1927 goto Loverflow; | |
1928 if (n && n2 / n != d2) | |
1929 { | |
1930 Loverflow: | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
1931 error(loc, "index %jd overflow for static array", d1); |
159 | 1932 dim = new IntegerExp(0, 1, tsize_t); |
1933 } | |
1934 } | |
1935 } | |
1936 switch (tbn->ty) | |
1937 { | |
1938 case Ttuple: | |
1939 { // Index the tuple to get the type | |
1940 assert(dim); | |
1941 TypeTuple *tt = (TypeTuple *)tbn; | |
1942 uinteger_t d = dim->toUInteger(); | |
1943 | |
1944 if (d >= tt->arguments->dim) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
1945 { error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim); |
159 | 1946 return Type::terror; |
1947 } | |
1948 Argument *arg = (Argument *)tt->arguments->data[(size_t)d]; | |
1949 return arg->type; | |
1950 } | |
1951 case Tfunction: | |
1952 case Tnone: | |
1953 error(loc, "can't have array of %s", tbn->toChars()); | |
1954 tbn = next = tint32; | |
1955 break; | |
1956 } | |
1957 if (tbn->isauto()) | |
1958 error(loc, "cannot have array of auto %s", tbn->toChars()); | |
1959 return merge(); | |
1960 } | |
1961 | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
1962 void TypeSArray::toDecoBuffer(OutBuffer *buf, bool mangle) |
159 | 1963 { |
1964 buf->writeByte(mangleChar[ty]); | |
1965 if (dim) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
1966 buf->printf("%ju", dim->toInteger()); |
159 | 1967 if (next) |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
1968 next->toDecoBuffer(buf, mangle); |
159 | 1969 } |
1970 | |
1971 void TypeSArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
1972 { | |
1973 if (mod != this->mod) | |
1974 { toCBuffer3(buf, hgs, mod); | |
1975 return; | |
1976 } | |
1977 next->toCBuffer2(buf, hgs, this->mod); | |
1978 buf->printf("[%s]", dim->toChars()); | |
1979 } | |
1980 | |
1981 Expression *TypeSArray::dotExp(Scope *sc, Expression *e, Identifier *ident) | |
1982 { | |
1983 #if LOGDOTEXP | |
1984 printf("TypeSArray::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); | |
1985 #endif | |
1986 if (ident == Id::length) | |
1987 { | |
1988 e = dim; | |
1989 } | |
1990 else if (ident == Id::ptr) | |
1991 { | |
1992 e = e->castTo(sc, next->pointerTo()); | |
1993 } | |
1994 else | |
1995 { | |
1996 e = TypeArray::dotExp(sc, e, ident); | |
1997 } | |
1998 return e; | |
1999 } | |
2000 | |
2001 int TypeSArray::isString() | |
2002 { | |
2003 TY nty = next->toBasetype()->ty; | |
2004 return nty == Tchar || nty == Twchar || nty == Tdchar; | |
2005 } | |
2006 | |
2007 unsigned TypeSArray::memalign(unsigned salign) | |
2008 { | |
2009 return next->memalign(salign); | |
2010 } | |
2011 | |
2012 MATCH TypeSArray::implicitConvTo(Type *to) | |
2013 { | |
2014 //printf("TypeSArray::implicitConvTo()\n"); | |
2015 | |
2016 // Allow implicit conversion of static array to pointer or dynamic array | |
2017 if ((IMPLICIT_ARRAY_TO_PTR && to->ty == Tpointer) && | |
2018 (to->next->ty == Tvoid || next->equals(to->next) | |
2019 /*|| to->next->isBaseOf(next)*/)) | |
2020 { | |
2021 return MATCHconvert; | |
2022 } | |
2023 if (to->ty == Tarray) | |
2024 { int offset = 0; | |
2025 | |
2026 if (next->equals(to->next) || | |
2027 (to->next->isBaseOf(next, &offset) && offset == 0) || | |
2028 to->next->ty == Tvoid) | |
2029 return MATCHconvert; | |
2030 } | |
2031 #if 0 | |
2032 if (to->ty == Tsarray) | |
2033 { | |
2034 TypeSArray *tsa = (TypeSArray *)to; | |
2035 | |
2036 if (next->equals(tsa->next) && dim->equals(tsa->dim)) | |
2037 { | |
2038 return MATCHconvert; | |
2039 } | |
2040 } | |
2041 #endif | |
2042 return Type::implicitConvTo(to); | |
2043 } | |
2044 | |
2045 Expression *TypeSArray::defaultInit(Loc loc) | |
2046 { | |
2047 #if LOGDEFAULTINIT | |
2048 printf("TypeSArray::defaultInit() '%s'\n", toChars()); | |
2049 #endif | |
2050 return next->defaultInit(loc); | |
2051 } | |
2052 | |
2053 int TypeSArray::isZeroInit() | |
2054 { | |
2055 return next->isZeroInit(); | |
2056 } | |
2057 | |
2058 | |
2059 Expression *TypeSArray::toExpression() | |
2060 { | |
2061 Expression *e = next->toExpression(); | |
2062 if (e) | |
2063 { Expressions *arguments = new Expressions(); | |
2064 arguments->push(dim); | |
2065 e = new ArrayExp(dim->loc, e, arguments); | |
2066 } | |
2067 return e; | |
2068 } | |
2069 | |
2070 int TypeSArray::hasPointers() | |
2071 { | |
2072 return next->hasPointers(); | |
2073 } | |
2074 | |
2075 /***************************** TypeDArray *****************************/ | |
2076 | |
2077 TypeDArray::TypeDArray(Type *t) | |
2078 : TypeArray(Tarray, t) | |
2079 { | |
2080 //printf("TypeDArray(t = %p)\n", t); | |
2081 } | |
2082 | |
2083 Type *TypeDArray::syntaxCopy() | |
2084 { | |
2085 Type *t = next->syntaxCopy(); | |
2086 if (t == next) | |
2087 t = this; | |
2088 else | |
2089 t = new TypeDArray(t); | |
2090 return t; | |
2091 } | |
2092 | |
2093 d_uns64 TypeDArray::size(Loc loc) | |
2094 { | |
2095 //printf("TypeDArray::size()\n"); | |
2096 return PTRSIZE * 2; | |
2097 } | |
2098 | |
2099 unsigned TypeDArray::alignsize() | |
2100 { | |
2101 // A DArray consists of two ptr-sized values, so align it on pointer size | |
2102 // boundary | |
2103 return PTRSIZE; | |
2104 } | |
2105 | |
2106 Type *TypeDArray::semantic(Loc loc, Scope *sc) | |
2107 { Type *tn = next; | |
2108 | |
2109 tn = next->semantic(loc,sc); | |
2110 Type *tbn = tn->toBasetype(); | |
2111 switch (tbn->ty) | |
2112 { | |
2113 case Tfunction: | |
2114 case Tnone: | |
2115 case Ttuple: | |
2116 error(loc, "can't have array of %s", tbn->toChars()); | |
2117 tn = next = tint32; | |
2118 break; | |
2119 } | |
2120 if (tn->isauto()) | |
2121 error(loc, "cannot have array of auto %s", tn->toChars()); | |
2122 if (next != tn) | |
2123 //deco = NULL; // redo | |
2124 return tn->arrayOf(); | |
2125 return merge(); | |
2126 } | |
2127 | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2128 void TypeDArray::toDecoBuffer(OutBuffer *buf, bool mangle) |
159 | 2129 { |
2130 buf->writeByte(mangleChar[ty]); | |
2131 if (next) | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2132 next->toDecoBuffer(buf, mangle); |
159 | 2133 } |
2134 | |
2135 void TypeDArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
2136 { | |
2137 if (mod != this->mod) | |
2138 { toCBuffer3(buf, hgs, mod); | |
2139 return; | |
2140 } | |
2141 next->toCBuffer2(buf, hgs, this->mod); | |
2142 buf->writestring("[]"); | |
2143 } | |
2144 | |
2145 Expression *TypeDArray::dotExp(Scope *sc, Expression *e, Identifier *ident) | |
2146 { | |
2147 #if LOGDOTEXP | |
2148 printf("TypeDArray::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); | |
2149 #endif | |
2150 if (ident == Id::length) | |
2151 { | |
2152 if (e->op == TOKstring) | |
2153 { StringExp *se = (StringExp *)e; | |
2154 | |
2155 return new IntegerExp(se->loc, se->len, Type::tindex); | |
2156 } | |
2157 e = new ArrayLengthExp(e->loc, e); | |
2158 e->type = Type::tsize_t; | |
2159 return e; | |
2160 } | |
2161 else if (ident == Id::ptr) | |
2162 { | |
2163 e = e->castTo(sc, next->pointerTo()); | |
2164 return e; | |
2165 } | |
2166 else | |
2167 { | |
2168 e = TypeArray::dotExp(sc, e, ident); | |
2169 } | |
2170 return e; | |
2171 } | |
2172 | |
2173 int TypeDArray::isString() | |
2174 { | |
2175 TY nty = next->toBasetype()->ty; | |
2176 return nty == Tchar || nty == Twchar || nty == Tdchar; | |
2177 } | |
2178 | |
2179 MATCH TypeDArray::implicitConvTo(Type *to) | |
2180 { | |
2181 //printf("TypeDArray::implicitConvTo()\n"); | |
2182 | |
2183 // Allow implicit conversion of array to pointer | |
2184 if (IMPLICIT_ARRAY_TO_PTR && | |
2185 to->ty == Tpointer && | |
2186 (to->next->ty == Tvoid || next->equals(to->next) /*|| to->next->isBaseOf(next)*/)) | |
2187 { | |
2188 return MATCHconvert; | |
2189 } | |
2190 | |
2191 if (to->ty == Tarray) | |
2192 { int offset = 0; | |
2193 | |
2194 if ((to->next->isBaseOf(next, &offset) && offset == 0) || | |
2195 to->next->ty == Tvoid) | |
2196 return MATCHconvert; | |
2197 } | |
2198 return Type::implicitConvTo(to); | |
2199 } | |
2200 | |
2201 Expression *TypeDArray::defaultInit(Loc loc) | |
2202 { | |
2203 #if LOGDEFAULTINIT | |
2204 printf("TypeDArray::defaultInit() '%s'\n", toChars()); | |
2205 #endif | |
2206 Expression *e; | |
2207 e = new NullExp(loc); | |
2208 e->type = this; | |
2209 return e; | |
2210 } | |
2211 | |
2212 int TypeDArray::isZeroInit() | |
2213 { | |
2214 return 1; | |
2215 } | |
2216 | |
2217 int TypeDArray::checkBoolean() | |
2218 { | |
2219 return TRUE; | |
2220 } | |
2221 | |
2222 int TypeDArray::hasPointers() | |
2223 { | |
2224 return TRUE; | |
2225 } | |
2226 | |
2227 /***************************** TypeAArray *****************************/ | |
2228 | |
2229 TypeAArray::TypeAArray(Type *t, Type *index) | |
2230 : TypeArray(Taarray, t) | |
2231 { | |
2232 this->index = index; | |
2233 this->key = NULL; | |
2234 } | |
2235 | |
2236 Type *TypeAArray::syntaxCopy() | |
2237 { | |
2238 Type *t = next->syntaxCopy(); | |
2239 Type *ti = index->syntaxCopy(); | |
2240 if (t == next && ti == index) | |
2241 t = this; | |
2242 else | |
2243 t = new TypeAArray(t, ti); | |
2244 return t; | |
2245 } | |
2246 | |
2247 d_uns64 TypeAArray::size(Loc loc) | |
2248 { | |
2249 return PTRSIZE /* * 2*/; | |
2250 } | |
2251 | |
2252 | |
2253 Type *TypeAArray::semantic(Loc loc, Scope *sc) | |
2254 { | |
2255 //printf("TypeAArray::semantic() %s index->ty = %d\n", toChars(), index->ty); | |
2256 | |
2257 // Deal with the case where we thought the index was a type, but | |
2258 // in reality it was an expression. | |
2259 if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray) | |
2260 { | |
2261 Expression *e; | |
2262 Type *t; | |
2263 Dsymbol *s; | |
2264 | |
2265 index->resolve(loc, sc, &e, &t, &s); | |
2266 if (e) | |
2267 { // It was an expression - | |
2268 // Rewrite as a static array | |
2269 TypeSArray *tsa; | |
2270 | |
2271 tsa = new TypeSArray(next, e); | |
2272 return tsa->semantic(loc,sc); | |
2273 } | |
2274 else if (t) | |
2275 index = t; | |
2276 else | |
2277 index->error(loc, "index is not a type or an expression"); | |
2278 } | |
2279 else | |
2280 index = index->semantic(loc,sc); | |
2281 | |
2282 // Compute key type; the purpose of the key type is to | |
2283 // minimize the permutations of runtime library | |
2284 // routines as much as possible. | |
2285 key = index->toBasetype(); | |
2286 switch (key->ty) | |
2287 { | |
2288 #if 0 | |
2289 case Tint8: | |
2290 case Tuns8: | |
2291 case Tint16: | |
2292 case Tuns16: | |
2293 key = tint32; | |
2294 break; | |
2295 #endif | |
2296 | |
2297 case Tsarray: | |
2298 #if 0 | |
2299 // Convert to Tarray | |
2300 key = key->next->arrayOf(); | |
2301 #endif | |
2302 break; | |
2303 case Tbit: | |
2304 case Tbool: | |
2305 case Tfunction: | |
2306 case Tvoid: | |
2307 case Tnone: | |
2308 error(loc, "can't have associative array key of %s", key->toChars()); | |
2309 break; | |
2310 } | |
2311 next = next->semantic(loc,sc); | |
2312 switch (next->toBasetype()->ty) | |
2313 { | |
2314 case Tfunction: | |
2315 case Tnone: | |
2316 error(loc, "can't have associative array of %s", next->toChars()); | |
2317 break; | |
2318 } | |
2319 if (next->isauto()) | |
2320 error(loc, "cannot have array of auto %s", next->toChars()); | |
2321 | |
2322 return merge(); | |
2323 } | |
2324 | |
336 | 2325 void TypeAArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) |
2326 { | |
2327 //printf("TypeAArray::resolve() %s\n", toChars()); | |
2328 | |
2329 // Deal with the case where we thought the index was a type, but | |
2330 // in reality it was an expression. | |
2331 if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray) | |
2332 { | |
2333 Expression *e; | |
2334 Type *t; | |
2335 Dsymbol *s; | |
2336 | |
2337 index->resolve(loc, sc, &e, &t, &s); | |
2338 if (e) | |
2339 { // It was an expression - | |
2340 // Rewrite as a static array | |
2341 | |
2342 TypeSArray *tsa = new TypeSArray(next, e); | |
2343 return tsa->resolve(loc, sc, pe, pt, ps); | |
2344 } | |
2345 else if (t) | |
2346 index = t; | |
2347 else | |
2348 index->error(loc, "index is not a type or an expression"); | |
2349 } | |
2350 Type::resolve(loc, sc, pe, pt, ps); | |
2351 } | |
2352 | |
2353 | |
159 | 2354 Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident) |
2355 { | |
2356 #if LOGDOTEXP | |
2357 printf("TypeAArray::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); | |
2358 #endif | |
2359 if (ident == Id::length) | |
2360 { | |
2361 Expression *ec; | |
2362 Expressions *arguments; | |
2363 | |
664
eef8ac26c66c
Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents:
658
diff
changeset
|
2364 //LDC: Build arguments. |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2365 static FuncDeclaration *aaLen_fd = NULL; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2366 if(!aaLen_fd) { |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2367 Arguments* args = new Arguments; |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
2368 args->push(new Argument(STCin, Type::tvoid->pointerTo(), NULL, NULL)); |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2369 aaLen_fd = FuncDeclaration::genCfunc(args, Type::tsize_t, Id::aaLen); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2370 } |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2371 |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2372 ec = new VarExp(0, aaLen_fd); |
159 | 2373 arguments = new Expressions(); |
2374 arguments->push(e); | |
2375 e = new CallExp(e->loc, ec, arguments); | |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2376 e->type = aaLen_fd->type->next; |
159 | 2377 } |
2378 else if (ident == Id::keys) | |
2379 { | |
2380 Expression *ec; | |
2381 Expressions *arguments; | |
2382 int size = key->size(e->loc); | |
2383 | |
2384 assert(size); | |
664
eef8ac26c66c
Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents:
658
diff
changeset
|
2385 //LDC: Build arguments. |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2386 static FuncDeclaration *aaKeys_fd = NULL; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2387 if(!aaKeys_fd) { |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2388 Arguments* args = new Arguments; |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
2389 args->push(new Argument(STCin, Type::tvoid->pointerTo(), NULL, NULL)); |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2390 args->push(new Argument(STCin, Type::tsize_t, NULL, NULL)); |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
2391 aaKeys_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::aaKeys); |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2392 } |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2393 |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2394 ec = new VarExp(0, aaKeys_fd); |
159 | 2395 arguments = new Expressions(); |
2396 arguments->push(e); | |
2397 arguments->push(new IntegerExp(0, size, Type::tsize_t)); | |
2398 e = new CallExp(e->loc, ec, arguments); | |
2399 e->type = index->arrayOf(); | |
2400 } | |
2401 else if (ident == Id::values) | |
2402 { | |
2403 Expression *ec; | |
2404 Expressions *arguments; | |
2405 | |
664
eef8ac26c66c
Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents:
658
diff
changeset
|
2406 //LDC: Build arguments. |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2407 static FuncDeclaration *aaValues_fd = NULL; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2408 if(!aaValues_fd) { |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2409 Arguments* args = new Arguments; |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
2410 args->push(new Argument(STCin, Type::tvoid->pointerTo(), NULL, NULL)); |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2411 args->push(new Argument(STCin, Type::tsize_t, NULL, NULL)); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2412 args->push(new Argument(STCin, Type::tsize_t, NULL, NULL)); |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
2413 aaValues_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::aaValues); |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2414 } |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2415 |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2416 ec = new VarExp(0, aaValues_fd); |
159 | 2417 arguments = new Expressions(); |
2418 arguments->push(e); | |
2419 size_t keysize = key->size(e->loc); | |
771
bfabbac8e705
Fixed 64bit problem with aaValues runtime calls (assumed 32bits)
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
742
diff
changeset
|
2420 keysize = (keysize + PTRSIZE - 1) & ~(PTRSIZE - 1); |
159 | 2421 arguments->push(new IntegerExp(0, keysize, Type::tsize_t)); |
2422 arguments->push(new IntegerExp(0, next->size(e->loc), Type::tsize_t)); | |
2423 e = new CallExp(e->loc, ec, arguments); | |
2424 e->type = next->arrayOf(); | |
2425 } | |
2426 else if (ident == Id::rehash) | |
2427 { | |
2428 Expression *ec; | |
2429 Expressions *arguments; | |
2430 | |
664
eef8ac26c66c
Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents:
658
diff
changeset
|
2431 //LDC: Build arguments. |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2432 static FuncDeclaration *aaRehash_fd = NULL; |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2433 if(!aaRehash_fd) { |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2434 Arguments* args = new Arguments; |
715
30b42a283c8e
Removed TypeOpaque from DMD.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
664
diff
changeset
|
2435 args->push(new Argument(STCin, Type::tvoid->pointerTo(), NULL, NULL)); |
389
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2436 args->push(new Argument(STCin, Type::typeinfo->type, NULL, NULL)); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2437 aaRehash_fd = FuncDeclaration::genCfunc(args, Type::tvoidptr, Id::aaRehash); |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2438 } |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2439 |
722f5e90c39c
Made setup for runtime calls in dmd frontend allocate less.
Christian Kamm <kamm incasoftware de>
parents:
387
diff
changeset
|
2440 ec = new VarExp(0, aaRehash_fd); |
159 | 2441 arguments = new Expressions(); |
2442 arguments->push(e->addressOf(sc)); | |
975
067bb8f19c36
Fix #217. getInternalTypeInfo doesn't work with LDC.
Christian Kamm <kamm incasoftware de>
parents:
938
diff
changeset
|
2443 arguments->push(key->getTypeInfo(sc)); // LDC doesn't support getInternalTypeInfo, see above |
159 | 2444 e = new CallExp(e->loc, ec, arguments); |
2445 e->type = this; | |
2446 } | |
2447 else | |
2448 { | |
2449 e = Type::dotExp(sc, e, ident); | |
2450 } | |
2451 return e; | |
2452 } | |
2453 | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2454 void TypeAArray::toDecoBuffer(OutBuffer *buf, bool mangle) |
159 | 2455 { |
2456 buf->writeByte(mangleChar[ty]); | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2457 index->toDecoBuffer(buf, mangle); |
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2458 next->toDecoBuffer(buf, mangle); |
159 | 2459 } |
2460 | |
2461 void TypeAArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
2462 { | |
2463 if (mod != this->mod) | |
2464 { toCBuffer3(buf, hgs, mod); | |
2465 return; | |
2466 } | |
2467 next->toCBuffer2(buf, hgs, this->mod); | |
2468 buf->writeByte('['); | |
2469 index->toCBuffer2(buf, hgs, 0); | |
2470 buf->writeByte(']'); | |
2471 } | |
2472 | |
2473 Expression *TypeAArray::defaultInit(Loc loc) | |
2474 { | |
2475 #if LOGDEFAULTINIT | |
2476 printf("TypeAArray::defaultInit() '%s'\n", toChars()); | |
2477 #endif | |
2478 Expression *e; | |
2479 e = new NullExp(loc); | |
2480 e->type = this; | |
2481 return e; | |
2482 } | |
2483 | |
211
f66219e0d530
[svn r227] Fixed: crash in lifetime.d when resizing array of AAs by .length assignment.
lindquist
parents:
162
diff
changeset
|
2484 int TypeAArray::isZeroInit() |
f66219e0d530
[svn r227] Fixed: crash in lifetime.d when resizing array of AAs by .length assignment.
lindquist
parents:
162
diff
changeset
|
2485 { |
846
bc982f1ad106
Merged DMD 1.037 frontend
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
822
diff
changeset
|
2486 return TRUE; |
211
f66219e0d530
[svn r227] Fixed: crash in lifetime.d when resizing array of AAs by .length assignment.
lindquist
parents:
162
diff
changeset
|
2487 } |
f66219e0d530
[svn r227] Fixed: crash in lifetime.d when resizing array of AAs by .length assignment.
lindquist
parents:
162
diff
changeset
|
2488 |
159 | 2489 int TypeAArray::checkBoolean() |
2490 { | |
2491 return TRUE; | |
2492 } | |
2493 | |
2494 int TypeAArray::hasPointers() | |
2495 { | |
2496 return TRUE; | |
2497 } | |
2498 | |
2499 /***************************** TypePointer *****************************/ | |
2500 | |
2501 TypePointer::TypePointer(Type *t) | |
2502 : Type(Tpointer, t) | |
2503 { | |
2504 } | |
2505 | |
2506 Type *TypePointer::syntaxCopy() | |
2507 { | |
2508 Type *t = next->syntaxCopy(); | |
2509 if (t == next) | |
2510 t = this; | |
2511 else | |
2512 t = new TypePointer(t); | |
2513 return t; | |
2514 } | |
2515 | |
2516 Type *TypePointer::semantic(Loc loc, Scope *sc) | |
2517 { | |
2518 //printf("TypePointer::semantic()\n"); | |
2519 Type *n = next->semantic(loc, sc); | |
2520 switch (n->toBasetype()->ty) | |
2521 { | |
2522 case Ttuple: | |
2523 error(loc, "can't have pointer to %s", n->toChars()); | |
2524 n = tint32; | |
2525 break; | |
2526 } | |
2527 if (n != next) | |
2528 deco = NULL; | |
2529 next = n; | |
2530 return merge(); | |
2531 } | |
2532 | |
2533 | |
2534 d_uns64 TypePointer::size(Loc loc) | |
2535 { | |
2536 return PTRSIZE; | |
2537 } | |
2538 | |
2539 void TypePointer::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
2540 { | |
2541 //printf("TypePointer::toCBuffer2() next = %d\n", next->ty); | |
2542 if (mod != this->mod) | |
2543 { toCBuffer3(buf, hgs, mod); | |
2544 return; | |
2545 } | |
2546 next->toCBuffer2(buf, hgs, this->mod); | |
2547 if (next->ty != Tfunction) | |
2548 buf->writeByte('*'); | |
2549 } | |
2550 | |
2551 MATCH TypePointer::implicitConvTo(Type *to) | |
2552 { | |
2553 //printf("TypePointer::implicitConvTo()\n"); | |
2554 | |
2555 if (this == to) | |
2556 return MATCHexact; | |
2557 if (to->ty == Tpointer && to->next) | |
2558 { | |
2559 if (to->next->ty == Tvoid) | |
2560 return MATCHconvert; | |
2561 | |
2562 #if 0 | |
2563 if (to->next->isBaseOf(next)) | |
2564 return MATCHconvert; | |
2565 #endif | |
2566 | |
2567 if (next->ty == Tfunction && to->next->ty == Tfunction) | |
2568 { TypeFunction *tf; | |
2569 TypeFunction *tfto; | |
2570 | |
2571 tf = (TypeFunction *)(next); | |
2572 tfto = (TypeFunction *)(to->next); | |
2573 return tfto->equals(tf) ? MATCHexact : MATCHnomatch; | |
2574 } | |
2575 } | |
2576 // if (to->ty == Tvoid) | |
2577 // return MATCHconvert; | |
2578 return MATCHnomatch; | |
2579 } | |
2580 | |
2581 int TypePointer::isscalar() | |
2582 { | |
2583 return TRUE; | |
2584 } | |
2585 | |
2586 Expression *TypePointer::defaultInit(Loc loc) | |
2587 { | |
2588 #if LOGDEFAULTINIT | |
2589 printf("TypePointer::defaultInit() '%s'\n", toChars()); | |
2590 #endif | |
2591 Expression *e; | |
2592 e = new NullExp(loc); | |
2593 e->type = this; | |
2594 return e; | |
2595 } | |
2596 | |
2597 int TypePointer::isZeroInit() | |
2598 { | |
2599 return 1; | |
2600 } | |
2601 | |
2602 int TypePointer::hasPointers() | |
2603 { | |
2604 return TRUE; | |
2605 } | |
2606 | |
2607 | |
2608 /***************************** TypeReference *****************************/ | |
2609 | |
2610 TypeReference::TypeReference(Type *t) | |
2611 : Type(Treference, t) | |
2612 { | |
2613 if (t->ty == Tbit) | |
2614 error(0,"cannot make reference to a bit"); | |
2615 // BUG: what about references to static arrays? | |
2616 } | |
2617 | |
2618 Type *TypeReference::syntaxCopy() | |
2619 { | |
2620 Type *t = next->syntaxCopy(); | |
2621 if (t == next) | |
2622 t = this; | |
2623 else | |
2624 t = new TypeReference(t); | |
2625 return t; | |
2626 } | |
2627 | |
2628 d_uns64 TypeReference::size(Loc loc) | |
2629 { | |
2630 return PTRSIZE; | |
2631 } | |
2632 | |
2633 void TypeReference::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
2634 { | |
2635 if (mod != this->mod) | |
2636 { toCBuffer3(buf, hgs, mod); | |
2637 return; | |
2638 } | |
2639 next->toCBuffer2(buf, hgs, this->mod); | |
2640 buf->writeByte('&'); | |
2641 } | |
2642 | |
2643 Expression *TypeReference::dotExp(Scope *sc, Expression *e, Identifier *ident) | |
2644 { | |
2645 #if LOGDOTEXP | |
2646 printf("TypeReference::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); | |
2647 #endif | |
2648 | |
2649 // References just forward things along | |
2650 return next->dotExp(sc, e, ident); | |
2651 } | |
2652 | |
2653 Expression *TypeReference::defaultInit(Loc loc) | |
2654 { | |
2655 #if LOGDEFAULTINIT | |
2656 printf("TypeReference::defaultInit() '%s'\n", toChars()); | |
2657 #endif | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
2658 Expression *e = new NullExp(loc); |
159 | 2659 e->type = this; |
2660 return e; | |
2661 } | |
2662 | |
2663 int TypeReference::isZeroInit() | |
2664 { | |
2665 return 1; | |
2666 } | |
2667 | |
2668 | |
2669 /***************************** TypeFunction *****************************/ | |
2670 | |
2671 TypeFunction::TypeFunction(Arguments *parameters, Type *treturn, int varargs, enum LINK linkage) | |
2672 : Type(Tfunction, treturn) | |
2673 { | |
2674 //if (!treturn) *(char*)0=0; | |
2675 // assert(treturn); | |
2676 this->parameters = parameters; | |
2677 this->varargs = varargs; | |
2678 this->linkage = linkage; | |
2679 this->inuse = 0; | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2680 |
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2681 #if IN_LLVM |
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2682 this->funcdecl = NULL; |
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2683 #endif |
159 | 2684 } |
2685 | |
2686 Type *TypeFunction::syntaxCopy() | |
2687 { | |
2688 Type *treturn = next ? next->syntaxCopy() : NULL; | |
2689 Arguments *params = Argument::arraySyntaxCopy(parameters); | |
217
0806379a5eca
[svn r233] Added: -oq command line option for writing fully qualified object names.
lindquist
parents:
211
diff
changeset
|
2690 TypeFunction *t = new TypeFunction(params, treturn, varargs, linkage); |
159 | 2691 return t; |
2692 } | |
2693 | |
2694 /******************************* | |
2695 * Returns: | |
2696 * 0 types are distinct | |
2697 * 1 this is covariant with t | |
2698 * 2 arguments match as far as overloading goes, | |
2699 * but types are not covariant | |
2700 * 3 cannot determine covariance because of forward references | |
2701 */ | |
2702 | |
2703 int Type::covariant(Type *t) | |
2704 { | |
2705 #if 0 | |
2706 printf("Type::covariant(t = %s) %s\n", t->toChars(), toChars()); | |
2707 printf("deco = %p, %p\n", deco, t->deco); | |
2708 printf("ty = %d\n", next->ty); | |
2709 #endif | |
2710 | |
2711 int inoutmismatch = 0; | |
2712 | |
2713 if (equals(t)) | |
2714 goto Lcovariant; | |
2715 if (ty != Tfunction || t->ty != Tfunction) | |
2716 goto Ldistinct; | |
2717 | |
2718 { | |
2719 TypeFunction *t1 = (TypeFunction *)this; | |
2720 TypeFunction *t2 = (TypeFunction *)t; | |
2721 | |
2722 if (t1->varargs != t2->varargs) | |
2723 goto Ldistinct; | |
2724 | |
2725 if (t1->parameters && t2->parameters) | |
2726 { | |
2727 size_t dim = Argument::dim(t1->parameters); | |
2728 if (dim != Argument::dim(t2->parameters)) | |
2729 goto Ldistinct; | |
2730 | |
2731 for (size_t i = 0; i < dim; i++) | |
2732 { Argument *arg1 = Argument::getNth(t1->parameters, i); | |
2733 Argument *arg2 = Argument::getNth(t2->parameters, i); | |
2734 | |
2735 if (!arg1->type->equals(arg2->type)) | |
2736 goto Ldistinct; | |
2737 if (arg1->storageClass != arg2->storageClass) | |
2738 inoutmismatch = 1; | |
2739 } | |
2740 } | |
2741 else if (t1->parameters != t2->parameters) | |
2742 goto Ldistinct; | |
2743 | |
2744 // The argument lists match | |
2745 if (inoutmismatch) | |
2746 goto Lnotcovariant; | |
2747 if (t1->linkage != t2->linkage) | |
2748 goto Lnotcovariant; | |
2749 | |
2750 Type *t1n = t1->next; | |
2751 Type *t2n = t2->next; | |
2752 | |
2753 if (t1n->equals(t2n)) | |
2754 goto Lcovariant; | |
2755 if (t1n->ty != Tclass || t2n->ty != Tclass) | |
2756 goto Lnotcovariant; | |
2757 | |
2758 // If t1n is forward referenced: | |
2759 ClassDeclaration *cd = ((TypeClass *)t1n)->sym; | |
2760 if (!cd->baseClass && cd->baseclasses.dim && !cd->isInterfaceDeclaration()) | |
2761 { | |
2762 return 3; | |
2763 } | |
2764 | |
2765 if (t1n->implicitConvTo(t2n)) | |
2766 goto Lcovariant; | |
2767 goto Lnotcovariant; | |
2768 } | |
2769 | |
2770 Lcovariant: | |
2771 //printf("\tcovaraint: 1\n"); | |
2772 return 1; | |
2773 | |
2774 Ldistinct: | |
2775 //printf("\tcovaraint: 0\n"); | |
2776 return 0; | |
2777 | |
2778 Lnotcovariant: | |
2779 //printf("\tcovaraint: 2\n"); | |
2780 return 2; | |
2781 } | |
2782 | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2783 void TypeFunction::toDecoBuffer(OutBuffer *buf, bool mangle) |
159 | 2784 { unsigned char mc; |
2785 | |
2786 //printf("TypeFunction::toDecoBuffer() this = %p %s\n", this, toChars()); | |
2787 //static int nest; if (++nest == 50) *(char*)0=0; | |
2788 if (inuse) | |
2789 { inuse = 2; // flag error to caller | |
2790 return; | |
2791 } | |
2792 inuse++; | |
2793 switch (linkage) | |
2794 { | |
2795 case LINKd: mc = 'F'; break; | |
2796 case LINKc: mc = 'U'; break; | |
2797 case LINKwindows: mc = 'W'; break; | |
2798 case LINKpascal: mc = 'V'; break; | |
2799 case LINKcpp: mc = 'R'; break; | |
723
55f6c2e454d7
Implemented correct parameter order according to x86-32 ABI documentation.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
720
diff
changeset
|
2800 |
55f6c2e454d7
Implemented correct parameter order according to x86-32 ABI documentation.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
720
diff
changeset
|
2801 // LDC |
55f6c2e454d7
Implemented correct parameter order according to x86-32 ABI documentation.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
720
diff
changeset
|
2802 case LINKintrinsic: mc = 'Q'; break; |
55f6c2e454d7
Implemented correct parameter order according to x86-32 ABI documentation.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
720
diff
changeset
|
2803 |
159 | 2804 default: |
2805 assert(0); | |
2806 } | |
2807 buf->writeByte(mc); | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2808 |
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2809 // LDC: if we're not producing a mangle string, add the this |
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2810 // type to prevent merging different member function |
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2811 if (!mangle && funcdecl) |
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2812 { |
1282
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2813 if (funcdecl->needThis()) |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2814 { |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2815 AggregateDeclaration* ad = funcdecl->isMember2(); |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2816 buf->writeByte('M'); |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2817 ad->type->toDecoBuffer(buf, false); |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2818 } |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2819 /* BUG This causes problems with delegate types |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2820 On the other hand, the llvm type for nested functions *is* different |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2821 so not doing anything here may be lead to bugs! |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2822 A sane solution would be DtoType(Dsymbol)... |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2823 if (funcdecl->isNested()) |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2824 { |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2825 buf->writeByte('M'); |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2826 if (funcdecl->toParent2() && funcdecl->toParent2()->isFuncDeclaration()) |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2827 { |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2828 FuncDeclaration* fd = funcdecl->toParent2()->isFuncDeclaration(); |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2829 fd->type->toDecoBuffer(buf, false); |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2830 } |
680b4df0ea36
Commit workaround for TypeFunction comparing issue.
Christian Kamm <kamm incasoftware de>
parents:
1257
diff
changeset
|
2831 }*/ |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2832 } |
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2833 |
159 | 2834 // Write argument types |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2835 Argument::argsToDecoBuffer(buf, parameters, mangle); |
159 | 2836 //if (buf->data[buf->offset - 1] == '@') halt(); |
2837 buf->writeByte('Z' - varargs); // mark end of arg list | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
2838 next->toDecoBuffer(buf, mangle); |
159 | 2839 inuse--; |
2840 } | |
2841 | |
2842 void TypeFunction::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs) | |
2843 { | |
2844 char *p = NULL; | |
2845 | |
2846 if (inuse) | |
2847 { inuse = 2; // flag error to caller | |
2848 return; | |
2849 } | |
2850 inuse++; | |
2851 if (next && (!ident || ident->toHChars2() == ident->toChars())) | |
2852 next->toCBuffer2(buf, hgs, 0); | |
2853 if (hgs->ddoc != 1) | |
2854 { | |
2855 switch (linkage) | |
2856 { | |
2857 case LINKd: p = NULL; break; | |
2858 case LINKc: p = "C "; break; | |
2859 case LINKwindows: p = "Windows "; break; | |
2860 case LINKpascal: p = "Pascal "; break; | |
2861 case LINKcpp: p = "C++ "; break; | |
723
55f6c2e454d7
Implemented correct parameter order according to x86-32 ABI documentation.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
720
diff
changeset
|
2862 |
55f6c2e454d7
Implemented correct parameter order according to x86-32 ABI documentation.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
720
diff
changeset
|
2863 // LDC |
55f6c2e454d7
Implemented correct parameter order according to x86-32 ABI documentation.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
720
diff
changeset
|
2864 case LINKintrinsic: p = "Intrinsic"; break; |
55f6c2e454d7
Implemented correct parameter order according to x86-32 ABI documentation.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
720
diff
changeset
|
2865 |
159 | 2866 default: |
2867 assert(0); | |
2868 } | |
2869 } | |
2870 | |
2871 if (!hgs->hdrgen && p) | |
2872 buf->writestring(p); | |
2873 if (ident) | |
2874 { buf->writeByte(' '); | |
2875 buf->writestring(ident->toHChars2()); | |
2876 } | |
2877 Argument::argsToCBuffer(buf, hgs, parameters, varargs); | |
2878 inuse--; | |
2879 } | |
2880 | |
2881 void TypeFunction::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
2882 { | |
2883 char *p = NULL; | |
2884 | |
2885 if (inuse) | |
2886 { inuse = 2; // flag error to caller | |
2887 return; | |
2888 } | |
2889 inuse++; | |
2890 if (next) | |
2891 next->toCBuffer2(buf, hgs, 0); | |
2892 if (hgs->ddoc != 1) | |
2893 { | |
2894 switch (linkage) | |
2895 { | |
2896 case LINKd: p = NULL; break; | |
2897 case LINKc: p = "C "; break; | |
2898 case LINKwindows: p = "Windows "; break; | |
2899 case LINKpascal: p = "Pascal "; break; | |
2900 case LINKcpp: p = "C++ "; break; | |
723
55f6c2e454d7
Implemented correct parameter order according to x86-32 ABI documentation.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
720
diff
changeset
|
2901 |
55f6c2e454d7
Implemented correct parameter order according to x86-32 ABI documentation.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
720
diff
changeset
|
2902 // LDC |
55f6c2e454d7
Implemented correct parameter order according to x86-32 ABI documentation.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
720
diff
changeset
|
2903 case LINKintrinsic: p = "Intrinsic"; break; |
55f6c2e454d7
Implemented correct parameter order according to x86-32 ABI documentation.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
720
diff
changeset
|
2904 |
159 | 2905 default: |
2906 assert(0); | |
2907 } | |
2908 } | |
2909 | |
2910 if (!hgs->hdrgen && p) | |
2911 buf->writestring(p); | |
2912 buf->writestring(" function"); | |
2913 Argument::argsToCBuffer(buf, hgs, parameters, varargs); | |
2914 inuse--; | |
2915 } | |
2916 | |
2917 Type *TypeFunction::semantic(Loc loc, Scope *sc) | |
2918 { | |
2919 if (deco) // if semantic() already run | |
2920 { | |
2921 //printf("already done\n"); | |
2922 return this; | |
2923 } | |
2924 //printf("TypeFunction::semantic() this = %p\n", this); | |
2925 | |
2926 TypeFunction *tf = (TypeFunction *)mem.malloc(sizeof(TypeFunction)); | |
2927 memcpy(tf, this, sizeof(TypeFunction)); | |
2928 if (parameters) | |
2929 { tf->parameters = (Arguments *)parameters->copy(); | |
2930 for (size_t i = 0; i < parameters->dim; i++) | |
2931 { Argument *arg = (Argument *)parameters->data[i]; | |
2932 Argument *cpy = (Argument *)mem.malloc(sizeof(Argument)); | |
2933 memcpy(cpy, arg, sizeof(Argument)); | |
2934 tf->parameters->data[i] = (void *)cpy; | |
2935 } | |
2936 } | |
2937 | |
2938 tf->linkage = sc->linkage; | |
2939 if (!tf->next) | |
2940 { | |
2941 assert(global.errors); | |
2942 tf->next = tvoid; | |
2943 } | |
2944 tf->next = tf->next->semantic(loc,sc); | |
2945 if (tf->next->toBasetype()->ty == Tsarray) | |
2946 { error(loc, "functions cannot return static array %s", tf->next->toChars()); | |
2947 tf->next = Type::terror; | |
2948 } | |
2949 if (tf->next->toBasetype()->ty == Tfunction) | |
2950 { error(loc, "functions cannot return a function"); | |
2951 tf->next = Type::terror; | |
2952 } | |
2953 if (tf->next->toBasetype()->ty == Ttuple) | |
2954 { error(loc, "functions cannot return a tuple"); | |
2955 tf->next = Type::terror; | |
2956 } | |
2957 if (tf->next->isauto() && !(sc->flags & SCOPEctor)) | |
2958 error(loc, "functions cannot return auto %s", tf->next->toChars()); | |
2959 | |
2960 if (tf->parameters) | |
2961 { size_t dim = Argument::dim(tf->parameters); | |
2962 | |
2963 for (size_t i = 0; i < dim; i++) | |
2964 { Argument *arg = Argument::getNth(tf->parameters, i); | |
2965 Type *t; | |
2966 | |
2967 tf->inuse++; | |
2968 arg->type = arg->type->semantic(loc,sc); | |
2969 if (tf->inuse == 1) tf->inuse--; | |
780
2cf440d511bb
Move tuple syntax copy for function arguments after semantic, to make sure
Christian Kamm <kamm incasoftware de>
parents:
772
diff
changeset
|
2970 |
2cf440d511bb
Move tuple syntax copy for function arguments after semantic, to make sure
Christian Kamm <kamm incasoftware de>
parents:
772
diff
changeset
|
2971 // each function needs its own copy of a tuple arg, since |
2cf440d511bb
Move tuple syntax copy for function arguments after semantic, to make sure
Christian Kamm <kamm incasoftware de>
parents:
772
diff
changeset
|
2972 // they mustn't share arg flags like inreg, ... |
2cf440d511bb
Move tuple syntax copy for function arguments after semantic, to make sure
Christian Kamm <kamm incasoftware de>
parents:
772
diff
changeset
|
2973 if (arg->type->ty == Ttuple) { |
2cf440d511bb
Move tuple syntax copy for function arguments after semantic, to make sure
Christian Kamm <kamm incasoftware de>
parents:
772
diff
changeset
|
2974 arg->type = arg->type->syntaxCopy(); |
2cf440d511bb
Move tuple syntax copy for function arguments after semantic, to make sure
Christian Kamm <kamm incasoftware de>
parents:
772
diff
changeset
|
2975 tf->inuse++; |
2cf440d511bb
Move tuple syntax copy for function arguments after semantic, to make sure
Christian Kamm <kamm incasoftware de>
parents:
772
diff
changeset
|
2976 arg->type = arg->type->semantic(loc,sc); |
2cf440d511bb
Move tuple syntax copy for function arguments after semantic, to make sure
Christian Kamm <kamm incasoftware de>
parents:
772
diff
changeset
|
2977 if (tf->inuse == 1) tf->inuse--; |
2cf440d511bb
Move tuple syntax copy for function arguments after semantic, to make sure
Christian Kamm <kamm incasoftware de>
parents:
772
diff
changeset
|
2978 } |
2cf440d511bb
Move tuple syntax copy for function arguments after semantic, to make sure
Christian Kamm <kamm incasoftware de>
parents:
772
diff
changeset
|
2979 |
159 | 2980 t = arg->type->toBasetype(); |
2981 | |
2982 if (arg->storageClass & (STCout | STCref | STClazy)) | |
2983 { | |
2984 if (t->ty == Tsarray) | |
2985 error(loc, "cannot have out or ref parameter of type %s", t->toChars()); | |
2986 } | |
2987 if (!(arg->storageClass & STClazy) && t->ty == Tvoid) | |
2988 error(loc, "cannot have parameter of type %s", arg->type->toChars()); | |
2989 | |
2990 if (arg->defaultArg) | |
2991 { | |
2992 arg->defaultArg = arg->defaultArg->semantic(sc); | |
2993 arg->defaultArg = resolveProperties(sc, arg->defaultArg); | |
2994 arg->defaultArg = arg->defaultArg->implicitCastTo(sc, arg->type); | |
2995 } | |
2996 | |
2997 /* If arg turns out to be a tuple, the number of parameters may | |
2998 * change. | |
2999 */ | |
3000 if (t->ty == Ttuple) | |
3001 { dim = Argument::dim(tf->parameters); | |
3002 i--; | |
3003 } | |
3004 } | |
3005 } | |
3006 tf->deco = tf->merge()->deco; | |
3007 | |
3008 if (tf->inuse) | |
3009 { error(loc, "recursive type"); | |
3010 tf->inuse = 0; | |
3011 return terror; | |
3012 } | |
3013 | |
3014 if (tf->varargs == 1 && tf->linkage != LINKd && Argument::dim(tf->parameters) == 0) | |
3015 error(loc, "variadic functions with non-D linkage must have at least one parameter"); | |
3016 | |
3017 /* Don't return merge(), because arg identifiers and default args | |
3018 * can be different | |
3019 * even though the types match | |
3020 */ | |
3021 return tf; | |
3022 } | |
3023 | |
3024 /******************************** | |
3025 * 'args' are being matched to function 'this' | |
3026 * Determine match level. | |
3027 * Returns: | |
3028 * MATCHxxxx | |
3029 */ | |
3030 | |
3031 int TypeFunction::callMatch(Expressions *args) | |
3032 { | |
3033 //printf("TypeFunction::callMatch()\n"); | |
3034 int match = MATCHexact; // assume exact match | |
3035 | |
3036 size_t nparams = Argument::dim(parameters); | |
3037 size_t nargs = args ? args->dim : 0; | |
3038 if (nparams == nargs) | |
3039 ; | |
3040 else if (nargs > nparams) | |
3041 { | |
3042 if (varargs == 0) | |
3043 goto Nomatch; // too many args; no match | |
3044 match = MATCHconvert; // match ... with a "conversion" match level | |
3045 } | |
3046 | |
3047 for (size_t u = 0; u < nparams; u++) | |
3048 { int m; | |
3049 Expression *arg; | |
3050 | |
3051 // BUG: what about out and ref? | |
3052 | |
3053 Argument *p = Argument::getNth(parameters, u); | |
3054 assert(p); | |
3055 if (u >= nargs) | |
3056 { | |
3057 if (p->defaultArg) | |
3058 continue; | |
3059 if (varargs == 2 && u + 1 == nparams) | |
3060 goto L1; | |
3061 goto Nomatch; // not enough arguments | |
3062 } | |
3063 arg = (Expression *)args->data[u]; | |
3064 assert(arg); | |
3065 if (p->storageClass & STClazy && p->type->ty == Tvoid && arg->type->ty != Tvoid) | |
3066 m = MATCHconvert; | |
3067 else | |
3068 m = arg->implicitConvTo(p->type); | |
3069 //printf("\tm = %d\n", m); | |
3070 if (m == MATCHnomatch) // if no match | |
3071 { | |
3072 L1: | |
3073 if (varargs == 2 && u + 1 == nparams) // if last varargs param | |
3074 { Type *tb = p->type->toBasetype(); | |
3075 TypeSArray *tsa; | |
1195
e961851fb8be
Merged DMD 1.042.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1192
diff
changeset
|
3076 dinteger_t sz; |
159 | 3077 |
3078 switch (tb->ty) | |
3079 { | |
3080 case Tsarray: | |
3081 tsa = (TypeSArray *)tb; | |
3082 sz = tsa->dim->toInteger(); | |
3083 if (sz != nargs - u) | |
3084 goto Nomatch; | |
3085 case Tarray: | |
3086 for (; u < nargs; u++) | |
3087 { | |
3088 arg = (Expression *)args->data[u]; | |
3089 assert(arg); | |
3090 #if 1 | |
3091 /* If lazy array of delegates, | |
3092 * convert arg(s) to delegate(s) | |
3093 */ | |
3094 Type *tret = p->isLazyArray(); | |
3095 if (tret) | |
3096 { | |
3097 if (tb->next->equals(arg->type)) | |
3098 { m = MATCHexact; | |
3099 } | |
3100 else | |
3101 { | |
3102 m = arg->implicitConvTo(tret); | |
3103 if (m == MATCHnomatch) | |
3104 { | |
3105 if (tret->toBasetype()->ty == Tvoid) | |
3106 m = MATCHconvert; | |
3107 } | |
3108 } | |
3109 } | |
3110 else | |
3111 m = arg->implicitConvTo(tb->next); | |
3112 #else | |
3113 m = arg->implicitConvTo(tb->next); | |
3114 #endif | |
3115 if (m == 0) | |
3116 goto Nomatch; | |
3117 if (m < match) | |
3118 match = m; | |
3119 } | |
3120 goto Ldone; | |
3121 | |
3122 case Tclass: | |
3123 // Should see if there's a constructor match? | |
3124 // Or just leave it ambiguous? | |
3125 goto Ldone; | |
3126 | |
3127 default: | |
3128 goto Nomatch; | |
3129 } | |
3130 } | |
3131 goto Nomatch; | |
3132 } | |
3133 if (m < match) | |
3134 match = m; // pick worst match | |
3135 } | |
3136 | |
3137 Ldone: | |
3138 //printf("match = %d\n", match); | |
3139 return match; | |
3140 | |
3141 Nomatch: | |
3142 //printf("no match\n"); | |
3143 return MATCHnomatch; | |
3144 } | |
3145 | |
3146 Type *TypeFunction::reliesOnTident() | |
3147 { | |
3148 if (parameters) | |
3149 { | |
3150 for (size_t i = 0; i < parameters->dim; i++) | |
3151 { Argument *arg = (Argument *)parameters->data[i]; | |
3152 Type *t = arg->type->reliesOnTident(); | |
3153 if (t) | |
3154 return t; | |
3155 } | |
3156 } | |
3157 return next->reliesOnTident(); | |
3158 } | |
3159 | |
3160 /***************************** TypeDelegate *****************************/ | |
3161 | |
3162 TypeDelegate::TypeDelegate(Type *t) | |
3163 : Type(Tfunction, t) | |
3164 { | |
3165 ty = Tdelegate; | |
3166 } | |
3167 | |
3168 Type *TypeDelegate::syntaxCopy() | |
3169 { | |
3170 Type *t = next->syntaxCopy(); | |
3171 if (t == next) | |
3172 t = this; | |
3173 else | |
3174 t = new TypeDelegate(t); | |
3175 return t; | |
3176 } | |
3177 | |
3178 Type *TypeDelegate::semantic(Loc loc, Scope *sc) | |
3179 { | |
3180 if (deco) // if semantic() already run | |
3181 { | |
3182 //printf("already done\n"); | |
3183 return this; | |
3184 } | |
3185 next = next->semantic(loc,sc); | |
3186 return merge(); | |
3187 } | |
3188 | |
3189 d_uns64 TypeDelegate::size(Loc loc) | |
3190 { | |
3191 return PTRSIZE * 2; | |
3192 } | |
3193 | |
797
340acf1535d0
Removed KDevelop3 project files, CMake can generate them just fine!
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
780
diff
changeset
|
3194 // LDC added, no reason to align to 2*PTRSIZE |
340acf1535d0
Removed KDevelop3 project files, CMake can generate them just fine!
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
780
diff
changeset
|
3195 unsigned TypeDelegate::alignsize() |
340acf1535d0
Removed KDevelop3 project files, CMake can generate them just fine!
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
780
diff
changeset
|
3196 { |
340acf1535d0
Removed KDevelop3 project files, CMake can generate them just fine!
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
780
diff
changeset
|
3197 // A Delegate consists of two ptr values, so align it on pointer size |
340acf1535d0
Removed KDevelop3 project files, CMake can generate them just fine!
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
780
diff
changeset
|
3198 // boundary |
340acf1535d0
Removed KDevelop3 project files, CMake can generate them just fine!
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
780
diff
changeset
|
3199 return PTRSIZE; |
340acf1535d0
Removed KDevelop3 project files, CMake can generate them just fine!
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
780
diff
changeset
|
3200 } |
340acf1535d0
Removed KDevelop3 project files, CMake can generate them just fine!
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
780
diff
changeset
|
3201 |
159 | 3202 void TypeDelegate::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) |
3203 { | |
3204 if (mod != this->mod) | |
3205 { toCBuffer3(buf, hgs, mod); | |
3206 return; | |
3207 } | |
3208 TypeFunction *tf = (TypeFunction *)next; | |
3209 | |
3210 tf->next->toCBuffer2(buf, hgs, 0); | |
3211 buf->writestring(" delegate"); | |
3212 Argument::argsToCBuffer(buf, hgs, tf->parameters, tf->varargs); | |
3213 } | |
3214 | |
3215 Expression *TypeDelegate::defaultInit(Loc loc) | |
3216 { | |
3217 #if LOGDEFAULTINIT | |
3218 printf("TypeDelegate::defaultInit() '%s'\n", toChars()); | |
3219 #endif | |
3220 Expression *e; | |
3221 e = new NullExp(loc); | |
3222 e->type = this; | |
3223 return e; | |
3224 } | |
3225 | |
3226 int TypeDelegate::isZeroInit() | |
3227 { | |
3228 return 1; | |
3229 } | |
3230 | |
3231 int TypeDelegate::checkBoolean() | |
3232 { | |
3233 return TRUE; | |
3234 } | |
3235 | |
3236 Expression *TypeDelegate::dotExp(Scope *sc, Expression *e, Identifier *ident) | |
3237 { | |
3238 #if LOGDOTEXP | |
3239 printf("TypeDelegate::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); | |
3240 #endif | |
3241 if (ident == Id::ptr) | |
3242 { | |
599
4435f57956e7
Fixed .funcptr property of delegates, no longer uses the infamous DMD rewrites to pointer arithmetic, instead a GEPExp has been introduced.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
591
diff
changeset
|
3243 e = new GEPExp(e->loc, e, ident, 0); |
159 | 3244 e->type = tvoidptr; |
3245 return e; | |
3246 } | |
3247 else if (ident == Id::funcptr) | |
3248 { | |
599
4435f57956e7
Fixed .funcptr property of delegates, no longer uses the infamous DMD rewrites to pointer arithmetic, instead a GEPExp has been introduced.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
591
diff
changeset
|
3249 e = new GEPExp(e->loc, e, ident, 1); |
4435f57956e7
Fixed .funcptr property of delegates, no longer uses the infamous DMD rewrites to pointer arithmetic, instead a GEPExp has been introduced.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
591
diff
changeset
|
3250 e->type = tvoidptr; |
159 | 3251 return e; |
3252 } | |
3253 else | |
3254 { | |
3255 e = Type::dotExp(sc, e, ident); | |
3256 } | |
3257 return e; | |
3258 } | |
3259 | |
3260 int TypeDelegate::hasPointers() | |
3261 { | |
3262 return TRUE; | |
3263 } | |
3264 | |
3265 | |
3266 | |
3267 /***************************** TypeQualified *****************************/ | |
3268 | |
3269 TypeQualified::TypeQualified(TY ty, Loc loc) | |
3270 : Type(ty, NULL) | |
3271 { | |
3272 this->loc = loc; | |
3273 } | |
3274 | |
3275 void TypeQualified::syntaxCopyHelper(TypeQualified *t) | |
3276 { | |
3277 //printf("TypeQualified::syntaxCopyHelper(%s) %s\n", t->toChars(), toChars()); | |
3278 idents.setDim(t->idents.dim); | |
3279 for (int i = 0; i < idents.dim; i++) | |
3280 { | |
3281 Identifier *id = (Identifier *)t->idents.data[i]; | |
3282 if (id->dyncast() == DYNCAST_DSYMBOL) | |
3283 { | |
3284 TemplateInstance *ti = (TemplateInstance *)id; | |
3285 | |
3286 ti = (TemplateInstance *)ti->syntaxCopy(NULL); | |
3287 id = (Identifier *)ti; | |
3288 } | |
3289 idents.data[i] = id; | |
3290 } | |
3291 } | |
3292 | |
3293 | |
3294 void TypeQualified::addIdent(Identifier *ident) | |
3295 { | |
3296 idents.push(ident); | |
3297 } | |
3298 | |
3299 void TypeQualified::toCBuffer2Helper(OutBuffer *buf, HdrGenState *hgs) | |
3300 { | |
3301 int i; | |
3302 | |
3303 for (i = 0; i < idents.dim; i++) | |
3304 { Identifier *id = (Identifier *)idents.data[i]; | |
3305 | |
3306 buf->writeByte('.'); | |
3307 | |
3308 if (id->dyncast() == DYNCAST_DSYMBOL) | |
3309 { | |
3310 TemplateInstance *ti = (TemplateInstance *)id; | |
3311 ti->toCBuffer(buf, hgs); | |
3312 } | |
3313 else | |
3314 buf->writestring(id->toChars()); | |
3315 } | |
3316 } | |
3317 | |
3318 d_uns64 TypeQualified::size(Loc loc) | |
3319 { | |
3320 error(this->loc, "size of type %s is not known", toChars()); | |
3321 return 1; | |
3322 } | |
3323 | |
3324 /************************************* | |
3325 * Takes an array of Identifiers and figures out if | |
3326 * it represents a Type or an Expression. | |
3327 * Output: | |
3328 * if expression, *pe is set | |
3329 * if type, *pt is set | |
3330 */ | |
3331 | |
3332 void TypeQualified::resolveHelper(Loc loc, Scope *sc, | |
3333 Dsymbol *s, Dsymbol *scopesym, | |
3334 Expression **pe, Type **pt, Dsymbol **ps) | |
3335 { | |
3336 Identifier *id = NULL; | |
3337 int i; | |
3338 VarDeclaration *v; | |
3339 EnumMember *em; | |
3340 TupleDeclaration *td; | |
3341 Type *t; | |
3342 Expression *e; | |
3343 | |
3344 #if 0 | |
3345 printf("TypeQualified::resolveHelper(sc = %p, idents = '%s')\n", sc, toChars()); | |
3346 if (scopesym) | |
3347 printf("\tscopesym = '%s'\n", scopesym->toChars()); | |
3348 #endif | |
3349 *pe = NULL; | |
3350 *pt = NULL; | |
3351 *ps = NULL; | |
3352 if (s) | |
3353 { | |
3354 //printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind()); | |
336 | 3355 s->checkDeprecated(loc, sc); // check for deprecated aliases |
159 | 3356 s = s->toAlias(); |
3357 //printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind()); | |
3358 for (i = 0; i < idents.dim; i++) | |
3359 { Dsymbol *sm; | |
3360 | |
3361 id = (Identifier *)idents.data[i]; | |
3362 sm = s->searchX(loc, sc, id); | |
3363 //printf("\t3: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind()); | |
3364 //printf("getType = '%s'\n", s->getType()->toChars()); | |
3365 if (!sm) | |
3366 { | |
3367 v = s->isVarDeclaration(); | |
3368 if (v && id == Id::length) | |
3369 { | |
3370 if (v->isConst() && v->getExpInitializer()) | |
3371 { e = v->getExpInitializer()->exp; | |
3372 } | |
3373 else | |
3374 e = new VarExp(loc, v); | |
3375 t = e->type; | |
3376 if (!t) | |
3377 goto Lerror; | |
3378 goto L3; | |
3379 } | |
3380 t = s->getType(); | |
3381 if (!t && s->isDeclaration()) | |
3382 t = s->isDeclaration()->type; | |
3383 if (t) | |
3384 { | |
3385 sm = t->toDsymbol(sc); | |
3386 if (sm) | |
3387 { sm = sm->search(loc, id, 0); | |
3388 if (sm) | |
3389 goto L2; | |
3390 } | |
3391 //e = t->getProperty(loc, id); | |
3392 e = new TypeExp(loc, t); | |
3393 e = t->dotExp(sc, e, id); | |
3394 i++; | |
3395 L3: | |
3396 for (; i < idents.dim; i++) | |
3397 { | |
3398 id = (Identifier *)idents.data[i]; | |
3399 //printf("e: '%s', id: '%s', type = %p\n", e->toChars(), id->toChars(), e->type); | |
3400 e = e->type->dotExp(sc, e, id); | |
3401 } | |
3402 *pe = e; | |
3403 } | |
3404 else | |
3405 Lerror: | |
3406 error(loc, "identifier '%s' of '%s' is not defined", id->toChars(), toChars()); | |
3407 return; | |
3408 } | |
3409 L2: | |
3410 s = sm->toAlias(); | |
3411 } | |
3412 | |
3413 v = s->isVarDeclaration(); | |
3414 if (v) | |
3415 { | |
3416 // It's not a type, it's an expression | |
3417 if (v->isConst() && v->getExpInitializer()) | |
3418 { | |
3419 ExpInitializer *ei = v->getExpInitializer(); | |
3420 assert(ei); | |
3421 *pe = ei->exp->copy(); // make copy so we can change loc | |
3422 (*pe)->loc = loc; | |
3423 } | |
3424 else | |
3425 { | |
3426 #if 0 | |
3427 WithScopeSymbol *withsym; | |
3428 if (scopesym && (withsym = scopesym->isWithScopeSymbol()) != NULL) | |
3429 { | |
3430 // Same as wthis.ident | |
3431 e = new VarExp(loc, withsym->withstate->wthis); | |
3432 e = new DotIdExp(loc, e, ident); | |
3433 //assert(0); // BUG: should handle this | |
3434 } | |
3435 else | |
3436 #endif | |
3437 *pe = new VarExp(loc, v); | |
3438 } | |
3439 return; | |
3440 } | |
3441 em = s->isEnumMember(); | |
3442 if (em) | |
3443 { | |
3444 // It's not a type, it's an expression | |
3445 *pe = em->value->copy(); | |
3446 return; | |
3447 } | |
3448 | |
3449 L1: | |
3450 t = s->getType(); | |
3451 if (!t) | |
3452 { | |
3453 // If the symbol is an import, try looking inside the import | |
3454 Import *si; | |
3455 | |
3456 si = s->isImport(); | |
3457 if (si) | |
3458 { | |
3459 s = si->search(loc, s->ident, 0); | |
3460 if (s && s != si) | |
3461 goto L1; | |
3462 s = si; | |
3463 } | |
3464 *ps = s; | |
3465 return; | |
3466 } | |
3467 if (t->ty == Tinstance && t != this && !t->deco) | |
3468 { error(loc, "forward reference to '%s'", t->toChars()); | |
3469 return; | |
3470 } | |
3471 | |
3472 if (t != this) | |
3473 { | |
3474 if (t->reliesOnTident()) | |
3475 { | |
3476 Scope *scx; | |
3477 | |
3478 for (scx = sc; 1; scx = scx->enclosing) | |
3479 { | |
3480 if (!scx) | |
3481 { error(loc, "forward reference to '%s'", t->toChars()); | |
3482 return; | |
3483 } | |
3484 if (scx->scopesym == scopesym) | |
3485 break; | |
3486 } | |
3487 t = t->semantic(loc, scx); | |
3488 //((TypeIdentifier *)t)->resolve(loc, scx, pe, &t, ps); | |
3489 } | |
3490 } | |
3491 if (t->ty == Ttuple) | |
772
cd7da2ba14d1
Fix bug reported by downs. Related to delegate types within tuple template parameters.
Christian Kamm <kamm incasoftware de>
parents:
771
diff
changeset
|
3492 *pt = t; |
159 | 3493 else |
3494 *pt = t->merge(); | |
3495 } | |
3496 if (!s) | |
3497 { | |
3498 error(loc, "identifier '%s' is not defined", toChars()); | |
3499 } | |
3500 } | |
3501 | |
3502 /***************************** TypeIdentifier *****************************/ | |
3503 | |
3504 TypeIdentifier::TypeIdentifier(Loc loc, Identifier *ident) | |
3505 : TypeQualified(Tident, loc) | |
3506 { | |
3507 this->ident = ident; | |
3508 } | |
3509 | |
3510 | |
3511 Type *TypeIdentifier::syntaxCopy() | |
3512 { | |
3513 TypeIdentifier *t; | |
3514 | |
3515 t = new TypeIdentifier(loc, ident); | |
3516 t->syntaxCopyHelper(this); | |
3517 return t; | |
3518 } | |
3519 | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
3520 void TypeIdentifier::toDecoBuffer(OutBuffer *buf, bool mangle) |
159 | 3521 { unsigned len; |
3522 char *name; | |
3523 | |
3524 name = ident->toChars(); | |
3525 len = strlen(name); | |
3526 buf->printf("%c%d%s", mangleChar[ty], len, name); | |
3527 //buf->printf("%c%s", mangleChar[ty], name); | |
3528 } | |
3529 | |
3530 void TypeIdentifier::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
3531 { | |
3532 if (mod != this->mod) | |
3533 { toCBuffer3(buf, hgs, mod); | |
3534 return; | |
3535 } | |
3536 buf->writestring(this->ident->toChars()); | |
3537 toCBuffer2Helper(buf, hgs); | |
3538 } | |
3539 | |
3540 /************************************* | |
3541 * Takes an array of Identifiers and figures out if | |
3542 * it represents a Type or an Expression. | |
3543 * Output: | |
3544 * if expression, *pe is set | |
3545 * if type, *pt is set | |
3546 */ | |
3547 | |
3548 void TypeIdentifier::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) | |
3549 { Dsymbol *s; | |
3550 Dsymbol *scopesym; | |
3551 | |
3552 //printf("TypeIdentifier::resolve(sc = %p, idents = '%s')\n", sc, toChars()); | |
3553 s = sc->search(loc, ident, &scopesym); | |
3554 resolveHelper(loc, sc, s, scopesym, pe, pt, ps); | |
3555 } | |
3556 | |
3557 /***************************************** | |
3558 * See if type resolves to a symbol, if so, | |
3559 * return that symbol. | |
3560 */ | |
3561 | |
3562 Dsymbol *TypeIdentifier::toDsymbol(Scope *sc) | |
3563 { | |
3564 //printf("TypeIdentifier::toDsymbol('%s')\n", toChars()); | |
3565 if (!sc) | |
3566 return NULL; | |
3567 //printf("ident = '%s'\n", ident->toChars()); | |
3568 | |
3569 Dsymbol *scopesym; | |
3570 Dsymbol *s = sc->search(loc, ident, &scopesym); | |
3571 if (s) | |
3572 { | |
3573 for (int i = 0; i < idents.dim; i++) | |
3574 { | |
3575 Identifier *id = (Identifier *)idents.data[i]; | |
3576 s = s->searchX(loc, sc, id); | |
3577 if (!s) // failed to find a symbol | |
3578 { //printf("\tdidn't find a symbol\n"); | |
3579 break; | |
3580 } | |
3581 } | |
3582 } | |
3583 return s; | |
3584 } | |
3585 | |
3586 Type *TypeIdentifier::semantic(Loc loc, Scope *sc) | |
3587 { | |
3588 Type *t; | |
3589 Expression *e; | |
3590 Dsymbol *s; | |
3591 | |
3592 //printf("TypeIdentifier::semantic(%s)\n", toChars()); | |
3593 resolve(loc, sc, &e, &t, &s); | |
3594 if (t) | |
3595 { | |
3596 //printf("\tit's a type %d, %s, %s\n", t->ty, t->toChars(), t->deco); | |
3597 | |
3598 if (t->ty == Ttypedef) | |
3599 { TypeTypedef *tt = (TypeTypedef *)t; | |
3600 | |
3601 if (tt->sym->sem == 1) | |
3602 error(loc, "circular reference of typedef %s", tt->toChars()); | |
3603 } | |
3604 } | |
3605 else | |
3606 { | |
3607 #ifdef DEBUG | |
3608 if (!global.gag) | |
3609 printf("1: "); | |
3610 #endif | |
3611 if (s) | |
3612 { | |
3613 s->error(loc, "is used as a type"); | |
3614 } | |
3615 else | |
3616 error(loc, "%s is used as a type", toChars()); | |
3617 t = tvoid; | |
3618 } | |
3619 //t->print(); | |
3620 return t; | |
3621 } | |
3622 | |
3623 Type *TypeIdentifier::reliesOnTident() | |
3624 { | |
3625 return this; | |
3626 } | |
3627 | |
3628 Expression *TypeIdentifier::toExpression() | |
3629 { | |
3630 Expression *e = new IdentifierExp(loc, ident); | |
3631 for (int i = 0; i < idents.dim; i++) | |
3632 { | |
3633 Identifier *id = (Identifier *)idents.data[i]; | |
3634 e = new DotIdExp(loc, e, id); | |
3635 } | |
3636 | |
3637 return e; | |
3638 } | |
3639 | |
3640 /***************************** TypeInstance *****************************/ | |
3641 | |
3642 TypeInstance::TypeInstance(Loc loc, TemplateInstance *tempinst) | |
3643 : TypeQualified(Tinstance, loc) | |
3644 { | |
3645 this->tempinst = tempinst; | |
3646 } | |
3647 | |
3648 Type *TypeInstance::syntaxCopy() | |
3649 { | |
3650 //printf("TypeInstance::syntaxCopy() %s, %d\n", toChars(), idents.dim); | |
3651 TypeInstance *t; | |
3652 | |
3653 t = new TypeInstance(loc, (TemplateInstance *)tempinst->syntaxCopy(NULL)); | |
3654 t->syntaxCopyHelper(this); | |
3655 return t; | |
3656 } | |
3657 | |
3658 | |
3659 void TypeInstance::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
3660 { | |
3661 if (mod != this->mod) | |
3662 { toCBuffer3(buf, hgs, mod); | |
3663 return; | |
3664 } | |
3665 tempinst->toCBuffer(buf, hgs); | |
3666 toCBuffer2Helper(buf, hgs); | |
3667 } | |
3668 | |
3669 void TypeInstance::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) | |
3670 { | |
3671 // Note close similarity to TypeIdentifier::resolve() | |
3672 | |
3673 Dsymbol *s; | |
3674 | |
3675 *pe = NULL; | |
3676 *pt = NULL; | |
3677 *ps = NULL; | |
3678 | |
3679 #if 0 | |
3680 if (!idents.dim) | |
3681 { | |
3682 error(loc, "template instance '%s' has no identifier", toChars()); | |
3683 return; | |
3684 } | |
3685 #endif | |
3686 //id = (Identifier *)idents.data[0]; | |
3687 //printf("TypeInstance::resolve(sc = %p, idents = '%s')\n", sc, id->toChars()); | |
3688 s = tempinst; | |
3689 if (s) | |
3690 s->semantic(sc); | |
3691 resolveHelper(loc, sc, s, NULL, pe, pt, ps); | |
3692 //printf("pt = '%s'\n", (*pt)->toChars()); | |
3693 } | |
3694 | |
3695 Type *TypeInstance::semantic(Loc loc, Scope *sc) | |
3696 { | |
3697 Type *t; | |
3698 Expression *e; | |
3699 Dsymbol *s; | |
3700 | |
3701 //printf("TypeInstance::semantic(%s)\n", toChars()); | |
3702 | |
3703 if (sc->parameterSpecialization) | |
3704 { | |
3705 unsigned errors = global.errors; | |
3706 global.gag++; | |
3707 | |
3708 resolve(loc, sc, &e, &t, &s); | |
3709 | |
3710 global.gag--; | |
3711 if (errors != global.errors) | |
3712 { if (global.gag == 0) | |
3713 global.errors = errors; | |
3714 return this; | |
3715 } | |
3716 } | |
3717 else | |
3718 resolve(loc, sc, &e, &t, &s); | |
3719 | |
3720 if (!t) | |
3721 { | |
3722 #ifdef DEBUG | |
3723 printf("2: "); | |
3724 #endif | |
3725 error(loc, "%s is used as a type", toChars()); | |
3726 t = tvoid; | |
3727 } | |
3728 return t; | |
3729 } | |
3730 | |
875
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3731 Dsymbol *TypeInstance::toDsymbol(Scope *sc) |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3732 { |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3733 Type *t; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3734 Expression *e; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3735 Dsymbol *s; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3736 |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3737 //printf("TypeInstance::semantic(%s)\n", toChars()); |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3738 |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3739 if (sc->parameterSpecialization) |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3740 { |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3741 unsigned errors = global.errors; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3742 global.gag++; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3743 |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3744 resolve(loc, sc, &e, &t, &s); |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3745 |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3746 global.gag--; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3747 if (errors != global.errors) |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3748 { if (global.gag == 0) |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3749 global.errors = errors; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3750 return NULL; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3751 } |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3752 } |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3753 else |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3754 resolve(loc, sc, &e, &t, &s); |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3755 |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3756 return s; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3757 } |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
3758 |
159 | 3759 |
3760 /***************************** TypeTypeof *****************************/ | |
3761 | |
3762 TypeTypeof::TypeTypeof(Loc loc, Expression *exp) | |
3763 : TypeQualified(Ttypeof, loc) | |
3764 { | |
3765 this->exp = exp; | |
3766 } | |
3767 | |
3768 Type *TypeTypeof::syntaxCopy() | |
3769 { | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
3770 //printf("TypeTypeof::syntaxCopy() %s\n", toChars()); |
159 | 3771 TypeTypeof *t; |
3772 | |
3773 t = new TypeTypeof(loc, exp->syntaxCopy()); | |
3774 t->syntaxCopyHelper(this); | |
3775 return t; | |
3776 } | |
3777 | |
3778 Dsymbol *TypeTypeof::toDsymbol(Scope *sc) | |
3779 { | |
3780 Type *t; | |
3781 | |
336 | 3782 t = semantic(loc, sc); |
159 | 3783 if (t == this) |
3784 return NULL; | |
3785 return t->toDsymbol(sc); | |
3786 } | |
3787 | |
3788 void TypeTypeof::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
3789 { | |
3790 if (mod != this->mod) | |
3791 { toCBuffer3(buf, hgs, mod); | |
3792 return; | |
3793 } | |
3794 buf->writestring("typeof("); | |
3795 exp->toCBuffer(buf, hgs); | |
3796 buf->writeByte(')'); | |
3797 toCBuffer2Helper(buf, hgs); | |
3798 } | |
3799 | |
3800 Type *TypeTypeof::semantic(Loc loc, Scope *sc) | |
3801 { Expression *e; | |
3802 Type *t; | |
3803 | |
3804 //printf("TypeTypeof::semantic() %p\n", this); | |
3805 | |
3806 //static int nest; if (++nest == 50) *(char*)0=0; | |
3807 | |
3808 #if 0 | |
3809 /* Special case for typeof(this) and typeof(super) since both | |
3810 * should work even if they are not inside a non-static member function | |
3811 */ | |
3812 if (exp->op == TOKthis || exp->op == TOKsuper) | |
3813 { | |
3814 // Find enclosing struct or class | |
3815 for (Dsymbol *s = sc->parent; 1; s = s->parent) | |
3816 { | |
3817 ClassDeclaration *cd; | |
3818 StructDeclaration *sd; | |
3819 | |
3820 if (!s) | |
3821 { | |
3822 error(loc, "%s is not in a struct or class scope", exp->toChars()); | |
3823 goto Lerr; | |
3824 } | |
3825 cd = s->isClassDeclaration(); | |
3826 if (cd) | |
3827 { | |
3828 if (exp->op == TOKsuper) | |
3829 { | |
3830 cd = cd->baseClass; | |
3831 if (!cd) | |
3832 { error(loc, "class %s has no 'super'", s->toChars()); | |
3833 goto Lerr; | |
3834 } | |
3835 } | |
3836 t = cd->type; | |
3837 break; | |
3838 } | |
3839 sd = s->isStructDeclaration(); | |
3840 if (sd) | |
3841 { | |
3842 if (exp->op == TOKsuper) | |
3843 { | |
3844 error(loc, "struct %s has no 'super'", sd->toChars()); | |
3845 goto Lerr; | |
3846 } | |
3847 t = sd->type->pointerTo(); | |
3848 break; | |
3849 } | |
3850 } | |
3851 } | |
3852 else | |
3853 #endif | |
3854 { | |
3855 sc->intypeof++; | |
3856 exp = exp->semantic(sc); | |
3857 sc->intypeof--; | |
336 | 3858 if (exp->op == TOKtype) |
3859 { | |
3860 error(loc, "argument %s to typeof is not an expression", exp->toChars()); | |
3861 } | |
159 | 3862 t = exp->type; |
3863 if (!t) | |
3864 { | |
3865 error(loc, "expression (%s) has no type", exp->toChars()); | |
3866 goto Lerr; | |
3867 } | |
3868 } | |
3869 | |
3870 if (idents.dim) | |
3871 { | |
3872 Dsymbol *s = t->toDsymbol(sc); | |
3873 for (size_t i = 0; i < idents.dim; i++) | |
3874 { | |
3875 if (!s) | |
3876 break; | |
3877 Identifier *id = (Identifier *)idents.data[i]; | |
3878 s = s->searchX(loc, sc, id); | |
3879 } | |
3880 if (s) | |
3881 { | |
3882 t = s->getType(); | |
3883 if (!t) | |
3884 { error(loc, "%s is not a type", s->toChars()); | |
3885 goto Lerr; | |
3886 } | |
3887 } | |
3888 else | |
3889 { error(loc, "cannot resolve .property for %s", toChars()); | |
3890 goto Lerr; | |
3891 } | |
3892 } | |
3893 return t; | |
3894 | |
3895 Lerr: | |
3896 return tvoid; | |
3897 } | |
3898 | |
3899 d_uns64 TypeTypeof::size(Loc loc) | |
3900 { | |
3901 if (exp->type) | |
3902 return exp->type->size(loc); | |
3903 else | |
3904 return TypeQualified::size(loc); | |
3905 } | |
3906 | |
3907 | |
3908 | |
3909 /***************************** TypeEnum *****************************/ | |
3910 | |
3911 TypeEnum::TypeEnum(EnumDeclaration *sym) | |
3912 : Type(Tenum, NULL) | |
3913 { | |
3914 this->sym = sym; | |
3915 } | |
3916 | |
3917 char *TypeEnum::toChars() | |
3918 { | |
3919 return sym->toChars(); | |
3920 } | |
3921 | |
486
a34078905d01
Added pragma(llvmdc, "string") for misc per-module compiler configuration, currently "string" can only be "verbose" which forces -vv for module it appears in.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
445
diff
changeset
|
3922 Type *TypeEnum::syntaxCopy() |
a34078905d01
Added pragma(llvmdc, "string") for misc per-module compiler configuration, currently "string" can only be "verbose" which forces -vv for module it appears in.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
445
diff
changeset
|
3923 { |
a34078905d01
Added pragma(llvmdc, "string") for misc per-module compiler configuration, currently "string" can only be "verbose" which forces -vv for module it appears in.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
445
diff
changeset
|
3924 return this; |
a34078905d01
Added pragma(llvmdc, "string") for misc per-module compiler configuration, currently "string" can only be "verbose" which forces -vv for module it appears in.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
445
diff
changeset
|
3925 } |
a34078905d01
Added pragma(llvmdc, "string") for misc per-module compiler configuration, currently "string" can only be "verbose" which forces -vv for module it appears in.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
445
diff
changeset
|
3926 |
159 | 3927 Type *TypeEnum::semantic(Loc loc, Scope *sc) |
3928 { | |
3929 sym->semantic(sc); | |
3930 return merge(); | |
3931 } | |
3932 | |
3933 d_uns64 TypeEnum::size(Loc loc) | |
3934 { | |
3935 if (!sym->memtype) | |
3936 { | |
3937 error(loc, "enum %s is forward referenced", sym->toChars()); | |
3938 return 4; | |
3939 } | |
3940 return sym->memtype->size(loc); | |
3941 } | |
3942 | |
3943 unsigned TypeEnum::alignsize() | |
3944 { | |
3945 if (!sym->memtype) | |
3946 { | |
3947 #ifdef DEBUG | |
3948 printf("1: "); | |
3949 #endif | |
3950 error(0, "enum %s is forward referenced", sym->toChars()); | |
3951 return 4; | |
3952 } | |
3953 return sym->memtype->alignsize(); | |
3954 } | |
3955 | |
3956 Dsymbol *TypeEnum::toDsymbol(Scope *sc) | |
3957 { | |
3958 return sym; | |
3959 } | |
3960 | |
3961 Type *TypeEnum::toBasetype() | |
3962 { | |
3963 if (!sym->memtype) | |
3964 { | |
3965 #ifdef DEBUG | |
3966 printf("2: "); | |
3967 #endif | |
3968 error(sym->loc, "enum %s is forward referenced", sym->toChars()); | |
3969 return tint32; | |
3970 } | |
3971 return sym->memtype->toBasetype(); | |
3972 } | |
3973 | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
3974 void TypeEnum::toDecoBuffer(OutBuffer *buf, bool mangle) |
159 | 3975 { char *name; |
3976 | |
3977 name = sym->mangle(); | |
3978 // if (name[0] == '_' && name[1] == 'D') | |
3979 // name += 2; | |
3980 buf->printf("%c%s", mangleChar[ty], name); | |
3981 } | |
3982 | |
3983 void TypeEnum::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
3984 { | |
3985 if (mod != this->mod) | |
3986 { toCBuffer3(buf, hgs, mod); | |
3987 return; | |
3988 } | |
3989 buf->writestring(sym->toChars()); | |
3990 } | |
3991 | |
3992 Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident) | |
3993 { | |
3994 EnumMember *m; | |
3995 Dsymbol *s; | |
3996 Expression *em; | |
3997 | |
3998 #if LOGDOTEXP | |
3999 printf("TypeEnum::dotExp(e = '%s', ident = '%s') '%s'\n", e->toChars(), ident->toChars(), toChars()); | |
4000 #endif | |
4001 if (!sym->symtab) | |
4002 goto Lfwd; | |
4003 s = sym->symtab->lookup(ident); | |
4004 if (!s) | |
4005 { | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
4006 if (ident == Id::max || |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
4007 ident == Id::min || |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
4008 ident == Id::init || |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
4009 ident == Id::stringof || |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
4010 !sym->memtype |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
4011 ) |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
4012 { |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
4013 return getProperty(e->loc, ident); |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
4014 } |
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
4015 return sym->memtype->dotExp(sc, e, ident); |
159 | 4016 } |
4017 m = s->isEnumMember(); | |
4018 em = m->value->copy(); | |
4019 em->loc = e->loc; | |
4020 return em; | |
4021 | |
4022 Lfwd: | |
4023 error(e->loc, "forward reference of %s.%s", toChars(), ident->toChars()); | |
4024 return new IntegerExp(0, 0, this); | |
4025 } | |
4026 | |
4027 Expression *TypeEnum::getProperty(Loc loc, Identifier *ident) | |
4028 { Expression *e; | |
4029 | |
4030 if (ident == Id::max) | |
4031 { | |
4032 if (!sym->symtab) | |
4033 goto Lfwd; | |
4034 e = new IntegerExp(0, sym->maxval, this); | |
4035 } | |
4036 else if (ident == Id::min) | |
4037 { | |
4038 if (!sym->symtab) | |
4039 goto Lfwd; | |
4040 e = new IntegerExp(0, sym->minval, this); | |
4041 } | |
4042 else if (ident == Id::init) | |
4043 { | |
4044 if (!sym->symtab) | |
4045 goto Lfwd; | |
4046 e = defaultInit(loc); | |
4047 } | |
846
bc982f1ad106
Merged DMD 1.037 frontend
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
822
diff
changeset
|
4048 else if (ident == Id::stringof) |
bc982f1ad106
Merged DMD 1.037 frontend
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
822
diff
changeset
|
4049 { char *s = toChars(); |
bc982f1ad106
Merged DMD 1.037 frontend
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
822
diff
changeset
|
4050 e = new StringExp(loc, s, strlen(s), 'c'); |
bc982f1ad106
Merged DMD 1.037 frontend
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
822
diff
changeset
|
4051 Scope sc; |
bc982f1ad106
Merged DMD 1.037 frontend
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
822
diff
changeset
|
4052 e = e->semantic(&sc); |
bc982f1ad106
Merged DMD 1.037 frontend
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
822
diff
changeset
|
4053 } |
159 | 4054 else |
4055 { | |
4056 if (!sym->memtype) | |
4057 goto Lfwd; | |
4058 e = sym->memtype->getProperty(loc, ident); | |
4059 } | |
4060 return e; | |
4061 | |
4062 Lfwd: | |
4063 error(loc, "forward reference of %s.%s", toChars(), ident->toChars()); | |
4064 return new IntegerExp(0, 0, this); | |
4065 } | |
4066 | |
4067 int TypeEnum::isintegral() | |
4068 { | |
4069 return 1; | |
4070 } | |
4071 | |
4072 int TypeEnum::isfloating() | |
4073 { | |
4074 return 0; | |
4075 } | |
4076 | |
4077 int TypeEnum::isunsigned() | |
4078 { | |
4079 return sym->memtype->isunsigned(); | |
4080 } | |
4081 | |
4082 int TypeEnum::isscalar() | |
4083 { | |
4084 return 1; | |
4085 //return sym->memtype->isscalar(); | |
4086 } | |
4087 | |
4088 MATCH TypeEnum::implicitConvTo(Type *to) | |
4089 { MATCH m; | |
4090 | |
4091 //printf("TypeEnum::implicitConvTo()\n"); | |
4092 if (this->equals(to)) | |
4093 m = MATCHexact; // exact match | |
4094 else if (sym->memtype->implicitConvTo(to)) | |
4095 m = MATCHconvert; // match with conversions | |
4096 else | |
4097 m = MATCHnomatch; // no match | |
4098 return m; | |
4099 } | |
4100 | |
4101 Expression *TypeEnum::defaultInit(Loc loc) | |
4102 { | |
4103 #if LOGDEFAULTINIT | |
4104 printf("TypeEnum::defaultInit() '%s'\n", toChars()); | |
4105 #endif | |
4106 // Initialize to first member of enum | |
4107 Expression *e; | |
4108 e = new IntegerExp(loc, sym->defaultval, this); | |
4109 return e; | |
4110 } | |
4111 | |
4112 int TypeEnum::isZeroInit() | |
4113 { | |
4114 return (sym->defaultval == 0); | |
4115 } | |
4116 | |
4117 int TypeEnum::hasPointers() | |
4118 { | |
4119 return toBasetype()->hasPointers(); | |
4120 } | |
4121 | |
4122 /***************************** TypeTypedef *****************************/ | |
4123 | |
4124 TypeTypedef::TypeTypedef(TypedefDeclaration *sym) | |
4125 : Type(Ttypedef, NULL) | |
4126 { | |
4127 this->sym = sym; | |
4128 } | |
4129 | |
4130 Type *TypeTypedef::syntaxCopy() | |
4131 { | |
4132 return this; | |
4133 } | |
4134 | |
4135 char *TypeTypedef::toChars() | |
4136 { | |
4137 return sym->toChars(); | |
4138 } | |
4139 | |
4140 Type *TypeTypedef::semantic(Loc loc, Scope *sc) | |
4141 { | |
4142 //printf("TypeTypedef::semantic(%s), sem = %d\n", toChars(), sym->sem); | |
4143 sym->semantic(sc); | |
4144 return merge(); | |
4145 } | |
4146 | |
4147 d_uns64 TypeTypedef::size(Loc loc) | |
4148 { | |
4149 return sym->basetype->size(loc); | |
4150 } | |
4151 | |
4152 unsigned TypeTypedef::alignsize() | |
4153 { | |
4154 return sym->basetype->alignsize(); | |
4155 } | |
4156 | |
4157 Dsymbol *TypeTypedef::toDsymbol(Scope *sc) | |
4158 { | |
4159 return sym; | |
4160 } | |
4161 | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
4162 void TypeTypedef::toDecoBuffer(OutBuffer *buf, bool mangle) |
159 | 4163 { unsigned len; |
4164 char *name; | |
4165 | |
4166 name = sym->mangle(); | |
4167 // if (name[0] == '_' && name[1] == 'D') | |
4168 // name += 2; | |
4169 //len = strlen(name); | |
4170 //buf->printf("%c%d%s", mangleChar[ty], len, name); | |
4171 buf->printf("%c%s", mangleChar[ty], name); | |
4172 } | |
4173 | |
4174 void TypeTypedef::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
4175 { | |
4176 //printf("TypeTypedef::toCBuffer2() '%s'\n", sym->toChars()); | |
4177 if (mod != this->mod) | |
4178 { toCBuffer3(buf, hgs, mod); | |
4179 return; | |
4180 } | |
4181 buf->writestring(sym->toChars()); | |
4182 } | |
4183 | |
4184 Expression *TypeTypedef::dotExp(Scope *sc, Expression *e, Identifier *ident) | |
4185 { | |
4186 #if LOGDOTEXP | |
4187 printf("TypeTypedef::dotExp(e = '%s', ident = '%s') '%s'\n", e->toChars(), ident->toChars(), toChars()); | |
4188 #endif | |
4189 if (ident == Id::init) | |
4190 { | |
4191 return Type::dotExp(sc, e, ident); | |
4192 } | |
4193 return sym->basetype->dotExp(sc, e, ident); | |
4194 } | |
4195 | |
4196 Expression *TypeTypedef::getProperty(Loc loc, Identifier *ident) | |
4197 { | |
4198 if (ident == Id::init) | |
4199 { | |
4200 return Type::getProperty(loc, ident); | |
4201 } | |
4202 return sym->basetype->getProperty(loc, ident); | |
4203 } | |
4204 | |
4205 int TypeTypedef::isbit() | |
4206 { | |
4207 return sym->basetype->isbit(); | |
4208 } | |
4209 | |
4210 int TypeTypedef::isintegral() | |
4211 { | |
4212 //printf("TypeTypedef::isintegral()\n"); | |
4213 //printf("sym = '%s'\n", sym->toChars()); | |
4214 //printf("basetype = '%s'\n", sym->basetype->toChars()); | |
4215 return sym->basetype->isintegral(); | |
4216 } | |
4217 | |
4218 int TypeTypedef::isfloating() | |
4219 { | |
4220 return sym->basetype->isfloating(); | |
4221 } | |
4222 | |
4223 int TypeTypedef::isreal() | |
4224 { | |
4225 return sym->basetype->isreal(); | |
4226 } | |
4227 | |
4228 int TypeTypedef::isimaginary() | |
4229 { | |
4230 return sym->basetype->isimaginary(); | |
4231 } | |
4232 | |
4233 int TypeTypedef::iscomplex() | |
4234 { | |
4235 return sym->basetype->iscomplex(); | |
4236 } | |
4237 | |
4238 int TypeTypedef::isunsigned() | |
4239 { | |
4240 return sym->basetype->isunsigned(); | |
4241 } | |
4242 | |
4243 int TypeTypedef::isscalar() | |
4244 { | |
4245 return sym->basetype->isscalar(); | |
4246 } | |
4247 | |
4248 int TypeTypedef::checkBoolean() | |
4249 { | |
4250 return sym->basetype->checkBoolean(); | |
4251 } | |
4252 | |
4253 Type *TypeTypedef::toBasetype() | |
4254 { | |
4255 if (sym->inuse) | |
4256 { | |
4257 sym->error("circular definition"); | |
4258 sym->basetype = Type::terror; | |
4259 return Type::terror; | |
4260 } | |
4261 sym->inuse = 1; | |
4262 Type *t = sym->basetype->toBasetype(); | |
4263 sym->inuse = 0; | |
4264 return t; | |
4265 } | |
4266 | |
4267 MATCH TypeTypedef::implicitConvTo(Type *to) | |
4268 { MATCH m; | |
4269 | |
4270 //printf("TypeTypedef::implicitConvTo()\n"); | |
4271 if (this->equals(to)) | |
4272 m = MATCHexact; // exact match | |
4273 else if (sym->basetype->implicitConvTo(to)) | |
4274 m = MATCHconvert; // match with conversions | |
4275 else | |
4276 m = MATCHnomatch; // no match | |
4277 return m; | |
4278 } | |
4279 | |
4280 Expression *TypeTypedef::defaultInit(Loc loc) | |
4281 { Expression *e; | |
4282 Type *bt; | |
4283 | |
4284 #if LOGDEFAULTINIT | |
4285 printf("TypeTypedef::defaultInit() '%s'\n", toChars()); | |
4286 #endif | |
4287 if (sym->init) | |
4288 { | |
4289 //sym->init->toExpression()->print(); | |
4290 return sym->init->toExpression(); | |
4291 } | |
4292 bt = sym->basetype; | |
4293 e = bt->defaultInit(loc); | |
4294 e->type = this; | |
4295 while (bt->ty == Tsarray) | |
4296 { | |
4297 e->type = bt->next; | |
4298 bt = bt->next->toBasetype(); | |
4299 } | |
4300 return e; | |
4301 } | |
4302 | |
4303 int TypeTypedef::isZeroInit() | |
4304 { | |
4305 if (sym->init) | |
4306 { | |
4307 if (sym->init->isVoidInitializer()) | |
4308 return 1; // initialize voids to 0 | |
4309 Expression *e = sym->init->toExpression(); | |
4310 if (e && e->isBool(FALSE)) | |
4311 return 1; | |
4312 return 0; // assume not | |
4313 } | |
4314 if (sym->inuse) | |
4315 { | |
4316 sym->error("circular definition"); | |
4317 sym->basetype = Type::terror; | |
4318 } | |
4319 sym->inuse = 1; | |
4320 int result = sym->basetype->isZeroInit(); | |
4321 sym->inuse = 0; | |
4322 return result; | |
4323 } | |
4324 | |
4325 int TypeTypedef::hasPointers() | |
4326 { | |
4327 return toBasetype()->hasPointers(); | |
4328 } | |
4329 | |
4330 /***************************** TypeStruct *****************************/ | |
4331 | |
4332 TypeStruct::TypeStruct(StructDeclaration *sym) | |
4333 : Type(Tstruct, NULL) | |
4334 { | |
4335 this->sym = sym; | |
1029
4d366a75d95f
Added hasUnalignedFields helper to check if a type has unaligned fields - as per request from fvbommel. Result is cached in TypeStruct.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
1024
diff
changeset
|
4336 |
4d366a75d95f
Added hasUnalignedFields helper to check if a type has unaligned fields - as per request from fvbommel. Result is cached in TypeStruct.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
1024
diff
changeset
|
4337 // LDC |
4d366a75d95f
Added hasUnalignedFields helper to check if a type has unaligned fields - as per request from fvbommel. Result is cached in TypeStruct.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
1024
diff
changeset
|
4338 this->unaligned = 0; |
159 | 4339 } |
4340 | |
4341 char *TypeStruct::toChars() | |
4342 { | |
4343 //printf("sym.parent: %s, deco = %s\n", sym->parent->toChars(), deco); | |
4344 TemplateInstance *ti = sym->parent->isTemplateInstance(); | |
4345 if (ti && ti->toAlias() == sym) | |
4346 return ti->toChars(); | |
4347 return sym->toChars(); | |
4348 } | |
4349 | |
4350 Type *TypeStruct::syntaxCopy() | |
4351 { | |
4352 return this; | |
4353 } | |
4354 | |
4355 Type *TypeStruct::semantic(Loc loc, Scope *sc) | |
4356 { | |
4357 //printf("TypeStruct::semantic('%s')\n", sym->toChars()); | |
4358 | |
4359 /* Cannot do semantic for sym because scope chain may not | |
4360 * be right. | |
4361 */ | |
4362 //sym->semantic(sc); | |
4363 | |
4364 return merge(); | |
4365 } | |
4366 | |
4367 d_uns64 TypeStruct::size(Loc loc) | |
4368 { | |
4369 return sym->size(loc); | |
4370 } | |
4371 | |
4372 unsigned TypeStruct::alignsize() | |
4373 { unsigned sz; | |
4374 | |
4375 sym->size(0); // give error for forward references | |
4376 sz = sym->alignsize; | |
4377 if (sz > sym->structalign) | |
4378 sz = sym->structalign; | |
4379 return sz; | |
4380 } | |
4381 | |
4382 Dsymbol *TypeStruct::toDsymbol(Scope *sc) | |
4383 { | |
4384 return sym; | |
4385 } | |
4386 | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
4387 void TypeStruct::toDecoBuffer(OutBuffer *buf, bool mangle) |
159 | 4388 { unsigned len; |
4389 char *name; | |
4390 | |
4391 name = sym->mangle(); | |
4392 //printf("TypeStruct::toDecoBuffer('%s') = '%s'\n", toChars(), name); | |
4393 // if (name[0] == '_' && name[1] == 'D') | |
4394 // name += 2; | |
4395 //len = strlen(name); | |
4396 //buf->printf("%c%d%s", mangleChar[ty], len, name); | |
4397 buf->printf("%c%s", mangleChar[ty], name); | |
4398 } | |
4399 | |
4400 void TypeStruct::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
4401 { | |
4402 if (mod != this->mod) | |
4403 { toCBuffer3(buf, hgs, mod); | |
4404 return; | |
4405 } | |
4406 TemplateInstance *ti = sym->parent->isTemplateInstance(); | |
4407 if (ti && ti->toAlias() == sym) | |
4408 buf->writestring(ti->toChars()); | |
4409 else | |
4410 buf->writestring(sym->toChars()); | |
4411 } | |
4412 | |
4413 Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident) | |
4414 { unsigned offset; | |
4415 | |
4416 Expression *b; | |
4417 VarDeclaration *v; | |
4418 Dsymbol *s; | |
4419 DotVarExp *de; | |
4420 Declaration *d; | |
4421 | |
4422 #if LOGDOTEXP | |
4423 printf("TypeStruct::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); | |
4424 #endif | |
4425 if (!sym->members) | |
4426 { | |
4427 error(e->loc, "struct %s is forward referenced", sym->toChars()); | |
4428 return new IntegerExp(e->loc, 0, Type::tint32); | |
4429 } | |
4430 | |
875
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
4431 /* If e.tupleof |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
4432 */ |
159 | 4433 if (ident == Id::tupleof) |
4434 { | |
875
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
4435 /* Create a TupleExp out of the fields of the struct e: |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
4436 * (e.field0, e.field1, e.field2, ...) |
159 | 4437 */ |
336 | 4438 e = e->semantic(sc); // do this before turning on noaccesscheck |
159 | 4439 Expressions *exps = new Expressions; |
4440 exps->reserve(sym->fields.dim); | |
4441 for (size_t i = 0; i < sym->fields.dim; i++) | |
4442 { VarDeclaration *v = (VarDeclaration *)sym->fields.data[i]; | |
4443 Expression *fe = new DotVarExp(e->loc, e, v); | |
4444 exps->push(fe); | |
4445 } | |
4446 e = new TupleExp(e->loc, exps); | |
336 | 4447 sc = sc->push(); |
4448 sc->noaccesscheck = 1; | |
159 | 4449 e = e->semantic(sc); |
336 | 4450 sc->pop(); |
159 | 4451 return e; |
4452 } | |
4453 | |
4454 if (e->op == TOKdotexp) | |
4455 { DotExp *de = (DotExp *)e; | |
4456 | |
4457 if (de->e1->op == TOKimport) | |
4458 { | |
4459 ScopeExp *se = (ScopeExp *)de->e1; | |
4460 | |
4461 s = se->sds->search(e->loc, ident, 0); | |
4462 e = de->e1; | |
4463 goto L1; | |
4464 } | |
4465 } | |
4466 | |
4467 s = sym->search(e->loc, ident, 0); | |
4468 L1: | |
4469 if (!s) | |
4470 { | |
4471 //return getProperty(e->loc, ident); | |
4472 return Type::dotExp(sc, e, ident); | |
4473 } | |
336 | 4474 if (!s->isFuncDeclaration()) // because of overloading |
4475 s->checkDeprecated(e->loc, sc); | |
159 | 4476 s = s->toAlias(); |
4477 | |
4478 v = s->isVarDeclaration(); | |
717
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
715
diff
changeset
|
4479 if (v && v->isConst() && v->type->toBasetype()->ty != Tsarray) |
159 | 4480 { ExpInitializer *ei = v->getExpInitializer(); |
4481 | |
4482 if (ei) | |
4483 { e = ei->exp->copy(); // need to copy it if it's a StringExp | |
4484 e = e->semantic(sc); | |
4485 return e; | |
4486 } | |
4487 } | |
4488 | |
4489 if (s->getType()) | |
4490 { | |
4491 //return new DotTypeExp(e->loc, e, s); | |
4492 return new TypeExp(e->loc, s->getType()); | |
4493 } | |
4494 | |
4495 EnumMember *em = s->isEnumMember(); | |
4496 if (em) | |
4497 { | |
4498 assert(em->value); | |
4499 return em->value->copy(); | |
4500 } | |
4501 | |
4502 TemplateMixin *tm = s->isTemplateMixin(); | |
4503 if (tm) | |
4504 { Expression *de; | |
4505 | |
4506 de = new DotExp(e->loc, e, new ScopeExp(e->loc, tm)); | |
4507 de->type = e->type; | |
4508 return de; | |
4509 } | |
4510 | |
4511 TemplateDeclaration *td = s->isTemplateDeclaration(); | |
4512 if (td) | |
4513 { | |
4514 e = new DotTemplateExp(e->loc, e, td); | |
4515 e->semantic(sc); | |
4516 return e; | |
4517 } | |
4518 | |
4519 TemplateInstance *ti = s->isTemplateInstance(); | |
4520 if (ti) | |
4521 { if (!ti->semanticdone) | |
4522 ti->semantic(sc); | |
4523 s = ti->inst->toAlias(); | |
4524 if (!s->isTemplateInstance()) | |
4525 goto L1; | |
4526 Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, ti)); | |
4527 de->type = e->type; | |
4528 return de; | |
4529 } | |
4530 | |
875
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
4531 Import *timp = s->isImport(); |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
4532 if (timp) |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
4533 { |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
4534 e = new DsymbolExp(e->loc, s); |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
4535 e = e->semantic(sc); |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
4536 return e; |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
4537 } |
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
4538 |
159 | 4539 d = s->isDeclaration(); |
4540 #ifdef DEBUG | |
4541 if (!d) | |
4542 printf("d = %s '%s'\n", s->kind(), s->toChars()); | |
4543 #endif | |
4544 assert(d); | |
4545 | |
4546 if (e->op == TOKtype) | |
4547 { FuncDeclaration *fd = sc->func; | |
4548 | |
4549 if (d->needThis() && fd && fd->vthis) | |
4550 { | |
4551 e = new DotVarExp(e->loc, new ThisExp(e->loc), d); | |
4552 e = e->semantic(sc); | |
4553 return e; | |
4554 } | |
4555 if (d->isTupleDeclaration()) | |
4556 { | |
4557 e = new TupleExp(e->loc, d->isTupleDeclaration()); | |
4558 e = e->semantic(sc); | |
4559 return e; | |
4560 } | |
4561 return new VarExp(e->loc, d); | |
4562 } | |
4563 | |
4564 if (d->isDataseg()) | |
4565 { | |
4566 // (e, d) | |
4567 VarExp *ve; | |
4568 | |
4569 accessCheck(e->loc, sc, e, d); | |
4570 ve = new VarExp(e->loc, d); | |
4571 e = new CommaExp(e->loc, e, ve); | |
4572 e->type = d->type; | |
4573 return e; | |
4574 } | |
4575 | |
4576 if (v) | |
4577 { | |
4578 if (v->toParent() != sym) | |
4579 sym->error(e->loc, "'%s' is not a member", v->toChars()); | |
4580 | |
4581 // *(&e + offset) | |
4582 accessCheck(e->loc, sc, e, d); | |
875
330f999ade44
Merged DMD 1.038
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
872
diff
changeset
|
4583 #if 0 |
159 | 4584 b = new AddrExp(e->loc, e); |
4585 b->type = e->type->pointerTo(); | |
4586 b = new AddExp(e->loc, b, new IntegerExp(e->loc, v->offset, Type::tint32)); | |
4587 b->type = v->type->pointerTo(); | |
4588 e = new PtrExp(e->loc, b); | |
4589 e->type = v->type; | |
4590 return e; | |
585
fbb1a366cfbc
Complex number should now follow the D ABI on x86. They're also treated as first class values now. Big change.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
509
diff
changeset
|
4591 #endif |
159 | 4592 } |
4593 | |
4594 de = new DotVarExp(e->loc, e, d); | |
4595 return de->semantic(sc); | |
4596 } | |
4597 | |
4598 unsigned TypeStruct::memalign(unsigned salign) | |
4599 { | |
4600 sym->size(0); // give error for forward references | |
4601 return sym->structalign; | |
4602 } | |
4603 | |
4604 Expression *TypeStruct::defaultInit(Loc loc) | |
913
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
900
diff
changeset
|
4605 { Declaration *d; |
159 | 4606 |
4607 #if LOGDEFAULTINIT | |
4608 printf("TypeStruct::defaultInit() '%s'\n", toChars()); | |
4609 #endif | |
913
29c0d1194033
Fix #198 and #199 by making CTFE on static struct initializers work.
Christian Kamm <kamm incasoftware de>
parents:
900
diff
changeset
|
4610 d = new StaticStructInitDeclaration(sym->loc, sym); |
159 | 4611 assert(d); |
4612 d->type = this; | |
4613 return new VarExp(sym->loc, d); | |
4614 } | |
4615 | |
4616 int TypeStruct::isZeroInit() | |
4617 { | |
4618 return sym->zeroInit; | |
4619 } | |
4620 | |
4621 int TypeStruct::checkBoolean() | |
4622 { | |
4623 return FALSE; | |
4624 } | |
4625 | |
4626 int TypeStruct::hasPointers() | |
4627 { | |
4628 StructDeclaration *s = sym; | |
4629 | |
4630 sym->size(0); // give error for forward references | |
4631 if (s->members) | |
4632 { | |
4633 for (size_t i = 0; i < s->members->dim; i++) | |
4634 { | |
4635 Dsymbol *sm = (Dsymbol *)s->members->data[i]; | |
4636 if (sm->hasPointers()) | |
4637 return TRUE; | |
4638 } | |
4639 } | |
4640 return FALSE; | |
4641 } | |
4642 | |
4643 | |
4644 /***************************** TypeClass *****************************/ | |
4645 | |
4646 TypeClass::TypeClass(ClassDeclaration *sym) | |
4647 : Type(Tclass, NULL) | |
4648 { | |
4649 this->sym = sym; | |
4650 } | |
4651 | |
4652 char *TypeClass::toChars() | |
4653 { | |
4654 return sym->toPrettyChars(); | |
4655 } | |
4656 | |
4657 Type *TypeClass::syntaxCopy() | |
4658 { | |
4659 return this; | |
4660 } | |
4661 | |
4662 Type *TypeClass::semantic(Loc loc, Scope *sc) | |
4663 { | |
4664 //printf("TypeClass::semantic(%s)\n", sym->toChars()); | |
4665 if (sym->scope) | |
4666 sym->semantic(sym->scope); | |
4667 return merge(); | |
4668 } | |
4669 | |
4670 d_uns64 TypeClass::size(Loc loc) | |
4671 { | |
4672 return PTRSIZE; | |
4673 } | |
4674 | |
4675 Dsymbol *TypeClass::toDsymbol(Scope *sc) | |
4676 { | |
4677 return sym; | |
4678 } | |
4679 | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
4680 void TypeClass::toDecoBuffer(OutBuffer *buf, bool mangle) |
159 | 4681 { unsigned len; |
4682 char *name; | |
4683 | |
4684 name = sym->mangle(); | |
4685 // if (name[0] == '_' && name[1] == 'D') | |
4686 // name += 2; | |
4687 //printf("TypeClass::toDecoBuffer('%s') = '%s'\n", toChars(), name); | |
4688 //len = strlen(name); | |
4689 //buf->printf("%c%d%s", mangleChar[ty], len, name); | |
4690 buf->printf("%c%s", mangleChar[ty], name); | |
4691 } | |
4692 | |
4693 void TypeClass::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
4694 { | |
4695 if (mod != this->mod) | |
4696 { toCBuffer3(buf, hgs, mod); | |
4697 return; | |
4698 } | |
4699 buf->writestring(sym->toChars()); | |
4700 } | |
4701 | |
4702 Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident) | |
4703 { unsigned offset; | |
4704 | |
4705 Expression *b; | |
4706 VarDeclaration *v; | |
4707 Dsymbol *s; | |
4708 DotVarExp *de; | |
4709 Declaration *d; | |
4710 | |
4711 #if LOGDOTEXP | |
4712 printf("TypeClass::dotExp(e='%s', ident='%s')\n", e->toChars(), ident->toChars()); | |
4713 #endif | |
4714 | |
4715 if (e->op == TOKdotexp) | |
4716 { DotExp *de = (DotExp *)e; | |
4717 | |
4718 if (de->e1->op == TOKimport) | |
4719 { | |
4720 ScopeExp *se = (ScopeExp *)de->e1; | |
4721 | |
4722 s = se->sds->search(e->loc, ident, 0); | |
4723 e = de->e1; | |
4724 goto L1; | |
4725 } | |
4726 } | |
4727 | |
4728 if (ident == Id::tupleof) | |
4729 { | |
4730 /* Create a TupleExp | |
4731 */ | |
336 | 4732 e = e->semantic(sc); // do this before turning on noaccesscheck |
159 | 4733 Expressions *exps = new Expressions; |
4734 exps->reserve(sym->fields.dim); | |
4735 for (size_t i = 0; i < sym->fields.dim; i++) | |
4736 { VarDeclaration *v = (VarDeclaration *)sym->fields.data[i]; | |
4737 Expression *fe = new DotVarExp(e->loc, e, v); | |
4738 exps->push(fe); | |
4739 } | |
4740 e = new TupleExp(e->loc, exps); | |
336 | 4741 sc = sc->push(); |
4742 sc->noaccesscheck = 1; | |
159 | 4743 e = e->semantic(sc); |
336 | 4744 sc->pop(); |
159 | 4745 return e; |
4746 } | |
4747 | |
4748 s = sym->search(e->loc, ident, 0); | |
4749 L1: | |
4750 if (!s) | |
4751 { | |
4752 // See if it's a base class | |
4753 ClassDeclaration *cbase; | |
4754 for (cbase = sym->baseClass; cbase; cbase = cbase->baseClass) | |
4755 { | |
4756 if (cbase->ident->equals(ident)) | |
4757 { | |
4758 e = new DotTypeExp(0, e, cbase); | |
4759 return e; | |
4760 } | |
4761 } | |
4762 | |
4763 if (ident == Id::classinfo) | |
4764 { | |
4765 Type *t; | |
4766 | |
4767 assert(ClassDeclaration::classinfo); | |
4768 t = ClassDeclaration::classinfo->type; | |
4769 if (e->op == TOKtype || e->op == TOKdottype) | |
4770 { | |
4771 /* For type.classinfo, we know the classinfo | |
4772 * at compile time. | |
4773 */ | |
4774 if (!sym->vclassinfo) | |
4775 sym->vclassinfo = new ClassInfoDeclaration(sym); | |
4776 e = new VarExp(e->loc, sym->vclassinfo); | |
4777 e = e->addressOf(sc); | |
4778 e->type = t; // do this so we don't get redundant dereference | |
4779 } | |
4780 else | |
4781 { | |
4782 /* For class objects, the classinfo reference is the first | |
4783 * entry in the vtbl[] | |
4784 */ | |
4785 #if IN_LLVM | |
4786 | |
4787 Type* ct; | |
4788 if (sym->isInterfaceDeclaration()) { | |
4789 ct = t->pointerTo()->pointerTo()->pointerTo(); | |
4790 } | |
4791 else { | |
4792 ct = t->pointerTo()->pointerTo(); | |
4793 } | |
4794 | |
4795 e = e->castTo(sc, ct); | |
4796 e = new PtrExp(e->loc, e); | |
4797 e->type = ct->next; | |
4798 e = new PtrExp(e->loc, e); | |
4799 e->type = ct->next->next; | |
4800 | |
4801 if (sym->isInterfaceDeclaration()) | |
4802 { | |
4803 if (sym->isCOMinterface()) | |
4804 { /* COM interface vtbl[]s are different in that the | |
4805 * first entry is always pointer to QueryInterface(). | |
4806 * We can't get a .classinfo for it. | |
4807 */ | |
4808 error(e->loc, "no .classinfo for COM interface objects"); | |
4809 } | |
4810 /* For an interface, the first entry in the vtbl[] | |
4811 * is actually a pointer to an instance of struct Interface. | |
4812 * The first member of Interface is the .classinfo, | |
4813 * so add an extra pointer indirection. | |
4814 */ | |
4815 e = new PtrExp(e->loc, e); | |
4816 e->type = ct->next->next->next; | |
4817 } | |
336 | 4818 } |
159 | 4819 |
4820 #else | |
4821 | |
4822 e = new PtrExp(e->loc, e); | |
4823 e->type = t->pointerTo(); | |
4824 if (sym->isInterfaceDeclaration()) | |
4825 { | |
4826 if (sym->isCOMinterface()) | |
4827 { /* COM interface vtbl[]s are different in that the | |
4828 * first entry is always pointer to QueryInterface(). | |
4829 * We can't get a .classinfo for it. | |
4830 */ | |
4831 error(e->loc, "no .classinfo for COM interface objects"); | |
4832 } | |
4833 /* For an interface, the first entry in the vtbl[] | |
4834 * is actually a pointer to an instance of struct Interface. | |
4835 * The first member of Interface is the .classinfo, | |
4836 * so add an extra pointer indirection. | |
4837 */ | |
4838 e->type = e->type->pointerTo(); | |
4839 e = new PtrExp(e->loc, e); | |
4840 e->type = t->pointerTo(); | |
4841 } | |
4842 e = new PtrExp(e->loc, e, t); | |
336 | 4843 } |
4844 | |
664
eef8ac26c66c
Some missed LLVMDC -> LDC.
Christian Kamm <kamm incasoftware de>
parents:
658
diff
changeset
|
4845 #endif // !LDC |
336 | 4846 |
4847 return e; | |
4848 } | |
4849 | |
4850 if (ident == Id::__vptr) | |
4851 { /* The pointer to the vtbl[] | |
4852 * *cast(void***)e | |
4853 */ | |
4854 e = e->castTo(sc, tvoidptr->pointerTo()->pointerTo()); | |
4855 e = new PtrExp(e->loc, e); | |
4856 e = e->semantic(sc); | |
4857 return e; | |
4858 } | |
4859 | |
4860 if (ident == Id::__monitor) | |
4861 { /* The handle to the monitor (call it a void*) | |
4862 * *(cast(void**)e + 1) | |
4863 */ | |
4864 e = e->castTo(sc, tvoidptr->pointerTo()); | |
4865 e = new AddExp(e->loc, e, new IntegerExp(1)); | |
4866 e = new PtrExp(e->loc, e); | |
4867 e = e->semantic(sc); | |
159 | 4868 return e; |
4869 } | |
4870 | |
4871 if (ident == Id::typeinfo) | |
4872 { | |
4873 if (!global.params.useDeprecated) | |
4874 error(e->loc, ".typeinfo deprecated, use typeid(type)"); | |
4875 return getTypeInfo(sc); | |
4876 } | |
4877 if (ident == Id::outer && sym->vthis) | |
4878 { | |
4879 s = sym->vthis; | |
4880 } | |
4881 else | |
4882 { | |
4883 //return getProperty(e->loc, ident); | |
4884 return Type::dotExp(sc, e, ident); | |
4885 } | |
4886 } | |
336 | 4887 if (!s->isFuncDeclaration()) // because of overloading |
4888 s->checkDeprecated(e->loc, sc); | |
159 | 4889 s = s->toAlias(); |
4890 v = s->isVarDeclaration(); | |
717
a26b0c5d5942
Merged DMD 1.036.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
715
diff
changeset
|
4891 if (v && v->isConst() && v->type->toBasetype()->ty != Tsarray) |
159 | 4892 { ExpInitializer *ei = v->getExpInitializer(); |
4893 | |
4894 if (ei) | |
4895 { e = ei->exp->copy(); // need to copy it if it's a StringExp | |
4896 e = e->semantic(sc); | |
4897 return e; | |
4898 } | |
4899 } | |
4900 | |
4901 if (s->getType()) | |
4902 { | |
4903 // if (e->op == TOKtype) | |
4904 return new TypeExp(e->loc, s->getType()); | |
4905 // return new DotTypeExp(e->loc, e, s); | |
4906 } | |
4907 | |
4908 EnumMember *em = s->isEnumMember(); | |
4909 if (em) | |
4910 { | |
4911 assert(em->value); | |
4912 return em->value->copy(); | |
4913 } | |
4914 | |
4915 TemplateMixin *tm = s->isTemplateMixin(); | |
4916 if (tm) | |
4917 { Expression *de; | |
4918 | |
4919 de = new DotExp(e->loc, e, new ScopeExp(e->loc, tm)); | |
4920 de->type = e->type; | |
4921 return de; | |
4922 } | |
4923 | |
4924 TemplateDeclaration *td = s->isTemplateDeclaration(); | |
4925 if (td) | |
4926 { | |
4927 e = new DotTemplateExp(e->loc, e, td); | |
4928 e->semantic(sc); | |
4929 return e; | |
4930 } | |
4931 | |
4932 TemplateInstance *ti = s->isTemplateInstance(); | |
4933 if (ti) | |
4934 { if (!ti->semanticdone) | |
4935 ti->semantic(sc); | |
4936 s = ti->inst->toAlias(); | |
4937 if (!s->isTemplateInstance()) | |
4938 goto L1; | |
4939 Expression *de = new DotExp(e->loc, e, new ScopeExp(e->loc, ti)); | |
4940 de->type = e->type; | |
4941 return de; | |
4942 } | |
4943 | |
4944 d = s->isDeclaration(); | |
4945 if (!d) | |
4946 { | |
4947 e->error("%s.%s is not a declaration", e->toChars(), ident->toChars()); | |
4948 return new IntegerExp(e->loc, 1, Type::tint32); | |
4949 } | |
4950 | |
4951 if (e->op == TOKtype) | |
4952 { | |
4953 VarExp *ve; | |
4954 | |
4955 if (d->needThis() && (hasThis(sc) || !d->isFuncDeclaration())) | |
4956 { | |
4957 if (sc->func) | |
4958 { | |
4959 ClassDeclaration *thiscd; | |
4960 thiscd = sc->func->toParent()->isClassDeclaration(); | |
4961 | |
4962 if (thiscd) | |
4963 { | |
4964 ClassDeclaration *cd = e->type->isClassHandle(); | |
4965 | |
4966 if (cd == thiscd) | |
4967 { | |
4968 e = new ThisExp(e->loc); | |
4969 e = new DotTypeExp(e->loc, e, cd); | |
4970 de = new DotVarExp(e->loc, e, d); | |
4971 e = de->semantic(sc); | |
4972 return e; | |
4973 } | |
4974 else if ((!cd || !cd->isBaseOf(thiscd, NULL)) && | |
4975 !d->isFuncDeclaration()) | |
4976 e->error("'this' is required, but %s is not a base class of %s", e->type->toChars(), thiscd->toChars()); | |
4977 } | |
4978 } | |
4979 | |
4980 de = new DotVarExp(e->loc, new ThisExp(e->loc), d); | |
4981 e = de->semantic(sc); | |
4982 return e; | |
4983 } | |
4984 else if (d->isTupleDeclaration()) | |
4985 { | |
4986 e = new TupleExp(e->loc, d->isTupleDeclaration()); | |
4987 e = e->semantic(sc); | |
4988 return e; | |
4989 } | |
4990 else | |
4991 ve = new VarExp(e->loc, d); | |
4992 return ve; | |
4993 } | |
4994 | |
4995 if (d->isDataseg()) | |
4996 { | |
4997 // (e, d) | |
4998 VarExp *ve; | |
4999 | |
5000 accessCheck(e->loc, sc, e, d); | |
5001 ve = new VarExp(e->loc, d); | |
5002 e = new CommaExp(e->loc, e, ve); | |
5003 e->type = d->type; | |
5004 return e; | |
5005 } | |
5006 | |
5007 if (d->parent && d->toParent()->isModule()) | |
5008 { | |
5009 // (e, d) | |
5010 VarExp *ve; | |
5011 | |
5012 ve = new VarExp(e->loc, d); | |
5013 e = new CommaExp(e->loc, e, ve); | |
5014 e->type = d->type; | |
5015 return e; | |
5016 } | |
5017 | |
5018 de = new DotVarExp(e->loc, e, d); | |
5019 return de->semantic(sc); | |
5020 } | |
5021 | |
5022 ClassDeclaration *TypeClass::isClassHandle() | |
5023 { | |
5024 return sym; | |
5025 } | |
5026 | |
5027 int TypeClass::isauto() | |
5028 { | |
5029 return sym->isauto; | |
5030 } | |
5031 | |
5032 int TypeClass::isBaseOf(Type *t, int *poffset) | |
5033 { | |
5034 if (t->ty == Tclass) | |
5035 { ClassDeclaration *cd; | |
5036 | |
5037 cd = ((TypeClass *)t)->sym; | |
5038 if (sym->isBaseOf(cd, poffset)) | |
5039 return 1; | |
5040 } | |
5041 return 0; | |
5042 } | |
5043 | |
5044 MATCH TypeClass::implicitConvTo(Type *to) | |
5045 { | |
5046 //printf("TypeClass::implicitConvTo('%s')\n", to->toChars()); | |
5047 if (this == to) | |
5048 return MATCHexact; | |
5049 | |
5050 ClassDeclaration *cdto = to->isClassHandle(); | |
5051 if (cdto && cdto->isBaseOf(sym, NULL)) | |
5052 { //printf("is base\n"); | |
5053 return MATCHconvert; | |
5054 } | |
5055 | |
5056 if (global.params.Dversion == 1) | |
5057 { | |
5058 // Allow conversion to (void *) | |
5059 if (to->ty == Tpointer && to->next->ty == Tvoid) | |
5060 return MATCHconvert; | |
5061 } | |
5062 | |
5063 return MATCHnomatch; | |
5064 } | |
5065 | |
5066 Expression *TypeClass::defaultInit(Loc loc) | |
5067 { | |
5068 #if LOGDEFAULTINIT | |
5069 printf("TypeClass::defaultInit() '%s'\n", toChars()); | |
5070 #endif | |
5071 Expression *e; | |
5072 e = new NullExp(loc); | |
5073 e->type = this; | |
5074 return e; | |
5075 } | |
5076 | |
5077 int TypeClass::isZeroInit() | |
5078 { | |
5079 return 1; | |
5080 } | |
5081 | |
5082 int TypeClass::checkBoolean() | |
5083 { | |
5084 return TRUE; | |
5085 } | |
5086 | |
5087 int TypeClass::hasPointers() | |
5088 { | |
5089 return TRUE; | |
5090 } | |
5091 | |
5092 /***************************** TypeTuple *****************************/ | |
5093 | |
5094 TypeTuple::TypeTuple(Arguments *arguments) | |
5095 : Type(Ttuple, NULL) | |
5096 { | |
5097 //printf("TypeTuple(this = %p)\n", this); | |
5098 this->arguments = arguments; | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
5099 //printf("TypeTuple() %s\n", toChars()); |
159 | 5100 #ifdef DEBUG |
5101 if (arguments) | |
5102 { | |
5103 for (size_t i = 0; i < arguments->dim; i++) | |
5104 { | |
5105 Argument *arg = (Argument *)arguments->data[i]; | |
5106 assert(arg && arg->type); | |
5107 } | |
5108 } | |
5109 #endif | |
5110 } | |
5111 | |
5112 /**************** | |
5113 * Form TypeTuple from the types of the expressions. | |
5114 * Assume exps[] is already tuple expanded. | |
5115 */ | |
5116 | |
5117 TypeTuple::TypeTuple(Expressions *exps) | |
5118 : Type(Ttuple, NULL) | |
5119 { | |
5120 Arguments *arguments = new Arguments; | |
5121 if (exps) | |
5122 { | |
5123 arguments->setDim(exps->dim); | |
5124 for (size_t i = 0; i < exps->dim; i++) | |
5125 { Expression *e = (Expression *)exps->data[i]; | |
5126 if (e->type->ty == Ttuple) | |
5127 e->error("cannot form tuple of tuples"); | |
5128 Argument *arg = new Argument(STCin, e->type, NULL, NULL); | |
5129 arguments->data[i] = (void *)arg; | |
5130 } | |
5131 } | |
5132 this->arguments = arguments; | |
5133 } | |
5134 | |
5135 Type *TypeTuple::syntaxCopy() | |
5136 { | |
5137 Arguments *args = Argument::arraySyntaxCopy(arguments); | |
5138 Type *t = new TypeTuple(args); | |
5139 return t; | |
5140 } | |
5141 | |
5142 Type *TypeTuple::semantic(Loc loc, Scope *sc) | |
5143 { | |
5144 //printf("TypeTuple::semantic(this = %p)\n", this); | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
5145 //printf("TypeTuple::semantic() %s\n", toChars()); |
159 | 5146 if (!deco) |
5147 deco = merge()->deco; | |
5148 | |
5149 /* Don't return merge(), because a tuple with one type has the | |
5150 * same deco as that type. | |
5151 */ | |
5152 return this; | |
5153 } | |
5154 | |
5155 int TypeTuple::equals(Object *o) | |
5156 { Type *t; | |
5157 | |
5158 t = (Type *)o; | |
5159 //printf("TypeTuple::equals(%s, %s)\n", toChars(), t->toChars()); | |
5160 if (this == t) | |
5161 { | |
5162 return 1; | |
5163 } | |
5164 if (t->ty == Ttuple) | |
5165 { TypeTuple *tt = (TypeTuple *)t; | |
5166 | |
5167 if (arguments->dim == tt->arguments->dim) | |
5168 { | |
5169 for (size_t i = 0; i < tt->arguments->dim; i++) | |
5170 { Argument *arg1 = (Argument *)arguments->data[i]; | |
5171 Argument *arg2 = (Argument *)tt->arguments->data[i]; | |
5172 | |
5173 if (!arg1->type->equals(arg2->type)) | |
5174 return 0; | |
5175 } | |
5176 return 1; | |
5177 } | |
5178 } | |
5179 return 0; | |
5180 } | |
5181 | |
5182 Type *TypeTuple::reliesOnTident() | |
5183 { | |
5184 if (arguments) | |
5185 { | |
5186 for (size_t i = 0; i < arguments->dim; i++) | |
5187 { | |
5188 Argument *arg = (Argument *)arguments->data[i]; | |
5189 Type *t = arg->type->reliesOnTident(); | |
5190 if (t) | |
5191 return t; | |
5192 } | |
5193 } | |
5194 return NULL; | |
5195 } | |
5196 | |
5197 void TypeTuple::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
5198 { | |
5199 Argument::argsToCBuffer(buf, hgs, arguments, 0); | |
5200 } | |
5201 | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
5202 void TypeTuple::toDecoBuffer(OutBuffer *buf, bool mangle) |
159 | 5203 { |
5204 //printf("TypeTuple::toDecoBuffer() this = %p\n", this); | |
5205 OutBuffer buf2; | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
5206 Argument::argsToDecoBuffer(&buf2, arguments, mangle); |
159 | 5207 unsigned len = buf2.offset; |
5208 buf->printf("%c%d%.*s", mangleChar[ty], len, len, (char *)buf2.extractData()); | |
5209 } | |
5210 | |
5211 Expression *TypeTuple::getProperty(Loc loc, Identifier *ident) | |
5212 { Expression *e; | |
5213 | |
5214 #if LOGDOTEXP | |
5215 printf("TypeTuple::getProperty(type = '%s', ident = '%s')\n", toChars(), ident->toChars()); | |
5216 #endif | |
5217 if (ident == Id::length) | |
5218 { | |
5219 e = new IntegerExp(loc, arguments->dim, Type::tsize_t); | |
5220 } | |
5221 else | |
5222 { | |
5223 error(loc, "no property '%s' for tuple '%s'", ident->toChars(), toChars()); | |
5224 e = new IntegerExp(loc, 1, Type::tint32); | |
5225 } | |
5226 return e; | |
5227 } | |
5228 | |
5229 /***************************** TypeSlice *****************************/ | |
5230 | |
5231 /* This is so we can slice a TypeTuple */ | |
5232 | |
5233 TypeSlice::TypeSlice(Type *next, Expression *lwr, Expression *upr) | |
5234 : Type(Tslice, next) | |
5235 { | |
5236 //printf("TypeSlice[%s .. %s]\n", lwr->toChars(), upr->toChars()); | |
5237 this->lwr = lwr; | |
5238 this->upr = upr; | |
5239 } | |
5240 | |
5241 Type *TypeSlice::syntaxCopy() | |
5242 { | |
5243 Type *t = new TypeSlice(next->syntaxCopy(), lwr->syntaxCopy(), upr->syntaxCopy()); | |
5244 return t; | |
5245 } | |
5246 | |
5247 Type *TypeSlice::semantic(Loc loc, Scope *sc) | |
5248 { | |
5249 //printf("TypeSlice::semantic() %s\n", toChars()); | |
5250 next = next->semantic(loc, sc); | |
5251 //printf("next: %s\n", next->toChars()); | |
5252 | |
5253 Type *tbn = next->toBasetype(); | |
5254 if (tbn->ty != Ttuple) | |
5255 { error(loc, "can only slice tuple types, not %s", tbn->toChars()); | |
5256 return Type::terror; | |
5257 } | |
5258 TypeTuple *tt = (TypeTuple *)tbn; | |
5259 | |
5260 lwr = semanticLength(sc, tbn, lwr); | |
5261 lwr = lwr->optimize(WANTvalue); | |
5262 uinteger_t i1 = lwr->toUInteger(); | |
5263 | |
5264 upr = semanticLength(sc, tbn, upr); | |
5265 upr = upr->optimize(WANTvalue); | |
5266 uinteger_t i2 = upr->toUInteger(); | |
5267 | |
5268 if (!(i1 <= i2 && i2 <= tt->arguments->dim)) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
5269 { error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, tt->arguments->dim); |
159 | 5270 return Type::terror; |
5271 } | |
5272 | |
5273 Arguments *args = new Arguments; | |
5274 args->reserve(i2 - i1); | |
5275 for (size_t i = i1; i < i2; i++) | |
5276 { Argument *arg = (Argument *)tt->arguments->data[i]; | |
5277 args->push(arg); | |
5278 } | |
5279 | |
5280 return new TypeTuple(args); | |
5281 } | |
5282 | |
5283 void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps) | |
5284 { | |
5285 next->resolve(loc, sc, pe, pt, ps); | |
5286 if (*pe) | |
5287 { // It's really a slice expression | |
5288 Expression *e; | |
5289 e = new SliceExp(loc, *pe, lwr, upr); | |
5290 *pe = e; | |
5291 } | |
5292 else if (*ps) | |
5293 { Dsymbol *s = *ps; | |
5294 TupleDeclaration *td = s->isTupleDeclaration(); | |
5295 if (td) | |
5296 { | |
5297 /* It's a slice of a TupleDeclaration | |
5298 */ | |
5299 ScopeDsymbol *sym = new ArrayScopeSymbol(td); | |
5300 sym->parent = sc->scopesym; | |
5301 sc = sc->push(sym); | |
5302 | |
5303 lwr = lwr->semantic(sc); | |
5304 lwr = lwr->optimize(WANTvalue); | |
5305 uinteger_t i1 = lwr->toUInteger(); | |
5306 | |
5307 upr = upr->semantic(sc); | |
5308 upr = upr->optimize(WANTvalue); | |
5309 uinteger_t i2 = upr->toUInteger(); | |
5310 | |
5311 sc = sc->pop(); | |
5312 | |
5313 if (!(i1 <= i2 && i2 <= td->objects->dim)) | |
1103
b30fe7e1dbb9
- Updated to DMD frontend 1.041.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1051
diff
changeset
|
5314 { error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, td->objects->dim); |
159 | 5315 goto Ldefault; |
5316 } | |
5317 | |
5318 if (i1 == 0 && i2 == td->objects->dim) | |
5319 { | |
5320 *ps = td; | |
5321 return; | |
5322 } | |
5323 | |
5324 /* Create a new TupleDeclaration which | |
5325 * is a slice [i1..i2] out of the old one. | |
5326 */ | |
5327 Objects *objects = new Objects; | |
5328 objects->setDim(i2 - i1); | |
5329 for (size_t i = 0; i < objects->dim; i++) | |
5330 { | |
5331 objects->data[i] = td->objects->data[(size_t)i1 + i]; | |
5332 } | |
5333 | |
5334 TupleDeclaration *tds = new TupleDeclaration(loc, td->ident, objects); | |
5335 *ps = tds; | |
5336 } | |
5337 else | |
5338 goto Ldefault; | |
5339 } | |
5340 else | |
5341 { | |
5342 Ldefault: | |
5343 Type::resolve(loc, sc, pe, pt, ps); | |
5344 } | |
5345 } | |
5346 | |
5347 void TypeSlice::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) | |
5348 { | |
5349 if (mod != this->mod) | |
5350 { toCBuffer3(buf, hgs, mod); | |
5351 return; | |
5352 } | |
5353 next->toCBuffer2(buf, hgs, this->mod); | |
5354 | |
5355 buf->printf("[%s .. ", lwr->toChars()); | |
5356 buf->printf("%s]", upr->toChars()); | |
5357 } | |
5358 | |
5359 /***************************** Argument *****************************/ | |
5360 | |
5361 Argument::Argument(unsigned storageClass, Type *type, Identifier *ident, Expression *defaultArg) | |
5362 { | |
5363 this->type = type; | |
5364 this->ident = ident; | |
5365 this->storageClass = storageClass; | |
5366 this->defaultArg = defaultArg; | |
5367 } | |
5368 | |
5369 Argument *Argument::syntaxCopy() | |
5370 { | |
5371 Argument *a = new Argument(storageClass, | |
5372 type ? type->syntaxCopy() : NULL, | |
5373 ident, | |
5374 defaultArg ? defaultArg->syntaxCopy() : NULL); | |
5375 return a; | |
5376 } | |
5377 | |
5378 Arguments *Argument::arraySyntaxCopy(Arguments *args) | |
5379 { Arguments *a = NULL; | |
5380 | |
5381 if (args) | |
5382 { | |
5383 a = new Arguments(); | |
5384 a->setDim(args->dim); | |
5385 for (size_t i = 0; i < a->dim; i++) | |
5386 { Argument *arg = (Argument *)args->data[i]; | |
5387 | |
5388 arg = arg->syntaxCopy(); | |
5389 a->data[i] = (void *)arg; | |
5390 } | |
5391 } | |
5392 return a; | |
5393 } | |
5394 | |
5395 char *Argument::argsTypesToChars(Arguments *args, int varargs) | |
5396 { OutBuffer *buf; | |
5397 | |
5398 buf = new OutBuffer(); | |
5399 | |
5400 buf->writeByte('('); | |
5401 if (args) | |
5402 { int i; | |
5403 OutBuffer argbuf; | |
5404 HdrGenState hgs; | |
5405 | |
5406 for (i = 0; i < args->dim; i++) | |
5407 { Argument *arg; | |
5408 | |
5409 if (i) | |
5410 buf->writeByte(','); | |
5411 arg = (Argument *)args->data[i]; | |
5412 argbuf.reset(); | |
5413 arg->type->toCBuffer2(&argbuf, &hgs, 0); | |
5414 buf->write(&argbuf); | |
5415 } | |
5416 if (varargs) | |
5417 { | |
5418 if (i && varargs == 1) | |
5419 buf->writeByte(','); | |
5420 buf->writestring("..."); | |
5421 } | |
5422 } | |
5423 buf->writeByte(')'); | |
5424 | |
5425 return buf->toChars(); | |
5426 } | |
5427 | |
5428 void Argument::argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Arguments *arguments, int varargs) | |
5429 { | |
5430 buf->writeByte('('); | |
5431 if (arguments) | |
5432 { int i; | |
5433 OutBuffer argbuf; | |
5434 | |
5435 for (i = 0; i < arguments->dim; i++) | |
5436 { Argument *arg; | |
5437 | |
5438 if (i) | |
5439 buf->writestring(", "); | |
5440 arg = (Argument *)arguments->data[i]; | |
5441 if (arg->storageClass & STCout) | |
5442 buf->writestring("out "); | |
5443 else if (arg->storageClass & STCref) | |
5444 buf->writestring((global.params.Dversion == 1) | |
5445 ? (char *)"inout " : (char *)"ref "); | |
5446 else if (arg->storageClass & STClazy) | |
5447 buf->writestring("lazy "); | |
5448 argbuf.reset(); | |
5449 arg->type->toCBuffer(&argbuf, arg->ident, hgs); | |
5450 if (arg->defaultArg) | |
5451 { | |
5452 argbuf.writestring(" = "); | |
5453 arg->defaultArg->toCBuffer(&argbuf, hgs); | |
5454 } | |
5455 buf->write(&argbuf); | |
5456 } | |
5457 if (varargs) | |
5458 { | |
5459 if (i && varargs == 1) | |
5460 buf->writeByte(','); | |
5461 buf->writestring("..."); | |
5462 } | |
5463 } | |
5464 buf->writeByte(')'); | |
5465 } | |
5466 | |
5467 | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
5468 void Argument::argsToDecoBuffer(OutBuffer *buf, Arguments *arguments, bool mangle) |
159 | 5469 { |
5470 //printf("Argument::argsToDecoBuffer()\n"); | |
5471 | |
5472 // Write argument types | |
5473 if (arguments) | |
5474 { | |
5475 size_t dim = Argument::dim(arguments); | |
5476 for (size_t i = 0; i < dim; i++) | |
5477 { | |
5478 Argument *arg = Argument::getNth(arguments, i); | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
5479 arg->toDecoBuffer(buf, mangle); |
159 | 5480 } |
5481 } | |
5482 } | |
5483 | |
5484 /**************************************************** | |
5485 * Determine if parameter is a lazy array of delegates. | |
5486 * If so, return the return type of those delegates. | |
5487 * If not, return NULL. | |
5488 */ | |
5489 | |
5490 Type *Argument::isLazyArray() | |
5491 { | |
5492 // if (inout == Lazy) | |
5493 { | |
5494 Type *tb = type->toBasetype(); | |
5495 if (tb->ty == Tsarray || tb->ty == Tarray) | |
5496 { | |
5497 Type *tel = tb->next->toBasetype(); | |
5498 if (tel->ty == Tdelegate) | |
5499 { | |
5500 TypeDelegate *td = (TypeDelegate *)tel; | |
5501 TypeFunction *tf = (TypeFunction *)td->next; | |
5502 | |
5503 if (!tf->varargs && Argument::dim(tf->parameters) == 0) | |
5504 { | |
5505 return tf->next; // return type of delegate | |
5506 } | |
5507 } | |
5508 } | |
5509 } | |
5510 return NULL; | |
5511 } | |
5512 | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
5513 void Argument::toDecoBuffer(OutBuffer *buf, bool mangle) |
159 | 5514 { |
5515 switch (storageClass & (STCin | STCout | STCref | STClazy)) | |
5516 { case 0: | |
5517 case STCin: | |
5518 break; | |
5519 case STCout: | |
5520 buf->writeByte('J'); | |
5521 break; | |
5522 case STCref: | |
5523 buf->writeByte('K'); | |
5524 break; | |
5525 case STClazy: | |
5526 buf->writeByte('L'); | |
5527 break; | |
5528 default: | |
5529 #ifdef DEBUG | |
5530 halt(); | |
5531 #endif | |
5532 assert(0); | |
5533 } | |
1228
79758fd2f48a
Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents:
1195
diff
changeset
|
5534 type->toDecoBuffer(buf, mangle); |
159 | 5535 } |
5536 | |
5537 /*************************************** | |
5538 * Determine number of arguments, folding in tuples. | |
5539 */ | |
5540 | |
5541 size_t Argument::dim(Arguments *args) | |
5542 { | |
5543 size_t n = 0; | |
5544 if (args) | |
5545 { | |
5546 for (size_t i = 0; i < args->dim; i++) | |
5547 { Argument *arg = (Argument *)args->data[i]; | |
5548 Type *t = arg->type->toBasetype(); | |
5549 | |
5550 if (t->ty == Ttuple) | |
5551 { TypeTuple *tu = (TypeTuple *)t; | |
5552 n += dim(tu->arguments); | |
5553 } | |
5554 else | |
5555 n++; | |
5556 } | |
5557 } | |
5558 return n; | |
5559 } | |
5560 | |
5561 /*************************************** | |
5562 * Get nth Argument, folding in tuples. | |
5563 * Returns: | |
5564 * Argument* nth Argument | |
5565 * NULL not found, *pn gets incremented by the number | |
5566 * of Arguments | |
5567 */ | |
5568 | |
5569 Argument *Argument::getNth(Arguments *args, size_t nth, size_t *pn) | |
5570 { | |
5571 if (!args) | |
5572 return NULL; | |
5573 | |
5574 size_t n = 0; | |
5575 for (size_t i = 0; i < args->dim; i++) | |
5576 { Argument *arg = (Argument *)args->data[i]; | |
5577 Type *t = arg->type->toBasetype(); | |
5578 | |
5579 if (t->ty == Ttuple) | |
5580 { TypeTuple *tu = (TypeTuple *)t; | |
5581 arg = getNth(tu->arguments, nth - n, &n); | |
5582 if (arg) | |
5583 return arg; | |
5584 } | |
5585 else if (n == nth) | |
5586 return arg; | |
5587 else | |
5588 n++; | |
5589 } | |
5590 | |
5591 if (pn) | |
5592 *pn += n; | |
5593 return NULL; | |
5594 } |