Changeset 884
- Timestamp:
- 03/08/08 17:29:17 (6 months ago)
- Files:
-
- trunk/rebuild/Makefile (modified) (1 diff)
- trunk/rebuild/access.c (modified) (1 diff)
- trunk/rebuild/aggregate.h (modified) (11 diffs)
- trunk/rebuild/attrib.c (modified) (4 diffs)
- trunk/rebuild/cast.c (modified) (30 diffs)
- trunk/rebuild/class.c (modified) (2 diffs)
- trunk/rebuild/clone.c (copied) (copied from branches/dmdfe-2.0/clone.c)
- trunk/rebuild/constfold.c (modified) (1 diff)
- trunk/rebuild/declaration.c (modified) (28 diffs)
- trunk/rebuild/declaration.h (modified) (5 diffs)
- trunk/rebuild/doc.c (modified) (10 diffs)
- trunk/rebuild/dsymbol.c (modified) (5 diffs)
- trunk/rebuild/dsymbol.h (modified) (4 diffs)
- trunk/rebuild/enum.c (modified) (12 diffs)
- trunk/rebuild/enum.h (modified) (3 diffs)
- trunk/rebuild/expression.c (modified) (81 diffs)
- trunk/rebuild/expression.h (modified) (15 diffs)
- trunk/rebuild/func.c (modified) (32 diffs)
- trunk/rebuild/idgen.c (modified) (4 diffs)
- trunk/rebuild/init.c (modified) (2 diffs)
- trunk/rebuild/interpret.c (modified) (14 diffs)
- trunk/rebuild/lexer.c (modified) (10 diffs)
- trunk/rebuild/lexer.h (modified) (5 diffs)
- trunk/rebuild/mangle.c (modified) (1 diff)
- trunk/rebuild/mars.c (modified) (4 diffs)
- trunk/rebuild/mtype.c (modified) (39 diffs)
- trunk/rebuild/mtype.h (modified) (6 diffs)
- trunk/rebuild/optimize.c (modified) (5 diffs)
- trunk/rebuild/parse.c (modified) (24 diffs)
- trunk/rebuild/parse.h (modified) (2 diffs)
- trunk/rebuild/scope.c (modified) (2 diffs)
- trunk/rebuild/scope.h (modified) (1 diff)
- trunk/rebuild/statement.c (modified) (59 diffs)
- trunk/rebuild/statement.h (modified) (35 diffs)
- trunk/rebuild/struct.c (modified) (5 diffs)
- trunk/rebuild/template.c (modified) (39 diffs)
- trunk/rebuild/template.h (modified) (1 diff)
- trunk/rebuild/traits.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/rebuild/Makefile
r785 r884 21 21 cast.o \ 22 22 class.o \ 23 clone.o \ 23 24 compile.o \ 24 25 cond.o \ trunk/rebuild/access.c
r459 r884 254 254 { 255 255 //error(loc, "member %s is not accessible", smember->toChars()); 256 halt(); 256 257 } 257 258 } trunk/rebuild/aggregate.h
r840 r884 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 7by Digital Mars3 // Copyright (c) 1999-2008 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 58 58 DeleteDeclaration *aggDelete; // deallocator 59 59 60 FuncDeclarations dtors; // Array of destructors 61 FuncDeclaration *dtor; // aggregate destructor 62 60 63 #ifdef IN_GCC 61 64 Array methods; // flat list of all methods for debug information … … 71 74 void addField(Scope *sc, VarDeclaration *v); 72 75 int isDeprecated(); // is aggregate deprecated? 76 FuncDeclaration *buildDtor(Scope *sc); 73 77 74 78 void emitComment(Scope *sc); … … 103 107 { 104 108 int zeroInit; // !=0 if initialize with 0 fill 109 int hasIdentityAssign; // !=0 if has identity opAssign 110 FuncDeclaration *cpctor; // generated copy-constructor, if any 111 112 FuncDeclarations postblits; // Array of postblit functions 113 FuncDeclaration *postblit; // aggregate postblit 105 114 106 115 StructDeclaration(Loc loc, Identifier *id); … … 110 119 char *mangle(); 111 120 char *kind(); 121 int needOpAssign(); 122 FuncDeclaration *buildOpAssign(Scope *sc); 123 FuncDeclaration *buildPostBlit(Scope *sc); 124 FuncDeclaration *buildCpCtor(Scope *sc); 112 125 void toDocBuffer(OutBuffer *buf); 113 126 … … 149 162 }; 150 163 164 #if V2 151 165 #define CLASSINFO_SIZE (0x3C+16) // value of ClassInfo.size 166 #else 167 #define CLASSINFO_SIZE (0x3C+12) // value of ClassInfo.size 168 #endif 152 169 153 170 struct ClassDeclaration : AggregateDeclaration … … 159 176 CtorDeclaration *ctor; 160 177 CtorDeclaration *defaultCtor; // default constructor 161 FuncDeclarations dtors; // Array of destructors162 178 FuncDeclaration *staticCtor; 163 179 FuncDeclaration *staticDtor; … … 194 210 195 211 Dsymbol *search(Loc, Identifier *ident, int flags); 212 #if V2 196 213 int isFuncHidden(FuncDeclaration *fd); 214 #endif 197 215 FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf); 198 216 void interfaceSemantic(Scope *sc); … … 200 218 int isCOMclass(); 201 219 virtual int isCOMinterface(); 220 #if V2 202 221 virtual int isCPPinterface(); 222 #endif 203 223 int isAbstract(); 204 224 virtual int vtblOffset(); … … 224 244 struct InterfaceDeclaration : ClassDeclaration 225 245 { 246 #if V2 226 247 int cpp; // !=0 if this is a C++ interface 227 248 #endif 228 249 InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 229 250 Dsymbol *syntaxCopy(Dsymbol *s); … … 233 254 char *kind(); 234 255 int vtblOffset(); 256 #if V2 235 257 int isCPPinterface(); 258 #endif 236 259 virtual int isCOMinterface(); 237 260 trunk/rebuild/attrib.c
r847 r884 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 7by Digital Mars3 // Copyright (c) 1999-2008 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 35 35 36 36 extern void obj_includelib(char *name); 37 void obj_startaddress(Symbol *s); 37 38 38 39 … … 308 309 { unsigned stc_save = sc->stc; 309 310 310 if (stc & (STCauto | STCscope | STCstatic | STCextern)) 311 sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern); 312 if (stc & (STCconst | STCinvariant)) 313 sc->stc &= ~(STCconst | STCinvariant); 311 /* These sets of storage classes are mutually exclusive, 312 * so choose the innermost or most recent one. 313 */ 314 if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 315 sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 316 if (stc & (STCconst | STCinvariant | STCmanifest)) 317 sc->stc &= ~(STCconst | STCinvariant | STCmanifest); 314 318 sc->stc |= stc; 315 319 for (unsigned i = 0; i < decl->dim; i++) … … 824 828 } 825 829 #endif 830 else if (ident == Id::startaddress) 831 { 832 if (!args || args->dim != 1) 833 error("function name expected for start address"); 834 else 835 { 836 Expression *e = (Expression *)args->data[0]; 837 e = e->semantic(sc); 838 e = e->optimize(WANTvalue | WANTinterpret); 839 args->data[0] = (void *)e; 840 Dsymbol *sa = getDsymbol(e); 841 if (!sa || !sa->isFuncDeclaration()) 842 error("function name expected for start address, not '%s'", e->toChars()); 843 } 844 goto Lnodecl; 845 } 826 846 else 827 847 error("unrecognized pragma(%s)", ident->toChars()); */ trunk/rebuild/cast.c
r847 r884 35 35 //printf("%s\n", toChars()); 36 36 37 if (implicitConvTo(t)) 37 MATCH match = implicitConvTo(t); 38 if (match) 38 39 { 39 40 if (global.params.warnings && … … 50 51 toChars(), type->toChars(), t->toChars());*/ 51 52 } 53 if (match == MATCHconst && t == type->constOf()) 54 { 55 Expression *e = copy(); 56 e->type = t; 57 return e; 58 } 52 59 return castTo(sc, t); 53 60 } … … 58 65 59 66 #if 0 67 printf("ty = %d\n", type->ty); 60 68 print(); 61 69 type->print(); … … 96 104 toChars(), type->toChars(), t->toChars()); 97 105 #endif 98 //static int nest; if (++nest == 10) halt();106 //static int nest; if (++nest == 50) halt(); 99 107 if (!type) 100 108 { //error("%s is not an expression", toChars()); … … 105 113 return MATCHexact; 106 114 if (e != this) 107 { //printf(" optimized to %s\n",e->toChars());115 { //printf("\toptimized to %s of type %s\n", e->toChars(), e->type->toChars()); 108 116 return e->implicitConvTo(t); 109 117 } … … 139 147 toChars(), type->toChars(), t->toChars()); 140 148 #endif 141 if (type->equals(t)) 142 return MATCHexact; 149 MATCH m = type->implicitConvTo(t); 150 if (m >= MATCHconst) 151 return m; 143 152 144 153 TY ty = type->toBasetype()->ty; 145 154 TY toty = t->toBasetype()->ty; 146 155 147 if ( type->implicitConvTo(t)== MATCHnomatch && t->ty == Tenum)156 if (m == MATCHnomatch && t->ty == Tenum) 148 157 goto Lno; 149 158 … … 333 342 if (this->type->equals(t)) 334 343 return MATCHexact; 344 345 /* Allow implicit conversions from invariant to mutable|const, 346 * and mutable to invariant. It works because, after all, a null 347 * doesn't actually point to anything. 348 */ 349 if (t->invariantOf()->equals(type->invariantOf())) 350 return MATCHconst; 351 335 352 // NULL implicitly converts to any pointer type or dynamic array 336 353 if (type->ty == Tpointer && type->nextOf()->ty == Tvoid) … … 344 361 } 345 362 return Expression::implicitConvTo(t); 363 } 364 365 MATCH StructLiteralExp::implicitConvTo(Type *t) 366 { 367 #if 0 368 printf("StructLiteralExp::implicitConvTo(this=%s, type=%s, t=%s)\n", 369 toChars(), type->toChars(), t->toChars()); 370 #endif 371 MATCH m = Expression::implicitConvTo(t); 372 if (m != MATCHnomatch) 373 return m; 374 if (type->ty == t->ty && type->ty == Tstruct && 375 ((TypeStruct *)type)->sym == ((TypeStruct *)t)->sym) 376 { 377 m = MATCHconst; 378 for (int i = 0; i < elements->dim; i++) 379 { Expression *e = (Expression *)elements->data[i]; 380 Type *te = e->type; 381 if (t->mod == 0) 382 te = te->mutableOf(); 383 else 384 { assert(t->mod == MODinvariant); 385 te = te->invariantOf(); 386 } 387 MATCH m2 = e->implicitConvTo(te); 388 //printf("\t%s => %s, match = %d\n", e->toChars(), te->toChars(), m2); 389 if (m2 < m) 390 m = m2; 391 } 392 } 393 return m; 346 394 } 347 395 … … 553 601 { if ((t->ty == Tdelegate && (f->needThis() || f->isNested())) || 554 602 (t->ty == Tpointer && !(f->needThis() || f->isNested()))) 603 { 555 604 result = MATCHexact; 605 } 556 606 } 557 607 } … … 608 658 609 659 Expression *Expression::castTo(Scope *sc, Type *t) 610 { Expression *e; 611 Type *tb; 612 660 { 613 661 //printf("Expression::castTo(this=%s, t=%s)\n", toChars(), t->toChars()); 614 662 #if 0 … … 618 666 if (type == t) 619 667 return this; 620 e = this;621 tb = t->toBasetype();622 type= type->toBasetype();623 if (tb != type )668 Expression *e = this; 669 Type *tb = t->toBasetype(); 670 Type *typeb = type->toBasetype(); 671 if (tb != typeb) 624 672 { 625 673 // Do (type *) cast of (type [dim]) 626 674 if (tb->ty == Tpointer && 627 type ->ty == Tsarray675 typeb->ty == Tsarray 628 676 ) 629 677 { 630 678 //printf("Converting [dim] to *\n"); 631 679 632 if (type ->size(loc) == 0)680 if (typeb->size(loc) == 0) 633 681 e = new NullExp(loc); 634 682 else … … 648 696 } 649 697 } 698 else 699 { 700 e = e->copy(); // because of COW for assignment to e->type 701 } 702 assert(e != this); 650 703 e->type = t; 651 704 //printf("Returning: %s\n", e->toChars()); … … 655 708 656 709 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; 710 { Expression *e = this; 711 if (type != t) 712 { 713 if ((type->isreal() && t->isreal()) || 714 (type->isimaginary() && t->isimaginary()) 715 ) 716 { e = copy(); 717 e->type = t; 718 } 719 else 720 e = Expression::castTo(sc, t); 721 } 722 return e; 665 723 } 666 724 667 725 668 726 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; 727 { Expression *e = this; 728 if (type != t) 729 { 730 if (type->iscomplex() && t->iscomplex()) 731 { e = copy(); 732 e->type = t; 733 } 734 else 735 e = Expression::castTo(sc, t); 736 } 737 return e; 675 738 } 676 739 677 740 678 741 Expression *NullExp::castTo(Scope *sc, Type *t) 679 { Expression*e;742 { NullExp *e; 680 743 Type *tb; 681 744 682 745 //printf("NullExp::castTo(t = %p)\n", t); 683 committed = 1; 684 e = this; 746 if (type == t) 747 { 748 committed = 1; 749 return this; 750 } 751 e = (NullExp *)copy(); 752 e->committed = 1; 685 753 tb = t->toBasetype(); 686 type = type->toBasetype();687 if (tb != type)754 e->type = type->toBasetype(); 755 if (tb != e->type) 688 756 { 689 757 // NULL implicitly converts to any pointer type or dynamic array 690 if ( type->ty == Tpointer &&type->nextOf()->ty == Tvoid &&758 if (e->type->ty == Tpointer && e->type->nextOf()->ty == Tvoid && 691 759 (tb->ty == Tpointer || tb->ty == Tarray || tb->ty == Taarray || 692 760 tb->ty == Tdelegate)) … … 708 776 else 709 777 { 710 return Expression::castTo(sc, t); 711 //e = new CastExp(loc, e, tb); 778 return e->Expression::castTo(sc, t); 712 779 } 713 780 } … … 1006 1073 1007 1074 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; 1075 { TupleExp *e = (TupleExp *)copy(); 1076 e->exps = (Expressions *)exps->copy(); 1077 for (size_t i = 0; i < e->exps->dim; i++) 1078 { Expression *ex = (Expression *)e->exps->data[i]; 1079 ex = ex->castTo(sc, t); 1080 e->exps->data[i] = (void *)ex; 1081 } 1082 return e; 1015 1083 } 1016 1084 … … 1024 1092 if (type == t) 1025 1093 return this; 1094 ArrayLiteralExp *e = this; 1026 1095 Type *typeb = type->toBasetype(); 1027 1096 Type *tb = t->toBasetype(); … … 1036 1105 } 1037 1106 1107 e = (ArrayLiteralExp *)copy(); 1108 e->elements = (Expressions *)elements->copy(); 1038 1109 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; 1110 { Expression *ex = (Expression *)elements->data[i]; 1111 ex = ex->castTo(sc, tb->nextOf()); 1112 e->elements->data[i] = (void *)ex; 1113 } 1114 e->type = t; 1115 return e; 1116 } 1117 if (tb->ty == Tpointer && typeb->ty == Tsarray) 1118 { 1119 e = (ArrayLiteralExp *)copy(); 1120 e->type = typeb->nextOf()->pointerTo(); 1121 } 1122 L1: 1123 return e->Expression::castTo(sc, t); 1124 } 1125 1126 Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t) 1127 { 1128 if (type == t) 1044 1129 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 { 1130 AssocArrayLiteralExp *e = this; 1056 1131 Type *typeb = type->toBasetype(); 1057 1132 Type *tb = t->toBasetype(); … … 1059 1134 tb->nextOf()->toBasetype()->ty != Tvoid) 1060 1135 { 1136 e = (AssocArrayLiteralExp *)copy(); 1137 e->keys = (Expressions *)keys->copy(); 1138 e->values = (Expressions *)values->copy(); 1061 1139 assert(keys->dim == values->dim); 1062 1140 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;1141 { Expression *ex = (Expression *)values->data[i]; 1142 ex = ex->castTo(sc, tb->nextOf()); 1143 e->values->data[i] = (void *)ex; 1144 1145 ex = (Expression *)keys->data[i]; 1146 ex = ex->castTo(sc, ((TypeAArray *)tb)->index); 1147 e->keys->data[i] = (void *)ex; 1148 } 1149 e->type = t; 1150 return e; 1073 1151 } 1074 1152 L1: 1075 return Expression::castTo(sc, t);1153 return e->Expression::castTo(sc, t); 1076 1154 } 1077 1155 1078 1156 Expression *SymOffExp::castTo(Scope *sc, Type *t) 1079 1157 { 1080 Type *tb;1081 1082 1158 #if 0 1083 1159 printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", 1084 1160 toChars(), type->toChars(), t->toChars()); 1085 1161 #endif 1086 Expression *e = this; 1087 1088 tb = t->toBasetype(); 1089 type = type->toBasetype(); 1090 if (tb != type) 1162 if (type == t && hasOverloads == 0) 1163 return this; 1164 Expression *e; 1165 Type *tb = t->toBasetype(); 1166 Type *typeb = type->toBasetype(); 1167 if (tb != typeb) 1091 1168 { 1092 1169 // Look for pointers to functions where the functions are overloaded. … … 1094 1171 1095 1172 if (hasOverloads && 1096 type ->ty == Tpointer && type->nextOf()->ty == Tfunction &&1173 typeb->ty == Tpointer && typeb->nextOf()->ty == Tfunction && 1097 1174 (tb->ty == Tpointer || tb->ty == Tdelegate) && tb->nextOf()->ty == Tfunction) 1098 1175 { … … 1125 1202 e = Expression::castTo(sc, t); 1126 1203 } 1127 if (e == this && hasOverloads) 1128 { e = syntaxCopy(); 1204 else 1205 { e = copy(); 1206 e->type = t; 1129 1207 ((SymOffExp *)e)->hasOverloads = 0; 1130 1208 } 1131 e->type = t;1132 1209 return e; 1133 1210 } … … 1135 1212 Expression *DelegateExp::castTo(Scope *sc, Type *t) 1136 1213 { 1137 Type *tb;1138 1214 #if 0 1139 1215 printf("DelegateExp::castTo(this=%s, type=%s, t=%s)\n", 1140 1216 toChars(), type->toChars(), t->toChars()); 1141 1217 #endif 1218 static char msg[] = "cannot form delegate due to covariant return type"; 1219 1142 1220 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) 1221 Type *tb = t->toBasetype(); 1222 Type *typeb = type->toBasetype(); 1223 if (tb != typeb) 1148 1224 { 1149 1225 // Look for delegates to functions where the functions are overloaded. 1150 1226 FuncDeclaration *f; 1151 1227 1152 if (type ->ty == Tdelegate && type->nextOf()->ty == Tfunction &&1228 if (typeb->ty == Tdelegate && typeb->nextOf()->ty == Tfunction && 1153 1229 tb->ty == Tdelegate && tb->nextOf()->ty == Tfunction) 1154 1230 { … … 1177 1253 if (func->tintro && func->tintro->nextOf()->isBaseOf(func->type->nextOf(), &offset) && offset) 1178 1254 error("%s", msg); 1179 } 1180 e->type = t; 1255 e = copy(); 1256 e->type = t; 1257 } 1181 1258 return e; 1182 1259 } … … 1262 1339 t2 = e2->type; 1263 1340 assert(t1); 1341 t = t1; 1264 1342 1265 1343 //if (t1) printf("\tt1 = %s\n", t1->toChars()); … … 1317 1395 return this; 1318 1396 } 1397 1398 t1 = t1b; 1399 t2 = t2b; 1319 1400 1320 1401 if (op == TOKcat) … … 1338 1419 else 1339 1420 e2 = e2->castTo(sc, t2); 1421 t = t1; 1340 1422 goto Lagain; 1341 1423 } … … 1343 1425 1344 1426 Lagain: 1345 t = t1;1346 1427 if (t1 == t2) 1347 1428 { … … 1366 1447 t1 = t1n->mutableOf()->constOf()->pointerTo(); 1367 1448 t2 = t2n->mutableOf()->constOf()->pointerTo(); 1449 t = t1; 1368 1450 goto Lagain; 1369 1451 } … … 1429 1511 else 1430 1512 t2 = t2->nextOf()->mutableOf()->constOf()->arrayOf(); 1513 t = t1; 1431 1514 goto Lagain; 1432 1515 } … … 1467 1550 goto Lt2; 1468 1551 } 1469 //else if (e2->op == TOKstring) { printf("test2\n"); }1470 1552 else if ((e2->op == TOKstring || e2->op == TOKnull) && e2->implicitConvTo(t1)) 1471 1553 { … … 1527 1609 1528 1610 Expression *Expression::integralPromotions(Scope *sc) 1529 { Expression *e; 1530 1531 e = this; 1611 { 1612 Expression *e = this; 1613 1614 //printf("integralPromotions %s %s\n", e->toChars(), e->type->toChars()); 1532 1615 switch (type->toBasetype()->ty) 1533 1616 { trunk/rebuild/class.c
r847 r884 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 7by Digital Mars3 // Copyright (c) 1999-2008 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 653 653 Module::dprogress++; 654 654 655 dtor = buildDtor(sc); 655 656 656 657 sc->pop(); trunk/rebuild/constfold.c
r840 r884 901 901 real_t r2; 902 902 903 if (e1->type->isreal()) 903 //printf("Cmp(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); 904 905 if (e1->op == TOKstring && e2->op == TOKstring) 906 { StringExp *es1 = (StringExp *)e1; 907 StringExp *es2 = (StringExp *)e2; 908 size_t sz = es1->sz; 909 assert(sz == es2->sz); 910 911 size_t len = es1->len; 912 if (es2->len < len) 913 len = es2->len; 914 915 int cmp = memcmp(es1->string, es2->string, sz * len); 916 if (cmp == 0) 917 cmp = es1->len - es2->len; 918 919 switch (op) 920 { 921 case TOKlt: n = cmp < 0; break; 922 case TOKle: n = cmp <= 0; break; 923 case TOKgt: n = cmp > 0; break; 924 case TOKge: n = cmp >= 0; break; 925 926 case TOKleg: n = 1; break; 927 case TOKlg: n = cmp != 0; break; 928 case TOKunord: n = 0; break; 929 case TOKue: n = cmp == 0; break; 930 case TOKug: n = cmp > 0; break; 931 case TOKuge: n = cmp >= 0; break; 932 case TOKul: n = cmp < 0; break; 933 case TOKule: n = cmp <= 0; break; 934 935 default: 936 assert(0); 937 } 938 } 939 else if (e1->isConst() != 1 || e2->isConst() != 1) 940 return EXP_CANT_INTERPRET; 941 else if (e1->type->isreal()) 904 942 { 905 943 r1 = e1->toReal(); trunk/rebuild/declaration.c
r847 r884 1 1 2 2 // Compiler implementation of the D programming language 3 // Copyright (c) 1999-200 7by Digital Mars3 // Copyright (c) 1999-2008 by Digital Mars 4 4 // All Rights Reserved 5 5 // written by Walter Bright … … 87 87 */ 88 88 89 void Declaration::checkModify(Loc loc, Scope *sc )89 void Declaration::checkModify(Loc loc, Scope *sc, Type *t) 90 90 { 91 91 /* if (sc->incontract && isParameter()) 92 92 error(loc, "cannot modify parameter '%s' in contract", toChars()); */ 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 93 99 94 if (isCtorinit()) … … 111 106 ) 112 107 { 108 VarDeclaration *v = isVarDeclaration(); 113 109 assert(v); 114 110 v->ctorinit = 1; … … 131 127 } 132 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 } 133 149 } 134 150 … … 372 388 Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s) 373 389 { 390 //printf("AliasDeclaration::syntaxCopy()\n"); 374 391 assert(!s); 375 392 AliasDeclaration *sa; … … 645 662 //printf(" type = %s\n", type ? type->toChars() : "null"); 646 663 //printf(" stc = x%x\n", sc->stc); 664 //printf(" storage_class = x%x\n", storage_class); 647 665 //printf("linkage = %d\n", sc->linkage); 648 666 //if (strcmp(toChars(), "mul") == 0) halt(); … … 672 690 type = type->semantic(loc, sc); 673 691 } 674 //printf(" type = %s\n", type ? type->toChars() : "null");692 //printf(" semantic type = %s\n", type ? type->toChars() : "null"); 675 693 676 694 type->checkDeprecated(loc, sc); … … 713 731 Objects *exps = new Objects(); 714 732 exps->setDim(nelems); 733 Expression *ie = init ? init->toExpression() : NULL; 715 734 716 735 for (size_t i = 0; i < nelems; i++) … … 723 742 Identifier *id = new Identifier(name, TOKidentifier); 724 743 725 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, NULL); 744 Expression *einit = ie; 745 if (ie && ie->op == TOKtuple) 746 { einit = (Expression *)((TupleExp *)ie)->exps->data[i]; 747 } 748 Initializer *ti = init; 749 if (einit) 750 { ti = new ExpInitializer(einit->loc, einit); 751 } 752 753 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti); 726 754 //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); 727 755 v->semantic(sc); … … 752 780 type = type->constOf(); 753 781 } 754 755 if (storage_class & (STCstatic | STCextern)) 756 { 757 } 758 else if (isSynchronized()) 782 else if (type->isConst()) 783 storage_class |= STCconst; 784 else if (type->isInvariant()) 785 storage_class |= STCinvariant; 786 787 if (isSynchronized()) 759 788 { 760 789 //error("variable %s cannot be synchronized", toChars()); … … 768 797 //error("abstract cannot be applied to variable"); 769 798 } 770 else if (storage_class & STCtemplateparameter) 799 else if (storage_class & STCfinal) 800 { 801 error("final cannot be applied to variable"); 802 } 803 804 if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter)) 771 805 { 772 806 } … … 819 853 if (type->isauto() && !noauto) 820 854 { 821 /* if (storage_class & (STCfield | STCout | STCref | STCstatic ) || !fd)822 { 823 error("globals, statics, fields, ref and out parameters cannot be auto");855 /* if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest) || !fd) 856 { 857 error("globals, statics, fields, manifest constants, ref and out parameters cannot be auto"); 824 858 } */ 825 859 … … 838 872 if (init) 839 873 storage_class |= STCinit; // remember we had an explicit initializer 840 874 else if (storage_class & STCmanifest) 875 error("manifest constants must have initializers"); 876 877 enum TOK op = TOKconstruct; 841 878 if (!init && !sc->inunion && !isStatic() && fd && 842 879 (!(storage_class & (STCfield | STCin | STCforeach | STCparameter)) || (storage_class & STCout)) && … … 877 914 init = getExpInitializer(); 878 915 } 916 // Default initializer is always a blit 917 op = TOKblit; 879 918 } 880 919 … … 906 945 // If local variable, use AssignExp to handle all the various 907 946 // possibilities. 908 if (fd && !isStatic() && 947 if (fd && !isStatic() && !(storage_class & STCmanifest) && 909 948 !init->isVoidInitializer()) 910 949 { … … 958 997 } 959 998 ei->exp = new AssignExp(loc, e1, ei->exp); 960 ei->exp->op = TOKconstruct;999 ei->exp->op = op; 961 1000 canassign++; 962 1001 ei->exp = ei->exp->semantic(sc); … … 969 1008 } 970 1009 } 971 else if (storage_class & (STCconst | STCinvariant ) ||1010 else if (storage_class & (STCconst | STCinvariant | STCmanifest) || 972 1011 type->isConst() || type->isInvariant()) 973 1012 { … … 1069 1108 void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 1070 1109 { 1110 if (storage_class & STCmanifest) 1111 buf->writestring("manifest "); 1071 1112 if (storage_class & STCstatic) 1072 1113 buf->writestring("static "); … … 1082 1123 if (init) 1083 1124 { buf->writestring(" = "); 1084 init->toCBuffer(buf, hgs); 1125 ExpInitializer *ie = init->isExpInitializer(); 1126 if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit)) 1127 ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs); 1128 else 1129 init->toCBuffer(buf, hgs); 1085 1130 } 1086 1131 buf->writeByte(';'); … … 1115 1160 void VarDeclaration::checkNestedReference(Scope *sc, Loc loc) 1116 1161 { 1117 if (parent && !isDataseg() && parent != sc->parent) 1162 if (parent && !isDataseg() && parent != sc->parent && 1163 !(storage_class & STCmanifest)) 1118 1164 { 1119 1165 // The function that this variable is in … … 1141 1187 goto L2; 1142 1188 } 1189 1143 1190 fdv->closureVars.push(this); 1144 1191 L2: ; … … 1177 1224 Expression *VarDeclaration::getConstInitializer() 1178 1225 { 1179 if ((isConst() || isInvariant() ) &&1226 if ((isConst() || isInvariant() || storage_class & STCmanifest) && 1180 1227 storage_class & STCinit) 1181 1228 { … … 1194 1241 int VarDeclaration::canTakeAddressOf() 1195 1242 { 1243 #if 0 1196 1244 /* Global variables and struct/class fields of the form: 1197 1245 * const int x = 3; … … 1207 1255 return 0; 1208 1256 } 1257 #else 1258 if (storage_class & STCmanifest) 1259 return 0; 1260 #endif 1209 1261 return 1; 1210 1262 } … … 1222 1274 printf("parent = '%s'\n", parent->toChars()); 1223 1275 #endif 1276 if (storage_class & STCmanifest) 1277 return 0; 1224 1278 Dsymbol *parent = this->toParent(); 1225 1279 if (!parent && !(storage_class & STCstatic)) … … 1236 1290 int VarDeclaration::hasPointers() 1237 1291 { 1292 //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty); 1238 1293 return (!isDataseg() && type->hasPointers()); 1239 1294 } 1295 1296 /****************************************** 1297 * Return TRUE if variable needs to call the destructor. 1298 */ 1299 1300 int VarDeclaration::needsAutoDtor() 1301 { 1302 //printf("VarDeclaration::needsAutoDtor() %s\n", toChars()); 1303 1304 if (noauto || storage_class & STCnodtor) 1305 return FALSE; 1306 1307 &n
