Mercurial > projects > ddmd
annotate dmd/AggregateDeclaration.d @ 178:e3afd1303184
Many small bugs fixed
Made all classes derive from TObject to detect memory leaks (functionality is disabled for now)
Began work on overriding backend memory allocations (to avoid memory leaks)
author | korDen |
---|---|
date | Sun, 17 Oct 2010 07:42:00 +0400 |
parents | fa9a71a9f5a8 |
children | b0d41ff5e0df |
rev | line source |
---|---|
0 | 1 module dmd.AggregateDeclaration; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.ScopeDsymbol; |
5 import dmd.Type; | |
6 import dmd.Id; | |
7 import dmd.ExpStatement; | |
8 import dmd.AddrExp; | |
9 import dmd.CastExp; | |
10 import dmd.TypeSArray; | |
11 import dmd.DotVarExp; | |
12 import dmd.TypeStruct; | |
13 import dmd.StructDeclaration; | |
14 import dmd.Declaration; | |
15 import dmd.TypeClass; | |
16 import dmd.TOK; | |
17 import dmd.ThisExp; | |
176 | 18 import dmd.Global; |
0 | 19 import dmd.PROT; |
20 import dmd.Expression; | |
21 import dmd.STC; | |
22 import dmd.DotIdExp; | |
23 import dmd.CallExp; | |
24 import dmd.DtorDeclaration; | |
25 import dmd.Lexer; | |
26 import dmd.TY; | |
27 import dmd.Array; | |
28 import dmd.ArrayTypes; | |
29 import dmd.VarDeclaration; | |
30 import dmd.InvariantDeclaration; | |
31 import dmd.NewDeclaration; | |
32 import dmd.DeleteDeclaration; | |
33 import dmd.CtorDeclaration; | |
34 import dmd.FuncDeclaration; | |
35 import dmd.Identifier; | |
79 | 36 import dmd.Json; |
0 | 37 import dmd.Loc; |
38 import dmd.Dsymbol; | |
39 import dmd.Scope; | |
40 import dmd.OutBuffer; | |
41 import dmd.ClassDeclaration; | |
42 import dmd.BaseClass; | |
43 import dmd.Util; | |
44 | |
45 import dmd.backend.Symbol; | |
46 import dmd.backend.Classsym; | |
47 import dmd.backend.Util; | |
48 import dmd.backend.LIST; | |
49 import dmd.backend.SC; | |
50 import dmd.backend.FL; | |
51 import dmd.backend.SFL; | |
52 import dmd.codegen.Util; | |
53 | |
54 /**************************************** | |
55 * Determine if scope sc has package level access to s. | |
56 */ | |
57 | |
58 bool hasPackageAccess(Scope sc, Dsymbol s) | |
59 { | |
60 version (LOG) { | |
61 printf("hasPackageAccess(s = '%s', sc = '%p')\n", s.toChars(), sc); | |
62 } | |
63 | |
64 for (; s; s = s.parent) | |
65 { | |
66 if (s.isPackage() && !s.isModule()) | |
67 break; | |
68 } | |
69 version (LOG) { | |
70 if (s) | |
71 printf("\tthis is in package '%s'\n", s.toChars()); | |
72 } | |
73 | |
74 if (s && s == sc.module_.parent) | |
75 { | |
76 version (LOG) { | |
77 printf("\ts is in same package as sc\n"); | |
78 } | |
79 return true; | |
80 } | |
81 | |
82 | |
83 version (LOG) { | |
84 printf("\tno package access\n"); | |
85 } | |
86 | |
87 return false; | |
88 } | |
89 | |
90 /******************************************************** | |
91 * Helper function for ClassDeclaration.accessCheck() | |
92 * Returns: | |
93 * 0 no access | |
94 * 1 access | |
95 */ | |
96 | |
97 bool accessCheckX(Dsymbol smember, Dsymbol sfunc, AggregateDeclaration dthis, AggregateDeclaration cdscope) | |
98 { | |
99 assert(dthis); | |
100 | |
101 static if (false) { | |
102 writef("accessCheckX for %s.%s in function %s() in scope %s\n", dthis.toChars(), smember.toChars(), sfunc ? sfunc.toChars() : "null", cdscope ? cdscope.toChars() : "null"); | |
103 } | |
104 if (dthis.hasPrivateAccess(sfunc) || dthis.isFriendOf(cdscope)) | |
105 { | |
106 if (smember.toParent() == dthis) | |
107 return true; | |
108 else | |
109 { | |
110 ClassDeclaration cdthis = dthis.isClassDeclaration(); | |
111 if (cdthis) | |
112 { | |
125
767a01c2a272
BaseClasses -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
113 foreach (b; cdthis.baseclasses) |
176 | 114 { |
0 | 115 PROT access = b.base.getAccess(smember); |
116 | |
117 if (access >= PROT.PROTprotected || accessCheckX(smember, sfunc, b.base, cdscope)) | |
118 return true; | |
119 } | |
120 } | |
121 } | |
122 } | |
123 else | |
124 { | |
125 if (smember.toParent() != dthis) | |
126 { | |
127 ClassDeclaration cdthis = dthis.isClassDeclaration(); | |
128 if (cdthis) | |
129 { | |
125
767a01c2a272
BaseClasses -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
130 foreach (b; cdthis.baseclasses) |
176 | 131 { |
0 | 132 if (accessCheckX(smember, sfunc, b.base, cdscope)) |
133 return true; | |
134 } | |
135 } | |
136 } | |
137 } | |
138 | |
139 return false; | |
140 } | |
141 | |
142 class AggregateDeclaration : ScopeDsymbol | |
143 { | |
144 Type type; | |
131
206db751bd4c
dmdfe 2.037 compiles now
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
130
diff
changeset
|
145 StorageClass storage_class; |
0 | 146 PROT protection = PROT.PROTpublic; |
147 Type handle; // 'this' type | |
148 uint structsize; // size of struct | |
149 uint alignsize; // size of struct for alignment purposes | |
150 uint structalign; // struct member alignment in effect | |
151 int hasUnions; // set if aggregate has overlapping fields | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
152 VarDeclarations fields; // VarDeclaration fields |
0 | 153 uint sizeok; // set when structsize contains valid data |
154 // 0: no size | |
155 // 1: size is correct | |
156 // 2: cannot determine size; fwd referenced | |
157 bool isdeprecated; // true if deprecated | |
176 | 158 |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
125
diff
changeset
|
159 version (DMDV2) { |
0 | 160 bool isnested; // true if is nested |
161 VarDeclaration vthis; // 'this' parameter if this aggregate is nested | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
125
diff
changeset
|
162 } |
0 | 163 // Special member functions |
164 InvariantDeclaration inv; // invariant | |
165 NewDeclaration aggNew; // allocator | |
166 DeleteDeclaration aggDelete; // deallocator | |
167 | |
168 version (DMDV2) { | |
169 //CtorDeclaration *ctor; | |
170 Dsymbol ctor; // CtorDeclaration or TemplateDeclaration | |
171 CtorDeclaration defaultCtor; // default constructor | |
172 Dsymbol aliasthis; // forward unresolved lookups to aliasthis | |
173 } | |
174 | |
175 FuncDeclarations dtors; // Array of destructors | |
176 FuncDeclaration dtor; // aggregate destructor | |
177 | |
178 version (IN_GCC) { | |
179 Array methods; // flat list of all methods for debug information | |
180 } | |
181 | |
182 this(Loc loc, Identifier id) | |
183 { | |
178 | 184 register(); |
0 | 185 super(id); |
186 this.loc = loc; | |
176 | 187 |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
188 fields = new VarDeclarations(); /// |
0 | 189 dtors = new FuncDeclarations(); |
190 } | |
191 | |
72 | 192 override void semantic2(Scope sc) |
0 | 193 { |
194 //printf("AggregateDeclaration.semantic2(%s)\n", toChars()); | |
195 if (scope_ && members) | |
176 | 196 { |
0 | 197 error("has forward references"); |
198 return; | |
199 } | |
200 if (members) | |
201 { | |
202 sc = sc.push(this); | |
77
ad4792a1cfd6
more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
74
diff
changeset
|
203 foreach(Dsymbol s; members) |
0 | 204 s.semantic2(sc); |
205 sc.pop(); | |
206 } | |
207 } | |
208 | |
72 | 209 override void semantic3(Scope sc) |
0 | 210 { |
211 //printf("AggregateDeclaration.semantic3(%s)\n", toChars()); | |
212 if (members) | |
213 { | |
214 sc = sc.push(this); | |
77
ad4792a1cfd6
more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
74
diff
changeset
|
215 foreach(Dsymbol s; members) |
0 | 216 s.semantic3(sc); |
217 sc.pop(); | |
218 } | |
219 } | |
220 | |
72 | 221 override void inlineScan() |
0 | 222 { |
223 //printf("AggregateDeclaration.inlineScan(%s)\n", toChars()); | |
224 if (members) | |
225 { | |
77
ad4792a1cfd6
more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
74
diff
changeset
|
226 foreach(Dsymbol s; members) |
0 | 227 { |
228 //printf("inline scan aggregate symbol '%s'\n", s.toChars()); | |
229 s.inlineScan(); | |
230 } | |
231 } | |
232 } | |
176 | 233 |
72 | 234 override uint size(Loc loc) |
0 | 235 { |
236 //printf("AggregateDeclaration.size() = %d\n", structsize); | |
237 if (!members) | |
238 error(loc, "unknown size"); | |
239 | |
240 if (sizeok != 1) | |
176 | 241 { |
0 | 242 error(loc, "no size yet for forward reference"); |
243 //*(char*)0=0; | |
244 } | |
245 | |
246 return structsize; | |
247 } | |
176 | 248 |
0 | 249 /**************************** |
250 * Do byte or word alignment as necessary. | |
251 * Align sizes of 0, as we may not know array sizes yet. | |
252 */ | |
253 static void alignmember(uint salign, uint size, uint* poffset) | |
254 { | |
255 //printf("salign = %d, size = %d, offset = %d\n",salign,size,offset); | |
256 if (salign > 1) | |
257 { | |
258 assert(size != 3); | |
259 int sa = size; | |
260 if (sa == 0 || salign < sa) | |
261 sa = salign; | |
262 *poffset = (*poffset + sa - 1) & ~(sa - 1); | |
263 } | |
264 //printf("result = %d\n",offset); | |
265 } | |
176 | 266 |
72 | 267 override Type getType() |
0 | 268 { |
269 return type; | |
270 } | |
176 | 271 |
0 | 272 void addField(Scope sc, VarDeclaration v) |
273 { | |
274 uint memsize; // size of member | |
275 uint memalignsize; // size of member for alignment purposes | |
276 uint xalign; // alignment boundaries | |
277 | |
278 //printf("AggregateDeclaration.addField('%s') %s\n", v.toChars(), toChars()); | |
279 assert(!(v.storage_class & (STC.STCstatic | STC.STCextern | STC.STCparameter | STC.STCtls))); | |
280 | |
281 // Check for forward referenced types which will fail the size() call | |
282 Type t = v.type.toBasetype(); | |
283 if (v.storage_class & STC.STCref) | |
284 { // References are the size of a pointer | |
176 | 285 t = global.tvoidptr; |
0 | 286 } |
287 if (t.ty == TY.Tstruct /*&& isStructDeclaration()*/) | |
288 { TypeStruct ts = cast(TypeStruct)t; | |
289 version (DMDV2) { | |
290 if (ts.sym == this) | |
291 { | |
292 error("cannot have field %s with same struct type", v.toChars()); | |
293 } | |
294 } | |
295 | |
296 if (ts.sym.sizeok != 1) | |
297 { | |
298 sizeok = 2; // cannot finish; flag as forward referenced | |
299 return; | |
300 } | |
301 } | |
302 if (t.ty == TY.Tident) | |
303 { | |
304 sizeok = 2; // cannot finish; flag as forward referenced | |
305 return; | |
306 } | |
307 | |
308 memsize = cast(uint)t.size(loc); /// | |
309 memalignsize = t.alignsize(); | |
310 xalign = t.memalign(sc.structalign); | |
311 alignmember(xalign, memalignsize, &sc.offset); | |
312 v.offset = sc.offset; | |
313 sc.offset += memsize; | |
314 if (sc.offset > structsize) | |
315 structsize = sc.offset; | |
316 if (sc.structalign < memalignsize) | |
317 memalignsize = sc.structalign; | |
318 if (alignsize < memalignsize) | |
319 alignsize = memalignsize; | |
320 //printf("\talignsize = %d\n", alignsize); | |
321 | |
322 v.storage_class |= STC.STCfield; | |
323 //printf(" addField '%s' to '%s' at offset %d, size = %d\n", v.toChars(), toChars(), v.offset, memsize); | |
79 | 324 fields.push(v); |
0 | 325 } |
176 | 326 |
72 | 327 override bool isDeprecated() // is aggregate deprecated? |
0 | 328 { |
329 return isdeprecated; | |
330 } | |
331 | |
332 /***************************************** | |
333 * Create inclusive destructor for struct/class by aggregating | |
334 * all the destructors in dtors[] with the destructors for | |
335 * all the members. | |
336 * Note the close similarity with StructDeclaration.buildPostBlit(), | |
337 * and the ordering changes (runs backward instead of forwards). | |
338 */ | |
339 FuncDeclaration buildDtor(Scope sc) | |
340 { | |
341 //printf("AggregateDeclaration.buildDtor() %s\n", toChars()); | |
342 Expression e = null; | |
343 | |
79 | 344 version (DMDV2) |
345 { | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
346 foreach (size_t i, VarDeclaration v; fields) |
0 | 347 { |
348 assert(v && v.storage_class & STC.STCfield); | |
349 if (v.storage_class & STC.STCref) | |
350 continue; | |
351 Type tv = v.type.toBasetype(); | |
352 size_t dim = 1; | |
353 while (tv.ty == TY.Tsarray) | |
354 { TypeSArray ta = cast(TypeSArray)tv; | |
355 dim *= (cast(TypeSArray)tv).dim.toInteger(); | |
356 tv = tv.nextOf().toBasetype(); | |
357 } | |
358 if (tv.ty == TY.Tstruct) | |
359 { TypeStruct ts = cast(TypeStruct)tv; | |
360 StructDeclaration sd = ts.sym; | |
361 if (sd.dtor) | |
176 | 362 { |
0 | 363 Expression ex; |
364 | |
365 // this.v | |
366 ex = new ThisExp(Loc(0)); | |
367 ex = new DotVarExp(Loc(0), ex, v, 0); | |
368 | |
369 if (dim == 1) | |
176 | 370 { |
0 | 371 // this.v.dtor() |
372 ex = new DotVarExp(Loc(0), ex, sd.dtor, 0); | |
373 ex = new CallExp(Loc(0), ex); | |
374 } | |
375 else | |
376 { | |
377 // Typeinfo.destroy(cast(void*)&this.v); | |
378 Expression ea = new AddrExp(Loc(0), ex); | |
379 ea = new CastExp(Loc(0), ea, Type.tvoid.pointerTo()); | |
380 | |
381 Expression et = v.type.getTypeInfo(sc); | |
382 et = new DotIdExp(Loc(0), et, Id.destroy); | |
383 | |
384 ex = new CallExp(Loc(0), et, ea); | |
385 } | |
386 e = Expression.combine(ex, e); // combine in reverse order | |
387 } | |
388 } | |
389 } | |
390 | |
391 /* Build our own "destructor" which executes e | |
392 */ | |
393 if (e) | |
176 | 394 { |
0 | 395 //printf("Building __fieldDtor()\n"); |
396 DtorDeclaration dd = new DtorDeclaration(Loc(0), Loc(0), Lexer.idPool("__fieldDtor")); | |
397 dd.fbody = new ExpStatement(Loc(0), e); | |
74
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
398 dtors.shift(dd); |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
399 members.push(dd); |
0 | 400 dd.semantic(sc); |
401 } | |
402 } | |
403 | |
404 switch (dtors.dim) | |
405 { | |
406 case 0: | |
407 return null; | |
408 | |
409 case 1: | |
77
ad4792a1cfd6
more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
74
diff
changeset
|
410 return cast(FuncDeclaration)dtors[0]; |
0 | 411 |
412 default: | |
413 e = null; | |
77
ad4792a1cfd6
more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
74
diff
changeset
|
414 foreach(FuncDeclaration fd; dtors) |
0 | 415 { |
416 Expression ex = new ThisExp(Loc(0)); | |
417 ex = new DotVarExp(Loc(0), ex, fd, 0); | |
418 ex = new CallExp(Loc(0), ex); | |
419 e = Expression.combine(ex, e); | |
420 } | |
77
ad4792a1cfd6
more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
74
diff
changeset
|
421 auto dd = new DtorDeclaration(Loc(0), Loc(0), Lexer.idPool("__aggrDtor")); |
0 | 422 dd.fbody = new ExpStatement(Loc(0), e); |
74
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
423 members.push(dd); |
0 | 424 dd.semantic(sc); |
425 return dd; | |
426 } | |
427 } | |
428 | |
429 /**************************************** | |
430 * Returns true if there's an extra member which is the 'this' | |
431 * pointer to the enclosing context (enclosing aggregate or function) | |
432 */ | |
433 bool isNested() | |
434 { | |
435 return isnested; | |
436 } | |
437 | |
72 | 438 override void emitComment(Scope sc) |
0 | 439 { |
440 assert(false); | |
441 } | |
176 | 442 |
79 | 443 override void toJsonBuffer(OutBuffer buf) |
444 { | |
445 //writef("AggregateDeclaration.toJsonBuffer()\n"); | |
446 buf.writestring("{\n"); | |
176 | 447 |
79 | 448 JsonProperty(buf, Pname, toChars()); |
449 JsonProperty(buf, Pkind, kind()); | |
450 if (comment) | |
451 JsonProperty(buf, Pcomment, comment); | |
452 if (loc.linnum) | |
453 JsonProperty(buf, Pline, loc.linnum); | |
176 | 454 |
79 | 455 ClassDeclaration cd = isClassDeclaration(); |
456 if (cd) | |
457 { | |
458 if (cd.baseClass) | |
459 { | |
460 JsonProperty(buf, "base", cd.baseClass.toChars()); | |
461 } | |
462 if (cd.interfaces_dim) | |
463 { | |
464 JsonString(buf, "interfaces"); | |
465 buf.writestring(" : [\n"); | |
466 size_t offset = buf.offset; | |
467 for (int i = 0; i < cd.interfaces_dim; i++) | |
468 { | |
469 BaseClass b = cd.interfaces[i]; | |
470 if (offset != buf.offset) | |
471 { | |
96 | 472 buf.writestring(",\n"); |
79 | 473 offset = buf.offset; |
474 } | |
475 JsonString(buf, b.base.toChars()); | |
476 } | |
96 | 477 JsonRemoveComma(buf); |
79 | 478 buf.writestring("],\n"); |
479 } | |
480 } | |
176 | 481 |
79 | 482 JsonString(buf, Pmembers); |
483 buf.writestring(" : [\n"); | |
484 size_t offset = buf.offset; | |
485 foreach (Dsymbol s; members) | |
486 { | |
487 if (offset != buf.offset) | |
488 { | |
96 | 489 buf.writestring(",\n"); |
79 | 490 offset = buf.offset; |
491 } | |
492 s.toJsonBuffer(buf); | |
493 } | |
96 | 494 JsonRemoveComma(buf); |
79 | 495 buf.writestring("]\n"); |
176 | 496 |
79 | 497 buf.writestring("}\n"); |
498 } | |
499 | |
72 | 500 override void toDocBuffer(OutBuffer buf) |
0 | 501 { |
502 assert(false); | |
503 } | |
504 | |
505 // For access checking | |
506 PROT getAccess(Dsymbol smember) // determine access to smember | |
507 { | |
508 assert(false); | |
509 } | |
510 | |
511 /**************************************** | |
512 * Determine if this is the same or friend of cd. | |
513 */ | |
514 bool isFriendOf(AggregateDeclaration cd) | |
515 { | |
516 version (LOG) { | |
517 printf("AggregateDeclaration.isFriendOf(this = '%s', cd = '%s')\n", toChars(), cd ? cd.toChars() : "null"); | |
518 } | |
519 if (this is cd) | |
520 return true; | |
521 | |
522 // Friends if both are in the same module | |
523 //if (toParent() == cd.toParent()) | |
524 if (cd && getModule() == cd.getModule()) | |
525 { | |
526 version (LOG) { | |
527 printf("\tin same module\n"); | |
528 } | |
529 return true; | |
530 } | |
531 | |
532 version (LOG) { | |
533 printf("\tnot friend\n"); | |
534 } | |
535 return false; | |
536 } | |
176 | 537 |
0 | 538 /********************************** |
539 * Determine if smember has access to private members of this declaration. | |
540 */ | |
541 bool hasPrivateAccess(Dsymbol smember) // does smember have private access to members of this class? | |
542 { | |
543 if (smember) | |
544 { | |
545 AggregateDeclaration cd = null; | |
546 Dsymbol smemberparent = smember.toParent(); | |
547 if (smemberparent) | |
548 cd = smemberparent.isAggregateDeclaration(); | |
549 | |
550 version (LOG) { | |
551 printf("AggregateDeclaration::hasPrivateAccess(class %s, member %s)\n", toChars(), smember.toChars()); | |
552 } | |
553 | |
554 if (this == cd) // smember is a member of this class | |
555 { | |
556 version (LOG) { | |
557 printf("\tyes 1\n"); | |
558 } | |
559 return true; // so we get private access | |
560 } | |
561 | |
562 // If both are members of the same module, grant access | |
563 while (true) | |
176 | 564 { |
0 | 565 Dsymbol sp = smember.toParent(); |
566 if (sp.isFuncDeclaration() && smember.isFuncDeclaration()) | |
567 smember = sp; | |
568 else | |
569 break; | |
570 } | |
571 if (!cd && toParent() == smember.toParent()) | |
572 { | |
573 version (LOG) { | |
574 printf("\tyes 2\n"); | |
575 } | |
576 return true; | |
577 } | |
578 if (!cd && getModule() == smember.getModule()) | |
579 { | |
580 version (LOG) { | |
581 printf("\tyes 3\n"); | |
582 } | |
583 return true; | |
584 } | |
585 } | |
586 version (LOG) { | |
587 printf("\tno\n"); | |
588 } | |
589 return false; | |
590 } | |
176 | 591 |
0 | 592 /******************************* |
593 * Do access check for member of this class, this class being the | |
594 * type of the 'this' pointer used to access smember. | |
595 */ | |
596 void accessCheck(Loc loc, Scope sc, Dsymbol smember) | |
597 { | |
598 bool result; | |
599 | |
600 FuncDeclaration f = sc.func; | |
601 AggregateDeclaration cdscope = sc.getStructClassScope(); | |
602 PROT access; | |
603 | |
604 version (LOG) { | |
605 printf("AggregateDeclaration.accessCheck() for %s.%s in function %s() in scope %s\n", toChars(), smember.toChars(), f ? f.toChars() : null, cdscope ? cdscope.toChars() : null); | |
606 } | |
607 | |
608 Dsymbol smemberparent = smember.toParent(); | |
609 if (!smemberparent || !smemberparent.isAggregateDeclaration()) | |
610 { | |
611 version (LOG) { | |
612 printf("not an aggregate member\n"); | |
613 } | |
614 return; // then it is accessible | |
615 } | |
616 | |
617 // BUG: should enable this check | |
618 //assert(smember.parent.isBaseOf(this, null)); | |
619 | |
620 if (smemberparent == this) | |
176 | 621 { |
0 | 622 PROT access2 = smember.prot(); |
623 | |
624 result = access2 >= PROT.PROTpublic || | |
625 hasPrivateAccess(f) || | |
626 isFriendOf(cdscope) || | |
627 (access2 == PROT.PROTpackage && hasPackageAccess(sc, this)); | |
628 | |
629 version (LOG) { | |
630 printf("result1 = %d\n", result); | |
631 } | |
632 } | |
633 else if ((access = this.getAccess(smember)) >= PROT.PROTpublic) | |
634 { | |
635 result = true; | |
636 version (LOG) { | |
637 printf("result2 = %d\n", result); | |
638 } | |
639 } | |
640 else if (access == PROT.PROTpackage && hasPackageAccess(sc, this)) | |
641 { | |
642 result = true; | |
643 version (LOG) { | |
644 printf("result3 = %d\n", result); | |
645 } | |
646 } | |
647 else | |
648 { | |
649 result = accessCheckX(smember, f, this, cdscope); | |
650 version (LOG) { | |
651 printf("result4 = %d\n", result); | |
652 } | |
653 } | |
654 if (!result) | |
655 { | |
656 error(loc, "member %s is not accessible", smember.toChars()); | |
657 halt(); | |
658 } | |
659 } | |
660 | |
72 | 661 override PROT prot() |
0 | 662 { |
663 assert(false); | |
664 } | |
665 | |
666 // Back end | |
667 Symbol* stag; // tag symbol for debug data | |
668 Symbol* sinit; | |
669 | |
670 Symbol* toInitializer() | |
671 { | |
672 Symbol* s; | |
673 Classsym* stag; | |
674 | |
675 if (!sinit) | |
676 { | |
677 stag = fake_classsym(Id.ClassInfo); | |
678 s = toSymbolX("__init", SC.SCextern, stag.Stype, "Z"); | |
679 s.Sfl = FL.FLextern; | |
680 s.Sflags |= SFL.SFLnodebug; | |
681 slist_add(s); | |
682 sinit = s; | |
683 } | |
684 | |
685 return sinit; | |
686 } | |
687 | |
72 | 688 override AggregateDeclaration isAggregateDeclaration() { return this; } |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
689 } |