Changeset 880
- Timestamp:
- 03/08/08 17:06:46 (7 months ago)
- Files:
-
- branches/dmdfe-2.0/attrib.c (modified) (1 diff)
- branches/dmdfe-2.0/cast.c (modified) (22 diffs)
- branches/dmdfe-2.0/constfold.c (modified) (1 diff)
- branches/dmdfe-2.0/declaration.c (modified) (15 diffs)
- branches/dmdfe-2.0/declaration.h (modified) (2 diffs)
- branches/dmdfe-2.0/dsymbol.c (modified) (1 diff)
- branches/dmdfe-2.0/enum.c (modified) (12 diffs)
- branches/dmdfe-2.0/enum.h (modified) (3 diffs)
- branches/dmdfe-2.0/expression.c (modified) (8 diffs)
- branches/dmdfe-2.0/func.c (modified) (2 diffs)
- branches/dmdfe-2.0/init.c (modified) (2 diffs)
- branches/dmdfe-2.0/interpret.c (modified) (11 diffs)
- branches/dmdfe-2.0/lexer.c (modified) (1 diff)
- branches/dmdfe-2.0/lexer.h (modified) (1 diff)
- branches/dmdfe-2.0/mangle.c (modified) (1 diff)
- branches/dmdfe-2.0/mars.c (modified) (1 diff)
- branches/dmdfe-2.0/mtype.c (modified) (16 diffs)
- branches/dmdfe-2.0/mtype.h (modified) (3 diffs)
- branches/dmdfe-2.0/optimize.c (modified) (2 diffs)
- branches/dmdfe-2.0/parse.c (modified) (11 diffs)
- branches/dmdfe-2.0/statement.c (modified) (2 diffs)
- branches/dmdfe-2.0/template.c (modified) (7 diffs)
- branches/dmdfe-2.0/toobj.c (modified) (3 diffs)
- branches/dmdfe-2.0/typinf.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmdfe-2.0/attrib.c
r846 r880 281 281 { unsigned stc_save = sc->stc; 282 282 283 if (stc & (STCauto | STCscope | STCstatic | STCextern)) 284 sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern); 285 if (stc & (STCconst | STCinvariant)) 286 sc->stc &= ~(STCconst | STCinvariant); 283 /* These sets of storage classes are mutually exclusive, 284 * so choose the innermost or most recent one. 285 */ 286 if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 287 sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 288 if (stc & (STCconst | STCinvariant | STCmanifest)) 289 sc->stc &= ~(STCconst | STCinvariant | STCmanifest); 287 290 sc->stc |= stc; 288 291 for (unsigned i = 0; i < decl->dim; i++) branches/dmdfe-2.0/cast.c
r846 r880 58 58 59 59 #if 0 60 printf("ty = %d\n", type->ty); 60 61 print(); 61 62 type->print(); … … 139 140 toChars(), type->toChars(), t->toChars()); 140 141 #endif 141 if (type->equals(t)) 142 return MATCHexact; 142 MATCH m = type->implicitConvTo(t); 143 if (m >= MATCHconst) 144 return m; 143 145 144 146 TY ty = type->toBasetype()->ty; 145 147 TY toty = t->toBasetype()->ty; 146 148 147 if ( type->implicitConvTo(t)== MATCHnomatch && t->ty == Tenum)149 if (m == MATCHnomatch && t->ty == Tenum) 148 150 goto Lno; 149 151 … … 608 610 609 611 Expression *Expression::castTo(Scope *sc, Type *t) 610 { Expression *e; 611 Type *tb; 612 612 { 613 613 //printf("Expression::castTo(this=%s, t=%s)\n", toChars(), t->toChars()); 614 614 #if 0 … … 618 618 if (type == t) 619 619 return this; 620 e = this;621 tb = t->toBasetype();622 type= type->toBasetype();623 if (tb != type )620 Expression *e = this; 621 Type *tb = t->toBasetype(); 622 Type *typeb = type->toBasetype(); 623 if (tb != typeb) 624 624 { 625 625 // Do (type *) cast of (type [dim]) 626 626 if (tb->ty == Tpointer && 627 type ->ty == Tsarray627 typeb->ty == Tsarray 628 628 ) 629 629 { 630 630 //printf("Converting [dim] to *\n"); 631 631 632 if (type ->size(loc) == 0)632 if (typeb->size(loc) == 0) 633 633 e = new NullExp(loc); 634 634 else … … 648 648 } 649 649 } 650 else 651 { 652 e = e->copy(); // because of COW for assignment to e->type 653 } 654 assert(e != this); 650 655 e->type = t; 651 656 //printf("Returning: %s\n", e->toChars()); … … 655 660 656 661 Expression *RealExp::castTo(Scope *sc, Type *t) 657 { 658 if (type->isreal() && t->isreal()) 659 type = t; 660 else if (type->isimaginary() && t->isimaginary()) 661 type = t; 662 else 663 return Expression::castTo(sc, t); 664 return this; 662 { Expression *e = this; 663 if (type != t) 664 { 665 if ((type->isreal() && t->isreal()) || 666 (type->isimaginary() && t->isimaginary()) 667 ) 668 { e = copy(); 669 e->type = t; 670 } 671 else 672 e = Expression::castTo(sc, t); 673 } 674 return e; 665 675 } 666 676 667 677 668 678 Expression *ComplexExp::castTo(Scope *sc, Type *t) 669 { 670 if (type->iscomplex() && t->iscomplex()) 671 type = t; 672 else 673 return Expression::castTo(sc, t); 674 return this; 679 { Expression *e = this; 680 if (type != t) 681 { 682 if (type->iscomplex() && t->iscomplex()) 683 { e = copy(); 684 e->type = t; 685 } 686 else 687 e = Expression::castTo(sc, t); 688 } 689 return e; 675 690 } 676 691 677 692 678 693 Expression *NullExp::castTo(Scope *sc, Type *t) 679 { Expression*e;694 { NullExp *e; 680 695 Type *tb; 681 696 682 697 //printf("NullExp::castTo(t = %p)\n", t); 683 committed = 1; 684 e = this; 698 if (type == t) 699 { 700 committed = 1; 701 return this; 702 } 703 e = (NullExp *)copy(); 704 e->committed = 1; 685 705 tb = t->toBasetype(); 686 type = type->toBasetype();687 if (tb != type)706 e->type = type->toBasetype(); 707 if (tb != e->type) 688 708 { 689 709 // NULL implicitly converts to any pointer type or dynamic array 690 if ( type->ty == Tpointer &&type->nextOf()->ty == Tvoid &&710 if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tvoid && 691 711 (tb->ty == Tpointer || tb->ty == Tarray || tb->ty == Taarray || 692 712 tb->ty == Tdelegate)) … … 708 728 else 709 729 { 710 return Expression::castTo(sc, t); 711 //e = new CastExp(loc, e, tb); 730 return e->Expression::castTo(sc, t); 712 731 } 713 732 } … … 1006 1025 1007 1026 Expression *TupleExp::castTo(Scope *sc, Type *t) 1008 { 1009 for (size_t i = 0; i < exps->dim; i++) 1010 { Expression *e = (Expression *)exps->data[i]; 1011 e = e->castTo(sc, t); 1012 exps->data[i] = (void *)e; 1013 } 1014 return this; 1027 { TupleExp *e = (TupleExp *)copy(); 1028 e->exps = (Expressions *)exps->copy(); 1029 for (size_t i = 0; i < e->exps->dim; i++) 1030 { Expression *ex = (Expression *)e->exps->data[i]; 1031 ex = ex->castTo(sc, t); 1032 e->exps->data[i] = (void *)ex; 1033 } 1034 return e; 1015 1035 } 1016 1036 … … 1024 1044 if (type == t) 1025 1045 return this; 1046 ArrayLiteralExp *e = this; 1026 1047 Type *typeb = type->toBasetype(); 1027 1048 Type *tb = t->toBasetype(); … … 1036 1057 } 1037 1058 1059 e = (ArrayLiteralExp *)copy(); 1060 e->elements = (Expressions *)elements->copy(); 1038 1061 for (int i = 0; i < elements->dim; i++) 1039 { Expression *e = (Expression *)elements->data[i]; 1040 e = e->castTo(sc, tb->nextOf()); 1041 elements->data[i] = (void *)e; 1042 } 1043 type = t; 1062 { Expression *ex = (Expression *)elements->data[i]; 1063 ex = ex->castTo(sc, tb->nextOf()); 1064 e->elements->data[i] = (void *)ex; 1065 } 1066 e->type = t; 1067 return e; 1068 } 1069 if (tb->ty == Tpointer && typeb->ty == Tsarray) 1070 { 1071 e = (ArrayLiteralExp *)copy(); 1072 e->type = typeb->nextOf()->pointerTo(); 1073 } 1074 L1: 1075 return e->Expression::castTo(sc, t); 1076 } 1077 1078 Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t) 1079 { 1080 if (type == t) 1044 1081 return this; 1045 } 1046 if (tb->ty == Tpointer && typeb->ty == Tsarray) 1047 { 1048 type = typeb->nextOf()->pointerTo(); 1049 } 1050 L1: 1051 return Expression::castTo(sc, t); 1052 } 1053 1054 Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t) 1055 { 1082 AssocArrayLiteralExp *e = this; 1056 1083 Type *typeb = type->toBasetype(); 1057 1084 Type *tb = t->toBasetype(); … … 1059 1086 tb->nextOf()->toBasetype()->ty != Tvoid) 1060 1087 { 1088 e = (AssocArrayLiteralExp *)copy(); 1089 e->keys = (Expressions *)keys->copy(); 1090 e->values = (Expressions *)values->copy(); 1061 1091 assert(keys->dim == values->dim); 1062 1092 for (size_t i = 0; i < keys->dim; i++) 1063 { Expression *e = (Expression *)values->data[i];1064 e = e->castTo(sc, tb->nextOf());1065 values->data[i] = (void *)e;1066 1067 e = (Expression *)keys->data[i];1068 e = e->castTo(sc, ((TypeAArray *)tb)->index);1069 keys->data[i] = (void *)e;1070 } 1071 type = t;1072 return this;1093 { Expression *ex = (Expression *)values->data[i]; 1094 ex = ex->castTo(sc, tb->nextOf()); 1095 e->values->data[i] = (void *)ex; 1096 1097 ex = (Expression *)keys->data[i]; 1098 ex = ex->castTo(sc, ((TypeAArray *)tb)->index); 1099 e->keys->data[i] = (void *)ex; 1100 } 1101 e->type = t; 1102 return e; 1073 1103 } 1074 1104 L1: 1075 return Expression::castTo(sc, t);1105 return e->Expression::castTo(sc, t); 1076 1106 } 1077 1107 1078 1108 Expression *SymOffExp::castTo(Scope *sc, Type *t) 1079 1109 { 1080 Type *tb;1081 1082 1110 #if 0 1083 1111 printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", 1084 1112 toChars(), type->toChars(), t->toChars()); 1085 1113 #endif 1086 Expression *e = this; 1087 1088 tb = t->toBasetype(); 1089 type = type->toBasetype(); 1090 if (tb != type) 1114 if (type == t && hasOverloads == 0) 1115 return this; 1116 Expression *e; 1117 Type *tb = t->toBasetype(); 1118 Type *typeb = type->toBasetype(); 1119 if (tb != typeb) 1091 1120 { 1092 1121 // Look for pointers to functions where the functions are overloaded. … … 1094 1123 1095 1124 if (hasOverloads && 1096 type ->ty == Tpointer && type->nextOf()->ty == Tfunction &&1125 typeb->ty == Tpointer && typeb->nextOf()->ty == Tfunction && 1097 1126 (tb->ty == Tpointer || tb->ty == Tdelegate) && tb->nextOf()->ty == Tfunction) 1098 1127 { … … 1125 1154 e = Expression::castTo(sc, t); 1126 1155 } 1127 if (e == this && hasOverloads) 1128 { e = syntaxCopy(); 1156 else 1157 { e = copy(); 1158 e->type = t; 1129 1159 ((SymOffExp *)e)->hasOverloads = 0; 1130 1160 } 1131 e->type = t;1132 1161 return e; 1133 1162 } … … 1135 1164 Expression *DelegateExp::castTo(Scope *sc, Type *t) 1136 1165 { 1137 Type *tb;1138 1166 #if 0 1139 1167 printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n", 1140 1168 toChars(), type->toChars(), t->toChars()); 1141 1169 #endif 1170 static char msg[] = "cannot form delegate due to covariant return type"; 1171 1142 1172 Expression *e = this; 1143 static char msg[] = "cannot form delegate due to covariant return type"; 1144 1145 tb = t->toBasetype(); 1146 type = type->toBasetype(); 1147 if (tb != type) 1173 Type *tb = t->toBasetype(); 1174 Type *typeb = type->toBasetype(); 1175 if (tb != typeb) 1148 1176 { 1149 1177 // Look for delegates to functions where the functions are overloaded. 1150 1178 FuncDeclaration *f; 1151 1179 1152 if (type ->ty == Tdelegate && type->nextOf()->ty == Tfunction &&1180 if (typeb->ty == Tdelegate && typeb->nextOf()->ty == Tfunction && 1153 1181 tb->ty == Tdelegate && tb->nextOf()->ty == Tfunction) 1154 1182 { … … 1177 1205 if (func->tintro && func->tintro->nextOf()->isBaseOf(func->type->nextOf(), &offset) && offset) 1178 1206 error("%s", msg); 1179 } 1180 e->type = t; 1207 e = copy(); 1208 e->type = t; 1209 } 1181 1210 return e; 1182 1211 } … … 1262 1291 t2 = e2->type; 1263 1292 assert(t1); 1293 t = t1; 1264 1294 1265 1295 //if (t1) printf("\tt1 = %s\n", t1->toChars()); … … 1317 1347 return this; 1318 1348 } 1349 1350 t1 = t1b; 1351 t2 = t2b; 1319 1352 1320 1353 if (op == TOKcat) … … 1338 1371 else 1339 1372 e2 = e2->castTo(sc, t2); 1373 t = t1; 1340 1374 goto Lagain; 1341 1375 } … … 1343 1377 1344 1378 Lagain: 1345 t = t1;1346 1379 if (t1 == t2) 1347 1380 { … … 1366 1399 t1 = t1n->mutableOf()->constOf()->pointerTo(); 1367 1400 t2 = t2n->mutableOf()->constOf()->pointerTo(); 1401 t = t1; 1368 1402 goto Lagain; 1369 1403 } … … 1429 1463 else 1430 1464 t2 = t2->nextOf()->mutableOf()->constOf()->arrayOf(); 1465 t = t1; 1431 1466 goto Lagain; 1432 1467 } … … 1527 1562 1528 1563 Expression *Expression::integralPromotions(Scope *sc) 1529 { Expression *e; 1530 1531 e = this; 1564 { 1565 Expression *e = this; 1566 1567 //printf("integralPromotions %s %s\n", e->toChars(), e->type->toChars()); 1532 1568 switch (type->toBasetype()->ty) 1533 1569 { branches/dmdfe-2.0/constfold.c
r836 r880 880 880 real_t r2; 881 881 882 if (e1->type->isreal()) 882 //printf("Cmp(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 883 884 if (e1->op == TOKstring && e2->op == TOKstring) 885 { StringExp *es1 = (StringExp *)e1; 886 StringExp *es2 = (StringExp *)e2; 887 size_t sz = es1->sz; 888 assert(sz == es2->sz); 889 890 size_t len = es1->len; 891 if (es2->len < len) 892 len = es2->len; 893 894 int cmp = memcmp(es1->string, es2->string, sz * len); 895 if (cmp == 0) 896 cmp = es1->len - es2->len; 897 898 switch (op) 899 { 900 case TOKlt: n = cmp < 0; break; 901 case TOKle: n = cmp <= 0; break; 902 case TOKgt: n = cmp > 0; break; 903 case TOKge: n = cmp >= 0; break; 904 905 case TOKleg: n = 1; break; 906 case TOKlg: n = cmp != 0; break; 907 case TOKunord: n = 0; break; 908 case TOKue: n = cmp == 0; break; 909 case TOKug: n = cmp > 0; break; 910 case TOKuge: n = cmp >= 0; break; 911 case TOKul: n = cmp < 0; break; 912 case TOKule: n = cmp <= 0; break; 913 914 default: 915 assert(0); 916 } 917 } 918 else if (e1->isConst() != 1 || e2->isConst() != 1) 919 return EXP_CANT_INTERPRET; 920 else if (e1->type->isreal()) 883 921 { 884 922 r1 = e1->toReal(); branches/dmdfe-2.0/declaration.c
r846 r880 92 92 error(loc, "cannot modify parameter '%s' in contract", toChars()); 93 93 94 VarDeclaration *v = isVarDeclaration();95 if (v && v->canassign == 0 &&96 (isConst() || isInvariant()) && !isCtorinit())97 error(loc, "cannot modify const/invariant variable '%s'", toChars());98 99 94 if (isCtorinit()) 100 95 { // It's only modifiable if inside the right constructor … … 111 106 ) 112 107 { 108 VarDeclaration *v = isVarDeclaration(); 113 109 assert(v); 114 110 v->ctorinit = 1; … … 129 125 } 130 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 (!type->isAssignable()) 142 p = "struct with immutable members"; 143 if (p) 144 error(loc, "cannot modify %s", p); 131 145 } 132 146 } … … 753 767 type = type->constOf(); 754 768 } 755 756 if (storage_class & (STCstatic | STCextern)) 757 { 758 } 759 else if (isSynchronized()) 769 else if (type->isConst()) 770 storage_class |= STCconst; 771 else if (type->isInvariant()) 772 storage_class |= STCinvariant; 773 774 if (isSynchronized()) 760 775 { 761 776 error("variable %s cannot be synchronized", toChars()); … … 769 784 error("abstract cannot be applied to variable"); 770 785 } 771 else if (storage_class & STCtemplateparameter) 786 else if (storage_class & STCfinal) 787 { 788 error("final cannot be applied to variable"); 789 } 790 791 if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter)) 772 792 { 773 793 } … … 820 840 if (type->isauto() && !noauto) 821 841 { 822 if (storage_class & (STCfield | STCout | STCref | STCstatic ) || !fd)823 { 824 error("globals, statics, fields, ref and out parameters cannot be auto");842 if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest) || !fd) 843 { 844 error("globals, statics, fields, manifest constants, ref and out parameters cannot be auto"); 825 845 } 826 846 … … 839 859 if (init) 840 860 storage_class |= STCinit; // remember we had an explicit initializer 861 else if (storage_class & STCmanifest) 862 error("manifest constants must have initializers"); 841 863 842 864 if (!init && !sc->inunion && !isStatic() && fd && … … 907 929 // If local variable, use AssignExp to handle all the various 908 930 // possibilities. 909 if (fd && !isStatic() && 931 if (fd && !isStatic() && !(storage_class & STCmanifest) && 910 932 !init->isVoidInitializer()) 911 933 { … … 970 992 } 971 993 } 972 else if (storage_class & (STCconst | STCinvariant ) ||994 else if (storage_class & (STCconst | STCinvariant | STCmanifest) || 973 995 type->isConst() || type->isInvariant()) 974 996 { … … 1070 1092 void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 1071 1093 { 1094 if (storage_class & STCmanifest) 1095 buf->writestring("manifest "); 1072 1096 if (storage_class & STCstatic) 1073 1097 buf->writestring("static "); … … 1116 1140 void VarDeclaration::checkNestedReference(Scope *sc, Loc loc) 1117 1141 { 1118 if (parent && !isDataseg() && parent != sc->parent) 1142 if (parent && !isDataseg() && parent != sc->parent && 1143 !(storage_class & STCmanifest)) 1119 1144 { 1120 1145 // The function that this variable is in … … 1178 1203 Expression *VarDeclaration::getConstInitializer() 1179 1204 { 1180 if ((isConst() || isInvariant() ) &&1205 if ((isConst() || isInvariant() || storage_class & STCmanifest) && 1181 1206 storage_class & STCinit) 1182 1207 { … … 1195 1220 int VarDeclaration::canTakeAddressOf() 1196 1221 { 1222 #if 0 1197 1223 /* Global variables and struct/class fields of the form: 1198 1224 * const int x = 3; … … 1208 1234 return 0; 1209 1235 } 1236 #else 1237 if (storage_class & STCmanifest) 1238 return 0; 1239 #endif 1210 1240 return 1; 1211 1241 } … … 1223 1253 printf("parent = '%s'\n", parent->toChars()); 1224 1254 #endif 1255 if (storage_class & STCmanifest) 1256 return 0; 1225 1257 Dsymbol *parent = this->toParent(); 1226 1258 if (!parent && !(storage_class & STCstatic)) branches/dmdfe-2.0/declaration.h
r846 r880 65 65 STCref = 0x200000, 66 66 STCinit = 0x400000, // has explicit initializer 67 STCmanifest = 0x800000, // manifest constant 67 68 }; 68 69 … … 251 252 VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } 252 253 }; 254 253 255 254 256 /**************************************************************/ branches/dmdfe-2.0/dsymbol.c
r846 r880 809 809 s2->locToChars()); 810 810 } 811 halt(); 811 812 } 812 813 branches/dmdfe-2.0/enum.c
r835 r880 1 1 2 // Copyright (c) 1999-200 6by Digital Mars2 // Copyright (c) 1999-2007 by Digital Mars 3 3 // All Rights Reserved 4 4 // written by Walter Bright … … 15 15 #include "mtype.h" 16 16 #include "scope.h" 17 #include "id.h" 18 #include "expression.h" 19 #include "module.h" 17 20 18 21 /********************************* EnumDeclaration ****************************/ … … 24 27 type = new TypeEnum(this); 25 28 this->memtype = memtype; 26 maxval = 0;27 minval = 0;28 defaultval = 0;29 maxval = NULL; 30 minval = NULL; 31 defaultval = NULL; 29 32 sinit = NULL; 33 scope = NULL; 30 34 } 31 35 … … 48 52 49 53 void EnumDeclaration::semantic(Scope *sc) 50 { int i; 51 uinteger_t number; 54 { 52 55 Type *t; 53 56 Scope *sce; 54 57 55 //printf("EnumDeclaration::semantic(sd = %p, '%s')\n", sc->scopesym, sc->scopesym->toChars()); 56 if (symtab) // if already done 57 return; 58 if (!memtype) 59 memtype = Type::tint32; 60 parent = sc->scopesym; 61 memtype = memtype->semantic(loc, sc); 62 63 /* Check to see if memtype is forward referenced 64 */ 65 if (memtype->ty == Tenum) 66 { EnumDeclaration *sym = (EnumDeclaration *)memtype->toDsymbol(sc); 67 if (!sym->memtype) 68 { 69 error("base enum %s is forward referenced", sym->toChars()); 70 memtype = Type::tint32; 71 } 72 } 73 74 if (!memtype->isintegral()) 75 { error("base type must be of integral type, not %s", memtype->toChars()); 76 memtype = Type::tint32; 77 } 78 79 t = isAnonymous() ? memtype : type; 80 symtab = new DsymbolTable(); 81 sce = sc->push(this); 82 sce->parent = this; 83 number = 0; 58 //printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc->scopesym, sc->scopesym->toChars(), toChars()); 59 //printf("EnumDeclaration::semantic() %s\n", toChars()); 84 60 if (!members) // enum ident; 85 61 return; 62 63 if (!memtype && !isAnonymous()) 64 { // Set memtype if we can to reduce fwd reference errors 65 memtype = Type::tint32; // case 1) enum ident { ... } 66 } 67 68 if (symtab) // if already done 69 { if (!scope) 70 return; // semantic() already completed 71 } 72 else 73 symtab = new DsymbolTable(); 74 75 Scope *scx = NULL; 76 if (scope) 77 { sc = scope; 78 scx = scope; // save so we don't make redundant copies 79 scope = NULL; 80 } 81 82 parent = sc->parent; 83 84 /* The separate, and distinct, cases are: 85 * 1. enum { ... } 86 * 2. enum : memtype { ... } 87 * 3. enum ident { ... } 88 * 4. enum ident : memtype { ... } 89 */ 90 91 if (memtype) 92 { 93 memtype = memtype->semantic(loc, sc); 94 95 /* Check to see if memtype is forward referenced 96 */ 97 if (memtype->ty == Tenum) 98 { EnumDeclaration *sym = (EnumDeclaration *)memtype->toDsymbol(sc); 99 if (!sym->memtype || !sym->members || !sym->symtab || sym->scope) 100 { // memtype is forward referenced, so try again later 101 scope = scx ? scx : new Scope(*sc); 102 scope->setNoFree(); 103 scope->module->addDeferredSemantic(this); 104 printf("\tdeferring %s\n", toChars()); 105 return; 106 } 107 } 108 #if 0 // Decided to abandon this restriction for D 2.0 109 if (!memtype->isintegral()) 110 { error("base type must be of integral type, not %s", memtype->toChars()); 111 memtype = Type::tint32; 112 } 113 #endif 114 } 115 116 type = type->semantic(loc, sc); 117 if (isAnonymous()) 118 sce = sc; 119 else 120 { sce = sc->push(this); 121 sce->parent = this; 122 } 86 123 if (members->dim == 0) 87 124 error("enum %s must have at least one member", toChars()); 88 125 int first = 1; 89 for (i = 0; i < members->dim; i++) 126 Expression *elast = NULL; 127 for (int i = 0; i < members->dim; i++) 90 128 { 91 129 EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember(); … … 98 136 continue; 99 137 100 //printf("Enum member '%s'\n",em->toChars()); 138 //printf(" Enum member '%s'\n",em->toChars()); 139 if (em->type) 140 em->type = em->type->semantic(em->loc, sce); 101 141 e = em->value; 102 142 if (e) … … 105 145 e = e->semantic(sce); 106 146 e = e->optimize(WANTvalue | WANTinterpret); 107 // Need to copy it because we're going to change the type 108 e = e->copy(); 109 e = e->implicitCastTo(sc, memtype); 147 if (memtype) 148 { 149 e = e->implicitCastTo(sce, memtype); 150 e = e->optimize(WANTvalue | WANTinterpret); 151 if (!isAnonymous()) 152 e = e->castTo(sce, type); 153 t = memtype; 154 } 155 else if (em->type) 156 { 157 e = e->implicitCastTo(sce, em->type); 158 e = e->optimize(WANTvalue | WANTinterpret); 159 assert(isAnonymous()); 160 t = e->type; 161 } 162 else 163 t = e->type; 164 } 165 else if (first) 166 { 167 if (memtype) 168 t = memtype; 169 else if (em->type) 170 t = em->type; 171 else 172 t = Type::tint32; 173 e = new IntegerExp(em->loc, 0, Type::tint32); 174 e = e->implicitCastTo(sce, t); 110 175 e = e->optimize(WANTvalue | WANTinterpret); 111 number = e->toInteger();112 e->type = t;176 if (!isAnonymous()) 177 e = e->castTo(sce, type); 113 178 } 114 179 else 115 { // Default is the previous number plus 1 116 117 // Check for overflow 118 if (!first) 119 { 120 switch (t->toBasetype()->ty) 121 { 122 case Tbool: 123 if (number == 2) goto Loverflow; 124 break; 125 126 case Tint8: 127 if (number == 128) goto Loverflow; 128 break; 129 130 case Tchar: 131 case Tuns8: 132 if (number == 256) goto Loverflow; 133 break; 134 135 case Tint16: 136 if (number == 0x8000) goto Loverflow; 137 break; 138 139 case Twchar: 140 case Tuns16: 141 if (number == 0x10000) goto Loverflow; 142 break; 143 144 case Tint32: 145 if (number == 0x80000000) goto Loverflow; 146 break; 147 148 case Tdchar: 149 case Tuns32: 150 if (number == 0x100000000LL) goto Loverflow; 151 break; 152 153 case Tint64: 154 if (number == 0x8000000000000000LL) goto Loverflow; 155 break; 156 157 case Tuns64: 158 if (number == 0) goto Loverflow; 159 break; 160 161 Loverflow: 162 error("overflow of enum value"); 163 break; 164 165 default: 166 assert(0); 167 } 168 } 169 e = new IntegerExp(em->loc, number, t); 170 } 180 { 181 // Set value to (elast + 1). 182 // But first check that (elast != t.max) 183 assert(elast); 184 e = new EqualExp(TOKequal, em->loc, elast, t->getProperty(0, Id::max)); 185 e = e->semantic(sce); 186 e = e->optimize(WANTvalue | WANTinterpret); 187 if (e->toInteger()) 188 error("overflow of enum value %s", elast->toChars()); 189 190 // Now set e to (elast + 1) 191 e = new AddExp(em->loc, elast, new IntegerExp(em->loc, 1, Type::tint32)); 192 e = e->semantic(sce); 193 e = e->castTo(sce, elast->type); 194 e = e->optimize(WANTvalue | WANTinterpret); 195 } 196 elast = e; 171 197 em->value = e; 172 198 … … 174 200 if (isAnonymous()) 175 201 { 176 //sce->enclosing->insert(em); 177 for (Scope *scx = sce->enclosing; scx; scx = scx->enclosing) 202 /* Anonymous enum members get added to enclosing scope. 203 */ 204 for (Scope *scx = sce; scx; scx = scx->enclosing) 178 205 { 179 206 if (scx->scopesym) … … 189 216 em->addMember(sc, this, 1); 190 217 191 if (first) 192 { first = 0; 193 defaultval = number; 194 minval = number; 195 maxval = number; 196 } 197 else if (memtype->isunsigned()) 198 { 199 if (number < minval) 200 minval = number; 201 if (number > maxval) 202 maxval = number; 203 } 204 else 205 { 206 if ((sinteger_t)number < (sinteger_t)minval) 207 minval = number; 208 if ((sinteger_t)number > (sinteger_t)maxval) 209 maxval = number; 210 } 211 212 number++; 218 /* Compute .min, .max and .default values. 219 * If enum doesn't have a name, we can never identify the enum type, 220 * so there is no purpose for a .min, .max or .default 221 */ 222 if (!isAnonymous()) 223 { 224 if (first) 225 { defaultval = e; 226 minval = e; 227 maxval = e; 228 } 229 else 230 { Expression *ec; 231 232 /* In order to work successfully with UDTs, 233 * build expressions to do the comparisons, 234 * and let the semantic analyzer and constant 235 * folder give us the result. 236 */ 237 238 // Compute if(e < minval) 239 ec = new CmpExp(TOKlt, em->loc, e, minval); 240 ec = ec->semantic(sce); 241 ec = ec->optimize(WANTvalue | WANTinterpret); 242 if (ec->toInteger()) 243 minval = e; 244 245 ec = new CmpExp(TOKgt, em->loc, e, maxval); 246 ec = ec->semantic(sce); 247 ec = ec->optimize(WANTvalue | WANTinterpret); 248 if (ec->toInteger()) 249 maxval = e; 250 } 251 } 252 first = 0; 213 253 } 214 254 //printf("defaultval = %lld\n", defaultval); 215 255 216 sce->pop(); 256 //if (defaultval) printf("defaultval: %s %s\n", defaultval->toChars(), defaultval->type->toChars()); 257 if (sc != sce) 258 sce->pop(); 217 259 //members->print(); 218 260 } … … 271 313 } 272 314 315 Dsymbol *EnumDeclaration::search(Loc loc, Identifier *ident, int flags) 316 { 317 //printf("%s.EnumDeclaration::search('%s')\n", toChars(), ident->toChars()); 318 if (scope) 319 // Try one last time to resolve this enum 320 semantic(scope); 321 322 if (!members || !symtab || scope) 323 { error("is forward referenced when looking for '%s'", ident->toChars()); 324 //*(char*)0=0; 325 return NULL; 326 } 327 328 Dsymbol *s = ScopeDsymbol::search(loc, ident, flags); 329 return s; 330 } 331 273 332 /********************************* EnumMember ****************************/ 274 333 275 EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value )334 EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value, Type *type) 276 335 : Dsymbol(id) 277 336 { 278 337 this->value = value; 338 this->type = type; 279 339 this->loc = loc; 280 340 } … … 285 345 if (value) 286 346 e = value->syntaxCopy(); 347 348 Type *t = NULL; 349 if (type) 350 t = type->syntaxCopy(); 287 351 288 352 EnumMember *em; … … 291 355 em->loc = loc; 292 356 em->value = e; 293 } 294 else 295 em = new EnumMember(loc, ident, e); 357 em->type = t; 358 } 359 else 360 em = new EnumMember(loc, ident, e, t); 296 361 return em; 297 362 } … … 299 364 void EnumMember::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 300 365 { 301 buf->writestring(ident->toChars()); 366 if (type) 367 type->toCBuffer(buf, ident, hgs); 368 else 369 buf-&
