2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars
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
24 #include "../root/mem.h"
28 #include "declaration.h"
33 #include "expression.h"
35 #include "aggregate.h"
40 extern void obj_includelib(char *name
);
41 void obj_startaddress(Symbol
*s
);
44 /********************************* AttribDeclaration ****************************/
46 AttribDeclaration::AttribDeclaration(Array
*decl
)
52 Array
*AttribDeclaration::include(Scope
*sc
, ScopeDsymbol
*sd
)
57 int AttribDeclaration::addMember(Scope
*sc
, ScopeDsymbol
*sd
, int memnum
)
61 Array
*d
= include(sc
, sd
);
65 for (i
= 0; i
< d
->dim
; i
++)
68 s
= (Dsymbol
*)d
->data
[i
];
69 m
|= s
->addMember(sc
, sd
, m
| memnum
);
75 void AttribDeclaration::semantic(Scope
*sc
)
77 Array
*d
= include(sc
, NULL
);
79 //printf("\tAttribDeclaration::semantic '%s'\n",toChars());
82 for (unsigned i
= 0; i
< d
->dim
; i
++)
84 Dsymbol
*s
= (Dsymbol
*)d
->data
[i
];
91 void AttribDeclaration::semantic2(Scope
*sc
)
94 Array
*d
= include(sc
, NULL
);
98 for (i
= 0; i
< d
->dim
; i
++)
101 s
= (Dsymbol
*)d
->data
[i
];
107 void AttribDeclaration::semantic3(Scope
*sc
)
110 Array
*d
= include(sc
, NULL
);
114 for (i
= 0; i
< d
->dim
; i
++)
117 s
= (Dsymbol
*)d
->data
[i
];
123 void AttribDeclaration::inlineScan()
126 Array
*d
= include(NULL
, NULL
);
130 for (i
= 0; i
< d
->dim
; i
++)
133 s
= (Dsymbol
*)d
->data
[i
];
134 //printf("AttribDeclaration::inlineScan %s\n", s->toChars());
140 void AttribDeclaration::addComment(unsigned char *comment
)
145 Array
*d
= include(NULL
, NULL
);
149 for (i
= 0; i
< d
->dim
; i
++)
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.
171 Array
*d
= include(NULL
, NULL
);
175 for (i
= 0; i
< d
->dim
; i
++)
178 s
= (Dsymbol
*)d
->data
[i
];
179 //printf("AttribDeclaration::emitComment %s\n", s->toChars());
185 void AttribDeclaration::toObjFile(int multiobj
)
188 Array
*d
= include(NULL
, NULL
);
192 for (i
= 0; i
< d
->dim
; i
++)
195 s
= (Dsymbol
*)d
->data
[i
];
196 s
->toObjFile(multiobj
);
201 int AttribDeclaration::cvMember(unsigned char *p
)
206 Array
*d
= include(NULL
, NULL
);
210 for (i
= 0; i
< d
->dim
; i
++)
213 s
= (Dsymbol
*)d
->data
[i
];
223 int AttribDeclaration::hasPointers()
225 Array
*d
= include(NULL
, NULL
);
229 for (size_t i
= 0; i
< d
->dim
; i
++)
231 Dsymbol
*s
= (Dsymbol
*)d
->data
[i
];
232 if (s
->hasPointers())
239 char *AttribDeclaration::kind()
244 int AttribDeclaration::oneMember(Dsymbol
**ps
)
246 Array
*d
= include(NULL
, NULL
);
248 return Dsymbol::oneMembers(d
, ps
);
251 void AttribDeclaration::checkCtorConstInit()
254 Array
*d
= include(NULL
, NULL
);
258 for (i
= 0; i
< d
->dim
; i
++)
261 s
= (Dsymbol
*)d
->data
[i
];
262 s
->checkCtorConstInit();
267 /****************************************
270 void AttribDeclaration::addLocalClass(ClassDeclarations
*aclasses
)
272 Array
*d
= include(NULL
, NULL
);
276 for (i
= 0; i
< d
->dim
; i
++)
279 s
= (Dsymbol
*)d
->data
[i
];
280 s
->addLocalClass(aclasses
);
286 void AttribDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
293 for (unsigned i
= 0; i
< decl
->dim
; i
++)
295 Dsymbol
*s
= (Dsymbol
*)decl
->data
[i
];
297 buf
->writestring(" ");
298 s
->toCBuffer(buf
, hgs
);
307 /************************* StorageClassDeclaration ****************************/
309 StorageClassDeclaration::StorageClassDeclaration(unsigned stc
, Array
*decl
)
310 : AttribDeclaration(decl
)
315 Dsymbol
*StorageClassDeclaration::syntaxCopy(Dsymbol
*s
)
317 StorageClassDeclaration
*scd
;
320 scd
= new StorageClassDeclaration(stc
, Dsymbol::arraySyntaxCopy(decl
));
324 void StorageClassDeclaration::semantic(Scope
*sc
)
327 { unsigned stc_save
= sc
->stc
;
329 if (stc
& (STCauto
| STCscope
| STCstatic
| STCextern
))
330 sc
->stc
&= ~(STCauto
| STCscope
| STCstatic
| STCextern
);
332 for (unsigned i
= 0; i
< decl
->dim
; i
++)
334 Dsymbol
*s
= (Dsymbol
*)decl
->data
[i
];
344 void StorageClassDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
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
},
367 for (int i
= 0; i
< sizeof(table
)/sizeof(table
[0]); i
++)
369 if (stc
& table
[i
].stc
)
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);
390 Dsymbol
*LinkDeclaration::syntaxCopy(Dsymbol
*s
)
395 ld
= new LinkDeclaration(linkage
, Dsymbol::arraySyntaxCopy(decl
));
399 void LinkDeclaration::semantic(Scope
*sc
)
401 //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, 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
];
412 sc
->linkage
= linkage_save
;
416 sc
->linkage
= linkage
;
420 void LinkDeclaration::semantic3(Scope
*sc
)
422 //printf("LinkDeclaration::semantic3(linkage = %d, decl = %p)\n", linkage, 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
];
433 sc
->linkage
= linkage_save
;
437 sc
->linkage
= linkage
;
441 void LinkDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
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;
455 buf
->writestring("extern (");
457 buf
->writestring(") ");
458 AttribDeclaration::toCBuffer(buf
, hgs
);
461 char *LinkDeclaration::toChars()
466 /********************************* ProtDeclaration ****************************/
468 ProtDeclaration::ProtDeclaration(enum PROT p
, Array
*decl
)
469 : AttribDeclaration(decl
)
472 //printf("decl = %p\n", decl);
475 Dsymbol
*ProtDeclaration::syntaxCopy(Dsymbol
*s
)
480 pd
= new ProtDeclaration(protection
, Dsymbol::arraySyntaxCopy(decl
));
484 void ProtDeclaration::semantic(Scope
*sc
)
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
];
498 sc
->protection
= protection_save
;
499 sc
->explicitProtection
= explicitProtection_save
;
502 { sc
->protection
= protection
;
503 sc
->explicitProtection
= 1;
507 void ProtDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
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;
522 AttribDeclaration::toCBuffer(buf
, hgs
);
525 /********************************* AlignDeclaration ****************************/
527 AlignDeclaration::AlignDeclaration(unsigned sa
, Array
*decl
)
528 : AttribDeclaration(decl
)
533 Dsymbol
*AlignDeclaration::syntaxCopy(Dsymbol
*s
)
535 AlignDeclaration
*ad
;
538 ad
= new AlignDeclaration(salign
, Dsymbol::arraySyntaxCopy(decl
));
542 void AlignDeclaration::semantic(Scope
*sc
)
544 //printf("\tAlignDeclaration::semantic '%s'\n",toChars());
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
];
555 sc
->structalign
= salign_save
;
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
)
574 this->isunion
= isunion
;
579 Dsymbol
*AnonDeclaration::syntaxCopy(Dsymbol
*s
)
584 ad
= new AnonDeclaration(loc
, isunion
, Dsymbol::arraySyntaxCopy(decl
));
588 void AnonDeclaration::semantic(Scope
*sc
)
590 //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
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");
612 AnonymousAggregateDeclaration aad
;
617 adisunion
= sc
->inunion
;
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);
628 sc
->stc
&= ~(STCauto
| STCscope
| STCstatic
);
629 sc
->inunion
= isunion
;
632 aad
.structalign
= sc
->structalign
;
635 for (unsigned i
= 0; i
< decl
->dim
; i
++)
637 Dsymbol
*s
= (Dsymbol
*)decl
->data
[i
];
649 // If failed due to forward references, unwind and try again later
653 //printf("\tsetting ad->sizeok %p to 2\n", ad);
656 scope
= scx
? scx
: new Scope(*sc
);
658 scope
->module
->addDeferredSemantic(this);
660 //printf("\tforward reference %p\n", this);
664 { Module::dprogress
++;
666 //printf("\tcompleted %p\n", this);
669 ;//printf("\talready completed %p\n", this);
671 // 0 sized structs are set to 1 byte
672 if (aad
.structsize
== 0)
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
;
694 // Add size of aad to ad
697 if (aad
.structsize
> ad
->structsize
)
698 ad
->structsize
= aad
.structsize
;
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");
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
)
745 Dsymbol
*PragmaDeclaration::syntaxCopy(Dsymbol
*s
)
747 PragmaDeclaration
*pd
;
750 pd
= new PragmaDeclaration(loc
, ident
,
751 Expression::arraySyntaxCopy(args
), Dsymbol::arraySyntaxCopy(decl
));
755 void PragmaDeclaration::semantic(Scope
*sc
)
756 { // Should be merged with PragmaStatement
759 //printf("\tPragmaDeclaration::semantic '%s'\n",toChars());
760 if (ident
== Id::msg
)
764 for (size_t i
= 0; i
< args
->dim
; i
++)
766 Expression
*e
= (Expression
*)args
->data
[i
];
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
);
776 error("string expected for message, not '%s'", e
->toChars());
778 fprintf(stdmsg
, "\n");
782 else if (ident
== Id::lib
)
784 if (!args
|| args
->dim
!= 1)
785 error("string expected for library name");
788 Expression
*e
= (Expression
*)args
->data
[0];
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
);
801 printf("library %s\n", name
);
808 else if (ident
== Id::GNU_asm
)
810 if (! args
|| args
->dim
!= 2)
811 error("identifier and string expected for asm name");
815 Declaration
*d
= NULL
;
818 e
= (Expression
*)args
->data
[0];
822 d
= ((VarExp
*)e
)->var
;
823 if (! d
->isFuncDeclaration() && ! d
->isVarDeclaration())
827 error("first argument of GNU_asm must be a function or variable declaration");
829 e
= (Expression
*)args
->data
[1];
831 e
= e
->optimize(WANTvalue
| WANTinterpret
);
832 if (e
->op
== TOKstring
&& ((StringExp
*)e
)->sz
== 1)
833 s
= ((StringExp
*)e
);
835 error("second argument of GNU_asm must be a character string");
838 d
->c_ident
= Lexer::idPool((char*) s
->string
);
842 else if (ident
== Id::GNU_attribute
)
846 // An empty list is allowed.
847 if (args
&& args
->dim
)
852 a
= (Expressions
*) sc
->attributes
->copy();
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
) {
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");
869 for (int unsigned ai
= 0; ai
< c
->arguments
->dim
; ai
++)
871 c
->arguments
->data
[ai
] =
872 ((Expression
*) c
->arguments
->data
[ai
])->semantic(sc
);
877 error("identifier or call expression expected for attribute");
884 else if (ident
== Id::GNU_set_attribute
)
886 if (!args
|| args
->dim
< 1)
887 error("declaration expected for setting attributes");
890 Array p_attributes_list
; // of Expressions**
892 Expression
* e
= (Expression
*) args
->data
[0];
893 Expressions
** pa
= NULL
;
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
;
916 p_attributes_list
.push(pa
);
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
) {
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");
934 for (int unsigned ai
= 0; ai
< c
->arguments
->dim
; ai
++)
936 c
->arguments
->data
[ai
] =
937 ((Expression
*) c
->arguments
->data
[ai
])->semantic(sc
);
942 error("identifier or call expression expected for attribute");
948 for (unsigned i
= 0; i
< p_attributes_list
.dim
; ++i
)
950 Expressions
** pa
= (Expressions
**) p_attributes_list
.data
[i
];
953 *pa
= (Expressions
*) (*pa
)->copy();
954 (*pa
)->append(new_attrs
);
963 else if (global
.params
.ignoreUnsupportedPragmas
)
965 if (global
.params
.verbose
)
967 /* Print unrecognized pragmas
969 printf("pragma %s", ident
->toChars());
972 for (size_t i
= 0; i
< args
->dim
; i
++)
974 Expression
*e
= (Expression
*)args
->data
[i
];
976 e
= e
->optimize(WANTvalue
| WANTinterpret
);
981 printf("%s", e
->toChars());
991 error("unrecognized pragma(%s)", ident
->toChars());
995 for (unsigned i
= 0; i
< decl
->dim
; i
++)
997 Dsymbol
*s
= (Dsymbol
*)decl
->data
[i
];
1005 if (ident
== Id::GNU_attribute
)
1012 error("pragma is missing closing ';'");
1015 int PragmaDeclaration::oneMember(Dsymbol
**ps
)
1021 char *PragmaDeclaration::kind()
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
);
1040 obj_includelib(name
);
1042 AttribDeclaration::toObjFile(multiobj
);
1045 void PragmaDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
1047 buf
->printf("pragma(%s", ident
->toChars());
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
;
1078 dd
= new ConditionalDeclaration(condition
->syntaxCopy(),
1079 Dsymbol::arraySyntaxCopy(decl
),
1080 Dsymbol::arraySyntaxCopy(elsedecl
));
1085 int ConditionalDeclaration::oneMember(Dsymbol
**ps
)
1087 //printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition->inc);
1090 Array
*d
= condition
->include(NULL
, NULL
) ? decl
: elsedecl
;
1091 return Dsymbol::oneMembers(d
, ps
);
1097 void ConditionalDeclaration::emitComment(Scope
*sc
)
1099 //printf("ConditionalDeclaration::emitComment(sc = %p)\n", sc);
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");
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.
1128 for (int j
= 0; j
< 2; j
++)
1132 for (unsigned i
= 0; i
< d
->dim
; i
++)
1135 s
= (Dsymbol
*)d
->data
[i
];
1136 //printf("ConditionalDeclaration::addComment %s\n", s->toChars());
1137 s
->addComment(comment
);
1145 void ConditionalDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
1147 condition
->toCBuffer(buf
, hgs
);
1148 if (decl
|| elsedecl
)
1151 buf
->writeByte('{');
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('}');
1167 buf
->writestring("else");
1169 buf
->writeByte('{');
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('}');
1182 buf
->writeByte(':');
1186 /***************************** StaticIfDeclaration ****************************/
1188 StaticIfDeclaration::StaticIfDeclaration(Condition
*condition
,
1189 Array
*decl
, Array
*elsedecl
)
1190 : ConditionalDeclaration(condition
, decl
, elsedecl
)
1192 //printf("StaticIfDeclaration::StaticIfDeclaration()\n");
1198 Dsymbol
*StaticIfDeclaration::syntaxCopy(Dsymbol
*s
)
1200 StaticIfDeclaration
*dd
;
1203 dd
= new StaticIfDeclaration(condition
->syntaxCopy(),
1204 Dsymbol::arraySyntaxCopy(decl
),
1205 Dsymbol::arraySyntaxCopy(elsedecl
));
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)
1227 { m
= AttribDeclaration::addMember(sc
, sd
, memnum
);
1234 void StaticIfDeclaration::semantic(Scope
*sc
)
1236 Array
*d
= include(sc
, sd
);
1238 //printf("\tStaticIfDeclaration::semantic '%s'\n",toChars());
1242 { AttribDeclaration::addMember(sc
, sd
, 1);
1246 for (unsigned i
= 0; i
< d
->dim
; i
++)
1248 Dsymbol
*s
= (Dsymbol
*)d
->data
[i
];
1255 char *StaticIfDeclaration::kind()
1261 /***************************** CompileDeclaration *****************************/
1263 CompileDeclaration::CompileDeclaration(Loc loc
, Expression
*exp
)
1264 : AttribDeclaration(NULL
)
1270 Dsymbol
*CompileDeclaration::syntaxCopy(Dsymbol
*s
)
1272 //printf("CompileDeclaration::syntaxCopy('%s')\n", toChars());
1273 CompileDeclaration
*sc
= new CompileDeclaration(loc
, exp
->syntaxCopy());
1277 int CompileDeclaration::addMember(Scope
*sc
, ScopeDsymbol
*sd
, int 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());
1293 StringExp
*se
= (StringExp
*)exp
;
1294 se
= se
->toUTF8(sc
);
1295 Parser
p(sc
->module
, (unsigned char *)se
->string
, se
->len
, 0);
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(");");