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
21 #include "declaration.h"
26 #include "aggregate.h"
29 #include "expression.h"
32 /********************************* Declaration ****************************/
34 Declaration::Declaration(Identifier
*id
)
39 storage_class
= STCundefined
;
40 protection
= PROTundefined
;
41 linkage
= LINKdefault
;
45 void Declaration::semantic(Scope
*sc
)
49 char *Declaration::kind()
54 target_size_t
Declaration::size(Loc loc
)
60 int Declaration::isStaticConstructor()
65 int Declaration::isStaticDestructor()
70 int Declaration::isDelete()
75 int Declaration::isDataseg()
80 int Declaration::isCodeseg()
85 enum PROT
Declaration::prot()
90 /*************************************
91 * Check to see if declaration can be modified in this context (sc).
95 void Declaration::checkModify(Loc loc
, Scope
*sc
, Type
*t
)
97 if (sc
->incontract
&& isParameter())
98 error(loc
, "cannot modify parameter '%s' in contract", toChars());
101 { // It's only modifiable if inside the right constructor
102 Dsymbol
*s
= sc
->func
;
105 FuncDeclaration
*fd
= NULL
;
107 fd
= s
->isFuncDeclaration();
109 ((fd
->isCtorDeclaration() && storage_class
& STCfield
) ||
110 (fd
->isStaticCtorDeclaration() && !(storage_class
& STCfield
))) &&
111 fd
->toParent() == toParent()
114 VarDeclaration
*v
= isVarDeclaration();
117 //printf("setting ctorinit\n");
122 { s
= s
->toParent2();
127 const char *p
= isStatic() ? "static " : "";
128 error(loc
, "can only initialize %sconst %s inside %sconstructor",
137 VarDeclaration
*v
= isVarDeclaration();
138 if (v
&& v
->canassign
== 0)
143 else if (isInvariant())
145 else if (storage_class
& STCmanifest
)
146 p
= "manifest constant";
147 else if (!t
->isAssignable())
148 p
= "struct with immutable members";
150 { error(loc
, "cannot modify %s", p
);
158 /********************************* TupleDeclaration ****************************/
160 TupleDeclaration::TupleDeclaration(Loc loc
, Identifier
*id
, Objects
*objects
)
164 this->objects
= objects
;
166 this->tupletype
= NULL
;
169 Dsymbol
*TupleDeclaration::syntaxCopy(Dsymbol
*s
)
175 char *TupleDeclaration::kind()
180 Type
*TupleDeclaration::getType()
182 /* If this tuple represents a type, return that type
185 //printf("TupleDeclaration::getType() %s\n", toChars());
190 /* It's only a type tuple if all the Object's are types
192 for (size_t i
= 0; i
< objects
->dim
; i
++)
193 { Object
*o
= (Object
*)objects
->data
[i
];
195 if (o
->dyncast() != DYNCAST_TYPE
)
197 //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast());
202 /* We know it's a type tuple, so build the TypeTuple
204 Arguments
*args
= new Arguments();
205 args
->setDim(objects
->dim
);
207 for (size_t i
= 0; i
< objects
->dim
; i
++)
208 { Type
*t
= (Type
*)objects
->data
[i
];
210 //printf("type = %s\n", t->toChars());
212 buf
.printf("_%s_%d", ident
->toChars(), i
);
213 char *name
= (char *)buf
.extractData();
214 Identifier
*id
= new Identifier(name
, TOKidentifier
);
215 Argument
*arg
= new Argument(STCin
, t
, id
, NULL
);
217 Argument
*arg
= new Argument(0, t
, NULL
, NULL
);
219 args
->data
[i
] = (void *)arg
;
222 tupletype
= new TypeTuple(args
);
228 int TupleDeclaration::needThis()
230 //printf("TupleDeclaration::needThis(%s)\n", toChars());
231 for (size_t i
= 0; i
< objects
->dim
; i
++)
232 { Object
*o
= (Object
*)objects
->data
[i
];
233 if (o
->dyncast() == DYNCAST_EXPRESSION
)
234 { Expression
*e
= (Expression
*)o
;
235 if (e
->op
== TOKdsymbol
)
236 { DsymbolExp
*ve
= (DsymbolExp
*)e
;
237 Declaration
*d
= ve
->s
->isDeclaration();
238 if (d
&& d
->needThis())
248 /********************************* TypedefDeclaration ****************************/
250 TypedefDeclaration::TypedefDeclaration(Loc loc
, Identifier
*id
, Type
*basetype
, Initializer
*init
)
253 this->type
= new TypeTypedef(this);
254 this->basetype
= basetype
->toBasetype();
258 this->hbasetype
= NULL
;
266 Dsymbol
*TypedefDeclaration::syntaxCopy(Dsymbol
*s
)
268 Type
*basetype
= this->basetype
->syntaxCopy();
270 Initializer
*init
= NULL
;
272 init
= this->init
->syntaxCopy();
275 TypedefDeclaration
*st
;
276 st
= new TypedefDeclaration(loc
, ident
, basetype
, init
);
278 // Syntax copy for header file
279 if (!htype
) // Don't overwrite original
280 { if (type
) // Make copy for both old and new instances
281 { htype
= type
->syntaxCopy();
282 st
->htype
= type
->syntaxCopy();
285 else // Make copy of original for new instance
286 st
->htype
= htype
->syntaxCopy();
289 { hbasetype
= basetype
->syntaxCopy();
290 st
->hbasetype
= basetype
->syntaxCopy();
294 st
->hbasetype
= hbasetype
->syntaxCopy();
299 void TypedefDeclaration::semantic(Scope
*sc
)
301 //printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem);
304 basetype
= basetype
->semantic(loc
, sc
);
306 type
= type
->semantic(loc
, sc
);
308 attributes
->append(sc
->attributes
);
310 attributes
= sc
->attributes
;
311 if (sc
->parent
->isFuncDeclaration() && init
)
316 error("circular definition");
320 void TypedefDeclaration::semantic2(Scope
*sc
)
322 //printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem);
327 init
= init
->semantic(sc
, basetype
);
329 ExpInitializer
*ie
= init
->isExpInitializer();
332 if (ie
->exp
->type
== basetype
)
333 ie
->exp
->type
= type
;
339 char *TypedefDeclaration::kind()
344 Type
*TypedefDeclaration::getType()
349 void TypedefDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
351 buf
->writestring("typedef ");
352 basetype
->toCBuffer(buf
, ident
, hgs
);
355 buf
->writestring(" = ");
356 init
->toCBuffer(buf
, hgs
);
362 /********************************* AliasDeclaration ****************************/
364 AliasDeclaration::AliasDeclaration(Loc loc
, Identifier
*id
, Type
*type
)
367 //printf("AliasDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
368 //printf("type = '%s'\n", type->toChars());
371 this->aliassym
= NULL
;
374 this->haliassym
= NULL
;
376 this->overnext
= NULL
;
377 this->inSemantic
= 0;
381 AliasDeclaration::AliasDeclaration(Loc loc
, Identifier
*id
, Dsymbol
*s
)
384 //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s);
391 this->haliassym
= NULL
;
393 this->overnext
= NULL
;
394 this->inSemantic
= 0;
398 Dsymbol
*AliasDeclaration::syntaxCopy(Dsymbol
*s
)
400 //printf("AliasDeclaration::syntaxCopy()\n");
402 AliasDeclaration
*sa
;
404 sa
= new AliasDeclaration(loc
, ident
, type
->syntaxCopy());
406 sa
= new AliasDeclaration(loc
, ident
, aliassym
->syntaxCopy(NULL
));
408 // Syntax copy for header file
409 if (!htype
) // Don't overwrite original
410 { if (type
) // Make copy for both old and new instances
411 { htype
= type
->syntaxCopy();
412 sa
->htype
= type
->syntaxCopy();
415 else // Make copy of original for new instance
416 sa
->htype
= htype
->syntaxCopy();
419 { haliassym
= aliassym
->syntaxCopy(s
);
420 sa
->haliassym
= aliassym
->syntaxCopy(s
);
424 sa
->haliassym
= haliassym
->syntaxCopy(s
);
429 void AliasDeclaration::semantic(Scope
*sc
)
431 //printf("AliasDeclaration::semantic() %s\n", toChars());
434 if (aliassym
->isTemplateInstance())
435 aliassym
->semantic(sc
);
438 this->inSemantic
= 1;
440 if (storage_class
& STCconst
)
441 error("cannot be const");
443 storage_class
|= sc
->stc
& STCdeprecated
;
446 // alias foo.bar.abc def;
447 // it is not knowable from the syntax whether this is an alias
448 // for a type or an alias for a symbol. It is up to the semantic()
449 // pass to distinguish.
450 // If it is a type, then type is set and getType() will return that
451 // type. If it is a symbol, then aliassym is set and type is NULL -
452 // toAlias() will return aliasssym.
458 /* This section is needed because resolve() will:
461 * try to alias y to 3.
463 s
= type
->toDsymbol(sc
);
464 if (s
&& ((s
->getType() && type
->equals(s
->getType())) || s
->isEnumMember()))
465 goto L2
; // it's a symbolic alias
467 //printf("alias type is %s\n", type->toChars());
468 type
->resolve(loc
, sc
, &e
, &t
, &s
);
475 // Try to convert Expression to Dsymbol
480 error("cannot alias an expression %s", e
->toChars());
486 ScopeDsymbol::multiplyDefined(0, this, overnext
);
487 this->inSemantic
= 0;
491 //printf("alias is a symbol %s %s\n", s->kind(), s->toChars());
493 VarDeclaration
*v
= s
->isVarDeclaration();
494 if (v
&& v
->linkage
== LINKdefault
)
496 error("forward reference of %s", v
->toChars());
501 FuncDeclaration
*f
= s
->toAlias()->isFuncDeclaration();
506 FuncAliasDeclaration
*fa
= new FuncAliasDeclaration(f
);
507 if (!fa
->overloadInsert(overnext
))
508 ScopeDsymbol::multiplyDefined(0, f
, overnext
);
511 s
->parent
= sc
->parent
;
515 ScopeDsymbol::multiplyDefined(0, s
, overnext
);
518 assert(global
.errors
);
523 this->inSemantic
= 0;
526 int AliasDeclaration::overloadInsert(Dsymbol
*s
)
528 /* Don't know yet what the aliased symbol is, so assume it can
529 * be overloaded and check later for correctness.
532 //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars());
533 if (overnext
== NULL
)
539 return overnext
->overloadInsert(s
);
543 char *AliasDeclaration::kind()
548 Type
*AliasDeclaration::getType()
553 Dsymbol
*AliasDeclaration::toAlias()
555 //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : "");
556 assert(this != aliassym
);
557 //static int count; if (++count == 10) *(char*)0=0;
559 { error("recursive alias declaration");
562 Dsymbol
*s
= aliassym
? aliassym
->toAlias() : this;
566 void AliasDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
568 buf
->writestring("alias ");
574 haliassym
->toCBuffer(buf
, hgs
);
576 buf
->writestring(ident
->toChars());
579 htype
->toCBuffer(buf
, ident
, hgs
);
586 aliassym
->toCBuffer(buf
, hgs
);
588 buf
->writestring(ident
->toChars());
591 type
->toCBuffer(buf
, ident
, hgs
);
597 /********************************* VarDeclaration ****************************/
599 VarDeclaration::VarDeclaration(Loc loc
, Type
*type
, Identifier
*id
, Initializer
*init
)
602 //printf("VarDeclaration('%s')\n", id->toChars());
605 { printf("VarDeclaration('%s')\n", id
->toChars());
609 assert(type
|| init
);
619 requirePointerInit
= 0;
630 Dsymbol
*VarDeclaration::syntaxCopy(Dsymbol
*s
)
632 //printf("VarDeclaration::syntaxCopy(%s)\n", toChars());
636 { sv
= (VarDeclaration
*)s
;
640 Initializer
*init
= NULL
;
642 { init
= this->init
->syntaxCopy();
643 //init->isExpInitializer()->exp->print();
644 //init->isExpInitializer()->exp->dump(0);
647 sv
= new VarDeclaration(loc
, type
? type
->syntaxCopy() : NULL
, ident
, init
);
648 sv
->storage_class
= storage_class
;
650 sv
->requirePointerInit
= requirePointerInit
;
652 // Syntax copy for header file
653 if (!htype
) // Don't overwrite original
654 { if (type
) // Make copy for both old and new instances
655 { htype
= type
->syntaxCopy();
656 sv
->htype
= type
->syntaxCopy();
659 else // Make copy of original for new instance
660 sv
->htype
= htype
->syntaxCopy();
663 { hinit
= init
->syntaxCopy();
664 sv
->hinit
= init
->syntaxCopy();
668 sv
->hinit
= hinit
->syntaxCopy();
673 void VarDeclaration::semantic(Scope
*sc
)
675 //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars());
676 //printf(" type = %s\n", type ? type->toChars() : "null");
677 //printf(" stc = x%x\n", sc->stc);
678 //printf(" storage_class = x%x\n", storage_class);
679 //printf("linkage = %d\n", sc->linkage);
680 //if (strcmp(toChars(), "mul") == 0) halt();
682 storage_class
|= sc
->stc
;
683 if (storage_class
& STCextern
&& init
)
684 error("extern symbols cannot have initializers");
686 if (dltNormalMode
&& (storage_class
& STCstatic
))
687 error("no static variables in Delight");
689 /* If auto type inference, do the inference
694 type
= init
->inferType(sc
);
698 /* This is a kludge to support the existing syntax for RAII
701 storage_class
&= ~STCauto
;
707 type
= type
->semantic(loc
, sc
);
709 //printf(" semantic type = %s\n", type ? type->toChars() : "null");
711 type
->checkDeprecated(loc
, sc
);
712 linkage
= sc
->linkage
;
713 this->parent
= sc
->parent
;
714 //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
715 protection
= sc
->protection
;
717 attributes
->append(sc
->attributes
);
719 attributes
= sc
->attributes
;
720 //printf("sc->stc = %x\n", sc->stc);
721 //printf("storage_class = x%x\n", storage_class);
723 Dsymbol
*parent
= toParent();
724 FuncDeclaration
*fd
= parent
->isFuncDeclaration();
726 Type
*tb
= type
->toBasetype();
727 if (tb
->ty
== Tvoid
&& !(storage_class
& STClazy
))
728 { error("voids have no value");
732 if (tb
->ty
== Tfunction
)
733 { error("cannot be declared to be a function");
737 if (tb
->ty
== Tstruct
)
738 { TypeStruct
*ts
= (TypeStruct
*)tb
;
740 if (!ts
->sym
->members
)
742 error("no definition of struct %s", ts
->toChars());
746 if (tb
->ty
== Ttuple
)
747 { /* Instead, declare variables for each of the tuple elements
750 TypeTuple
*tt
= (TypeTuple
*)tb
;
751 size_t nelems
= Argument::dim(tt
->arguments
);
752 Objects
*exps
= new Objects();
753 exps
->setDim(nelems
);
754 Expression
*ie
= init
? init
->toExpression() : NULL
;
756 for (size_t i
= 0; i
< nelems
; i
++)
757 { Argument
*arg
= Argument::getNth(tt
->arguments
, i
);
760 buf
.printf("_%s_field_%"PRIuSIZE
, ident
->toChars(), i
);
762 char *name
= (char *)buf
.extractData();
763 Identifier
*id
= new Identifier(name
, TOKidentifier
);
765 Expression
*einit
= ie
;
766 if (ie
&& ie
->op
== TOKtuple
)
767 { einit
= (Expression
*)((TupleExp
*)ie
)->exps
->data
[i
];
769 Initializer
*ti
= init
;
771 { ti
= new ExpInitializer(einit
->loc
, einit
);
774 VarDeclaration
*v
= new VarDeclaration(loc
, arg
->type
, id
, ti
);
775 //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
779 { //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars());
780 if (sc
->scopesym
->members
)
781 sc
->scopesym
->members
->push(v
);
784 Expression
*e
= new DsymbolExp(loc
, v
);
787 TupleDeclaration
*v2
= new TupleDeclaration(loc
, ident
, exps
);
794 if (storage_class
& STCinvariant
)
796 type
= type
->invariantOf();
798 else if (storage_class
& (STCconst
| STCin
))
800 if (!type
->isInvariant())
801 type
= type
->constOf();
803 else if (type
->isConst())
804 storage_class
|= STCconst
;
805 else if (type
->isInvariant())
806 storage_class
|= STCinvariant
;
808 if (isSynchronized())
810 error("variable %s cannot be synchronized", toChars());
812 else if (isOverride())
814 error("override cannot be applied to variable");
816 else if (isAbstract())
818 error("abstract cannot be applied to variable");
820 else if (storage_class
& STCfinal
)
822 error("final cannot be applied to variable");
825 if (storage_class
& (STCstatic
| STCextern
| STCmanifest
| STCtemplateparameter
| STCtls
))
830 AggregateDeclaration
*aad
= sc
->anonAgg
;
832 aad
= parent
->isAggregateDeclaration();
834 { assert(!(storage_class
& (STCextern
| STCstatic
| STCtls
)));
836 if (storage_class
& (STCconst
| STCinvariant
) && init
)
838 if (!type
->toBasetype()->isTypeBasic())
839 storage_class
|= STCstatic
;
842 aad
->addField(sc
, this);
845 InterfaceDeclaration
*id
= parent
->isInterfaceDeclaration();
848 error("field not allowed in interface");
851 /* Templates cannot add fields to aggregates
853 TemplateInstance
*ti
= parent
->isTemplateInstance();
856 // Take care of nested templates
859 TemplateInstance
*ti2
= ti
->tempdecl
->parent
->isTemplateInstance();
865 // If it's a member template
866 AggregateDeclaration
*ad
= ti
->tempdecl
->isMember();
867 if (ad
&& storage_class
!= STCundefined
)
869 error("cannot use template to add field to aggregate '%s'", ad
->toChars());
874 if (type
->isauto() && !noauto
)
876 if (storage_class
& (STCfield
| STCout
| STCref
| STCstatic
| STCmanifest
| STCtls
) || !fd
)
878 error("globals, statics, fields, manifest constants, ref and out parameters cannot be auto");
881 if (!(storage_class
& (STCauto
| STCscope
)))
883 if (!(storage_class
& STCparameter
) && ident
!= Id::withSym
)
884 error("reference to scope class must be scope");
888 if ((isConst() || isInvariant()) && !init
&& !fd
)
889 { // Initialize by constructor only
890 storage_class
|= STCctorinit
;
894 storage_class
|= STCinit
; // remember we had an explicit initializer
895 else if (storage_class
& STCmanifest
)
896 error("manifest constants must have initializers");
898 enum TOK op
= TOKconstruct
;
899 if (!init
&& !sc
->inunion
&& !isStatic() && fd
&&
900 (!(storage_class
& (STCfield
| STCin
| STCforeach
| STCparameter
)) || (storage_class
& STCout
)) &&
903 // Provide a default initializer
904 //printf("Providing default initializer for '%s'\n", toChars());
905 if (type
->ty
== Tstruct
&&
906 ((TypeStruct
*)type
)->sym
->zeroInit
== 1)
907 { /* If a struct is all zeros, as a special case
908 * set it's initializer to the integer 0.
909 * In AssignExp::toElem(), we check for this and issue
910 * a memset() to initialize the struct.
911 * Must do same check in interpreter.
913 Expression
*e
= new IntegerExp(loc
, 0, Type::tint32
);
915 e1
= new VarExp(loc
, this);
916 e
= new AssignExp(loc
, e1
, e
);
917 e
->type
= e1
->type
; // don't type check this, it would fail
918 init
= new ExpInitializer(loc
, e
);
921 else if (type
->ty
== Ttypedef
)
922 { TypeTypedef
*td
= (TypeTypedef
*)type
;
924 { init
= td
->sym
->init
;
925 ExpInitializer
*ie
= init
->isExpInitializer();
927 // Make copy so we can modify it
928 init
= new ExpInitializer(ie
->loc
, ie
->exp
);
931 init
= getExpInitializer();
935 init
= getExpInitializer();
937 // Default initializer is always a blit
943 ArrayInitializer
*ai
= init
->isArrayInitializer();
944 if (ai
&& tb
->ty
== Taarray
)
946 init
= ai
->toAssocArrayInitializer();
949 StructInitializer
*si
= init
->isStructInitializer();
950 ExpInitializer
*ei
= init
->isExpInitializer();
952 // See if we can allocate on the stack
953 if (ei
&& isScope() && ei
->exp
->op
== TOKnew
)
954 { NewExp
*ne
= (NewExp
*)ei
->exp
;
955 if (!(ne
->newargs
&& ne
->newargs
->dim
))
958 if (type
->isBaseOf(ne
->newtype
->semantic(loc
, sc
), NULL
))
963 // If inside function, there is no semantic3() call
966 // If local variable, use AssignExp to handle all the various
968 if (fd
&& !isStatic() && !(storage_class
& STCmanifest
) &&
969 !init
->isVoidInitializer())
971 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars());
974 Expression
*e
= init
->toExpression();
977 init
= init
->semantic(sc
, type
);
978 e
= init
->toExpression();
980 { error("is not a static and cannot have static initializer");
984 ei
= new ExpInitializer(init
->loc
, e
);
988 Expression
*e1
= new VarExp(loc
, this);
990 Type
*t
= type
->toBasetype();
991 if (t
->ty
== Tsarray
)
993 ei
->exp
= ei
->exp
->semantic(sc
);
994 if (!ei
->exp
->implicitConvTo(type
))
996 sinteger_t dim
= ((TypeSArray
*)t
)->dim
->toInteger();
997 // If multidimensional static array, treat as one large array
1000 t
= t
->nextOf()->toBasetype();
1001 if (t
->ty
!= Tsarray
)
1003 dim
*= ((TypeSArray
*)t
)->dim
->toInteger();
1004 e1
->type
= new TypeSArray(t
->nextOf(), new IntegerExp(0, dim
, Type::tindex
));
1007 e1
= new SliceExp(loc
, e1
, NULL
, NULL
);
1009 else if (t
->ty
== Tstruct
)
1011 ei
->exp
= ei
->exp
->semantic(sc
);
1012 if (!ei
->exp
->implicitConvTo(type
))
1013 { Type
*ti
= ei
->exp
->type
->toBasetype();
1014 // Don't cast away invariant or mutability in initializer
1015 if (!(ti
->ty
== Tstruct
&& t
->toDsymbol(sc
) == ti
->toDsymbol(sc
)))
1016 ei
->exp
= new CastExp(loc
, ei
->exp
, type
);
1019 ei
->exp
= new AssignExp(loc
, e1
, ei
->exp
);
1022 ei
->exp
= ei
->exp
->semantic(sc
);
1024 ei
->exp
->optimize(WANTvalue
);
1028 init
= init
->semantic(sc
, type
);
1031 else if (storage_class
& (STCconst
| STCinvariant
| STCmanifest
) ||
1032 type
->isConst() || type
->isInvariant())
1034 /* Because we may need the results of a const declaration in a
1035 * subsequent type, such as an array dimension, before semantic2()
1036 * gets ordinarily run, try to run semantic2() now.
1040 if (!global
.errors
&& !inferred
)
1042 unsigned errors
= global
.errors
;
1046 Initializer
*i2
= init
;
1050 e
= ei
->exp
->syntaxCopy();
1051 e
= e
->semantic(sc
);
1052 e
= e
->implicitCastTo(sc
, type
);
1055 { i2
= init
->syntaxCopy();
1056 i2
= i2
->semantic(sc
, type
);
1061 if (errors
!= global
.errors
) // if errors happened
1063 if (global
.gag
== 0)
1064 global
.errors
= errors
; // act as if nothing happened
1066 /* Save scope for later use, to try again
1068 scope
= new Scope(*sc
);
1074 /* static const/invariant does CTFE
1076 e
= e
->optimize(WANTvalue
| WANTinterpret
);
1078 e
= e
->optimize(WANTvalue
);
1079 if (e
->op
== TOKint64
|| e
->op
== TOKstring
)
1081 ei
->exp
= e
; // no errors, keep result
1085 /* Save scope for later use, to try again
1087 scope
= new Scope(*sc
);
1092 init
= i2
; // no errors, keep result
1098 void VarDeclaration::semantic2(Scope
*sc
)
1100 //printf("VarDeclaration::semantic2('%s')\n", toChars());
1101 if (init
&& !toParent()->isFuncDeclaration())
1104 ExpInitializer
*ei
= init
->isExpInitializer();
1108 printf("type = %p\n", ei
->exp
->type
);
1111 init
= init
->semantic(sc
, type
);
1116 char *VarDeclaration::kind()
1121 Dsymbol
*VarDeclaration::toAlias()
1123 //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
1124 assert(this != aliassym
);
1125 Dsymbol
*s
= aliassym
? aliassym
->toAlias() : this;
1129 void VarDeclaration::toCBuffer(OutBuffer
*buf
, HdrGenState
*hgs
)
1131 if (storage_class
& STCmanifest
)
1132 buf
->writestring("manifest ");
1133 if (storage_class
& STCstatic
)
1134 buf
->writestring("static ");
1135 if (storage_class
& STCtls
)
1136 buf
->writestring("__tls ");
1137 if (storage_class
& STCconst
)
1138 buf
->writestring("const ");
1139 if (storage_class
& STCinvariant
)
1140 buf
->writestring("invariant ");
1143 type
->toCBuffer(buf
, ident
, hgs
);
1145 buf
->writestring(ident
->toChars());
1147 { buf
->writestring(" = ");
1148 ExpInitializer
*ie
= init
->isExpInitializer();
1149 if (ie
&& (ie
->exp
->op
== TOKconstruct
|| ie
->exp
->op
== TOKblit
))
1150 ((AssignExp
*)ie
->exp
)->e2
->toCBuffer(buf
, hgs
);
1152 init
->toCBuffer(buf
, hgs
);
1154 buf
->writeByte(';');
1158 int VarDeclaration::needThis()
1160 //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class);
1161 return storage_class
& STCfield
;
1164 int VarDeclaration::isImportedSymbol()
1166 if (protection
== PROTexport
&& !init
&&
1167 (storage_class
& STCstatic
|| parent
->isModule()))
1172 void VarDeclaration::checkCtorConstInit()
1174 if (ctorinit
== 0 && isCtorinit() && !(storage_class
& STCfield
))
1175 error("missing initializer in static constructor for const variable");
1178 /************************************
1179 * Check to see if this variable is actually in an enclosing function
1180 * rather than the current one.
1183 void VarDeclaration::checkNestedReference(Scope
*sc
, Loc loc
)
1185 if (parent
&& !isDataseg() && parent
!= sc
->parent
&&
1186 !(storage_class
& STCmanifest
))
1188 // The function that this variable is in
1189 FuncDeclaration
*fdv
= toParent()->isFuncDeclaration();
1190 // The current function
1191 FuncDeclaration
*fdthis
= sc
->parent
->isFuncDeclaration();
1193 if (fdv
&& fdthis
&& fdv
!= fdthis
)
1196 fdthis
->getLevel(loc
, fdv
);
1198 for (int i
= 0; i
< nestedrefs
.dim
; i
++)
1199 { FuncDeclaration
*f
= (FuncDeclaration
*)nestedrefs
.data
[i
];
1203 nestedrefs
.push(fdthis
);
1207 for (int i
= 0; i
< fdv
->closureVars
.dim
; i
++)
1208 { Dsymbol
*s
= (Dsymbol
*)fdv
->closureVars
.data
[i
];
1213 fdv
->closureVars
.push(this);
1216 //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
1221 /****************************
1222 * Get ExpInitializer for a variable, if there is one.
1225 ExpInitializer
*VarDeclaration::getExpInitializer()
1230 ei
= init
->isExpInitializer();
1233 if ((type
->ty
== Tclass
|| type
->ty
== Tpointer
) && requirePointerInit
)
1234 error("non-null, but missing initialiser");
1236 Expression
*e
= type
->defaultInit();
1238 ei
= new ExpInitializer(loc
, e
);
1246 /*******************************************
1247 * If variable has a constant expression initializer, get it.
1248 * Otherwise, return NULL.
1251 Expression
*VarDeclaration::getConstInitializer()
1253 if ((isConst() || isInvariant() || storage_class
& STCmanifest
) &&
1254 storage_class
& STCinit
)
1256 ExpInitializer
*ei
= getExpInitializer();
1264 /*************************************
1265 * Return !=0 if we can take the address of this variable.
1268 int VarDeclaration::canTakeAddressOf()
1271 /* Global variables and struct/class fields of the form:
1273 * are not stored and hence cannot have their address taken.
1275 if ((isConst() || isInvariant()) &&
1276 storage_class
& STCinit
&&
1277 (!(storage_class
& (STCstatic
| STCextern
)) || (storage_class
& STCfield
)) &&
1278 (!parent
|| toParent()->isModule() || toParent()->isTemplateInstance()) &&
1279 type
->toBasetype()->isTypeBasic()
1285 if (storage_class
& STCmanifest
)
1291 /*******************************
1292 * Does symbol go into data segment?
1293 * Includes extern variables.
1296 int VarDeclaration::isDataseg()
1299 printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars());
1300 printf("%x, %p, %p\n", storage_class
& (STCstatic
| STCconst
), parent
->isModule(), parent
->isTemplateInstance());
1301 printf("parent = '%s'\n", parent
->toChars());
1303 if (storage_class
& STCmanifest
)
1305 Dsymbol
*parent
= this->toParent();
1306 if (!parent
&& !(storage_class
& STCstatic
))
1307 { error("forward referenced");
1308 type
= Type::terror
;
1311 return canTakeAddressOf() &&
1312 (storage_class
& (STCstatic
| STCextern
| STCtls
) ||
1313 toParent()->isModule() ||
1314 toParent()->isTemplateInstance());
1317 int VarDeclaration::hasPointers()
1319 //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty);
1320 return (!isDataseg() && type
->hasPointers());
1323 /******************************************
1324 * Return TRUE if variable needs to call the destructor.
1327 int VarDeclaration::needsAutoDtor()
1329 //printf("VarDeclaration::needsAutoDtor() %s\n", toChars());
1331 if (noauto
|| storage_class
& STCnodtor
)
1334 // Destructors for structs and arrays of structs
1335 Type
*tv
= type
->toBasetype();
1336 while (tv
->ty
== Tsarray
)
1337 { TypeSArray
*ta
= (TypeSArray
*)tv
;
1338 tv
= tv
->nextOf()->toBasetype();
1340 if (tv
->ty
== Tstruct
)
1341 { TypeStruct
*ts
= (TypeStruct
*)tv
;
1342 StructDeclaration
*sd
= ts
->sym
;
1347 // Destructors for classes
1348 if (storage_class
& (STCauto
| STCscope
))
1350 if (type
->isClassHandle())
1357 /******************************************
1358 * If a variable has an auto destructor call, return call for it.
1359 * Otherwise, return NULL.
1362 Expression
*VarDeclaration::callAutoDtor(Scope
*sc
)
1363 { Expression
*e
= NULL
;
1365 //printf("VarDeclaration::callAutoDtor() %s\n", toChars());
1367 if (noauto
|| storage_class
& STCnodtor
)
1370 // Destructors for structs and arrays of structs
1372 Type
*tv
= type
->toBasetype();
1373 while (tv
->ty
== Tsarray
)
1374 { TypeSArray
*ta
= (TypeSArray
*)tv
;
1376 tv
= tv
->nextOf()->toBasetype();
1378 if (tv
->ty
== Tstruct
)
1379 { TypeStruct
*ts
= (TypeStruct
*)tv
;
1380 StructDeclaration
*sd
= ts
->sym
;
1385 // Typeinfo.destroy(cast(void*)&v);
1386 Expression
*ea
= new SymOffExp(loc
, this, 0, 0);
1387 ea
= new CastExp(loc
, ea
, Type::tvoid
->pointerTo());
1388 Expressions
*args
= new Expressions();
1391 Expression
*et
= type
->getTypeInfo(sc
);
1392 et
= new DotIdExp(loc
, et
, Id::destroy
);
1394 e
= new CallExp(loc
, et
, args
);
1398 e
= new VarExp(loc
, this);
1399 e
= new DotVarExp(loc
, e
, sd
->dtor
, 0);
1400 e
= new CallExp(loc
, e
);
1406 // Destructors for classes
1407 if (storage_class
& (STCauto
| STCscope
))
1409 for (ClassDeclaration
*cd
= type
->isClassHandle();
1413 /* We can do better if there's a way with onstack
1414 * classes to determine if there's no way the monitor
1417 //if (cd->isInterfaceDeclaration())
1418 //error("interface %s cannot be scope", cd->toChars());
1419 if (1 || onstack
|| cd
->dtors
.dim
) // if any destructors
1424 ec
= new VarExp(loc
, this);
1425 e
= new DeleteExp(loc
, ec
);
1426 e
->type
= Type::tvoid
;
1435 /********************************* ClassInfoDeclaration ****************************/
1437 ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration
*cd
)
1438 : VarDeclaration(0, ClassDeclaration::classinfo
->type
, cd
->ident
, NULL
)
1441 storage_class
= STCstatic
;
1444 Dsymbol
*ClassInfoDeclaration::syntaxCopy(Dsymbol
*s
)
1446 assert(0); // should never be produced by syntax
1450 void ClassInfoDeclaration::semantic(Scope
*sc
)
1454 /********************************* ModuleInfoDeclaration ****************************/
1456 ModuleInfoDeclaration::ModuleInfoDeclaration(Module
*mod
)
1457 : VarDeclaration(0, Module::moduleinfo
->type
, mod
->ident
, NULL
)
1460 storage_class
= STCstatic
;
1463 Dsymbol
*ModuleInfoDeclaration::syntaxCopy(Dsymbol
*s
)
1465 assert(0); // should never be produced by syntax
1469 void ModuleInfoDeclaration::semantic(Scope
*sc
)
1473 /********************************* TypeInfoDeclaration ****************************/
1475 TypeInfoDeclaration::TypeInfoDeclaration(Type
*tinfo
, int internal
)
1476 : VarDeclaration(0, Type::typeinfo
->type
, tinfo
->getTypeInfoIdent(internal
), NULL
)
1478 this->tinfo
= tinfo
;
1479 storage_class
= STCstatic
;
1480 protection
= PROTpublic
;
1484 Dsymbol
*TypeInfoDeclaration::syntaxCopy(Dsymbol
*s
)
1486 assert(0); // should never be produced by syntax
1490 void TypeInfoDeclaration::semantic(Scope
*sc
)
1492 assert(linkage
== LINKc
);
1495 /***************************** TypeInfoConstDeclaration **********************/
1498 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type
*tinfo
)
1499 : TypeInfoDeclaration(tinfo
, 0)
1504 /***************************** TypeInfoInvariantDeclaration **********************/
1507 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type
*tinfo
)
1508 : TypeInfoDeclaration(tinfo
, 0)
1513 /***************************** TypeInfoStructDeclaration **********************/
1515 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type
*tinfo
)
1516 : TypeInfoDeclaration(tinfo
, 0)
1520 /***************************** TypeInfoClassDeclaration ***********************/
1522 TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type
*tinfo
)
1523 : TypeInfoDeclaration(tinfo
, 0)
1527 /***************************** TypeInfoInterfaceDeclaration *******************/
1529 TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type
*tinfo
)
1530 : TypeInfoDeclaration(tinfo
, 0)
1534 /***************************** TypeInfoTypedefDeclaration *********************/
1536 TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type
*tinfo
)
1537 : TypeInfoDeclaration(tinfo
, 0)
1541 /***************************** TypeInfoPointerDeclaration *********************/
1543 TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type
*tinfo
)
1544 : TypeInfoDeclaration(tinfo
, 0)
1548 /***************************** TypeInfoArrayDeclaration ***********************/
1550 TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type
*tinfo
)
1551 : TypeInfoDeclaration(tinfo
, 0)
1555 /***************************** TypeInfoStaticArrayDeclaration *****************/
1557 TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type
*tinfo
)
1558 : TypeInfoDeclaration(tinfo
, 0)
1562 /***************************** TypeInfoAssociativeArrayDeclaration ************/
1564 TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type
*tinfo
)
1565 : TypeInfoDeclaration(tinfo
, 0)
1569 /***************************** TypeInfoEnumDeclaration ***********************/
1571 TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type
*tinfo
)
1572 : TypeInfoDeclaration(tinfo
, 0)
1576 /***************************** TypeInfoFunctionDeclaration ********************/
1578 TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type
*tinfo
)
1579 : TypeInfoDeclaration(tinfo
, 0)
1583 /***************************** TypeInfoDelegateDeclaration ********************/
1585 TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type
*tinfo
)
1586 : TypeInfoDeclaration(tinfo
, 0)
1590 /***************************** TypeInfoTupleDeclaration **********************/
1592 TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type
*tinfo
)
1593 : TypeInfoDeclaration(tinfo
, 0)
1597 /********************************* ThisDeclaration ****************************/
1599 // For the "this" parameter to member functions
1601 ThisDeclaration::ThisDeclaration(Type
*t
)
1602 : VarDeclaration(0, t
, Id::This
, NULL
)
1607 Dsymbol
*ThisDeclaration::syntaxCopy(Dsymbol
*s
)
1609 assert(0); // should never be produced by syntax