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