root/trunk/rebuild/attrib.c

Revision 915, 28.4 kB (checked in by Gregor, 3 months ago)

MERGE: dmdfe-2.0 r914 (DMD 2.019)

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