Fixed semi-colon parsing in C-style for loops
[delight/core.git] / dmd / attrib.c
blobed4c1dddf74b46f6f5ff486193c3dede9a53fc05
2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars
4 // All Rights Reserved
5 // written by Walter Bright
6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
9 // See the included readme.txt for details.
11 /* NOTE: This file has been patched from the original DMD distribution to
12 work with the GDC compiler.
14 Modified by David Friedman, December 2006
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <assert.h>
21 #if _WIN32 || IN_GCC
22 #include "mem.h"
23 #elif linux
24 #include "../root/mem.h"
25 #endif
27 #include "init.h"
28 #include "declaration.h"
29 #include "attrib.h"
30 #include "cond.h"
31 #include "scope.h"
32 #include "id.h"
33 #include "expression.h"
34 #include "dsymbol.h"
35 #include "aggregate.h"
36 #include "module.h"
37 #include "parse.h"
38 #include "template.h"
40 extern void obj_includelib(char *name);
41 void obj_startaddress(Symbol *s);
44 /********************************* AttribDeclaration ****************************/
46 AttribDeclaration::AttribDeclaration(Array *decl)
47 : Dsymbol()
49 this->decl = decl;
52 Array *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd)
54 return decl;
57 int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
59 unsigned i;
60 int m = 0;
61 Array *d = include(sc, sd);
63 if (d)
65 for (i = 0; i < d->dim; i++)
66 { Dsymbol *s;
68 s = (Dsymbol *)d->data[i];
69 m |= s->addMember(sc, sd, m | memnum);
72 return m;
75 void AttribDeclaration::semantic(Scope *sc)
77 Array *d = include(sc, NULL);
79 //printf("\tAttribDeclaration::semantic '%s'\n",toChars());
80 if (d)
82 for (unsigned i = 0; i < d->dim; i++)
84 Dsymbol *s = (Dsymbol *)d->data[i];
86 s->semantic(sc);
91 void AttribDeclaration::semantic2(Scope *sc)
93 unsigned i;
94 Array *d = include(sc, NULL);
96 if (d)
98 for (i = 0; i < d->dim; i++)
99 { Dsymbol *s;
101 s = (Dsymbol *)d->data[i];
102 s->semantic2(sc);
107 void AttribDeclaration::semantic3(Scope *sc)
109 unsigned i;
110 Array *d = include(sc, NULL);
112 if (d)
114 for (i = 0; i < d->dim; i++)
115 { Dsymbol *s;
117 s = (Dsymbol *)d->data[i];
118 s->semantic3(sc);
123 void AttribDeclaration::inlineScan()
125 unsigned i;
126 Array *d = include(NULL, NULL);
128 if (d)
130 for (i = 0; i < d->dim; i++)
131 { Dsymbol *s;
133 s = (Dsymbol *)d->data[i];
134 //printf("AttribDeclaration::inlineScan %s\n", s->toChars());
135 s->inlineScan();
140 void AttribDeclaration::addComment(unsigned char *comment)
142 if (comment)
144 unsigned i;
145 Array *d = include(NULL, NULL);
147 if (d)
149 for (i = 0; i < d->dim; i++)
150 { Dsymbol *s;
152 s = (Dsymbol *)d->data[i];
153 //printf("AttribDeclaration::addComment %s\n", s->toChars());
154 s->addComment(comment);
160 void AttribDeclaration::emitComment(Scope *sc)
162 //printf("AttribDeclaration::emitComment(sc = %p)\n", sc);
164 /* If generating doc comment, skip this because if we're inside
165 * a template, then include(NULL, NULL) will fail.
167 // if (sc->docbuf)
168 // return;
170 unsigned i;
171 Array *d = include(NULL, NULL);
173 if (d)
175 for (i = 0; i < d->dim; i++)
176 { Dsymbol *s;
178 s = (Dsymbol *)d->data[i];
179 //printf("AttribDeclaration::emitComment %s\n", s->toChars());
180 s->emitComment(sc);
185 void AttribDeclaration::toObjFile(int multiobj)
187 unsigned i;
188 Array *d = include(NULL, NULL);
190 if (d)
192 for (i = 0; i < d->dim; i++)
193 { Dsymbol *s;
195 s = (Dsymbol *)d->data[i];
196 s->toObjFile(multiobj);
201 int AttribDeclaration::cvMember(unsigned char *p)
203 unsigned i;
204 int nwritten = 0;
205 int n;
206 Array *d = include(NULL, NULL);
208 if (d)
210 for (i = 0; i < d->dim; i++)
211 { Dsymbol *s;
213 s = (Dsymbol *)d->data[i];
214 n = s->cvMember(p);
215 if (p)
216 p += n;
217 nwritten += n;
220 return nwritten;
223 int AttribDeclaration::hasPointers()
225 Array *d = include(NULL, NULL);
227 if (d)
229 for (size_t i = 0; i < d->dim; i++)
231 Dsymbol *s = (Dsymbol *)d->data[i];
232 if (s->hasPointers())
233 return 1;
236 return 0;
239 char *AttribDeclaration::kind()
241 return "attribute";
244 int AttribDeclaration::oneMember(Dsymbol **ps)
246 Array *d = include(NULL, NULL);
248 return Dsymbol::oneMembers(d, ps);
251 void AttribDeclaration::checkCtorConstInit()
253 unsigned i;
254 Array *d = include(NULL, NULL);
256 if (d)
258 for (i = 0; i < d->dim; i++)
259 { Dsymbol *s;
261 s = (Dsymbol *)d->data[i];
262 s->checkCtorConstInit();
267 /****************************************
270 void AttribDeclaration::addLocalClass(ClassDeclarations *aclasses)
271 { unsigned i;
272 Array *d = include(NULL, NULL);
274 if (d)
276 for (i = 0; i < d->dim; i++)
277 { Dsymbol *s;
279 s = (Dsymbol *)d->data[i];
280 s->addLocalClass(aclasses);
286 void AttribDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
288 if (decl)
290 buf->writenl();
291 buf->writeByte('{');
292 buf->writenl();
293 for (unsigned i = 0; i < decl->dim; i++)
295 Dsymbol *s = (Dsymbol *)decl->data[i];
297 buf->writestring(" ");
298 s->toCBuffer(buf, hgs);
300 buf->writeByte('}');
302 else
303 buf->writeByte(';');
304 buf->writenl();
307 /************************* StorageClassDeclaration ****************************/
309 StorageClassDeclaration::StorageClassDeclaration(unsigned stc, Array *decl)
310 : AttribDeclaration(decl)
312 this->stc = stc;
315 Dsymbol *StorageClassDeclaration::syntaxCopy(Dsymbol *s)
317 StorageClassDeclaration *scd;
319 assert(!s);
320 scd = new StorageClassDeclaration(stc, Dsymbol::arraySyntaxCopy(decl));
321 return scd;
324 void StorageClassDeclaration::semantic(Scope *sc)
326 if (decl)
327 { unsigned stc_save = sc->stc;
329 if (stc & (STCauto | STCscope | STCstatic | STCextern))
330 sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern);
331 sc->stc |= stc;
332 for (unsigned i = 0; i < decl->dim; i++)
334 Dsymbol *s = (Dsymbol *)decl->data[i];
336 s->semantic(sc);
338 sc->stc = stc_save;
340 else
341 sc->stc = stc;
344 void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
346 struct SCstring
348 int stc;
349 enum TOK tok;
352 static SCstring table[] =
354 { STCauto, TOKauto },
355 { STCscope, TOKscope },
356 { STCstatic, TOKstatic },
357 { STCextern, TOKextern },
358 { STCconst, TOKconst },
359 { STCfinal, TOKfinal },
360 { STCabstract, TOKabstract },
361 { STCsynchronized, TOKsynchronized },
362 { STCdeprecated, TOKdeprecated },
363 { STCoverride, TOKoverride },
366 int written = 0;
367 for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++)
369 if (stc & table[i].stc)
371 if (written)
372 buf->writeByte(' ');
373 written = 1;
374 buf->writestring(Token::toChars(table[i].tok));
378 AttribDeclaration::toCBuffer(buf, hgs);
381 /********************************* LinkDeclaration ****************************/
383 LinkDeclaration::LinkDeclaration(enum LINK p, Array *decl)
384 : AttribDeclaration(decl)
386 //printf("LinkDeclaration(linkage = %d, decl = %p)\n", p, decl);
387 linkage = p;
390 Dsymbol *LinkDeclaration::syntaxCopy(Dsymbol *s)
392 LinkDeclaration *ld;
394 assert(!s);
395 ld = new LinkDeclaration(linkage, Dsymbol::arraySyntaxCopy(decl));
396 return ld;
399 void LinkDeclaration::semantic(Scope *sc)
401 //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, decl);
402 if (decl)
403 { enum LINK linkage_save = sc->linkage;
405 sc->linkage = linkage;
406 for (unsigned i = 0; i < decl->dim; i++)
408 Dsymbol *s = (Dsymbol *)decl->data[i];
410 s->semantic(sc);
412 sc->linkage = linkage_save;
414 else
416 sc->linkage = linkage;
420 void LinkDeclaration::semantic3(Scope *sc)
422 //printf("LinkDeclaration::semantic3(linkage = %d, decl = %p)\n", linkage, decl);
423 if (decl)
424 { enum LINK linkage_save = sc->linkage;
426 sc->linkage = linkage;
427 for (unsigned i = 0; i < decl->dim; i++)
429 Dsymbol *s = (Dsymbol *)decl->data[i];
431 s->semantic3(sc);
433 sc->linkage = linkage_save;
435 else
437 sc->linkage = linkage;
441 void LinkDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
442 { char *p;
444 switch (linkage)
446 case LINKd: p = "D"; break;
447 case LINKc: p = "C"; break;
448 case LINKcpp: p = "C++"; break;
449 case LINKwindows: p = "Windows"; break;
450 case LINKpascal: p = "Pascal"; break;
451 default:
452 assert(0);
453 break;
455 buf->writestring("extern (");
456 buf->writestring(p);
457 buf->writestring(") ");
458 AttribDeclaration::toCBuffer(buf, hgs);
461 char *LinkDeclaration::toChars()
463 return "extern ()";
466 /********************************* ProtDeclaration ****************************/
468 ProtDeclaration::ProtDeclaration(enum PROT p, Array *decl)
469 : AttribDeclaration(decl)
471 protection = p;
472 //printf("decl = %p\n", decl);
475 Dsymbol *ProtDeclaration::syntaxCopy(Dsymbol *s)
477 ProtDeclaration *pd;
479 assert(!s);
480 pd = new ProtDeclaration(protection, Dsymbol::arraySyntaxCopy(decl));
481 return pd;
484 void ProtDeclaration::semantic(Scope *sc)
486 if (decl)
487 { enum PROT protection_save = sc->protection;
488 int explicitProtection_save = sc->explicitProtection;
490 sc->protection = protection;
491 sc->explicitProtection = 1;
492 for (unsigned i = 0; i < decl->dim; i++)
494 Dsymbol *s = (Dsymbol *)decl->data[i];
496 s->semantic(sc);
498 sc->protection = protection_save;
499 sc->explicitProtection = explicitProtection_save;
501 else
502 { sc->protection = protection;
503 sc->explicitProtection = 1;
507 void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
508 { char *p;
510 switch (protection)
512 case PROTprivate: p = "private"; break;
513 case PROTpackage: p = "package"; break;
514 case PROTprotected: p = "protected"; break;
515 case PROTpublic: p = "public"; break;
516 case PROTexport: p = "export"; break;
517 default:
518 assert(0);
519 break;
521 buf->writestring(p);
522 AttribDeclaration::toCBuffer(buf, hgs);
525 /********************************* AlignDeclaration ****************************/
527 AlignDeclaration::AlignDeclaration(unsigned sa, Array *decl)
528 : AttribDeclaration(decl)
530 salign = sa;
533 Dsymbol *AlignDeclaration::syntaxCopy(Dsymbol *s)
535 AlignDeclaration *ad;
537 assert(!s);
538 ad = new AlignDeclaration(salign, Dsymbol::arraySyntaxCopy(decl));
539 return ad;
542 void AlignDeclaration::semantic(Scope *sc)
544 //printf("\tAlignDeclaration::semantic '%s'\n",toChars());
545 if (decl)
546 { unsigned salign_save = sc->structalign;
548 sc->structalign = salign;
549 for (unsigned i = 0; i < decl->dim; i++)
551 Dsymbol *s = (Dsymbol *)decl->data[i];
553 s->semantic(sc);
555 sc->structalign = salign_save;
557 else
558 sc->structalign = salign;
562 void AlignDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
564 buf->printf("align (%d)", salign);
565 AttribDeclaration::toCBuffer(buf, hgs);
568 /********************************* AnonDeclaration ****************************/
570 AnonDeclaration::AnonDeclaration(Loc loc, int isunion, Array *decl)
571 : AttribDeclaration(decl)
573 this->loc = loc;
574 this->isunion = isunion;
575 this->scope = NULL;
576 this->sem = 0;
579 Dsymbol *AnonDeclaration::syntaxCopy(Dsymbol *s)
581 AnonDeclaration *ad;
583 assert(!s);
584 ad = new AnonDeclaration(loc, isunion, Dsymbol::arraySyntaxCopy(decl));
585 return ad;
588 void AnonDeclaration::semantic(Scope *sc)
590 //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
592 Scope *scx = NULL;
593 if (scope)
594 { sc = scope;
595 scx = scope;
596 scope = NULL;
599 assert(sc->parent);
601 Dsymbol *parent = sc->parent->pastMixin();
602 AggregateDeclaration *ad = parent->isAggregateDeclaration();
604 if (!ad || (!ad->isStructDeclaration() && !ad->isClassDeclaration()))
606 error("can only be a part of an aggregate");
607 return;
610 if (decl)
612 AnonymousAggregateDeclaration aad;
613 int adisunion;
615 if (sc->anonAgg)
616 { ad = sc->anonAgg;
617 adisunion = sc->inunion;
619 else
620 adisunion = ad->isUnionDeclaration() != NULL;
622 // printf("\tsc->anonAgg = %p\n", sc->anonAgg);
623 // printf("\tad = %p\n", ad);
624 // printf("\taad = %p\n", &aad);
626 sc = sc->push();
627 sc->anonAgg = &aad;
628 sc->stc &= ~(STCauto | STCscope | STCstatic);
629 sc->inunion = isunion;
630 sc->offset = 0;
631 sc->flags = 0;
632 aad.structalign = sc->structalign;
633 aad.parent = ad;
635 for (unsigned i = 0; i < decl->dim; i++)
637 Dsymbol *s = (Dsymbol *)decl->data[i];
639 s->semantic(sc);
640 if (isunion)
641 sc->offset = 0;
642 if (aad.sizeok == 2)
644 break;
647 sc = sc->pop();
649 // If failed due to forward references, unwind and try again later
650 if (aad.sizeok == 2)
652 ad->sizeok = 2;
653 //printf("\tsetting ad->sizeok %p to 2\n", ad);
654 if (!sc->anonAgg)
656 scope = scx ? scx : new Scope(*sc);
657 scope->setNoFree();
658 scope->module->addDeferredSemantic(this);
660 //printf("\tforward reference %p\n", this);
661 return;
663 if (sem == 0)
664 { Module::dprogress++;
665 sem = 1;
666 //printf("\tcompleted %p\n", this);
668 else
669 ;//printf("\talready completed %p\n", this);
671 // 0 sized structs are set to 1 byte
672 if (aad.structsize == 0)
674 aad.structsize = 1;
675 aad.alignsize = 1;
678 // Align size of anonymous aggregate
679 //printf("aad.structalign = %d, aad.alignsize = %d, sc->offset = %d\n", aad.structalign, aad.alignsize, sc->offset);
680 ad->alignmember(aad.structalign, aad.alignsize, &sc->offset);
681 //ad->structsize = sc->offset;
682 //printf("sc->offset = %d\n", sc->offset);
684 // Add members of aad to ad
685 //printf("\tadding members of aad to '%s'\n", ad->toChars());
686 for (unsigned i = 0; i < aad.fields.dim; i++)
688 VarDeclaration *v = (VarDeclaration *)aad.fields.data[i];
690 v->offset += sc->offset;
691 ad->fields.push(v);
694 // Add size of aad to ad
695 if (adisunion)
697 if (aad.structsize > ad->structsize)
698 ad->structsize = aad.structsize;
699 sc->offset = 0;
701 else
703 ad->structsize = sc->offset + aad.structsize;
704 sc->offset = ad->structsize;
707 if (ad->alignsize < aad.alignsize)
708 ad->alignsize = aad.alignsize;
713 void AnonDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
715 buf->printf(isunion ? "union" : "struct");
716 buf->writestring("\n{\n");
717 if (decl)
719 for (unsigned i = 0; i < decl->dim; i++)
721 Dsymbol *s = (Dsymbol *)decl->data[i];
723 //buf->writestring(" ");
724 s->toCBuffer(buf, hgs);
727 buf->writestring("}\n");
730 char *AnonDeclaration::kind()
732 return (char *)(isunion ? "anonymous union" : "anonymous struct");
735 /********************************* PragmaDeclaration ****************************/
737 PragmaDeclaration::PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl)
738 : AttribDeclaration(decl)
740 this->loc = loc;
741 this->ident = ident;
742 this->args = args;
745 Dsymbol *PragmaDeclaration::syntaxCopy(Dsymbol *s)
747 PragmaDeclaration *pd;
749 assert(!s);
750 pd = new PragmaDeclaration(loc, ident,
751 Expression::arraySyntaxCopy(args), Dsymbol::arraySyntaxCopy(decl));
752 return pd;
755 void PragmaDeclaration::semantic(Scope *sc)
756 { // Should be merged with PragmaStatement
757 Scope sc_save;
759 //printf("\tPragmaDeclaration::semantic '%s'\n",toChars());
760 if (ident == Id::msg)
762 if (args)
764 for (size_t i = 0; i < args->dim; i++)
766 Expression *e = (Expression *)args->data[i];
768 e = e->semantic(sc);
769 e = e->optimize(WANTvalue | WANTinterpret);
770 if (e->op == TOKstring)
772 StringExp *se = (StringExp *)e;
773 fprintf(stdmsg, "%.*s", (int)se->len, se->string);
775 else
776 error("string expected for message, not '%s'", e->toChars());
778 fprintf(stdmsg, "\n");
780 goto Lnodecl;
782 else if (ident == Id::lib)
784 if (!args || args->dim != 1)
785 error("string expected for library name");
786 else
788 Expression *e = (Expression *)args->data[0];
790 e = e->semantic(sc);
791 e = e->optimize(WANTvalue | WANTinterpret);
792 args->data[0] = (void *)e;
793 if (e->op != TOKstring)
794 error("string expected for library name, not '%s'", e->toChars());
795 else if (global.params.verbose)
797 StringExp *se = (StringExp *)e;
798 char *name = (char *)mem.malloc(se->len + 1);
799 memcpy(name, se->string, se->len);
800 name[se->len] = 0;
801 printf("library %s\n", name);
802 mem.free(name);
805 goto Lnodecl;
807 #if IN_GCC
808 else if (ident == Id::GNU_asm)
810 if (! args || args->dim != 2)
811 error("identifier and string expected for asm name");
812 else
814 Expression *e;
815 Declaration *d = NULL;
816 StringExp *s = NULL;
818 e = (Expression *)args->data[0];
819 e = e->semantic(sc);
820 if (e->op == TOKvar)
822 d = ((VarExp *)e)->var;
823 if (! d->isFuncDeclaration() && ! d->isVarDeclaration())
824 d = NULL;
826 if (!d)
827 error("first argument of GNU_asm must be a function or variable declaration");
829 e = (Expression *)args->data[1];
830 e = e->semantic(sc);
831 e = e->optimize(WANTvalue | WANTinterpret);
832 if (e->op == TOKstring && ((StringExp *)e)->sz == 1)
833 s = ((StringExp *)e);
834 else
835 error("second argument of GNU_asm must be a character string");
837 if (d && s)
838 d->c_ident = Lexer::idPool((char*) s->string);
840 goto Lnodecl;
842 else if (ident == Id::GNU_attribute)
844 sc_save = *sc;
846 // An empty list is allowed.
847 if (args && args->dim)
849 Expressions * a;
851 if (sc->attributes)
852 a = (Expressions *) sc->attributes->copy();
853 else
854 a = new Expressions;
855 sc->attributes = a;
857 for (unsigned i = 0; i < args->dim; i++)
859 Expression * e = (Expression *) args->data[i];
860 //e = e->semantic(sc);
862 if (e->op == TOKidentifier) {
863 /* ok */
864 } else if (e->op == TOKcall) {
865 CallExp * c = (CallExp *) e;
866 if (c->e1->op != TOKidentifier)
867 error("identifier or call expression expected for attribute");
868 if (c->arguments)
869 for (int unsigned ai = 0; ai < c->arguments->dim; ai++)
871 c->arguments->data[ai] =
872 ((Expression *) c->arguments->data[ai])->semantic(sc);
875 else
877 error("identifier or call expression expected for attribute");
878 continue;
880 a->push(e);
884 else if (ident == Id::GNU_set_attribute)
886 if (!args || args->dim < 1)
887 error("declaration expected for setting attributes");
888 else
890 Array p_attributes_list; // of Expressions**
892 Expression * e = (Expression *) args->data[0];
893 Expressions ** pa = NULL;
895 e = e->semantic(sc);
896 if (e->op == TOKvar)
898 Declaration * d = ((VarExp *)e)->var;
899 if (d->isFuncDeclaration() || d->isVarDeclaration())
900 pa = & d->attributes;
902 else if (e->op == TOKtype)
904 Type * t = ((TypeExp *)e)->type;
905 if (t->ty == Ttypedef)
906 pa = & ((TypeTypedef *) t)->sym->attributes;
907 else if (t->ty == Tenum)
908 pa = & ((TypeEnum *) t)->sym->attributes;
909 else if (t->ty == Tstruct)
910 pa = & ((TypeStruct *) t)->sym->attributes;
911 else if (t->ty == Tclass)
912 pa = & ((TypeClass *) t)->sym->attributes;
915 if (pa)
916 p_attributes_list.push(pa);
917 else
918 error("first argument must be a function, variable, or type declaration");
921 Expressions * new_attrs = new Expressions;
922 for (unsigned i = 1; i < args->dim; i++)
924 Expression * e = (Expression *) args->data[i];
925 //e = e->semantic(sc);
927 if (e->op == TOKidentifier) {
928 /* ok */
929 } else if (e->op == TOKcall) {
930 CallExp * c = (CallExp *) e;
931 if (c->e1->op != TOKidentifier)
932 error("identifier or call expression expected for attribute");
933 if (c->arguments)
934 for (int unsigned ai = 0; ai < c->arguments->dim; ai++)
936 c->arguments->data[ai] =
937 ((Expression *) c->arguments->data[ai])->semantic(sc);
940 else
942 error("identifier or call expression expected for attribute");
943 continue;
945 new_attrs->push(e);
948 for (unsigned i = 0; i < p_attributes_list.dim; ++i)
950 Expressions ** pa = (Expressions **) p_attributes_list.data[i];
951 if (*pa)
953 *pa = (Expressions *) (*pa)->copy();
954 (*pa)->append(new_attrs);
956 else
957 *pa = new_attrs;
960 goto Lnodecl;
962 #endif
963 else if (global.params.ignoreUnsupportedPragmas)
965 if (global.params.verbose)
967 /* Print unrecognized pragmas
969 printf("pragma %s", ident->toChars());
970 if (args)
972 for (size_t i = 0; i < args->dim; i++)
974 Expression *e = (Expression *)args->data[i];
975 e = e->semantic(sc);
976 e = e->optimize(WANTvalue | WANTinterpret);
977 if (i == 0)
978 printf(" (");
979 else
980 printf(",");
981 printf("%s", e->toChars());
983 if (args->dim)
984 printf(")");
986 printf("\n");
988 goto Lnodecl;
990 else
991 error("unrecognized pragma(%s)", ident->toChars());
993 if (decl)
995 for (unsigned i = 0; i < decl->dim; i++)
997 Dsymbol *s = (Dsymbol *)decl->data[i];
999 s->semantic(sc);
1003 #if IN_GCC
1004 if (decl)
1005 if (ident == Id::GNU_attribute)
1006 *sc = sc_save;
1007 #endif
1008 return;
1010 Lnodecl:
1011 if (decl)
1012 error("pragma is missing closing ';'");
1015 int PragmaDeclaration::oneMember(Dsymbol **ps)
1017 *ps = NULL;
1018 return TRUE;
1021 char *PragmaDeclaration::kind()
1023 return "pragma";
1026 void PragmaDeclaration::toObjFile(int multiobj)
1028 if (ident == Id::lib)
1030 assert(args && args->dim == 1);
1032 Expression *e = (Expression *)args->data[0];
1034 assert(e->op == TOKstring);
1036 StringExp *se = (StringExp *)e;
1037 char *name = (char *)mem.malloc(se->len + 1);
1038 memcpy(name, se->string, se->len);
1039 name[se->len] = 0;
1040 obj_includelib(name);
1042 AttribDeclaration::toObjFile(multiobj);
1045 void PragmaDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
1047 buf->printf("pragma(%s", ident->toChars());
1048 if (args)
1050 for (size_t i = 0; i < args->dim; i++)
1052 Expression *e = (Expression *)args->data[i];
1054 buf->writestring(", ");
1055 e->toCBuffer(buf, hgs);
1058 buf->writestring(")");
1059 AttribDeclaration::toCBuffer(buf, hgs);
1063 /********************************* ConditionalDeclaration ****************************/
1065 ConditionalDeclaration::ConditionalDeclaration(Condition *condition, Array *decl, Array *elsedecl)
1066 : AttribDeclaration(decl)
1068 //printf("ConditionalDeclaration::ConditionalDeclaration()\n");
1069 this->condition = condition;
1070 this->elsedecl = elsedecl;
1073 Dsymbol *ConditionalDeclaration::syntaxCopy(Dsymbol *s)
1075 ConditionalDeclaration *dd;
1077 assert(!s);
1078 dd = new ConditionalDeclaration(condition->syntaxCopy(),
1079 Dsymbol::arraySyntaxCopy(decl),
1080 Dsymbol::arraySyntaxCopy(elsedecl));
1081 return dd;
1085 int ConditionalDeclaration::oneMember(Dsymbol **ps)
1087 //printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition->inc);
1088 if (condition->inc)
1090 Array *d = condition->include(NULL, NULL) ? decl : elsedecl;
1091 return Dsymbol::oneMembers(d, ps);
1093 *ps = NULL;
1094 return TRUE;
1097 void ConditionalDeclaration::emitComment(Scope *sc)
1099 //printf("ConditionalDeclaration::emitComment(sc = %p)\n", sc);
1100 if (condition->inc)
1102 AttribDeclaration::emitComment(sc);
1106 // Decide if 'then' or 'else' code should be included
1108 Array *ConditionalDeclaration::include(Scope *sc, ScopeDsymbol *sd)
1110 //printf("ConditionalDeclaration::include()\n");
1111 assert(condition);
1112 return condition->include(sc, sd) ? decl : elsedecl;
1116 void ConditionalDeclaration::addComment(unsigned char *comment)
1118 /* Because addComment is called by the parser, if we called
1119 * include() it would define a version before it was used.
1120 * But it's no problem to drill down to both decl and elsedecl,
1121 * so that's the workaround.
1124 if (comment)
1126 Array *d = decl;
1128 for (int j = 0; j < 2; j++)
1130 if (d)
1132 for (unsigned i = 0; i < d->dim; i++)
1133 { Dsymbol *s;
1135 s = (Dsymbol *)d->data[i];
1136 //printf("ConditionalDeclaration::addComment %s\n", s->toChars());
1137 s->addComment(comment);
1140 d = elsedecl;
1145 void ConditionalDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
1147 condition->toCBuffer(buf, hgs);
1148 if (decl || elsedecl)
1150 buf->writenl();
1151 buf->writeByte('{');
1152 buf->writenl();
1153 if (decl)
1155 for (unsigned i = 0; i < decl->dim; i++)
1157 Dsymbol *s = (Dsymbol *)decl->data[i];
1159 buf->writestring(" ");
1160 s->toCBuffer(buf, hgs);
1163 buf->writeByte('}');
1164 if (elsedecl)
1166 buf->writenl();
1167 buf->writestring("else");
1168 buf->writenl();
1169 buf->writeByte('{');
1170 buf->writenl();
1171 for (unsigned i = 0; i < elsedecl->dim; i++)
1173 Dsymbol *s = (Dsymbol *)elsedecl->data[i];
1175 buf->writestring(" ");
1176 s->toCBuffer(buf, hgs);
1178 buf->writeByte('}');
1181 else
1182 buf->writeByte(':');
1183 buf->writenl();
1186 /***************************** StaticIfDeclaration ****************************/
1188 StaticIfDeclaration::StaticIfDeclaration(Condition *condition,
1189 Array *decl, Array *elsedecl)
1190 : ConditionalDeclaration(condition, decl, elsedecl)
1192 //printf("StaticIfDeclaration::StaticIfDeclaration()\n");
1193 sd = NULL;
1194 addisdone = 0;
1198 Dsymbol *StaticIfDeclaration::syntaxCopy(Dsymbol *s)
1200 StaticIfDeclaration *dd;
1202 assert(!s);
1203 dd = new StaticIfDeclaration(condition->syntaxCopy(),
1204 Dsymbol::arraySyntaxCopy(decl),
1205 Dsymbol::arraySyntaxCopy(elsedecl));
1206 return dd;
1210 int StaticIfDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
1212 /* This is deferred until semantic(), so that
1213 * expressions in the condition can refer to declarations
1214 * in the same scope, such as:
1216 * template Foo(int i)
1218 * const int j = i + 1;
1219 * static if (j == 3)
1220 * const int k;
1223 this->sd = sd;
1224 int m = 0;
1226 if (memnum == 0)
1227 { m = AttribDeclaration::addMember(sc, sd, memnum);
1228 addisdone = 1;
1230 return m;
1234 void StaticIfDeclaration::semantic(Scope *sc)
1236 Array *d = include(sc, sd);
1238 //printf("\tStaticIfDeclaration::semantic '%s'\n",toChars());
1239 if (d)
1241 if (!addisdone)
1242 { AttribDeclaration::addMember(sc, sd, 1);
1243 addisdone = 1;
1246 for (unsigned i = 0; i < d->dim; i++)
1248 Dsymbol *s = (Dsymbol *)d->data[i];
1250 s->semantic(sc);
1255 char *StaticIfDeclaration::kind()
1257 return "static if";
1261 /***************************** CompileDeclaration *****************************/
1263 CompileDeclaration::CompileDeclaration(Loc loc, Expression *exp)
1264 : AttribDeclaration(NULL)
1266 this->exp = exp;
1267 this->sd = NULL;
1270 Dsymbol *CompileDeclaration::syntaxCopy(Dsymbol *s)
1272 //printf("CompileDeclaration::syntaxCopy('%s')\n", toChars());
1273 CompileDeclaration *sc = new CompileDeclaration(loc, exp->syntaxCopy());
1274 return sc;
1277 int CompileDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
1279 this->sd = sd;
1280 return memnum;
1283 void CompileDeclaration::semantic(Scope *sc)
1285 //printf("CompileDeclaration::semantic()\n");
1286 exp = exp->semantic(sc);
1287 exp = resolveProperties(sc, exp);
1288 exp = exp->optimize(WANTvalue | WANTinterpret);
1289 if (exp->op != TOKstring)
1290 { error("argument to mixin must be a string, not (%s)", exp->toChars());
1291 return;
1293 StringExp *se = (StringExp *)exp;
1294 se = se->toUTF8(sc);
1295 Parser p(sc->module, (unsigned char *)se->string, se->len, 0);
1296 p.loc = loc;
1297 p.nextToken();
1298 decl = p.parseDeclDefs(0);
1299 if (p.token.value != TOKeof)
1301 error("incomplete mixin declaration (%s)", se->toChars());
1304 AttribDeclaration::addMember(sc, sd, 0);
1305 AttribDeclaration::semantic(sc);
1308 void CompileDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
1310 buf->writestring("mixin(");
1311 exp->toCBuffer(buf, hgs);
1312 buf->writestring(");");
1313 buf->writenl();