Mercurial > projects > ldc
comparison dmd2/struct.c @ 1452:638d16625da2
LDC 2 compiles again.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 30 May 2009 17:23:32 +0100 |
parents | de97188378bc |
children | f62347c22d81 |
comparison
equal
deleted
inserted
replaced
1423:42bd767ec5a4 | 1452:638d16625da2 |
---|---|
1 | 1 |
2 // Compiler implementation of the D programming language | 2 // Compiler implementation of the D programming language |
3 // Copyright (c) 1999-2008 by Digital Mars | 3 // Copyright (c) 1999-2009 by Digital Mars |
4 // All Rights Reserved | 4 // All Rights Reserved |
5 // written by Walter Bright | 5 // written by Walter Bright |
6 // http://www.digitalmars.com | 6 // http://www.digitalmars.com |
7 // License for redistribution is by either the Artistic License | 7 // License for redistribution is by either the Artistic License |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | 8 // in artistic.txt, or the GNU General Public License in gnu.txt. |
17 #include "mtype.h" | 17 #include "mtype.h" |
18 #include "declaration.h" | 18 #include "declaration.h" |
19 #include "module.h" | 19 #include "module.h" |
20 #include "id.h" | 20 #include "id.h" |
21 #include "statement.h" | 21 #include "statement.h" |
22 #include "template.h" | |
22 | 23 |
23 /********************************* AggregateDeclaration ****************************/ | 24 /********************************* AggregateDeclaration ****************************/ |
24 | 25 |
25 AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id) | 26 AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id) |
26 : ScopeDsymbol(id) | 27 : ScopeDsymbol(id) |
39 isdeprecated = 0; | 40 isdeprecated = 0; |
40 inv = NULL; | 41 inv = NULL; |
41 aggNew = NULL; | 42 aggNew = NULL; |
42 aggDelete = NULL; | 43 aggDelete = NULL; |
43 | 44 |
45 #if IN_DMD | |
44 stag = NULL; | 46 stag = NULL; |
45 sinit = NULL; | 47 sinit = NULL; |
48 #endif | |
46 scope = NULL; | 49 scope = NULL; |
47 dtor = NULL; | 50 isnested = 0; |
48 | 51 vthis = NULL; |
52 | |
53 #if DMDV2 | |
49 ctor = NULL; | 54 ctor = NULL; |
50 defaultCtor = NULL; | 55 defaultCtor = NULL; |
56 aliasthis = NULL; | |
57 #endif | |
58 dtor = NULL; | |
51 } | 59 } |
52 | 60 |
53 enum PROT AggregateDeclaration::prot() | 61 enum PROT AggregateDeclaration::prot() |
54 { | 62 { |
55 return protection; | 63 return protection; |
130 /**************************** | 138 /**************************** |
131 * Do byte or word alignment as necessary. | 139 * Do byte or word alignment as necessary. |
132 * Align sizes of 0, as we may not know array sizes yet. | 140 * Align sizes of 0, as we may not know array sizes yet. |
133 */ | 141 */ |
134 | 142 |
135 void AggregateDeclaration::alignmember(unsigned salign, unsigned size, unsigned *poffset) | 143 void AggregateDeclaration::alignmember( |
136 { | 144 unsigned salign, // struct alignment that is in effect |
137 //printf("salign = %d, size = %d, offset = %d\n",salign,size,*poffset); | 145 unsigned size, // alignment requirement of field |
146 unsigned *poffset) | |
147 { | |
148 //printf("salign = %d, size = %d, offset = %d\n",salign,size,offset); | |
138 if (salign > 1) | 149 if (salign > 1) |
139 { int sa; | 150 { |
140 | 151 assert(size != 3); |
141 switch (size) | 152 int sa = size; |
142 { case 1: | 153 if (sa == 0 || salign < sa) |
143 break; | 154 sa = salign; |
144 case 2: | 155 *poffset = (*poffset + sa - 1) & ~(sa - 1); |
145 case_2: | 156 } |
146 *poffset = (*poffset + 1) & ~1; // align to word | 157 //printf("result = %d\n",offset); |
147 break; | |
148 case 3: | |
149 case 4: | |
150 if (salign == 2) | |
151 goto case_2; | |
152 *poffset = (*poffset + 3) & ~3; // align to dword | |
153 break; | |
154 default: | |
155 *poffset = (*poffset + size - 1) & ~(size - 1); | |
156 break; | |
157 } | |
158 } | |
159 //printf("result = %d\n",*poffset); | |
160 } | 158 } |
161 | 159 |
162 | 160 |
163 void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v) | 161 void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v) |
164 { | 162 { |
169 //printf("AggregateDeclaration::addField('%s') %s\n", v->toChars(), toChars()); | 167 //printf("AggregateDeclaration::addField('%s') %s\n", v->toChars(), toChars()); |
170 assert(!(v->storage_class & (STCstatic | STCextern | STCparameter | STCtls))); | 168 assert(!(v->storage_class & (STCstatic | STCextern | STCparameter | STCtls))); |
171 | 169 |
172 // Check for forward referenced types which will fail the size() call | 170 // Check for forward referenced types which will fail the size() call |
173 Type *t = v->type->toBasetype(); | 171 Type *t = v->type->toBasetype(); |
172 if (v->storage_class & STCref) | |
173 { // References are the size of a pointer | |
174 t = Type::tvoidptr; | |
175 } | |
174 if (t->ty == Tstruct /*&& isStructDeclaration()*/) | 176 if (t->ty == Tstruct /*&& isStructDeclaration()*/) |
175 { TypeStruct *ts = (TypeStruct *)t; | 177 { TypeStruct *ts = (TypeStruct *)t; |
176 | 178 #if DMDV2 |
177 if (ts->sym == this) | 179 if (ts->sym == this) |
178 { | 180 { |
179 error("cannot have field %s with same struct type", v->toChars()); | 181 error("cannot have field %s with same struct type", v->toChars()); |
180 } | 182 } |
183 #endif | |
181 | 184 |
182 if (ts->sym->sizeok != 1) | 185 if (ts->sym->sizeok != 1) |
183 { | 186 { |
184 sizeok = 2; // cannot finish; flag as forward referenced | 187 sizeok = 2; // cannot finish; flag as forward referenced |
185 return; | 188 return; |
189 { | 192 { |
190 sizeok = 2; // cannot finish; flag as forward referenced | 193 sizeok = 2; // cannot finish; flag as forward referenced |
191 return; | 194 return; |
192 } | 195 } |
193 | 196 |
194 memsize = v->type->size(loc); | 197 memsize = t->size(loc); |
195 memalignsize = v->type->alignsize(); | 198 memalignsize = t->alignsize(); |
196 xalign = v->type->memalign(sc->structalign); | 199 xalign = t->memalign(sc->structalign); |
197 alignmember(xalign, memalignsize, &sc->offset); | 200 alignmember(xalign, memalignsize, &sc->offset); |
198 v->offset = sc->offset; | 201 v->offset = sc->offset; |
199 sc->offset += memsize; | 202 sc->offset += memsize; |
200 if (sc->offset > structsize) | 203 if (sc->offset > structsize) |
201 structsize = sc->offset; | 204 structsize = sc->offset; |
209 //printf(" addField '%s' to '%s' at offset %d, size = %d\n", v->toChars(), toChars(), v->offset, memsize); | 212 //printf(" addField '%s' to '%s' at offset %d, size = %d\n", v->toChars(), toChars(), v->offset, memsize); |
210 fields.push(v); | 213 fields.push(v); |
211 } | 214 } |
212 | 215 |
213 | 216 |
217 /**************************************** | |
218 * Returns !=0 if there's an extra member which is the 'this' | |
219 * pointer to the enclosing context (enclosing aggregate or function) | |
220 */ | |
221 | |
222 int AggregateDeclaration::isNested() | |
223 { | |
224 return isnested; | |
225 } | |
226 | |
227 | |
214 /********************************* StructDeclaration ****************************/ | 228 /********************************* StructDeclaration ****************************/ |
215 | 229 |
216 StructDeclaration::StructDeclaration(Loc loc, Identifier *id) | 230 StructDeclaration::StructDeclaration(Loc loc, Identifier *id) |
217 : AggregateDeclaration(loc, id) | 231 : AggregateDeclaration(loc, id) |
218 { | 232 { |
219 zeroInit = 0; // assume false until we do semantic processing | 233 zeroInit = 0; // assume false until we do semantic processing |
234 #if DMDV2 | |
220 hasIdentityAssign = 0; | 235 hasIdentityAssign = 0; |
221 cpctor = NULL; | 236 cpctor = NULL; |
222 postblit = NULL; | 237 postblit = NULL; |
238 #endif | |
223 | 239 |
224 // For forward references | 240 // For forward references |
225 type = new TypeStruct(this); | 241 type = new TypeStruct(this); |
226 } | 242 } |
227 | 243 |
275 if (sc->stc & STCdeprecated) | 291 if (sc->stc & STCdeprecated) |
276 isdeprecated = 1; | 292 isdeprecated = 1; |
277 assert(!isAnonymous()); | 293 assert(!isAnonymous()); |
278 if (sc->stc & STCabstract) | 294 if (sc->stc & STCabstract) |
279 error("structs, unions cannot be abstract"); | 295 error("structs, unions cannot be abstract"); |
280 if (storage_class & STCinvariant) | 296 #if DMDV2 |
297 if (storage_class & STCimmutable) | |
281 type = type->invariantOf(); | 298 type = type->invariantOf(); |
282 else if (storage_class & STCconst) | 299 else if (storage_class & STCconst) |
283 type = type->constOf(); | 300 type = type->constOf(); |
301 else if (storage_class & STCshared) | |
302 type = type->sharedOf(); | |
303 #endif | |
284 | 304 |
285 if (sizeok == 0) // if not already done the addMember step | 305 if (sizeok == 0) // if not already done the addMember step |
286 { | 306 { |
307 int hasfunctions = 0; | |
287 for (i = 0; i < members->dim; i++) | 308 for (i = 0; i < members->dim; i++) |
288 { | 309 { |
289 Dsymbol *s = (Dsymbol *)members->data[i]; | 310 Dsymbol *s = (Dsymbol *)members->data[i]; |
290 //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars()); | 311 //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars()); |
291 s->addMember(sc, this, 1); | 312 s->addMember(sc, this, 1); |
292 } | 313 if (s->isFuncDeclaration()) |
314 hasfunctions = 1; | |
315 } | |
316 | |
317 // If nested struct, add in hidden 'this' pointer to outer scope | |
318 if (hasfunctions && !(storage_class & STCstatic)) | |
319 { Dsymbol *s = toParent2(); | |
320 if (s) | |
321 { | |
322 AggregateDeclaration *ad = s->isAggregateDeclaration(); | |
323 FuncDeclaration *fd = s->isFuncDeclaration(); | |
324 | |
325 TemplateInstance *ti; | |
326 if (ad && (ti = ad->parent->isTemplateInstance()) != NULL && ti->isnested || fd) | |
327 { isnested = 1; | |
328 Type *t; | |
329 if (ad) | |
330 t = ad->handle; | |
331 else if (fd) | |
332 { AggregateDeclaration *ad = fd->isMember2(); | |
333 if (ad) | |
334 t = ad->handle; | |
335 else | |
336 t = Type::tvoidptr; | |
337 } | |
338 else | |
339 assert(0); | |
340 if (t->ty == Tstruct) | |
341 t = Type::tvoidptr; // t should not be a ref type | |
342 assert(!vthis); | |
343 vthis = new ThisDeclaration(loc, t); | |
344 //vthis->storage_class |= STCref; | |
345 members->push(vthis); | |
346 } | |
347 } | |
348 } | |
293 } | 349 } |
294 | 350 |
295 sizeok = 0; | 351 sizeok = 0; |
296 sc2 = sc->push(this); | 352 sc2 = sc->push(this); |
297 sc2->stc &= storage_class & (STCconst | STCinvariant); | 353 sc2->stc &= storage_class & STC_TYPECTOR; |
298 sc2->parent = this; | 354 sc2->parent = this; |
299 if (isUnionDeclaration()) | 355 if (isUnionDeclaration()) |
300 sc2->inunion = 1; | 356 sc2->inunion = 1; |
301 sc2->protection = PROTpublic; | 357 sc2->protection = PROTpublic; |
302 sc2->explicitProtection = 0; | 358 sc2->explicitProtection = 0; |
312 if (sizeok == 2) | 368 if (sizeok == 2) |
313 { //printf("forward reference\n"); | 369 { //printf("forward reference\n"); |
314 break; | 370 break; |
315 } | 371 } |
316 #endif | 372 #endif |
373 Type *t; | |
374 if (s->isDeclaration() && | |
375 (t = s->isDeclaration()->type) != NULL && | |
376 t->toBasetype()->ty == Tstruct) | |
377 { StructDeclaration *sd = (StructDeclaration *)t->toDsymbol(sc); | |
378 if (sd->isnested) | |
379 error("inner struct %s cannot be a field", sd->toChars()); | |
380 } | |
317 } | 381 } |
318 | 382 |
319 /* The TypeInfo_Struct is expecting an opEquals and opCmp with | 383 /* The TypeInfo_Struct is expecting an opEquals and opCmp with |
320 * a parameter that is a pointer to the struct. But if there | 384 * a parameter that is a pointer to the struct. But if there |
321 * isn't one, but is an opEquals or opCmp with a value, write | 385 * isn't one, but is an opEquals or opCmp with a value, write |
347 for (int i = 0; i < 2; i++) | 411 for (int i = 0; i < 2; i++) |
348 { | 412 { |
349 Dsymbol *s = search_function(this, id); | 413 Dsymbol *s = search_function(this, id); |
350 FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL; | 414 FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL; |
351 if (fdx) | 415 if (fdx) |
352 { FuncDeclaration *fd = fdx->overloadExactMatch(tfeqptr); | 416 { FuncDeclaration *fd = fdx->overloadExactMatch(tfeqptr, getModule()); |
353 if (!fd) | 417 if (!fd) |
354 { fd = fdx->overloadExactMatch(tfeq); | 418 { fd = fdx->overloadExactMatch(tfeq, getModule()); |
355 if (fd) | 419 if (fd) |
356 { // Create the thunk, fdptr | 420 { // Create the thunk, fdptr |
357 FuncDeclaration *fdptr = new FuncDeclaration(loc, loc, fdx->ident, STCundefined, tfeqptr); | 421 FuncDeclaration *fdptr = new FuncDeclaration(loc, loc, fdx->ident, STCundefined, tfeqptr); |
358 Expression *e = new IdentifierExp(loc, Id::p); | 422 Expression *e = new IdentifierExp(loc, Id::p); |
359 e = new PtrExp(loc, e); | 423 e = new PtrExp(loc, e); |
371 } | 435 } |
372 } | 436 } |
373 | 437 |
374 id = Id::cmp; | 438 id = Id::cmp; |
375 } | 439 } |
376 | 440 #if DMDV2 |
377 dtor = buildDtor(sc2); | 441 dtor = buildDtor(sc2); |
378 postblit = buildPostBlit(sc2); | 442 postblit = buildPostBlit(sc2); |
379 cpctor = buildCpCtor(sc2); | 443 cpctor = buildCpCtor(sc2); |
380 buildOpAssign(sc2); | 444 buildOpAssign(sc2); |
445 #endif | |
381 | 446 |
382 sc2->pop(); | 447 sc2->pop(); |
383 | 448 |
384 if (sizeok == 2) | 449 if (sizeok == 2) |
385 { // semantic() failed because of forward references. | 450 { // semantic() failed because of forward references. |
427 zeroInit = 0; | 492 zeroInit = 0; |
428 break; | 493 break; |
429 } | 494 } |
430 else | 495 else |
431 { | 496 { |
432 if (!vd->type->isZeroInit()) | 497 if (!vd->type->isZeroInit(loc)) |
433 { | 498 { |
434 zeroInit = 0; | 499 zeroInit = 0; |
435 break; | 500 break; |
436 } | 501 } |
437 } | 502 } |
438 } | 503 } |
439 } | 504 } |
440 | 505 |
441 /* Look for special member functions. | 506 /* Look for special member functions. |
442 */ | 507 */ |
443 ctor = (CtorDeclaration *)search(0, Id::ctor, 0); | 508 #if DMDV2 |
509 ctor = search(0, Id::ctor, 0); | |
510 #endif | |
444 inv = (InvariantDeclaration *)search(0, Id::classInvariant, 0); | 511 inv = (InvariantDeclaration *)search(0, Id::classInvariant, 0); |
445 aggNew = (NewDeclaration *)search(0, Id::classNew, 0); | 512 aggNew = (NewDeclaration *)search(0, Id::classNew, 0); |
446 aggDelete = (DeleteDeclaration *)search(0, Id::classDelete, 0); | 513 aggDelete = (DeleteDeclaration *)search(0, Id::classDelete, 0); |
447 | 514 |
448 if (sc->func) | 515 if (sc->func) |