Mercurial > projects > ldc
comparison dmd2/declaration.c @ 1452:638d16625da2
LDC 2 compiles again.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sat, 30 May 2009 17:23:32 +0100 |
parents | 0749c0757a43 |
children | f62347c22d81 |
comparison
equal
deleted
inserted
replaced
1423:42bd767ec5a4 | 1452:638d16625da2 |
---|---|
1 | 1 |
2 // Compiler implementation of the D programming language | 2 // Compiler implementation of the D programming language |
3 // Copyright (c) 1999-2008 by Digital Mars | 3 // Copyright (c) 1999-2009 by Digital Mars |
4 // All Rights Reserved | 4 // All Rights Reserved |
5 // written by Walter Bright | 5 // written by Walter Bright |
6 // http://www.digitalmars.com | 6 // http://www.digitalmars.com |
7 // License for redistribution is by either the Artistic License | 7 // License for redistribution is by either the Artistic License |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | 8 // in artistic.txt, or the GNU General Public License in gnu.txt. |
31 type = NULL; | 31 type = NULL; |
32 originalType = NULL; | 32 originalType = NULL; |
33 storage_class = STCundefined; | 33 storage_class = STCundefined; |
34 protection = PROTundefined; | 34 protection = PROTundefined; |
35 linkage = LINKdefault; | 35 linkage = LINKdefault; |
36 inuse = 0; | |
36 } | 37 } |
37 | 38 |
38 void Declaration::semantic(Scope *sc) | 39 void Declaration::semantic(Scope *sc) |
39 { | 40 { |
40 } | 41 } |
64 { | 65 { |
65 return FALSE; | 66 return FALSE; |
66 } | 67 } |
67 | 68 |
68 int Declaration::isDataseg() | 69 int Declaration::isDataseg() |
70 { | |
71 return FALSE; | |
72 } | |
73 | |
74 int Declaration::isThreadlocal() | |
69 { | 75 { |
70 return FALSE; | 76 return FALSE; |
71 } | 77 } |
72 | 78 |
73 int Declaration::isCodeseg() | 79 int Declaration::isCodeseg() |
133 { | 139 { |
134 const char *p = NULL; | 140 const char *p = NULL; |
135 if (isConst()) | 141 if (isConst()) |
136 p = "const"; | 142 p = "const"; |
137 else if (isInvariant()) | 143 else if (isInvariant()) |
138 p = "invariant"; | 144 p = "mutable"; |
139 else if (storage_class & STCmanifest) | 145 else if (storage_class & STCmanifest) |
140 p = "manifest constant"; | 146 p = "enum"; |
141 else if (!t->isAssignable()) | 147 else if (!t->isAssignable()) |
142 p = "struct with immutable members"; | 148 p = "struct with immutable members"; |
143 if (p) | 149 if (p) |
144 { error(loc, "cannot modify %s", p); | 150 { error(loc, "cannot modify %s", p); |
145 halt(); | |
146 } | 151 } |
147 } | 152 } |
148 } | 153 } |
149 } | 154 } |
150 #endif | 155 #endif |
251 #ifdef _DH | 256 #ifdef _DH |
252 this->htype = NULL; | 257 this->htype = NULL; |
253 this->hbasetype = NULL; | 258 this->hbasetype = NULL; |
254 #endif | 259 #endif |
255 this->sem = 0; | 260 this->sem = 0; |
256 this->inuse = 0; | |
257 this->loc = loc; | 261 this->loc = loc; |
262 #if IN_DMD | |
258 this->sinit = NULL; | 263 this->sinit = NULL; |
264 #endif | |
259 } | 265 } |
260 | 266 |
261 Dsymbol *TypedefDeclaration::syntaxCopy(Dsymbol *s) | 267 Dsymbol *TypedefDeclaration::syntaxCopy(Dsymbol *s) |
262 { | 268 { |
263 Type *basetype = this->basetype->syntaxCopy(); | 269 Type *basetype = this->basetype->syntaxCopy(); |
365 this->htype = NULL; | 371 this->htype = NULL; |
366 this->haliassym = NULL; | 372 this->haliassym = NULL; |
367 #endif | 373 #endif |
368 this->overnext = NULL; | 374 this->overnext = NULL; |
369 this->inSemantic = 0; | 375 this->inSemantic = 0; |
376 this->importprot = PROTundefined; | |
370 assert(type); | 377 assert(type); |
371 } | 378 } |
372 | 379 |
373 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s) | 380 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s) |
374 : Declaration(id) | 381 : Declaration(id) |
454 */ | 461 */ |
455 s = type->toDsymbol(sc); | 462 s = type->toDsymbol(sc); |
456 if (s && ((s->getType() && type->equals(s->getType())) || s->isEnumMember())) | 463 if (s && ((s->getType() && type->equals(s->getType())) || s->isEnumMember())) |
457 goto L2; // it's a symbolic alias | 464 goto L2; // it's a symbolic alias |
458 | 465 |
459 //printf("alias type is %s\n", type->toChars()); | 466 if (storage_class & STCref) |
460 type->resolve(loc, sc, &e, &t, &s); | 467 { // For 'ref' to be attached to function types, and picked |
468 // up by Type::resolve(), it has to go into sc. | |
469 sc = sc->push(); | |
470 sc->stc |= STCref; | |
471 type->resolve(loc, sc, &e, &t, &s); | |
472 sc = sc->pop(); | |
473 } | |
474 else | |
475 type->resolve(loc, sc, &e, &t, &s); | |
461 if (s) | 476 if (s) |
462 { | 477 { |
463 goto L2; | 478 goto L2; |
464 } | 479 } |
465 else if (e) | 480 else if (e) |
494 if (f) | 509 if (f) |
495 { | 510 { |
496 if (overnext) | 511 if (overnext) |
497 { | 512 { |
498 FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); | 513 FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); |
514 fa->importprot = importprot; | |
499 if (!fa->overloadInsert(overnext)) | 515 if (!fa->overloadInsert(overnext)) |
500 ScopeDsymbol::multiplyDefined(0, f, overnext); | 516 ScopeDsymbol::multiplyDefined(0, f, overnext); |
501 overnext = NULL; | 517 overnext = NULL; |
502 s = fa; | 518 s = fa; |
503 s->parent = sc->parent; | 519 s->parent = sc->parent; |
547 //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); | 563 //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); |
548 assert(this != aliassym); | 564 assert(this != aliassym); |
549 //static int count; if (++count == 10) *(char*)0=0; | 565 //static int count; if (++count == 10) *(char*)0=0; |
550 if (inSemantic) | 566 if (inSemantic) |
551 { error("recursive alias declaration"); | 567 { error("recursive alias declaration"); |
552 // return this; | 568 aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL); |
553 } | 569 } |
554 Dsymbol *s = aliassym ? aliassym->toAlias() : this; | 570 Dsymbol *s = aliassym ? aliassym->toAlias() : this; |
555 return s; | 571 return s; |
556 } | 572 } |
557 | 573 |
561 #if 0 && _DH | 577 #if 0 && _DH |
562 if (hgs->hdrgen) | 578 if (hgs->hdrgen) |
563 { | 579 { |
564 if (haliassym) | 580 if (haliassym) |
565 { | 581 { |
566 haliassym->toCBuffer(buf, hgs); | 582 buf->writestring(haliassym->toChars()); |
567 buf->writeByte(' '); | 583 buf->writeByte(' '); |
568 buf->writestring(ident->toChars()); | 584 buf->writestring(ident->toChars()); |
569 } | 585 } |
570 else | 586 else |
571 htype->toCBuffer(buf, ident, hgs); | 587 htype->toCBuffer(buf, ident, hgs); |
606 this->hinit = NULL; | 622 this->hinit = NULL; |
607 #endif | 623 #endif |
608 this->loc = loc; | 624 this->loc = loc; |
609 offset = 0; | 625 offset = 0; |
610 noauto = 0; | 626 noauto = 0; |
611 inuse = 0; | |
612 ctorinit = 0; | 627 ctorinit = 0; |
613 aliassym = NULL; | 628 aliassym = NULL; |
614 onstack = 0; | 629 onstack = 0; |
615 canassign = 0; | 630 canassign = 0; |
616 value = NULL; | 631 value = NULL; |
617 scope = NULL; | 632 scope = NULL; |
633 #if IN_LLVM | |
634 aggrIndex = 0; | |
618 | 635 |
619 // LDC | 636 // LDC |
620 anonDecl = NULL; | 637 anonDecl = NULL; |
621 offset2 = 0; | 638 offset2 = 0; |
639 | |
622 nakedUse = false; | 640 nakedUse = false; |
641 #endif | |
623 } | 642 } |
624 | 643 |
625 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) | 644 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) |
626 { | 645 { |
627 //printf("VarDeclaration::syntaxCopy(%s)\n", toChars()); | 646 //printf("VarDeclaration::syntaxCopy(%s)\n", toChars()); |
706 this->parent = sc->parent; | 725 this->parent = sc->parent; |
707 //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); | 726 //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); |
708 protection = sc->protection; | 727 protection = sc->protection; |
709 //printf("sc->stc = %x\n", sc->stc); | 728 //printf("sc->stc = %x\n", sc->stc); |
710 //printf("storage_class = x%x\n", storage_class); | 729 //printf("storage_class = x%x\n", storage_class); |
730 | |
731 if (storage_class & STCgshared && global.params.safe && !sc->module->safe) | |
732 { | |
733 error("__gshared not allowed in safe mode; use shared"); | |
734 } | |
711 | 735 |
712 Dsymbol *parent = toParent(); | 736 Dsymbol *parent = toParent(); |
713 FuncDeclaration *fd = parent->isFuncDeclaration(); | 737 FuncDeclaration *fd = parent->isFuncDeclaration(); |
714 | 738 |
715 Type *tb = type->toBasetype(); | 739 Type *tb = type->toBasetype(); |
744 | 768 |
745 for (size_t i = 0; i < nelems; i++) | 769 for (size_t i = 0; i < nelems; i++) |
746 { Argument *arg = Argument::getNth(tt->arguments, i); | 770 { Argument *arg = Argument::getNth(tt->arguments, i); |
747 | 771 |
748 OutBuffer buf; | 772 OutBuffer buf; |
749 buf.printf("_%s_field_%"PRIuSIZE, ident->toChars(), i); | 773 buf.printf("_%s_field_%zu", ident->toChars(), i); |
750 buf.writeByte(0); | 774 buf.writeByte(0); |
751 char *name = (char *)buf.extractData(); | 775 char *name = (char *)buf.extractData(); |
752 Identifier *id = new Identifier(name, TOKidentifier); | 776 Identifier *id = new Identifier(name, TOKidentifier); |
753 | 777 |
754 Expression *einit = ie; | 778 Expression *einit = ie; |
761 } | 785 } |
762 | 786 |
763 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti); | 787 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti); |
764 //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); | 788 //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); |
765 v->semantic(sc); | 789 v->semantic(sc); |
766 | 790 |
791 /* | |
792 // removed for LDC since TupleDeclaration::toObj already creates the fields; | |
793 // adding them to the scope again leads to duplicates | |
767 if (sc->scopesym) | 794 if (sc->scopesym) |
768 { //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars()); | 795 { //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars()); |
769 if (sc->scopesym->members) | 796 if (sc->scopesym->members) |
770 sc->scopesym->members->push(v); | 797 sc->scopesym->members->push(v); |
771 } | 798 } |
772 | 799 */ |
773 Expression *e = new DsymbolExp(loc, v); | 800 Expression *e = new DsymbolExp(loc, v); |
774 exps->data[i] = e; | 801 exps->data[i] = e; |
775 } | 802 } |
776 TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps); | 803 TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps); |
777 v2->isexp = 1; | 804 v2->isexp = 1; |
778 aliassym = v2; | 805 aliassym = v2; |
779 return; | 806 return; |
780 } | 807 } |
781 | 808 |
782 Lagain: | 809 Lagain: |
783 if (storage_class & STCinvariant) | 810 /* Storage class can modify the type |
784 { | 811 */ |
785 type = type->invariantOf(); | 812 type = type->addStorageClass(storage_class); |
786 } | 813 |
787 else if (storage_class & (STCconst | STCin)) | 814 /* Adjust storage class to reflect type |
788 { | 815 */ |
789 if (!type->isInvariant()) | 816 if (type->isConst()) |
790 type = type->constOf(); | 817 { storage_class |= STCconst; |
791 } | 818 if (type->isShared()) |
792 else if (type->isConst()) | 819 storage_class |= STCshared; |
793 storage_class |= STCconst; | 820 } |
794 else if (type->isInvariant()) | 821 else if (type->isInvariant()) |
795 storage_class |= STCinvariant; | 822 storage_class |= STCimmutable; |
823 else if (type->isShared()) | |
824 storage_class |= STCshared; | |
796 | 825 |
797 if (isSynchronized()) | 826 if (isSynchronized()) |
798 { | 827 { |
799 error("variable %s cannot be synchronized", toChars()); | 828 error("variable %s cannot be synchronized", toChars()); |
800 } | 829 } |
809 else if (storage_class & STCfinal) | 838 else if (storage_class & STCfinal) |
810 { | 839 { |
811 error("final cannot be applied to variable"); | 840 error("final cannot be applied to variable"); |
812 } | 841 } |
813 | 842 |
814 if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls)) | 843 if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls | STCgshared)) |
815 { | 844 { |
816 } | 845 } |
817 else | 846 else |
818 { | 847 { |
819 AggregateDeclaration *aad = sc->anonAgg; | 848 AggregateDeclaration *aad = sc->anonAgg; |
820 if (!aad) | 849 if (!aad) |
821 aad = parent->isAggregateDeclaration(); | 850 aad = parent->isAggregateDeclaration(); |
822 if (aad) | 851 if (aad) |
823 { assert(!(storage_class & (STCextern | STCstatic | STCtls))); | 852 { assert(!(storage_class & (STCextern | STCstatic | STCtls | STCgshared))); |
824 | 853 |
825 if (storage_class & (STCconst | STCinvariant) && init) | 854 if (storage_class & (STCconst | STCimmutable) && init) |
826 { | 855 { |
827 if (!type->toBasetype()->isTypeBasic()) | 856 if (!type->toBasetype()->isTypeBasic()) |
828 storage_class |= STCstatic; | 857 storage_class |= STCstatic; |
829 } | 858 } |
830 else | 859 else |
858 error("cannot use template to add field to aggregate '%s'", ad->toChars()); | 887 error("cannot use template to add field to aggregate '%s'", ad->toChars()); |
859 } | 888 } |
860 } | 889 } |
861 } | 890 } |
862 | 891 |
863 if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref) | 892 if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && |
893 ident != Id::This) | |
894 { | |
864 error("only parameters or foreach declarations can be ref"); | 895 error("only parameters or foreach declarations can be ref"); |
896 } | |
865 | 897 |
866 if (type->isauto() && !noauto) | 898 if (type->isauto() && !noauto) |
867 { | 899 { |
868 if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls) || !fd) | 900 if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls | STCgshared) || !fd) |
869 { | 901 { |
870 error("globals, statics, fields, manifest constants, ref and out parameters cannot be auto"); | 902 error("globals, statics, fields, manifest constants, ref and out parameters cannot be scope"); |
871 } | 903 } |
872 | 904 |
873 if (!(storage_class & (STCauto | STCscope))) | 905 if (!(storage_class & (STCauto | STCscope))) |
874 { | 906 { |
875 if (!(storage_class & STCparameter) && ident != Id::withSym) | 907 if (!(storage_class & STCparameter) && ident != Id::withSym) |
904 */ | 936 */ |
905 Expression *e = new IntegerExp(loc, 0, Type::tint32); | 937 Expression *e = new IntegerExp(loc, 0, Type::tint32); |
906 Expression *e1; | 938 Expression *e1; |
907 e1 = new VarExp(loc, this); | 939 e1 = new VarExp(loc, this); |
908 e = new AssignExp(loc, e1, e); | 940 e = new AssignExp(loc, e1, e); |
941 e->op = TOKconstruct; | |
909 e->type = e1->type; // don't type check this, it would fail | 942 e->type = e1->type; // don't type check this, it would fail |
910 init = new ExpInitializer(loc, e); | 943 init = new ExpInitializer(loc, e); |
911 return; | 944 return; |
912 } | 945 } |
913 else if (type->ty == Ttypedef) | 946 else if (type->ty == Ttypedef) |
931 } | 964 } |
932 | 965 |
933 if (init) | 966 if (init) |
934 { | 967 { |
935 sc = sc->push(); | 968 sc = sc->push(); |
936 sc->stc &= ~(STCconst | STCinvariant | STCpure | STCnothrow | STCref | STCshared); | 969 sc->stc &= ~(STC_TYPECTOR | STCpure | STCnothrow | STCref); |
937 | 970 |
938 ArrayInitializer *ai = init->isArrayInitializer(); | 971 ArrayInitializer *ai = init->isArrayInitializer(); |
939 if (ai && tb->ty == Taarray) | 972 if (ai && tb->ty == Taarray) |
940 { | 973 { |
941 init = ai->toAssocArrayInitializer(); | 974 init = ai->toAssocArrayInitializer(); |
958 // If inside function, there is no semantic3() call | 991 // If inside function, there is no semantic3() call |
959 if (sc->func) | 992 if (sc->func) |
960 { | 993 { |
961 // If local variable, use AssignExp to handle all the various | 994 // If local variable, use AssignExp to handle all the various |
962 // possibilities. | 995 // possibilities. |
963 if (fd && !isStatic() && !(storage_class & STCmanifest) && | 996 if (fd && |
997 !(storage_class & (STCmanifest | STCstatic | STCtls | STCgshared | STCextern)) && | |
964 !init->isVoidInitializer()) | 998 !init->isVoidInitializer()) |
965 { | 999 { |
966 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars()); | 1000 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars()); |
967 if (!ei) | 1001 if (!ei) |
968 { | 1002 { |
1060 else | 1094 else |
1061 { | 1095 { |
1062 init = init->semantic(sc, type); | 1096 init = init->semantic(sc, type); |
1063 } | 1097 } |
1064 } | 1098 } |
1065 else if (storage_class & (STCconst | STCinvariant | STCmanifest) || | 1099 else if (storage_class & (STCconst | STCimmutable | STCmanifest) || |
1066 type->isConst() || type->isInvariant()) | 1100 type->isConst() || type->isInvariant()) |
1067 { | 1101 { |
1068 /* Because we may need the results of a const declaration in a | 1102 /* Because we may need the results of a const declaration in a |
1069 * subsequent type, such as an array dimension, before semantic2() | 1103 * subsequent type, such as an array dimension, before semantic2() |
1070 * gets ordinarily run, try to run semantic2() now. | 1104 * gets ordinarily run, try to run semantic2() now. |
1161 return s; | 1195 return s; |
1162 } | 1196 } |
1163 | 1197 |
1164 void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 1198 void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
1165 { | 1199 { |
1166 if (storage_class & STCconst) | 1200 StorageClassDeclaration::stcToCBuffer(buf, storage_class); |
1167 buf->writestring("const "); | 1201 |
1168 if (storage_class & STCstatic) | 1202 /* If changing, be sure and fix CompoundDeclarationStatement::toCBuffer() |
1169 buf->writestring("static "); | 1203 * too. |
1170 if (storage_class & STCauto) | 1204 */ |
1171 buf->writestring("auto "); | |
1172 #if DMDV2 | |
1173 if (storage_class & STCmanifest) | |
1174 buf->writestring("manifest "); | |
1175 if (storage_class & STCinvariant) | |
1176 buf->writestring("invariant "); | |
1177 if (storage_class & STCtls) | |
1178 buf->writestring("__thread "); | |
1179 #endif | |
1180 | |
1181 if (type) | 1205 if (type) |
1182 type->toCBuffer(buf, ident, hgs); | 1206 type->toCBuffer(buf, ident, hgs); |
1183 else | 1207 else |
1184 buf->writestring(ident->toChars()); | 1208 buf->writestring(ident->toChars()); |
1185 if (init) | 1209 if (init) |
1239 for (int i = 0; i < nestedrefs.dim; i++) | 1263 for (int i = 0; i < nestedrefs.dim; i++) |
1240 { FuncDeclaration *f = (FuncDeclaration *)nestedrefs.data[i]; | 1264 { FuncDeclaration *f = (FuncDeclaration *)nestedrefs.data[i]; |
1241 if (f == fdthis) | 1265 if (f == fdthis) |
1242 goto L1; | 1266 goto L1; |
1243 } | 1267 } |
1244 fdv->nestedVars.insert(this); | |
1245 nestedrefs.push(fdthis); | 1268 nestedrefs.push(fdthis); |
1246 L1: ; | 1269 L1: ; |
1247 | 1270 |
1248 | 1271 |
1249 for (int i = 0; i < fdv->closureVars.dim; i++) | 1272 for (int i = 0; i < fdv->closureVars.dim; i++) |
1253 } | 1276 } |
1254 | 1277 |
1255 fdv->closureVars.push(this); | 1278 fdv->closureVars.push(this); |
1256 L2: ; | 1279 L2: ; |
1257 | 1280 |
1281 //printf("fdthis is %s\n", fdthis->toChars()); | |
1258 //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars()); | 1282 //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars()); |
1259 } | 1283 } |
1260 } | 1284 } |
1261 } | 1285 } |
1262 | 1286 |
1345 { error("forward referenced"); | 1369 { error("forward referenced"); |
1346 type = Type::terror; | 1370 type = Type::terror; |
1347 return 0; | 1371 return 0; |
1348 } | 1372 } |
1349 return canTakeAddressOf() && | 1373 return canTakeAddressOf() && |
1350 (storage_class & (STCstatic | STCextern | STCtls) || | 1374 (storage_class & (STCstatic | STCextern | STCtls | STCgshared) || |
1351 toParent()->isModule() || | 1375 toParent()->isModule() || |
1352 toParent()->isTemplateInstance()); | 1376 toParent()->isTemplateInstance()); |
1377 } | |
1378 | |
1379 /************************************ | |
1380 * Does symbol go into thread local storage? | |
1381 */ | |
1382 | |
1383 int VarDeclaration::isThreadlocal() | |
1384 { | |
1385 //printf("VarDeclaration::isThreadlocal(%p, '%s')\n", this, toChars()); | |
1386 #if 0 || TARGET_OSX | |
1387 /* To be thread-local, must use the __thread storage class. | |
1388 * BUG: OSX doesn't support thread local yet. | |
1389 */ | |
1390 return isDataseg() && | |
1391 (storage_class & (STCtls | STCconst | STCimmutable | STCshared | STCgshared)) == STCtls; | |
1392 #else | |
1393 /* Data defaults to being thread-local. It is not thread-local | |
1394 * if it is immutable, const or shared. | |
1395 */ | |
1396 int i = isDataseg() && | |
1397 !(storage_class & (STCimmutable | STCconst | STCshared | STCgshared)); | |
1398 //printf("\treturn %d\n", i); | |
1399 return i; | |
1400 #endif | |
1353 } | 1401 } |
1354 | 1402 |
1355 int VarDeclaration::hasPointers() | 1403 int VarDeclaration::hasPointers() |
1356 { | 1404 { |
1357 //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty); | 1405 //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty); |
1474 | 1522 |
1475 ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd) | 1523 ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd) |
1476 : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL) | 1524 : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL) |
1477 { | 1525 { |
1478 this->cd = cd; | 1526 this->cd = cd; |
1479 storage_class = STCstatic; | 1527 storage_class = STCstatic | STCgshared; |
1480 } | 1528 } |
1481 | 1529 |
1482 Dsymbol *ClassInfoDeclaration::syntaxCopy(Dsymbol *s) | 1530 Dsymbol *ClassInfoDeclaration::syntaxCopy(Dsymbol *s) |
1483 { | 1531 { |
1484 assert(0); // should never be produced by syntax | 1532 assert(0); // should never be produced by syntax |
1493 | 1541 |
1494 ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod) | 1542 ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod) |
1495 : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL) | 1543 : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL) |
1496 { | 1544 { |
1497 this->mod = mod; | 1545 this->mod = mod; |
1498 storage_class = STCstatic; | 1546 storage_class = STCstatic | STCgshared; |
1499 } | 1547 } |
1500 | 1548 |
1501 Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s) | 1549 Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s) |
1502 { | 1550 { |
1503 assert(0); // should never be produced by syntax | 1551 assert(0); // should never be produced by syntax |
1512 | 1560 |
1513 TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal) | 1561 TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal) |
1514 : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL) | 1562 : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL) |
1515 { | 1563 { |
1516 this->tinfo = tinfo; | 1564 this->tinfo = tinfo; |
1517 storage_class = STCstatic; | 1565 storage_class = STCstatic | STCgshared; |
1518 protection = PROTpublic; | 1566 protection = PROTpublic; |
1519 linkage = LINKc; | 1567 linkage = LINKc; |
1520 } | 1568 } |
1521 | 1569 |
1522 Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s) | 1570 Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s) |
1546 : TypeInfoDeclaration(tinfo, 0) | 1594 : TypeInfoDeclaration(tinfo, 0) |
1547 { | 1595 { |
1548 } | 1596 } |
1549 #endif | 1597 #endif |
1550 | 1598 |
1599 /***************************** TypeInfoSharedDeclaration **********************/ | |
1600 | |
1601 #if DMDV2 | |
1602 TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo) | |
1603 : TypeInfoDeclaration(tinfo, 0) | |
1604 { | |
1605 } | |
1606 #endif | |
1607 | |
1551 /***************************** TypeInfoStructDeclaration **********************/ | 1608 /***************************** TypeInfoStructDeclaration **********************/ |
1552 | 1609 |
1553 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo) | 1610 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo) |
1554 : TypeInfoDeclaration(tinfo, 0) | 1611 : TypeInfoDeclaration(tinfo, 0) |
1555 { | 1612 { |
1634 | 1691 |
1635 /********************************* ThisDeclaration ****************************/ | 1692 /********************************* ThisDeclaration ****************************/ |
1636 | 1693 |
1637 // For the "this" parameter to member functions | 1694 // For the "this" parameter to member functions |
1638 | 1695 |
1639 ThisDeclaration::ThisDeclaration(Type *t) | 1696 ThisDeclaration::ThisDeclaration(Loc loc, Type *t) |
1640 : VarDeclaration(0, t, Id::This, NULL) | 1697 : VarDeclaration(loc, t, Id::This, NULL) |
1641 { | 1698 { |
1642 noauto = 1; | 1699 noauto = 1; |
1643 } | 1700 } |
1644 | 1701 |
1645 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s) | 1702 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s) |
1646 { | 1703 { |
1647 assert(0); // should never be produced by syntax | 1704 assert(0); // should never be produced by syntax |
1648 return NULL; | 1705 return NULL; |
1649 } | 1706 } |
1650 | 1707 |
1651 | 1708 /********************** StaticStructInitDeclaration ***************************/ |
1652 /********************** StaticStructInitDeclaration ***************************/ | 1709 |
1653 | 1710 StaticStructInitDeclaration::StaticStructInitDeclaration(Loc loc, StructDeclaration *dsym) |
1654 StaticStructInitDeclaration::StaticStructInitDeclaration(Loc loc, StructDeclaration *dsym) | 1711 : Declaration(new Identifier("", TOKidentifier)) |
1655 : Declaration(new Identifier("", TOKidentifier)) | 1712 { |
1656 { | 1713 this->loc = loc; |
1657 this->loc = loc; | 1714 this->dsym = dsym; |
1658 this->dsym = dsym; | 1715 storage_class |= STCconst; |
1659 storage_class |= STCconst; | 1716 } |
1660 } |