Mercurial > projects > ddmd
annotate dmd/AggregateDeclaration.d @ 114:e28b18c23469
added a module dmd.common for commonly used stuff
it currently holds code for consistency checking of predefined versions
also added a VisualD project file
author | Trass3r |
---|---|
date | Wed, 01 Sep 2010 18:21:58 +0200 |
parents | acd69f84627e |
children | 767a01c2a272 |
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; | |
18 import dmd.PROT; | |
19 import dmd.Expression; | |
20 import dmd.STC; | |
21 import dmd.DotIdExp; | |
22 import dmd.CallExp; | |
23 import dmd.DtorDeclaration; | |
24 import dmd.Lexer; | |
25 import dmd.TY; | |
26 import dmd.Array; | |
27 import dmd.ArrayTypes; | |
28 import dmd.VarDeclaration; | |
29 import dmd.InvariantDeclaration; | |
30 import dmd.NewDeclaration; | |
31 import dmd.DeleteDeclaration; | |
32 import dmd.CtorDeclaration; | |
33 import dmd.FuncDeclaration; | |
34 import dmd.Identifier; | |
79 | 35 import dmd.Json; |
0 | 36 import dmd.Loc; |
37 import dmd.Dsymbol; | |
38 import dmd.Scope; | |
39 import dmd.OutBuffer; | |
40 import dmd.ClassDeclaration; | |
41 import dmd.BaseClass; | |
42 import dmd.Util; | |
43 | |
44 import dmd.backend.Symbol; | |
45 import dmd.backend.Classsym; | |
46 import dmd.backend.Util; | |
47 import dmd.backend.LIST; | |
48 import dmd.backend.SC; | |
49 import dmd.backend.FL; | |
50 import dmd.backend.SFL; | |
51 import dmd.codegen.Util; | |
52 | |
53 /**************************************** | |
54 * Determine if scope sc has package level access to s. | |
55 */ | |
56 | |
57 bool hasPackageAccess(Scope sc, Dsymbol s) | |
58 { | |
59 version (LOG) { | |
60 printf("hasPackageAccess(s = '%s', sc = '%p')\n", s.toChars(), sc); | |
61 } | |
62 | |
63 for (; s; s = s.parent) | |
64 { | |
65 if (s.isPackage() && !s.isModule()) | |
66 break; | |
67 } | |
68 version (LOG) { | |
69 if (s) | |
70 printf("\tthis is in package '%s'\n", s.toChars()); | |
71 } | |
72 | |
73 if (s && s == sc.module_.parent) | |
74 { | |
75 version (LOG) { | |
76 printf("\ts is in same package as sc\n"); | |
77 } | |
78 return true; | |
79 } | |
80 | |
81 | |
82 version (LOG) { | |
83 printf("\tno package access\n"); | |
84 } | |
85 | |
86 return false; | |
87 } | |
88 | |
89 /******************************************************** | |
90 * Helper function for ClassDeclaration.accessCheck() | |
91 * Returns: | |
92 * 0 no access | |
93 * 1 access | |
94 */ | |
95 | |
96 bool accessCheckX(Dsymbol smember, Dsymbol sfunc, AggregateDeclaration dthis, AggregateDeclaration cdscope) | |
97 { | |
98 assert(dthis); | |
99 | |
100 static if (false) { | |
101 writef("accessCheckX for %s.%s in function %s() in scope %s\n", dthis.toChars(), smember.toChars(), sfunc ? sfunc.toChars() : "null", cdscope ? cdscope.toChars() : "null"); | |
102 } | |
103 if (dthis.hasPrivateAccess(sfunc) || dthis.isFriendOf(cdscope)) | |
104 { | |
105 if (smember.toParent() == dthis) | |
106 return true; | |
107 else | |
108 { | |
109 ClassDeclaration cdthis = dthis.isClassDeclaration(); | |
110 if (cdthis) | |
111 { | |
112 for (int i = 0; i < cdthis.baseclasses.dim; i++) | |
113 { | |
114 BaseClass b = cast(BaseClass)cdthis.baseclasses.data[i]; | |
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 { | |
130 for (int i = 0; i < cdthis.baseclasses.dim; i++) | |
131 { | |
132 BaseClass b = cast(BaseClass)cdthis.baseclasses.data[i]; | |
133 | |
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 { | |
146 Type type; | |
147 uint storage_class; | |
148 PROT protection = PROT.PROTpublic; | |
149 Type handle; // 'this' type | |
150 uint structsize; // size of struct | |
151 uint alignsize; // size of struct for alignment purposes | |
152 uint structalign; // struct member alignment in effect | |
153 int hasUnions; // set if aggregate has overlapping fields | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
154 VarDeclarations fields; // VarDeclaration fields |
0 | 155 uint sizeok; // set when structsize contains valid data |
156 // 0: no size | |
157 // 1: size is correct | |
158 // 2: cannot determine size; fwd referenced | |
159 bool isdeprecated; // true if deprecated | |
160 | |
161 bool isnested; // true if is nested | |
162 VarDeclaration vthis; // 'this' parameter if this aggregate is nested | |
163 | |
164 // Special member functions | |
165 InvariantDeclaration inv; // invariant | |
166 NewDeclaration aggNew; // allocator | |
167 DeleteDeclaration aggDelete; // deallocator | |
168 | |
169 version (DMDV2) { | |
170 //CtorDeclaration *ctor; | |
171 Dsymbol ctor; // CtorDeclaration or TemplateDeclaration | |
172 CtorDeclaration defaultCtor; // default constructor | |
173 Dsymbol aliasthis; // forward unresolved lookups to aliasthis | |
174 } | |
175 | |
176 FuncDeclarations dtors; // Array of destructors | |
177 FuncDeclaration dtor; // aggregate destructor | |
178 | |
179 version (IN_GCC) { | |
180 Array methods; // flat list of all methods for debug information | |
181 } | |
182 | |
183 this(Loc loc, Identifier id) | |
184 { | |
185 super(id); | |
186 this.loc = loc; | |
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) | |
196 { | |
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 } | |
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) | |
241 { | |
242 error(loc, "no size yet for forward reference"); | |
243 //*(char*)0=0; | |
244 } | |
245 | |
246 return structsize; | |
247 } | |
248 | |
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 } | |
266 | |
72 | 267 override Type getType() |
0 | 268 { |
269 return type; | |
270 } | |
271 | |
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 | |
285 t = Type.tvoidptr; | |
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 } |
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) | |
362 { | |
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) | |
370 { | |
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) | |
394 { | |
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 } | |
442 | |
79 | 443 override void toJsonBuffer(OutBuffer buf) |
444 { | |
445 //writef("AggregateDeclaration.toJsonBuffer()\n"); | |
446 buf.writestring("{\n"); | |
447 | |
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); | |
454 | |
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 } | |
481 | |
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"); |
496 | |
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 } | |
537 | |
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) | |
564 { | |
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 } | |
591 | |
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) | |
621 { | |
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 } |