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 /* These sets of storage classes are mutually exclusive,
330 * so choose the innermost or most recent one.
332 if (stc
& (STCauto
| STCscope
| STCstatic
| STCextern
| STCmanifest
))
333 sc
->stc
&= ~(STCauto
| STCscope
| STCstatic
| STCextern
| STCmanifest
);
334 if (stc
& (STCauto
| STCscope
| STCstatic
| STCtls
| STCmanifest
))
335 sc
->stc
&= ~(STCauto
| STCscope
| STCstatic
| STCtls
| STCmanifest
);
336 if (stc
& (STCconst
| STCinvariant
| STCmanifest
))
337 sc
->stc
&= ~(STCconst
| STCinvariant
| STCmanifest
);
339 for (unsigned i
= 0; i
< decl
->dim
; i
++)
341 Dsymbol
*s
= (Dsymbol
*)decl
->data
[i
];
351 void StorageClassDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
359 static SCstring table
[] =
361 { STCauto
, TOKauto
},
362 { STCscope
, TOKscope
},
363 { STCstatic
, TOKstatic
},
364 { STCextern
, TOKextern
},
365 { STCconst
, TOKconst
},
366 { STCinvariant
, TOKinvariant
},
367 { STCfinal
, TOKfinal
},
368 { STCabstract
, TOKabstract
},
369 { STCsynchronized
, TOKsynchronized
},
370 { STCdeprecated
, TOKdeprecated
},
371 { STCoverride
, TOKoverride
},
372 { STCnothrow
, TOKnothrow
},
373 { STCpure
, TOKpure
},
378 for (int i
= 0; i
< sizeof(table
)/sizeof(table
[0]); i
++)
380 if (stc
& table
[i
].stc
)
385 buf
->writestring(Token::toChars(table
[i
].tok
));
389 AttribDeclaration::toCBuffer(buf
, hgs
);
392 /********************************* LinkDeclaration ****************************/
394 LinkDeclaration::LinkDeclaration(enum LINK p
, Array
*decl
)
395 : AttribDeclaration(decl
)
397 //printf("LinkDeclaration(linkage = %d, decl = %p)\n", p, decl);
401 Dsymbol
*LinkDeclaration::syntaxCopy(Dsymbol
*s
)
406 ld
= new LinkDeclaration(linkage
, Dsymbol::arraySyntaxCopy(decl
));
410 void LinkDeclaration::semantic(Scope
*sc
)
412 //printf("LinkDeclaration::semantic(linkage = %d, decl = %p)\n", linkage, decl);
414 { enum LINK linkage_save
= sc
->linkage
;
416 sc
->linkage
= linkage
;
417 for (unsigned i
= 0; i
< decl
->dim
; i
++)
419 Dsymbol
*s
= (Dsymbol
*)decl
->data
[i
];
423 sc
->linkage
= linkage_save
;
427 sc
->linkage
= linkage
;
431 void LinkDeclaration::semantic3(Scope
*sc
)
433 //printf("LinkDeclaration::semantic3(linkage = %d, decl = %p)\n", linkage, decl);
435 { enum LINK linkage_save
= sc
->linkage
;
437 sc
->linkage
= linkage
;
438 for (unsigned i
= 0; i
< decl
->dim
; i
++)
440 Dsymbol
*s
= (Dsymbol
*)decl
->data
[i
];
444 sc
->linkage
= linkage_save
;
448 sc
->linkage
= linkage
;
452 void LinkDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
457 case LINKd
: p
= "D"; break;
458 case LINKc
: p
= "C"; break;
459 case LINKcpp
: p
= "C++"; break;
460 case LINKwindows
: p
= "Windows"; break;
461 case LINKpascal
: p
= "Pascal"; break;
466 buf
->writestring("extern (");
468 buf
->writestring(") ");
469 AttribDeclaration::toCBuffer(buf
, hgs
);
472 char *LinkDeclaration::toChars()
477 /********************************* ProtDeclaration ****************************/
479 ProtDeclaration::ProtDeclaration(enum PROT p
, Array
*decl
)
480 : AttribDeclaration(decl
)
483 //printf("decl = %p\n", decl);
486 Dsymbol
*ProtDeclaration::syntaxCopy(Dsymbol
*s
)
491 pd
= new ProtDeclaration(protection
, Dsymbol::arraySyntaxCopy(decl
));
495 void ProtDeclaration::semantic(Scope
*sc
)
498 { enum PROT protection_save
= sc
->protection
;
499 int explicitProtection_save
= sc
->explicitProtection
;
501 sc
->protection
= protection
;
502 sc
->explicitProtection
= 1;
503 for (unsigned i
= 0; i
< decl
->dim
; i
++)
505 Dsymbol
*s
= (Dsymbol
*)decl
->data
[i
];
509 sc
->protection
= protection_save
;
510 sc
->explicitProtection
= explicitProtection_save
;
513 { sc
->protection
= protection
;
514 sc
->explicitProtection
= 1;
518 void ProtDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
523 case PROTprivate
: p
= "private"; break;
524 case PROTpackage
: p
= "package"; break;
525 case PROTprotected
: p
= "protected"; break;
526 case PROTpublic
: p
= "public"; break;
527 case PROTexport
: p
= "export"; break;
533 AttribDeclaration::toCBuffer(buf
, hgs
);
536 /********************************* AlignDeclaration ****************************/
538 AlignDeclaration::AlignDeclaration(unsigned sa
, Array
*decl
)
539 : AttribDeclaration(decl
)
544 Dsymbol
*AlignDeclaration::syntaxCopy(Dsymbol
*s
)
546 AlignDeclaration
*ad
;
549 ad
= new AlignDeclaration(salign
, Dsymbol::arraySyntaxCopy(decl
));
553 void AlignDeclaration::semantic(Scope
*sc
)
555 //printf("\tAlignDeclaration::semantic '%s'\n",toChars());
557 { unsigned salign_save
= sc
->structalign
;
559 sc
->structalign
= salign
;
560 for (unsigned i
= 0; i
< decl
->dim
; i
++)
562 Dsymbol
*s
= (Dsymbol
*)decl
->data
[i
];
566 sc
->structalign
= salign_save
;
569 sc
->structalign
= salign
;
573 void AlignDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
575 buf
->printf("align (%d)", salign
);
576 AttribDeclaration::toCBuffer(buf
, hgs
);
579 /********************************* AnonDeclaration ****************************/
581 AnonDeclaration::AnonDeclaration(Loc loc
, int isunion
, Array
*decl
)
582 : AttribDeclaration(decl
)
585 this->isunion
= isunion
;
590 Dsymbol
*AnonDeclaration::syntaxCopy(Dsymbol
*s
)
595 ad
= new AnonDeclaration(loc
, isunion
, Dsymbol::arraySyntaxCopy(decl
));
599 void AnonDeclaration::semantic(Scope
*sc
)
601 //printf("\tAnonDeclaration::semantic %s %p\n", isunion ? "union" : "struct", this);
612 Dsymbol
*parent
= sc
->parent
->pastMixin();
613 AggregateDeclaration
*ad
= parent
->isAggregateDeclaration();
615 if (!ad
|| (!ad
->isStructDeclaration() && !ad
->isClassDeclaration()))
617 error("can only be a part of an aggregate");
623 AnonymousAggregateDeclaration aad
;
628 adisunion
= sc
->inunion
;
631 adisunion
= ad
->isUnionDeclaration() != NULL
;
633 // printf("\tsc->anonAgg = %p\n", sc->anonAgg);
634 // printf("\tad = %p\n", ad);
635 // printf("\taad = %p\n", &aad);
639 sc
->stc
&= ~(STCauto
| STCscope
| STCstatic
| STCtls
);
640 sc
->inunion
= isunion
;
643 aad
.structalign
= sc
->structalign
;
646 for (unsigned i
= 0; i
< decl
->dim
; i
++)
648 Dsymbol
*s
= (Dsymbol
*)decl
->data
[i
];
660 // If failed due to forward references, unwind and try again later
664 //printf("\tsetting ad->sizeok %p to 2\n", ad);
667 scope
= scx
? scx
: new Scope(*sc
);
669 scope
->module
->addDeferredSemantic(this);
671 //printf("\tforward reference %p\n", this);
675 { Module::dprogress
++;
677 //printf("\tcompleted %p\n", this);
680 ;//printf("\talready completed %p\n", this);
682 // 0 sized structs are set to 1 byte
683 if (aad
.structsize
== 0)
689 // Align size of anonymous aggregate
690 //printf("aad.structalign = %d, aad.alignsize = %d, sc->offset = %d\n", aad.structalign, aad.alignsize, sc->offset);
691 ad
->alignmember(aad
.structalign
, aad
.alignsize
, &sc
->offset
);
692 //ad->structsize = sc->offset;
693 //printf("sc->offset = %d\n", sc->offset);
695 // Add members of aad to ad
696 //printf("\tadding members of aad to '%s'\n", ad->toChars());
697 for (unsigned i
= 0; i
< aad
.fields
.dim
; i
++)
699 VarDeclaration
*v
= (VarDeclaration
*)aad
.fields
.data
[i
];
701 v
->offset
+= sc
->offset
;
705 // Add size of aad to ad
708 if (aad
.structsize
> ad
->structsize
)
709 ad
->structsize
= aad
.structsize
;
714 ad
->structsize
= sc
->offset
+ aad
.structsize
;
715 sc
->offset
= ad
->structsize
;
718 if (ad
->alignsize
< aad
.alignsize
)
719 ad
->alignsize
= aad
.alignsize
;
724 void AnonDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
726 buf
->printf(isunion
? "union" : "struct");
727 buf
->writestring("\n{\n");
730 for (unsigned i
= 0; i
< decl
->dim
; i
++)
732 Dsymbol
*s
= (Dsymbol
*)decl
->data
[i
];
734 //buf->writestring(" ");
735 s
->toCBuffer(buf
, hgs
);
738 buf
->writestring("}\n");
741 char *AnonDeclaration::kind()
743 return (char *)(isunion
? "anonymous union" : "anonymous struct");
746 /********************************* PragmaDeclaration ****************************/
748 PragmaDeclaration::PragmaDeclaration(Loc loc
, Identifier
*ident
, Expressions
*args
, Array
*decl
)
749 : AttribDeclaration(decl
)
756 Dsymbol
*PragmaDeclaration::syntaxCopy(Dsymbol
*s
)
758 PragmaDeclaration
*pd
;
761 pd
= new PragmaDeclaration(loc
, ident
,
762 Expression::arraySyntaxCopy(args
), Dsymbol::arraySyntaxCopy(decl
));
766 void PragmaDeclaration::semantic(Scope
*sc
)
767 { // Should be merged with PragmaStatement
770 //printf("\tPragmaDeclaration::semantic '%s'\n",toChars());
771 if (ident
== Id::msg
)
775 for (size_t i
= 0; i
< args
->dim
; i
++)
777 Expression
*e
= (Expression
*)args
->data
[i
];
780 e
= e
->optimize(WANTvalue
| WANTinterpret
);
781 if (e
->op
== TOKstring
)
783 StringExp
*se
= (StringExp
*)e
;
784 fprintf(stdmsg
, "%.*s", (int)se
->len
, se
->string
);
787 error("string expected for message, not '%s'", e
->toChars());
789 fprintf(stdmsg
, "\n");
793 else if (ident
== Id::lib
)
795 if (!args
|| args
->dim
!= 1)
796 error("string expected for library name");
799 Expression
*e
= (Expression
*)args
->data
[0];
802 e
= e
->optimize(WANTvalue
| WANTinterpret
);
803 args
->data
[0] = (void *)e
;
804 if (e
->op
!= TOKstring
)
805 error("string expected for library name, not '%s'", e
->toChars());
806 else if (global
.params
.verbose
)
808 StringExp
*se
= (StringExp
*)e
;
809 char *name
= (char *)mem
.malloc(se
->len
+ 1);
810 memcpy(name
, se
->string
, se
->len
);
812 printf("library %s\n", name
);
819 else if (ident
== Id::GNU_asm
)
821 if (! args
|| args
->dim
!= 2)
822 error("identifier and string expected for asm name");
826 Declaration
*d
= NULL
;
829 e
= (Expression
*)args
->data
[0];
833 d
= ((VarExp
*)e
)->var
;
834 if (! d
->isFuncDeclaration() && ! d
->isVarDeclaration())
838 error("first argument of GNU_asm must be a function or variable declaration");
840 e
= (Expression
*)args
->data
[1];
842 e
= e
->optimize(WANTvalue
| WANTinterpret
);
843 if (e
->op
== TOKstring
&& ((StringExp
*)e
)->sz
== 1)
844 s
= ((StringExp
*)e
);
846 error("second argument of GNU_asm must be a character string");
849 d
->c_ident
= Lexer::idPool((char*) s
->string
);
853 else if (ident
== Id::GNU_attribute
)
857 // An empty list is allowed.
858 if (args
&& args
->dim
)
863 a
= (Expressions
*) sc
->attributes
->copy();
868 for (unsigned i
= 0; i
< args
->dim
; i
++)
870 Expression
* e
= (Expression
*) args
->data
[i
];
871 //e = e->semantic(sc);
873 if (e
->op
== TOKidentifier
) {
875 } else if (e
->op
== TOKcall
) {
876 CallExp
* c
= (CallExp
*) e
;
877 if (c
->e1
->op
!= TOKidentifier
)
878 error("identifier or call expression expected for attribute");
880 for (int unsigned ai
= 0; ai
< c
->arguments
->dim
; ai
++)
882 c
->arguments
->data
[ai
] =
883 ((Expression
*) c
->arguments
->data
[ai
])->semantic(sc
);
888 error("identifier or call expression expected for attribute");
895 else if (ident
== Id::GNU_set_attribute
)
897 if (!args
|| args
->dim
< 1)
898 error("declaration expected for setting attributes");
901 Array p_attributes_list
; // of Expressions**
903 Expression
* e
= (Expression
*) args
->data
[0];
904 Expressions
** pa
= NULL
;
909 Declaration
* d
= ((VarExp
*)e
)->var
;
910 if (d
->isFuncDeclaration() || d
->isVarDeclaration())
911 pa
= & d
->attributes
;
913 else if (e
->op
== TOKtype
)
915 Type
* t
= ((TypeExp
*)e
)->type
;
916 if (t
->ty
== Ttypedef
)
917 pa
= & ((TypeTypedef
*) t
)->sym
->attributes
;
918 else if (t
->ty
== Tenum
)
919 pa
= & ((TypeEnum
*) t
)->sym
->attributes
;
920 else if (t
->ty
== Tstruct
)
921 pa
= & ((TypeStruct
*) t
)->sym
->attributes
;
922 else if (t
->ty
== Tclass
)
923 pa
= & ((TypeClass
*) t
)->sym
->attributes
;
927 p_attributes_list
.push(pa
);
929 error("first argument must be a function, variable, or type declaration");
932 Expressions
* new_attrs
= new Expressions
;
933 for (unsigned i
= 1; i
< args
->dim
; i
++)
935 Expression
* e
= (Expression
*) args
->data
[i
];
936 //e = e->semantic(sc);
938 if (e
->op
== TOKidentifier
) {
940 } else if (e
->op
== TOKcall
) {
941 CallExp
* c
= (CallExp
*) e
;
942 if (c
->e1
->op
!= TOKidentifier
)
943 error("identifier or call expression expected for attribute");
945 for (int unsigned ai
= 0; ai
< c
->arguments
->dim
; ai
++)
947 c
->arguments
->data
[ai
] =
948 ((Expression
*) c
->arguments
->data
[ai
])->semantic(sc
);
953 error("identifier or call expression expected for attribute");
959 for (unsigned i
= 0; i
< p_attributes_list
.dim
; ++i
)
961 Expressions
** pa
= (Expressions
**) p_attributes_list
.data
[i
];
964 *pa
= (Expressions
*) (*pa
)->copy();
965 (*pa
)->append(new_attrs
);
974 else if (ident
== Id::startaddress
)
976 if (!args
|| args
->dim
!= 1)
977 error("function name expected for start address");
980 Expression
*e
= (Expression
*)args
->data
[0];
982 e
= e
->optimize(WANTvalue
| WANTinterpret
);
983 args
->data
[0] = (void *)e
;
984 Dsymbol
*sa
= getDsymbol(e
);
985 if (!sa
|| !sa
->isFuncDeclaration())
986 error("function name expected for start address, not '%s'", e
->toChars());
990 else if (global
.params
.ignoreUnsupportedPragmas
)
992 if (global
.params
.verbose
)
994 /* Print unrecognized pragmas
996 printf("pragma %s", ident
->toChars());
999 for (size_t i
= 0; i
< args
->dim
; i
++)
1001 Expression
*e
= (Expression
*)args
->data
[i
];
1002 e
= e
->semantic(sc
);
1003 e
= e
->optimize(WANTvalue
| WANTinterpret
);
1008 printf("%s", e
->toChars());
1018 error("unrecognized pragma(%s)", ident
->toChars());
1022 for (unsigned i
= 0; i
< decl
->dim
; i
++)
1024 Dsymbol
*s
= (Dsymbol
*)decl
->data
[i
];
1032 if (ident
== Id::GNU_attribute
)
1039 error("pragma is missing closing ';'");
1042 int PragmaDeclaration::oneMember(Dsymbol
**ps
)
1048 char *PragmaDeclaration::kind()
1053 void PragmaDeclaration::toObjFile(int multiobj
)
1055 if (ident
== Id::lib
)
1057 assert(args
&& args
->dim
== 1);
1059 Expression
*e
= (Expression
*)args
->data
[0];
1061 assert(e
->op
== TOKstring
);
1063 StringExp
*se
= (StringExp
*)e
;
1064 char *name
= (char *)mem
.malloc(se
->len
+ 1);
1065 memcpy(name
, se
->string
, se
->len
);
1067 obj_includelib(name
);
1069 else if (ident
== Id::startaddress
)
1071 assert(args
&& args
->dim
== 1);
1072 Expression
*e
= (Expression
*)args
->data
[0];
1073 Dsymbol
*sa
= getDsymbol(e
);
1074 FuncDeclaration
*f
= sa
->isFuncDeclaration();
1076 Symbol
*s
= f
->toSymbol();
1077 obj_startaddress(s
);
1079 AttribDeclaration::toObjFile(multiobj
);
1082 void PragmaDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
1084 buf
->printf("pragma (%s", ident
->toChars());
1085 if (args
&& args
->dim
)
1087 buf
->writestring(", ");
1088 argsToCBuffer(buf
, args
, hgs
);
1090 buf
->writeByte(')');
1091 AttribDeclaration::toCBuffer(buf
, hgs
);
1095 /********************************* ConditionalDeclaration ****************************/
1097 ConditionalDeclaration::ConditionalDeclaration(Condition
*condition
, Array
*decl
, Array
*elsedecl
)
1098 : AttribDeclaration(decl
)
1100 //printf("ConditionalDeclaration::ConditionalDeclaration()\n");
1101 this->condition
= condition
;
1102 this->elsedecl
= elsedecl
;
1105 Dsymbol
*ConditionalDeclaration::syntaxCopy(Dsymbol
*s
)
1107 ConditionalDeclaration
*dd
;
1110 dd
= new ConditionalDeclaration(condition
->syntaxCopy(),
1111 Dsymbol::arraySyntaxCopy(decl
),
1112 Dsymbol::arraySyntaxCopy(elsedecl
));
1117 int ConditionalDeclaration::oneMember(Dsymbol
**ps
)
1119 //printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition->inc);
1122 Array
*d
= condition
->include(NULL
, NULL
) ? decl
: elsedecl
;
1123 return Dsymbol::oneMembers(d
, ps
);
1129 void ConditionalDeclaration::emitComment(Scope
*sc
)
1131 //printf("ConditionalDeclaration::emitComment(sc = %p)\n", sc);
1134 AttribDeclaration::emitComment(sc
);
1138 // Decide if 'then' or 'else' code should be included
1140 Array
*ConditionalDeclaration::include(Scope
*sc
, ScopeDsymbol
*sd
)
1142 //printf("ConditionalDeclaration::include()\n");
1144 return condition
->include(sc
, sd
) ? decl
: elsedecl
;
1148 void ConditionalDeclaration::addComment(unsigned char *comment
)
1150 /* Because addComment is called by the parser, if we called
1151 * include() it would define a version before it was used.
1152 * But it's no problem to drill down to both decl and elsedecl,
1153 * so that's the workaround.
1160 for (int j
= 0; j
< 2; j
++)
1164 for (unsigned i
= 0; i
< d
->dim
; i
++)
1167 s
= (Dsymbol
*)d
->data
[i
];
1168 //printf("ConditionalDeclaration::addComment %s\n", s->toChars());
1169 s
->addComment(comment
);
1177 void ConditionalDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
1179 condition
->toCBuffer(buf
, hgs
);
1180 if (decl
|| elsedecl
)
1183 buf
->writeByte('{');
1187 for (unsigned i
= 0; i
< decl
->dim
; i
++)
1189 Dsymbol
*s
= (Dsymbol
*)decl
->data
[i
];
1191 buf
->writestring(" ");
1192 s
->toCBuffer(buf
, hgs
);
1195 buf
->writeByte('}');
1199 buf
->writestring("else");
1201 buf
->writeByte('{');
1203 for (unsigned i
= 0; i
< elsedecl
->dim
; i
++)
1205 Dsymbol
*s
= (Dsymbol
*)elsedecl
->data
[i
];
1207 buf
->writestring(" ");
1208 s
->toCBuffer(buf
, hgs
);
1210 buf
->writeByte('}');
1214 buf
->writeByte(':');
1218 /***************************** StaticIfDeclaration ****************************/
1220 StaticIfDeclaration::StaticIfDeclaration(Condition
*condition
,
1221 Array
*decl
, Array
*elsedecl
)
1222 : ConditionalDeclaration(condition
, decl
, elsedecl
)
1224 //printf("StaticIfDeclaration::StaticIfDeclaration()\n");
1230 Dsymbol
*StaticIfDeclaration::syntaxCopy(Dsymbol
*s
)
1232 StaticIfDeclaration
*dd
;
1235 dd
= new StaticIfDeclaration(condition
->syntaxCopy(),
1236 Dsymbol::arraySyntaxCopy(decl
),
1237 Dsymbol::arraySyntaxCopy(elsedecl
));
1242 int StaticIfDeclaration::addMember(Scope
*sc
, ScopeDsymbol
*sd
, int memnum
)
1244 /* This is deferred until semantic(), so that
1245 * expressions in the condition can refer to declarations
1246 * in the same scope, such as:
1248 * template Foo(int i)
1250 * const int j = i + 1;
1251 * static if (j == 3)
1259 { m
= AttribDeclaration::addMember(sc
, sd
, memnum
);
1266 void StaticIfDeclaration::semantic(Scope
*sc
)
1268 Array
*d
= include(sc
, sd
);
1270 //printf("\tStaticIfDeclaration::semantic '%s'\n",toChars());
1274 { AttribDeclaration::addMember(sc
, sd
, 1);
1278 for (unsigned i
= 0; i
< d
->dim
; i
++)
1280 Dsymbol
*s
= (Dsymbol
*)d
->data
[i
];
1287 char *StaticIfDeclaration::kind()
1293 /***************************** CompileDeclaration *****************************/
1295 CompileDeclaration::CompileDeclaration(Loc loc
, Expression
*exp
)
1296 : AttribDeclaration(NULL
)
1302 Dsymbol
*CompileDeclaration::syntaxCopy(Dsymbol
*s
)
1304 //printf("CompileDeclaration::syntaxCopy('%s')\n", toChars());
1305 CompileDeclaration
*sc
= new CompileDeclaration(loc
, exp
->syntaxCopy());
1309 int CompileDeclaration::addMember(Scope
*sc
, ScopeDsymbol
*sd
, int memnum
)
1315 void CompileDeclaration::semantic(Scope
*sc
)
1317 //printf("CompileDeclaration::semantic()\n");
1318 exp
= exp
->semantic(sc
);
1319 exp
= resolveProperties(sc
, exp
);
1320 exp
= exp
->optimize(WANTvalue
| WANTinterpret
);
1321 if (exp
->op
!= TOKstring
)
1322 { error("argument to mixin must be a string, not (%s)", exp
->toChars());
1325 StringExp
*se
= (StringExp
*)exp
;
1326 se
= se
->toUTF8(sc
);
1327 Parser
p(sc
->module
, (unsigned char *)se
->string
, se
->len
, 0);
1330 decl
= p
.parseDeclDefs(0);
1331 if (p
.token
.value
!= TOKeof
)
1333 error("incomplete mixin declaration (%s)", se
->toChars());
1336 AttribDeclaration::addMember(sc
, sd
, 0);
1337 AttribDeclaration::semantic(sc
);
1340 void CompileDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
1342 buf
->writestring("mixin(");
1343 exp
->toCBuffer(buf
, hgs
);
1344 buf
->writestring(");");