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