Mercurial > projects > ldc
comparison dmd/declaration.c @ 336:aaade6ded589 trunk
[svn r357] Merged DMD 1.033
author | lindquist |
---|---|
date | Sat, 12 Jul 2008 19:38:31 +0200 |
parents | 2b72433d5c8c |
children | 45a67b6f1310 |
comparison
equal
deleted
inserted
replaced
335:17b844102023 | 336:aaade6ded589 |
---|---|
1 | 1 |
2 // Compiler implementation of the D programming language | 2 // Compiler implementation of the D programming language |
3 // Copyright (c) 1999-2007 by Digital Mars | 3 // Copyright (c) 1999-2008 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. |
37 | 37 |
38 void Declaration::semantic(Scope *sc) | 38 void Declaration::semantic(Scope *sc) |
39 { | 39 { |
40 } | 40 } |
41 | 41 |
42 char *Declaration::kind() | 42 const char *Declaration::kind() |
43 { | 43 { |
44 return "declaration"; | 44 return "declaration"; |
45 } | 45 } |
46 | 46 |
47 unsigned Declaration::size(Loc loc) | 47 unsigned Declaration::size(Loc loc) |
77 | 77 |
78 enum PROT Declaration::prot() | 78 enum PROT Declaration::prot() |
79 { | 79 { |
80 return protection; | 80 return protection; |
81 } | 81 } |
82 | |
83 /************************************* | |
84 * Check to see if declaration can be modified in this context (sc). | |
85 * Issue error if not. | |
86 */ | |
87 | |
88 #if DMDV2 | |
89 void Declaration::checkModify(Loc loc, Scope *sc, Type *t) | |
90 { | |
91 if (sc->incontract && isParameter()) | |
92 error(loc, "cannot modify parameter '%s' in contract", toChars()); | |
93 | |
94 if (isCtorinit()) | |
95 { // It's only modifiable if inside the right constructor | |
96 Dsymbol *s = sc->func; | |
97 while (1) | |
98 { | |
99 FuncDeclaration *fd = NULL; | |
100 if (s) | |
101 fd = s->isFuncDeclaration(); | |
102 if (fd && | |
103 ((fd->isCtorDeclaration() && storage_class & STCfield) || | |
104 (fd->isStaticCtorDeclaration() && !(storage_class & STCfield))) && | |
105 fd->toParent() == toParent() | |
106 ) | |
107 { | |
108 VarDeclaration *v = isVarDeclaration(); | |
109 assert(v); | |
110 v->ctorinit = 1; | |
111 //printf("setting ctorinit\n"); | |
112 } | |
113 else | |
114 { | |
115 if (s) | |
116 { s = s->toParent2(); | |
117 continue; | |
118 } | |
119 else | |
120 { | |
121 const char *p = isStatic() ? "static " : ""; | |
122 error(loc, "can only initialize %sconst %s inside %sconstructor", | |
123 p, toChars(), p); | |
124 } | |
125 } | |
126 break; | |
127 } | |
128 } | |
129 else | |
130 { | |
131 VarDeclaration *v = isVarDeclaration(); | |
132 if (v && v->canassign == 0) | |
133 { | |
134 char *p = NULL; | |
135 if (isConst()) | |
136 p = "const"; | |
137 else if (isInvariant()) | |
138 p = "invariant"; | |
139 else if (storage_class & STCmanifest) | |
140 p = "manifest constant"; | |
141 else if (!t->isAssignable()) | |
142 p = "struct with immutable members"; | |
143 if (p) | |
144 { error(loc, "cannot modify %s", p); | |
145 halt(); | |
146 } | |
147 } | |
148 } | |
149 } | |
150 #endif | |
151 | |
82 | 152 |
83 /********************************* TupleDeclaration ****************************/ | 153 /********************************* TupleDeclaration ****************************/ |
84 | 154 |
85 TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects) | 155 TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects) |
86 : Declaration(id) | 156 : Declaration(id) |
95 { | 165 { |
96 assert(0); | 166 assert(0); |
97 return NULL; | 167 return NULL; |
98 } | 168 } |
99 | 169 |
100 char *TupleDeclaration::kind() | 170 const char *TupleDeclaration::kind() |
101 { | 171 { |
102 return "tuple"; | 172 return "tuple"; |
103 } | 173 } |
104 | 174 |
105 Type *TupleDeclaration::getType() | 175 Type *TupleDeclaration::getType() |
229 basetype = basetype->semantic(loc, sc); | 299 basetype = basetype->semantic(loc, sc); |
230 sem = 2; | 300 sem = 2; |
231 type = type->semantic(loc, sc); | 301 type = type->semantic(loc, sc); |
232 if (sc->parent->isFuncDeclaration() && init) | 302 if (sc->parent->isFuncDeclaration() && init) |
233 semantic2(sc); | 303 semantic2(sc); |
304 storage_class |= sc->stc & STCdeprecated; | |
234 } | 305 } |
235 else if (sem == 1) | 306 else if (sem == 1) |
236 { | 307 { |
237 error("circular definition"); | 308 error("circular definition"); |
238 } | 309 } |
255 } | 326 } |
256 } | 327 } |
257 } | 328 } |
258 } | 329 } |
259 | 330 |
260 char *TypedefDeclaration::kind() | 331 const char *TypedefDeclaration::kind() |
261 { | 332 { |
262 return "typedef"; | 333 return "typedef"; |
263 } | 334 } |
264 | 335 |
265 Type *TypedefDeclaration::getType() | 336 Type *TypedefDeclaration::getType() |
316 assert(s); | 387 assert(s); |
317 } | 388 } |
318 | 389 |
319 Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s) | 390 Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s) |
320 { | 391 { |
392 //printf("AliasDeclaration::syntaxCopy()\n"); | |
321 assert(!s); | 393 assert(!s); |
322 AliasDeclaration *sa; | 394 AliasDeclaration *sa; |
323 if (type) | 395 if (type) |
324 sa = new AliasDeclaration(loc, ident, type->syntaxCopy()); | 396 sa = new AliasDeclaration(loc, ident, type->syntaxCopy()); |
325 else | 397 else |
464 { | 536 { |
465 return overnext->overloadInsert(s); | 537 return overnext->overloadInsert(s); |
466 } | 538 } |
467 } | 539 } |
468 | 540 |
469 char *AliasDeclaration::kind() | 541 const char *AliasDeclaration::kind() |
470 { | 542 { |
471 return "alias"; | 543 return "alias"; |
472 } | 544 } |
473 | 545 |
474 Type *AliasDeclaration::getType() | 546 Type *AliasDeclaration::getType() |
599 } | 671 } |
600 | 672 |
601 void VarDeclaration::semantic(Scope *sc) | 673 void VarDeclaration::semantic(Scope *sc) |
602 { | 674 { |
603 //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); | 675 //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); |
604 //printf("type = %s\n", type->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); | |
605 //printf("linkage = %d\n", sc->linkage); | 679 //printf("linkage = %d\n", sc->linkage); |
606 //if (strcmp(toChars(), "mul") == 0) halt(); | 680 //if (strcmp(toChars(), "mul") == 0) halt(); |
607 | 681 |
608 storage_class |= sc->stc; | 682 storage_class |= sc->stc; |
609 if (storage_class & STCextern && init) | 683 if (storage_class & STCextern && init) |
627 else | 701 else |
628 { if (!originalType) | 702 { if (!originalType) |
629 originalType = type; | 703 originalType = type; |
630 type = type->semantic(loc, sc); | 704 type = type->semantic(loc, sc); |
631 } | 705 } |
706 //printf(" semantic type = %s\n", type ? type->toChars() : "null"); | |
632 | 707 |
633 type->checkDeprecated(loc, sc); | 708 type->checkDeprecated(loc, sc); |
634 linkage = sc->linkage; | 709 linkage = sc->linkage; |
635 this->parent = sc->parent; | 710 this->parent = sc->parent; |
636 //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); | 711 //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); |
637 protection = sc->protection; | 712 protection = sc->protection; |
638 //printf("sc->stc = %x\n", sc->stc); | 713 //printf("sc->stc = %x\n", sc->stc); |
639 //printf("storage_class = %x\n", storage_class); | 714 //printf("storage_class = x%x\n", storage_class); |
640 | 715 |
641 Dsymbol *parent = toParent(); | 716 Dsymbol *parent = toParent(); |
642 FuncDeclaration *fd = parent->isFuncDeclaration(); | 717 FuncDeclaration *fd = parent->isFuncDeclaration(); |
643 | 718 |
644 Type *tb = type->toBasetype(); | 719 Type *tb = type->toBasetype(); |
747 if (id) | 822 if (id) |
748 { | 823 { |
749 error("field not allowed in interface"); | 824 error("field not allowed in interface"); |
750 } | 825 } |
751 | 826 |
827 /* Templates cannot add fields to aggregates | |
828 */ | |
752 TemplateInstance *ti = parent->isTemplateInstance(); | 829 TemplateInstance *ti = parent->isTemplateInstance(); |
753 if (ti) | 830 if (ti) |
754 { | 831 { |
755 // Take care of nested templates | 832 // Take care of nested templates |
756 while (1) | 833 while (1) |
851 { | 928 { |
852 // If local variable, use AssignExp to handle all the various | 929 // If local variable, use AssignExp to handle all the various |
853 // possibilities. | 930 // possibilities. |
854 if (fd && !isStatic() && !isConst() && !init->isVoidInitializer()) | 931 if (fd && !isStatic() && !isConst() && !init->isVoidInitializer()) |
855 { | 932 { |
856 Expression *e1; | |
857 Type *t; | |
858 int dim; | |
859 | |
860 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars()); | 933 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars()); |
861 if (!ei) | 934 if (!ei) |
862 { | 935 { |
863 Expression *e = init->toExpression(); | 936 Expression *e = init->toExpression(); |
864 if (!e) | 937 if (!e) |
872 } | 945 } |
873 ei = new ExpInitializer(init->loc, e); | 946 ei = new ExpInitializer(init->loc, e); |
874 init = ei; | 947 init = ei; |
875 } | 948 } |
876 | 949 |
877 e1 = new VarExp(loc, this); | 950 Expression *e1 = new VarExp(loc, this); |
878 | 951 |
879 t = type->toBasetype(); | 952 Type *t = type->toBasetype(); |
880 if (t->ty == Tsarray) | 953 if (t->ty == Tsarray) |
881 { | 954 { |
882 ei->exp = ei->exp->semantic(sc); | 955 ei->exp = ei->exp->semantic(sc); |
883 if (!ei->exp->implicitConvTo(type)) | 956 if (!ei->exp->implicitConvTo(type)) |
884 { | 957 { |
885 dim = ((TypeSArray *)t)->dim->toInteger(); | 958 int dim = ((TypeSArray *)t)->dim->toInteger(); |
886 // If multidimensional static array, treat as one large array | 959 // If multidimensional static array, treat as one large array |
887 while (1) | 960 while (1) |
888 { | 961 { |
889 t = t->nextOf()->toBasetype(); | 962 t = t->nextOf()->toBasetype(); |
890 if (t->ty != Tsarray) | 963 if (t->ty != Tsarray) |
972 | 1045 |
973 if (init) | 1046 if (init) |
974 ei = init->isExpInitializer(); | 1047 ei = init->isExpInitializer(); |
975 else | 1048 else |
976 { | 1049 { |
977 Expression *e = type->defaultInit(); | 1050 Expression *e = type->defaultInit(loc); |
978 if (e) | 1051 if (e) |
979 ei = new ExpInitializer(loc, e); | 1052 ei = new ExpInitializer(loc, e); |
980 else | 1053 else |
981 ei = NULL; | 1054 ei = NULL; |
982 } | 1055 } |
999 init = init->semantic(sc, type); | 1072 init = init->semantic(sc, type); |
1000 inuse--; | 1073 inuse--; |
1001 } | 1074 } |
1002 } | 1075 } |
1003 | 1076 |
1004 char *VarDeclaration::kind() | 1077 const char *VarDeclaration::kind() |
1005 { | 1078 { |
1006 return "variable"; | 1079 return "variable"; |
1007 } | 1080 } |
1008 | 1081 |
1009 Dsymbol *VarDeclaration::toAlias() | 1082 Dsymbol *VarDeclaration::toAlias() |
1018 { | 1091 { |
1019 if (storage_class & STCconst) | 1092 if (storage_class & STCconst) |
1020 buf->writestring("const "); | 1093 buf->writestring("const "); |
1021 if (storage_class & STCstatic) | 1094 if (storage_class & STCstatic) |
1022 buf->writestring("static "); | 1095 buf->writestring("static "); |
1096 if (storage_class & STCauto) | |
1097 buf->writestring("auto "); | |
1098 #if DMDV2 | |
1099 if (storage_class & STCmanifest) | |
1100 buf->writestring("manifest "); | |
1101 if (storage_class & STCinvariant) | |
1102 buf->writestring("invariant "); | |
1103 if (storage_class & STCtls) | |
1104 buf->writestring("__thread "); | |
1105 #endif | |
1106 | |
1023 if (type) | 1107 if (type) |
1024 type->toCBuffer(buf, ident, hgs); | 1108 type->toCBuffer(buf, ident, hgs); |
1025 else | 1109 else |
1026 buf->writestring(ident->toChars()); | 1110 buf->writestring(ident->toChars()); |
1027 if (init) | 1111 if (init) |
1050 if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield)) | 1134 if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield)) |
1051 error("missing initializer in static constructor for const variable"); | 1135 error("missing initializer in static constructor for const variable"); |
1052 } | 1136 } |
1053 | 1137 |
1054 /************************************ | 1138 /************************************ |
1055 * Check to see if variable is a reference to an enclosing function | 1139 * Check to see if this variable is actually in an enclosing function |
1056 * or not. | 1140 * rather than the current one. |
1057 */ | 1141 */ |
1058 | 1142 |
1059 void VarDeclaration::checkNestedReference(Scope *sc, Loc loc) | 1143 void VarDeclaration::checkNestedReference(Scope *sc, Loc loc) |
1060 { | 1144 { |
1145 //printf("VarDeclaration::checkNestedReference() %s\n", toChars()); | |
1061 if (parent && !isDataseg() && parent != sc->parent) | 1146 if (parent && !isDataseg() && parent != sc->parent) |
1062 { | 1147 { |
1148 // The function that this variable is in | |
1063 FuncDeclaration *fdv = toParent()->isFuncDeclaration(); | 1149 FuncDeclaration *fdv = toParent()->isFuncDeclaration(); |
1150 // The current function | |
1064 FuncDeclaration *fdthis = sc->parent->isFuncDeclaration(); | 1151 FuncDeclaration *fdthis = sc->parent->isFuncDeclaration(); |
1065 | 1152 |
1066 if (fdv && fdthis) | 1153 if (fdv && fdthis) |
1067 { | 1154 { |
1068 if (loc.filename) | 1155 if (loc.filename) |
1075 } | 1162 } |
1076 } | 1163 } |
1077 | 1164 |
1078 /******************************* | 1165 /******************************* |
1079 * Does symbol go into data segment? | 1166 * Does symbol go into data segment? |
1167 * Includes extern variables. | |
1080 */ | 1168 */ |
1081 | 1169 |
1082 int VarDeclaration::isDataseg() | 1170 int VarDeclaration::isDataseg() |
1083 { | 1171 { |
1084 #if 0 | 1172 #if 0 |
1199 assert(linkage == LINKc); | 1287 assert(linkage == LINKc); |
1200 } | 1288 } |
1201 | 1289 |
1202 /***************************** TypeInfoConstDeclaration **********************/ | 1290 /***************************** TypeInfoConstDeclaration **********************/ |
1203 | 1291 |
1204 #if V2 | 1292 #if DMDV2 |
1205 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo) | 1293 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo) |
1206 : TypeInfoDeclaration(tinfo, 0) | 1294 : TypeInfoDeclaration(tinfo, 0) |
1207 { | 1295 { |
1208 } | 1296 } |
1209 #endif | 1297 #endif |
1210 | 1298 |
1211 /***************************** TypeInfoInvariantDeclaration **********************/ | 1299 /***************************** TypeInfoInvariantDeclaration **********************/ |
1212 | 1300 |
1213 #if V2 | 1301 #if DMDV2 |
1214 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo) | 1302 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo) |
1215 : TypeInfoDeclaration(tinfo, 0) | 1303 : TypeInfoDeclaration(tinfo, 0) |
1216 { | 1304 { |
1217 } | 1305 } |
1218 #endif | 1306 #endif |