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)