Mercurial > projects > ddmd
comparison dmd/AggregateDeclaration.d @ 176:fa9a71a9f5a8
Moved all the mutable globals to Global
author | korDen |
---|---|
date | Sun, 10 Oct 2010 05:22:45 +0400 |
parents | 206db751bd4c |
children | e3afd1303184 |
comparison
equal
deleted
inserted
replaced
175:94b6033c07f3 | 176:fa9a71a9f5a8 |
---|---|
13 import dmd.StructDeclaration; | 13 import dmd.StructDeclaration; |
14 import dmd.Declaration; | 14 import dmd.Declaration; |
15 import dmd.TypeClass; | 15 import dmd.TypeClass; |
16 import dmd.TOK; | 16 import dmd.TOK; |
17 import dmd.ThisExp; | 17 import dmd.ThisExp; |
18 import dmd.Global; | |
18 import dmd.PROT; | 19 import dmd.PROT; |
19 import dmd.Expression; | 20 import dmd.Expression; |
20 import dmd.STC; | 21 import dmd.STC; |
21 import dmd.DotIdExp; | 22 import dmd.DotIdExp; |
22 import dmd.CallExp; | 23 import dmd.CallExp; |
108 { | 109 { |
109 ClassDeclaration cdthis = dthis.isClassDeclaration(); | 110 ClassDeclaration cdthis = dthis.isClassDeclaration(); |
110 if (cdthis) | 111 if (cdthis) |
111 { | 112 { |
112 foreach (b; cdthis.baseclasses) | 113 foreach (b; cdthis.baseclasses) |
113 { | 114 { |
114 PROT access = b.base.getAccess(smember); | 115 PROT access = b.base.getAccess(smember); |
115 | 116 |
116 if (access >= PROT.PROTprotected || accessCheckX(smember, sfunc, b.base, cdscope)) | 117 if (access >= PROT.PROTprotected || accessCheckX(smember, sfunc, b.base, cdscope)) |
117 return true; | 118 return true; |
118 } | 119 } |
125 { | 126 { |
126 ClassDeclaration cdthis = dthis.isClassDeclaration(); | 127 ClassDeclaration cdthis = dthis.isClassDeclaration(); |
127 if (cdthis) | 128 if (cdthis) |
128 { | 129 { |
129 foreach (b; cdthis.baseclasses) | 130 foreach (b; cdthis.baseclasses) |
130 { | 131 { |
131 if (accessCheckX(smember, sfunc, b.base, cdscope)) | 132 if (accessCheckX(smember, sfunc, b.base, cdscope)) |
132 return true; | 133 return true; |
133 } | 134 } |
134 } | 135 } |
135 } | 136 } |
152 uint sizeok; // set when structsize contains valid data | 153 uint sizeok; // set when structsize contains valid data |
153 // 0: no size | 154 // 0: no size |
154 // 1: size is correct | 155 // 1: size is correct |
155 // 2: cannot determine size; fwd referenced | 156 // 2: cannot determine size; fwd referenced |
156 bool isdeprecated; // true if deprecated | 157 bool isdeprecated; // true if deprecated |
157 | 158 |
158 version (DMDV2) { | 159 version (DMDV2) { |
159 bool isnested; // true if is nested | 160 bool isnested; // true if is nested |
160 VarDeclaration vthis; // 'this' parameter if this aggregate is nested | 161 VarDeclaration vthis; // 'this' parameter if this aggregate is nested |
161 } | 162 } |
162 // Special member functions | 163 // Special member functions |
180 | 181 |
181 this(Loc loc, Identifier id) | 182 this(Loc loc, Identifier id) |
182 { | 183 { |
183 super(id); | 184 super(id); |
184 this.loc = loc; | 185 this.loc = loc; |
185 | 186 |
186 fields = new VarDeclarations(); /// | 187 fields = new VarDeclarations(); /// |
187 dtors = new FuncDeclarations(); | 188 dtors = new FuncDeclarations(); |
188 } | 189 } |
189 | 190 |
190 override void semantic2(Scope sc) | 191 override void semantic2(Scope sc) |
191 { | 192 { |
192 //printf("AggregateDeclaration.semantic2(%s)\n", toChars()); | 193 //printf("AggregateDeclaration.semantic2(%s)\n", toChars()); |
193 if (scope_ && members) | 194 if (scope_ && members) |
194 { | 195 { |
195 error("has forward references"); | 196 error("has forward references"); |
196 return; | 197 return; |
197 } | 198 } |
198 if (members) | 199 if (members) |
199 { | 200 { |
226 //printf("inline scan aggregate symbol '%s'\n", s.toChars()); | 227 //printf("inline scan aggregate symbol '%s'\n", s.toChars()); |
227 s.inlineScan(); | 228 s.inlineScan(); |
228 } | 229 } |
229 } | 230 } |
230 } | 231 } |
231 | 232 |
232 override uint size(Loc loc) | 233 override uint size(Loc loc) |
233 { | 234 { |
234 //printf("AggregateDeclaration.size() = %d\n", structsize); | 235 //printf("AggregateDeclaration.size() = %d\n", structsize); |
235 if (!members) | 236 if (!members) |
236 error(loc, "unknown size"); | 237 error(loc, "unknown size"); |
237 | 238 |
238 if (sizeok != 1) | 239 if (sizeok != 1) |
239 { | 240 { |
240 error(loc, "no size yet for forward reference"); | 241 error(loc, "no size yet for forward reference"); |
241 //*(char*)0=0; | 242 //*(char*)0=0; |
242 } | 243 } |
243 | 244 |
244 return structsize; | 245 return structsize; |
245 } | 246 } |
246 | 247 |
247 /**************************** | 248 /**************************** |
248 * Do byte or word alignment as necessary. | 249 * Do byte or word alignment as necessary. |
249 * Align sizes of 0, as we may not know array sizes yet. | 250 * Align sizes of 0, as we may not know array sizes yet. |
250 */ | 251 */ |
251 static void alignmember(uint salign, uint size, uint* poffset) | 252 static void alignmember(uint salign, uint size, uint* poffset) |
259 sa = salign; | 260 sa = salign; |
260 *poffset = (*poffset + sa - 1) & ~(sa - 1); | 261 *poffset = (*poffset + sa - 1) & ~(sa - 1); |
261 } | 262 } |
262 //printf("result = %d\n",offset); | 263 //printf("result = %d\n",offset); |
263 } | 264 } |
264 | 265 |
265 override Type getType() | 266 override Type getType() |
266 { | 267 { |
267 return type; | 268 return type; |
268 } | 269 } |
269 | 270 |
270 void addField(Scope sc, VarDeclaration v) | 271 void addField(Scope sc, VarDeclaration v) |
271 { | 272 { |
272 uint memsize; // size of member | 273 uint memsize; // size of member |
273 uint memalignsize; // size of member for alignment purposes | 274 uint memalignsize; // size of member for alignment purposes |
274 uint xalign; // alignment boundaries | 275 uint xalign; // alignment boundaries |
278 | 279 |
279 // Check for forward referenced types which will fail the size() call | 280 // Check for forward referenced types which will fail the size() call |
280 Type t = v.type.toBasetype(); | 281 Type t = v.type.toBasetype(); |
281 if (v.storage_class & STC.STCref) | 282 if (v.storage_class & STC.STCref) |
282 { // References are the size of a pointer | 283 { // References are the size of a pointer |
283 t = Type.tvoidptr; | 284 t = global.tvoidptr; |
284 } | 285 } |
285 if (t.ty == TY.Tstruct /*&& isStructDeclaration()*/) | 286 if (t.ty == TY.Tstruct /*&& isStructDeclaration()*/) |
286 { TypeStruct ts = cast(TypeStruct)t; | 287 { TypeStruct ts = cast(TypeStruct)t; |
287 version (DMDV2) { | 288 version (DMDV2) { |
288 if (ts.sym == this) | 289 if (ts.sym == this) |
319 | 320 |
320 v.storage_class |= STC.STCfield; | 321 v.storage_class |= STC.STCfield; |
321 //printf(" addField '%s' to '%s' at offset %d, size = %d\n", v.toChars(), toChars(), v.offset, memsize); | 322 //printf(" addField '%s' to '%s' at offset %d, size = %d\n", v.toChars(), toChars(), v.offset, memsize); |
322 fields.push(v); | 323 fields.push(v); |
323 } | 324 } |
324 | 325 |
325 override bool isDeprecated() // is aggregate deprecated? | 326 override bool isDeprecated() // is aggregate deprecated? |
326 { | 327 { |
327 return isdeprecated; | 328 return isdeprecated; |
328 } | 329 } |
329 | 330 |
355 } | 356 } |
356 if (tv.ty == TY.Tstruct) | 357 if (tv.ty == TY.Tstruct) |
357 { TypeStruct ts = cast(TypeStruct)tv; | 358 { TypeStruct ts = cast(TypeStruct)tv; |
358 StructDeclaration sd = ts.sym; | 359 StructDeclaration sd = ts.sym; |
359 if (sd.dtor) | 360 if (sd.dtor) |
360 { | 361 { |
361 Expression ex; | 362 Expression ex; |
362 | 363 |
363 // this.v | 364 // this.v |
364 ex = new ThisExp(Loc(0)); | 365 ex = new ThisExp(Loc(0)); |
365 ex = new DotVarExp(Loc(0), ex, v, 0); | 366 ex = new DotVarExp(Loc(0), ex, v, 0); |
366 | 367 |
367 if (dim == 1) | 368 if (dim == 1) |
368 { | 369 { |
369 // this.v.dtor() | 370 // this.v.dtor() |
370 ex = new DotVarExp(Loc(0), ex, sd.dtor, 0); | 371 ex = new DotVarExp(Loc(0), ex, sd.dtor, 0); |
371 ex = new CallExp(Loc(0), ex); | 372 ex = new CallExp(Loc(0), ex); |
372 } | 373 } |
373 else | 374 else |
387 } | 388 } |
388 | 389 |
389 /* Build our own "destructor" which executes e | 390 /* Build our own "destructor" which executes e |
390 */ | 391 */ |
391 if (e) | 392 if (e) |
392 { | 393 { |
393 //printf("Building __fieldDtor()\n"); | 394 //printf("Building __fieldDtor()\n"); |
394 DtorDeclaration dd = new DtorDeclaration(Loc(0), Loc(0), Lexer.idPool("__fieldDtor")); | 395 DtorDeclaration dd = new DtorDeclaration(Loc(0), Loc(0), Lexer.idPool("__fieldDtor")); |
395 dd.fbody = new ExpStatement(Loc(0), e); | 396 dd.fbody = new ExpStatement(Loc(0), e); |
396 dtors.shift(dd); | 397 dtors.shift(dd); |
397 members.push(dd); | 398 members.push(dd); |
435 | 436 |
436 override void emitComment(Scope sc) | 437 override void emitComment(Scope sc) |
437 { | 438 { |
438 assert(false); | 439 assert(false); |
439 } | 440 } |
440 | 441 |
441 override void toJsonBuffer(OutBuffer buf) | 442 override void toJsonBuffer(OutBuffer buf) |
442 { | 443 { |
443 //writef("AggregateDeclaration.toJsonBuffer()\n"); | 444 //writef("AggregateDeclaration.toJsonBuffer()\n"); |
444 buf.writestring("{\n"); | 445 buf.writestring("{\n"); |
445 | 446 |
446 JsonProperty(buf, Pname, toChars()); | 447 JsonProperty(buf, Pname, toChars()); |
447 JsonProperty(buf, Pkind, kind()); | 448 JsonProperty(buf, Pkind, kind()); |
448 if (comment) | 449 if (comment) |
449 JsonProperty(buf, Pcomment, comment); | 450 JsonProperty(buf, Pcomment, comment); |
450 if (loc.linnum) | 451 if (loc.linnum) |
451 JsonProperty(buf, Pline, loc.linnum); | 452 JsonProperty(buf, Pline, loc.linnum); |
452 | 453 |
453 ClassDeclaration cd = isClassDeclaration(); | 454 ClassDeclaration cd = isClassDeclaration(); |
454 if (cd) | 455 if (cd) |
455 { | 456 { |
456 if (cd.baseClass) | 457 if (cd.baseClass) |
457 { | 458 { |
474 } | 475 } |
475 JsonRemoveComma(buf); | 476 JsonRemoveComma(buf); |
476 buf.writestring("],\n"); | 477 buf.writestring("],\n"); |
477 } | 478 } |
478 } | 479 } |
479 | 480 |
480 JsonString(buf, Pmembers); | 481 JsonString(buf, Pmembers); |
481 buf.writestring(" : [\n"); | 482 buf.writestring(" : [\n"); |
482 size_t offset = buf.offset; | 483 size_t offset = buf.offset; |
483 foreach (Dsymbol s; members) | 484 foreach (Dsymbol s; members) |
484 { | 485 { |
489 } | 490 } |
490 s.toJsonBuffer(buf); | 491 s.toJsonBuffer(buf); |
491 } | 492 } |
492 JsonRemoveComma(buf); | 493 JsonRemoveComma(buf); |
493 buf.writestring("]\n"); | 494 buf.writestring("]\n"); |
494 | 495 |
495 buf.writestring("}\n"); | 496 buf.writestring("}\n"); |
496 } | 497 } |
497 | 498 |
498 override void toDocBuffer(OutBuffer buf) | 499 override void toDocBuffer(OutBuffer buf) |
499 { | 500 { |
530 version (LOG) { | 531 version (LOG) { |
531 printf("\tnot friend\n"); | 532 printf("\tnot friend\n"); |
532 } | 533 } |
533 return false; | 534 return false; |
534 } | 535 } |
535 | 536 |
536 /********************************** | 537 /********************************** |
537 * Determine if smember has access to private members of this declaration. | 538 * Determine if smember has access to private members of this declaration. |
538 */ | 539 */ |
539 bool hasPrivateAccess(Dsymbol smember) // does smember have private access to members of this class? | 540 bool hasPrivateAccess(Dsymbol smember) // does smember have private access to members of this class? |
540 { | 541 { |
557 return true; // so we get private access | 558 return true; // so we get private access |
558 } | 559 } |
559 | 560 |
560 // If both are members of the same module, grant access | 561 // If both are members of the same module, grant access |
561 while (true) | 562 while (true) |
562 { | 563 { |
563 Dsymbol sp = smember.toParent(); | 564 Dsymbol sp = smember.toParent(); |
564 if (sp.isFuncDeclaration() && smember.isFuncDeclaration()) | 565 if (sp.isFuncDeclaration() && smember.isFuncDeclaration()) |
565 smember = sp; | 566 smember = sp; |
566 else | 567 else |
567 break; | 568 break; |
584 version (LOG) { | 585 version (LOG) { |
585 printf("\tno\n"); | 586 printf("\tno\n"); |
586 } | 587 } |
587 return false; | 588 return false; |
588 } | 589 } |
589 | 590 |
590 /******************************* | 591 /******************************* |
591 * Do access check for member of this class, this class being the | 592 * Do access check for member of this class, this class being the |
592 * type of the 'this' pointer used to access smember. | 593 * type of the 'this' pointer used to access smember. |
593 */ | 594 */ |
594 void accessCheck(Loc loc, Scope sc, Dsymbol smember) | 595 void accessCheck(Loc loc, Scope sc, Dsymbol smember) |
614 | 615 |
615 // BUG: should enable this check | 616 // BUG: should enable this check |
616 //assert(smember.parent.isBaseOf(this, null)); | 617 //assert(smember.parent.isBaseOf(this, null)); |
617 | 618 |
618 if (smemberparent == this) | 619 if (smemberparent == this) |
619 { | 620 { |
620 PROT access2 = smember.prot(); | 621 PROT access2 = smember.prot(); |
621 | 622 |
622 result = access2 >= PROT.PROTpublic || | 623 result = access2 >= PROT.PROTpublic || |
623 hasPrivateAccess(f) || | 624 hasPrivateAccess(f) || |
624 isFriendOf(cdscope) || | 625 isFriendOf(cdscope) || |