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