root/branches/dmdfe/attrib.c

Revision 740, 22.7 kB (checked in by Gregor, 1 year ago)

MERGE: DMD 1.019

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