root/branches/tango/rebuild/attrib.c

Revision 796, 26.2 kB (checked in by Gregor, 1 year ago)

MERGE: trunk r795

Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2007 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <assert.h>
13
14 #if _WIN32 || IN_GCC || IN_DMDFE
15 #include "mem.h"
16 #elif linux
17 #include "../root/mem.h"
18 #endif
19
20 #include "import.h"
21 #include "init.h"
22 #include "declaration.h"
23 #include "attrib.h"
24 #include "cond.h"
25 #include "scope.h"
26 #include "id.h"
27 #include "expression.h"
28 #include "dsymbol.h"
29 #include "aggregate.h"
30 #include "module.h"
31 #include "parse.h"
32 #include "config.h"
33 #include "version.h"
34
35 extern void obj_includelib(char *name);
36
37
38 /********************************* AttribDeclaration ****************************/
39
40 AttribDeclaration::AttribDeclaration(Array *decl)
41     : Dsymbol()
42 {
43     this->decl = decl;
44 }
45
46 Array *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd)
47 {
48     return decl;
49 }
50
51 int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
52 {
53     unsigned i;
54     int m = 0;
55     Array *d = include(sc, sd);
56
57     if (d)
58     {
59     for (i = 0; i < d->dim; i++)
60     {   Dsymbol *s;
61
62         s = (Dsymbol *)d->data[i];
63         m |= s->addMember(sc, sd, m | memnum);
64     }
65     }
66     return m;
67 }
68
69 void AttribDeclaration::semantic(Scope *sc)
70 {
71     Array *d = include(sc, NULL);
72
73     //printf("\tAttribDeclaration::semantic '%s'\n",toChars());
74     if (d)
75     {
76     for (unsigned i = 0; i < d->dim; i++)
77     {
78         Dsymbol *s = (Dsymbol *)d->data[i];
79
80         s->semantic(sc);
81     }
82     }
83 }
84
85 void AttribDeclaration::semantic2(Scope *sc)
86 {
87     unsigned i;
88     Array *d = include(sc, NULL);
89
90     if (d)
91     {
92     for (i = 0; i < d->dim; i++)
93     {   Dsymbol *s;
94
95         s = (Dsymbol *)d->data[i];
96         s->semantic2(sc);
97     }
98     }
99 }
100
101 void AttribDeclaration::semantic3(Scope *sc)
102 {
103     unsigned i;
104     Array *d = include(sc, NULL);
105
106     if (d)
107     {
108     for (i = 0; i < d->dim; i++)
109     {   Dsymbol *s;
110
111         s = (Dsymbol *)d->data[i];
112         s->semantic3(sc);
113     }
114     }
115 }
116
117 void AttribDeclaration::inlineScan()
118 {
119     unsigned i;
120     Array *d = include(NULL, NULL);
121
122     if (d)
123     {
124     for (i = 0; i < d->dim; i++)
125     {   Dsymbol *s;
126
127         s = (Dsymbol *)d->data[i];
128         //printf("AttribDeclaration::inlineScan %s\n", s->toChars());
129         s->inlineScan();
130     }
131     }
132 }
133
134 void AttribDeclaration::addComment(unsigned char *comment)
135 {
136     if (comment)
137     {
138     unsigned i;
139     Array *d = include(NULL, NULL);
140
141     if (d)
142     {
143         for (i = 0; i < d->dim; i++)
144         {   Dsymbol *s;
145
146         s = (Dsymbol *)d->data[i];
147         //printf("AttribDeclaration::addComment %s\n", s->toChars());
148         s->addComment(comment);
149         }
150     }
151     }
152 }
153
154 void AttribDeclaration::emitComment(Scope *sc)
155 {
156     //printf("AttribDeclaration::emitComment(sc = %p)\n", sc);
157
158     /* If generating doc comment, skip this because if we're inside
159      * a template, then include(NULL, NULL) will fail.
160      */
161 //    if (sc->docbuf)
162 //  return;
163
164     unsigned i;
165     Array *d = include(NULL, NULL);
166
167     if (d)
168     {
169     for (i = 0; i < d->dim; i++)
170     {   Dsymbol *s;
171
172         s = (Dsymbol *)d->data[i];
173         //printf("AttribDeclaration::emitComment %s\n", s->toChars());
174         s->emitComment(sc);
175     }
176     }
177 }
178
179 int AttribDeclaration::hasPointers()
180 {
181     Array *d = include(NULL, NULL);
182
183     if (d)
184     {
185     for (size_t i = 0; i < d->dim; i++)
186     {
187         Dsymbol *s = (Dsymbol *)d->data[i];
188         if (s->hasPointers())
189         return 1;
190     }
191     }
192     return 0;
193 }
194
195 char *AttribDeclaration::kind()
196 {
197     return "attribute";
198 }
199
200 int AttribDeclaration::oneMember(Dsymbol **ps)
201 {
202     Array *d = include(NULL, NULL);
203
204     return Dsymbol::oneMembers(d, ps);
205 }
206
207 void AttribDeclaration::checkCtorConstInit()
208 {
209     unsigned i;
210     Array *d = include(NULL, NULL);
211
212     if (d)
213     {
214     for (i = 0; i < d->dim; i++)
215     {   Dsymbol *s;
216
217         s = (Dsymbol *)d->data[i];
218         s->checkCtorConstInit();
219     }
220     }
221 }
222
223 /****************************************
224  */
225
226 void AttribDeclaration::addLocalClass(ClassDeclarations *aclasses)
227 {   unsigned i;
228     Array *d = include(NULL, NULL);
229
230     if (d)
231     {
232     for (i = 0; i < d->dim; i++)
233     {   Dsymbol *s;
234
235         s = (Dsymbol *)d->data[i];
236         s->addLocalClass(aclasses);
237     }
238     }
239 }
240
241
242 void AttribDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
243 {
244     if (decl)
245     {
246     buf->writenl();
247     buf->writeByte('{');
248     buf->writenl();
249     for (unsigned i = 0; i < decl->dim; i++)
250     {
251         Dsymbol *s = (Dsymbol *)decl->data[i];
252
253         buf->writestring("    ");
254         s->toCBuffer(buf, hgs);
255     }
256     buf->writeByte('}');
257     }
258     else
259     buf->writeByte(';');
260     buf->writenl();
261 }
262
263 void AttribDeclaration::parsepragmas(Module *m)
264 {
265     if (decl) {
266         for (int i = 0; i < decl->dim; i++) {
267             Dsymbol *ds = (Dsymbol *) decl->data[i];
268            
269             if (ds->isAttribDeclaration()) {
270                 AttribDeclaration *ad = (AttribDeclaration *) ds;
271                 ad->parsepragmas(m);
272                
273             } else if (ds->isImport()) {
274                 Import *im = (Import *) ds;
275                 im->load(m, NULL);
276                 im->mod->parsepragmas();
277                
278             } else if (dynamic_cast<VersionSymbol*>(ds)) {
279                 VersionSymbol *vs = (VersionSymbol *) ds;
280                 vs->addMember(NULL, m, 0);
281                
282             }
283         }
284     }
285 }
286
287 /************************* StorageClassDeclaration ****************************/
288
289 StorageClassDeclaration::StorageClassDeclaration(unsigned stc, Array *decl)
290     : AttribDeclaration(decl)
291 {
292     this->stc = stc;
293 }
294
295 Dsymbol *StorageClassDeclaration::syntaxCopy(Dsymbol *s)
296 {
297     StorageClassDeclaration *scd;
298
299     assert(!s);
300     scd = new StorageClassDeclaration(stc, Dsymbol::arraySyntaxCopy(decl));
301     return scd;
302 }
303
304 void StorageClassDeclaration::semantic(Scope *sc)
305 {
306     if (decl)
307     {   unsigned stc_save = sc->stc;
308
309     if (stc & (STCauto | STCscope | STCstatic | STCextern))
310         sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern);
311     sc->stc |= stc;
312     for (unsigned i = 0; i < decl->dim; i++)
313     {
314         Dsymbol *s = (Dsymbol *)decl->data[i];
315
316         s->semantic(sc);
317     }
318     sc->stc = stc_save;
319     }
320     else
321     sc->stc = stc;
322 }
323
324 void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
325 {
326     struct SCstring
327     {
328     int stc;
329     enum TOK tok;
330     };
331
332     static SCstring table[] =
333     {
334     { STCauto,         TOKauto },
335     { STCscope,        TOKscope },
336     { STCstatic,       TOKstatic },
337     { STCextern,       TOKextern },
338     { STCconst,        TOKconst },
339     { STCfinal,        TOKfinal },
340     { STCabstract,     TOKabstract },
341     { STCsynchronized, TOKsynchronized },
342     { STCdeprecated,   TOKdeprecated },
343     { STCoverride,     TOKoverride },
344     };
345
346     int written = 0;
347     for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++)
348     {
349     if (stc & table[i].stc)
350     {
351         if (written)
352         buf->writeByte(' ');
353         written = 1;
354         buf->writestring(Token::toChars(table[i].tok));
355     }
356     }
357
358     AttribDeclaration::toCBuffer(buf, hgs);
359 }
360
361 /********************************* LinkDeclaration ****************************/
362
363 LinkDeclaration::LinkDeclaration(enum LINK p, Array *decl)
364     : AttribDeclaration(decl)
365 {
366     //printf("LinkDeclaration(linkage = %d, decl = %p)\n", p, decl);
367     linkage = p;
368 }
369
370 Dsymbol *LinkDeclaration::syntaxCopy(Dsymbol *s)
371 {
372     LinkDeclaration *ld;
373
374     assert(!s);
375     ld = new LinkDeclaration(linkage, Dsymbol::arraySyntaxCopy(decl));
376     return ld;
377 }
378
379 void LinkDeclaration::semantic(Scope *sc)
380 {
381     //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, decl);
382     if (decl)
383     {   enum LINK linkage_save = sc->linkage;
384
385     sc->linkage = linkage;
386     for (unsigned i = 0; i < decl->dim; i++)
387     {
388         Dsymbol *s = (Dsymbol *)decl->data[i];
389
390         s->semantic(sc);
391     }
392     sc->linkage = linkage_save;
393     }
394     else
395     {
396     sc->linkage = linkage;
397     }
398 }
399
400 void LinkDeclaration::semantic3(Scope *sc)
401 {
402     //printf("LinkDeclaration::semantic3(linkage = %d, decl = %p)\n", linkage, decl);
403     if (decl)
404     {   enum LINK linkage_save = sc->linkage;
405
406     sc->linkage = linkage;
407     for (unsigned i = 0; i < decl->dim; i++)
408     {
409         Dsymbol *s = (Dsymbol *)decl->data[i];
410
411         s->semantic3(sc);
412     }
413     sc->linkage = linkage_save;
414     }
415     else
416     {
417     sc->linkage = linkage;
418     }
419 }
420
421 void LinkDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
422 {   char *p;
423
424     switch (linkage)
425     {
426     case LINKd:     p = "D";        break;
427     case LINKc:     p = "C";        break;
428     case LINKcpp:       p = "C++";      break;
429     case LINKwindows:   p = "Windows";      break;
430     case LINKpascal:    p = "Pascal";       break;
431     default:
432         assert(0);
433         break;
434     }
435     buf->writestring("extern (");
436     buf->writestring(p);
437     buf->writestring(") ");
438     AttribDeclaration::toCBuffer(buf, hgs);
439 }
440
441 char *LinkDeclaration::toChars()
442 {
443     return "extern ()";
444 }
445
446 /********************************* ProtDeclaration ****************************/
447
448 ProtDeclaration::ProtDeclaration(enum PROT p, Array *decl)
449     : AttribDeclaration(decl)
450 {
451     protection = p;
452     //printf("decl = %p\n", decl);
453 }
454
455 Dsymbol *ProtDeclaration::syntaxCopy(Dsymbol *s)
456 {
457     ProtDeclaration *pd;
458
459     assert(!s);
460     pd = new ProtDeclaration(protection, Dsymbol::arraySyntaxCopy(decl));
461     return pd;
462 }
463
464 void ProtDeclaration::semantic(Scope *sc)
465 {
466     if (decl)
467     {   enum PROT protection_save = sc->protection;
468     int explicitProtection_save = sc->explicitProtection;
469
470     sc->protection = protection;
471     sc->explicitProtection = 1;
472     for (unsigned i = 0; i < decl->dim; i++)
473     {
474         Dsymbol *s = (Dsymbol *)decl->data[i];
475
476         s->semantic(sc);
477     }
478     sc->protection = protection_save;
479     sc->explicitProtection = explicitProtection_save;
480     }
481     else
482     {   sc->protection = protection;
483     sc->explicitProtection = 1;
484     }
485 }
486
487 void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
488 {   char *p;
489
490     switch (protection)
491     {
492     case PROTprivate:   p = "private";      break;
493     case PROTpackage:   p = "package";      break;
494     case PROTprotected: p = "protected";    break;
495     case PROTpublic:    p = "public";       break;
496     case PROTexport:    p = "export";       break;
497     default:
498         assert(0);
499         break;
500     }
501     buf->writestring(p);
502     AttribDeclaration::toCBuffer(buf, hgs);
503 }
504
505 /********************************* AlignDeclaration ****************************/
506
507 AlignDeclaration::AlignDeclaration(unsigned sa, Array *decl)
508     : AttribDeclaration(decl)
509 {
510     salign = sa;
511 }
512
513 Dsymbol *AlignDeclaration::syntaxCopy(Dsymbol *s)
514 {
515     AlignDeclaration *ad;
516
517     assert(!s);
518     ad = new AlignDeclaration(salign, Dsymbol::arraySyntaxCopy(decl));
519     return ad;
520 }
521
522 void AlignDeclaration::semantic(Scope *sc)
523 {
524     //printf("\tAlignDeclaration::semantic '%s'\n",toChars());
525     if (decl)
526     {   unsigned salign_save = sc->structalign;
527
528     sc->structalign = salign;
529     for (unsigned i = 0; i < decl->dim; i++)
530     {
531         Dsymbol *s = (Dsymbol *)decl->data[i];
532
533         s->semantic(sc);
534     }
535     sc->structalign = salign_save;
536     }
537     else
538     sc->structalign = salign;
539 }
540
541
542 void AlignDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
543 {
544     buf->printf("align (%d)", salign);
545     AttribDeclaration::toCBuffer(buf, hgs);
546 }
547
548 /********************************* AnonDeclaration ****************************/
549
550 AnonDeclaration::AnonDeclaration(Loc loc, int isunion, Array *decl)
551     : AttribDeclaration(decl)
552 {
553     this->loc = loc;
554     this->isunion = isunion;
555     this->scope = NULL;
556     this->sem = 0;
557 }
558
559 Dsymbol *AnonDeclaration::syntaxCopy(Dsymbol *s)
560 {
561     AnonDeclaration *ad;
562
563     assert(!s);
564     ad = new AnonDeclaration(loc, isunion, Dsymbol::arraySyntaxCopy(decl));
565     return ad;
566 }
567
568 void AnonDeclaration::semantic(Scope *sc)
569 {
570     //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
571
572     Scope *scx = NULL;
573     if (scope)
574     {   sc = scope;
575     scx = scope;
576     scope = NULL;
577     }
578
579     assert(sc->parent);
580
581     Dsymbol *parent = sc->parent->pastMixin();
582     AggregateDeclaration *ad = parent->isAggregateDeclaration();
583
584     if (!ad || (!ad->isStructDeclaration() && !ad->isClassDeclaration()))
585     {
586     //error("can only be a part of an aggregate");
587     return;
588     }
589
590     if (decl)
591     {
592     AnonymousAggregateDeclaration aad;
593     int adisunion;
594
595     if (sc->anonAgg)
596     {   ad = sc->anonAgg;
597         adisunion = sc->inunion;
598     }
599     else
600         adisunion = ad->isUnionDeclaration() != NULL;
601
602 //  printf("\tsc->anonAgg = %p\n", sc->anonAgg);
603 //  printf("\tad  = %p\n", ad);
604 //  printf("\taad = %p\n", &aad);
605
606     sc = sc->push();
607     sc->anonAgg = &aad;
608     sc->stc &= ~(STCauto | STCscope | STCstatic);
609     sc->inunion = isunion;
610     sc->offset = 0;
611     sc->flags = 0;
612     aad.structalign = sc->structalign;
613     aad.parent = ad;
614
615     for (unsigned i = 0; i < decl->dim; i++)
616     {
617         Dsymbol *s = (Dsymbol *)decl->data[i];
618
619         s->semantic(sc);
620         if (isunion)
621         sc->offset = 0;
622         if (aad.sizeok == 2)
623         {
624         break;
625         }
626     }
627     sc = sc->pop();
628
629     // If failed due to forward references, unwind and try again later
630     if (aad.sizeok == 2)
631     {
632         ad->sizeok = 2;
633         //printf("\tsetting ad->sizeok %p to 2\n", ad);
634         if (!sc->anonAgg)
635         {
636         scope = scx ? scx : new Scope(*sc);
637         scope->setNoFree();
638         scope->module->addDeferredSemantic(this);
639         }
640         //printf("\tforward reference %p\n", this);
641         return;
642     }
643     if (sem == 0)
644     {   Module::dprogress++;
645         sem = 1;
646         //printf("\tcompleted %p\n", this);
647     }
648     else
649         ;//printf("\talready completed %p\n", this);
650
651     // 0 sized structs are set to 1 byte
652     if (aad.structsize == 0)
653     {
654         aad.structsize = 1;
655         aad.alignsize = 1;
656     }
657
658     // Align size of anonymous aggregate
659 //printf("aad.structalign = %d, aad.alignsize = %d, sc->offset = %d\n", aad.structalign, aad.alignsize, sc->offset);
660     ad->alignmember(aad.structalign, aad.alignsize, &sc->offset);
661     //ad->structsize = sc->offset;
662 //printf("sc->offset = %d\n", sc->offset);
663
664     // Add members of aad to ad
665     //printf("\tadding members of aad to '%s'\n", ad->toChars());
666     for (unsigned i = 0; i < aad.fields.dim; i++)
667     {
668         VarDeclaration *v = (VarDeclaration *)aad.fields.data[i];
669
670         v->offset += sc->offset;
671         ad->fields.push(v);
672     }
673
674     // Add size of aad to ad
675     if (adisunion)
676     {