Changeset 847
- Timestamp:
- 12/20/07 16:27:15 (10 months ago)
- Files:
-
- trunk/rebuild/attrib.c (modified) (2 diffs)
- trunk/rebuild/cast.c (modified) (1 diff)
- trunk/rebuild/class.c (modified) (6 diffs)
- trunk/rebuild/declaration.c (modified) (17 diffs)
- trunk/rebuild/declaration.h (modified) (5 diffs)
- trunk/rebuild/doc.c (modified) (5 diffs)
- trunk/rebuild/dsymbol.c (modified) (5 diffs)
- trunk/rebuild/expression.c (modified) (33 diffs)
- trunk/rebuild/func.c (modified) (13 diffs)
- trunk/rebuild/init.c (modified) (1 diff)
- trunk/rebuild/inline.c (modified) (1 diff)
- trunk/rebuild/interpret.c (modified) (2 diffs)
- trunk/rebuild/mars.c (modified) (1 diff)
- trunk/rebuild/module.c (modified) (1 diff)
- trunk/rebuild/module.h (modified) (1 diff)
- trunk/rebuild/mtype.c (modified) (29 diffs)
- trunk/rebuild/mtype.h (modified) (7 diffs)
- trunk/rebuild/opover.c (modified) (6 diffs)
- trunk/rebuild/optimize.c (modified) (4 diffs)
- trunk/rebuild/parse.c (modified) (17 diffs)
- trunk/rebuild/parse.h (modified) (3 diffs)
- trunk/rebuild/statement.c (modified) (1 diff)
- trunk/rebuild/struct.c (modified) (3 diffs)
- trunk/rebuild/template.c (modified) (31 diffs)
- trunk/rebuild/template.h (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/rebuild/attrib.c
r800 r847 310 310 if (stc & (STCauto | STCscope | STCstatic | STCextern)) 311 311 sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern); 312 if (stc & (STCconst | STCinvariant)) 313 sc->stc &= ~(STCconst | STCinvariant); 312 314 sc->stc |= stc; 313 315 for (unsigned i = 0; i < decl->dim; i++) … … 338 340 { STCextern, TOKextern }, 339 341 { STCconst, TOKconst }, 342 { STCinvariant, TOKinvariant }, 340 343 { STCfinal, TOKfinal }, 341 344 { STCabstract, TOKabstract }, trunk/rebuild/cast.c
r840 r847 1330 1330 //t1 = t1->constOf(); 1331 1331 //t2 = t2->constOf(); 1332 e1 = e1->castTo(sc, t1); 1333 e2 = e2->castTo(sc, t2); 1332 if (e1->op == TOKstring && !((StringExp *)e1)->committed) 1333 e1->type = t1; 1334 else 1335 e1 = e1->castTo(sc, t1); 1336 if (e2->op == TOKstring && !((StringExp *)e2)->committed) 1337 e2->type = t2; 1338 else 1339 e2 = e2->castTo(sc, t2); 1334 1340 goto Lagain; 1335 1341 } trunk/rebuild/class.c
r840 r847 450 450 isauto = baseClass->isauto; 451 451 vthis = baseClass->vthis; 452 storage_class |= baseClass->storage_class & (STCconst | STCinvariant); 452 453 } 453 454 else … … 522 523 if (storage_class & STCabstract) 523 524 isabstract = 1; 525 if (storage_class & STCinvariant) 526 type = type->invariantOf(); 527 else if (storage_class & STCconst) 528 type = type->constOf(); 524 529 525 530 sc = sc->push(this); 526 531 sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 527 STCabstract | STCdeprecated); 532 STCabstract | STCdeprecated | STCconst | STCinvariant); 533 sc->stc |= storage_class & (STCconst | STCinvariant); 528 534 sc->parent = this; 529 535 sc->inunion = 0; … … 938 944 } 939 945 946 940 947 /**************************************** 941 948 * Returns !=0 if there's an extra member which is the 'this' … … 1104 1111 } 1105 1112 } 1113 #if 0 1114 // Inherit const/invariant from base class 1115 storage_class |= b->base->storage_class & (STCconst | STCinvariant); 1116 #endif 1106 1117 i++; 1107 1118 } … … 1145 1156 } 1146 1157 1158 protection = sc->protection; 1159 storage_class |= sc->stc & (STCconst | STCinvariant); 1160 1147 1161 for (i = 0; i < members->dim; i++) 1148 1162 { … … 1152 1166 1153 1167 sc = sc->push(this); 1168 sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 1169 STCabstract | STCdeprecated | STCconst | STCinvariant); 1170 sc->stc |= storage_class & (STCconst | STCinvariant); 1154 1171 sc->parent = this; 1155 1172 if (isCOMinterface()) trunk/rebuild/declaration.c
r840 r847 31 31 { 32 32 type = NULL; 33 originalType = NULL; 33 34 storage_class = STCundefined; 34 35 protection = PROTundefined; … … 93 94 VarDeclaration *v = isVarDeclaration(); 94 95 /* if (v && v->canassign == 0 && 95 (isConst() || isInvariant() || (isFinal() && !isCtorinit())))96 error(loc, "cannot modify final/const/invariant variable '%s'", toChars()); */96 (isConst() || isInvariant()) && !isCtorinit()) 97 error(loc, "cannot modify const/invariant variable '%s'", toChars()); */ 97 98 98 99 if (isCtorinit()) … … 434 435 */ 435 436 s = type->toDsymbol(sc); 436 if (s )437 if (s && ((s->getType() && type->equals(s->getType())) || s->isEnumMember())) 437 438 goto L2; // it's a symbolic alias 438 439 … … 642 643 { 643 644 //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); 644 //printf(" type = %s\n", type ->toChars());645 //printf(" stc = x%x\n", sc->stc);645 //printf(" type = %s\n", type ? type->toChars() : "null"); 646 //printf(" stc = x%x\n", sc->stc); 646 647 //printf("linkage = %d\n", sc->linkage); 647 648 //if (strcmp(toChars(), "mul") == 0) halt(); … … 664 665 */ 665 666 storage_class &= ~STCauto; 667 originalType = type; 666 668 } 667 669 else 670 { if (!originalType) 671 originalType = type; 668 672 type = type->semantic(loc, sc); 673 } 674 //printf(" type = %s\n", type ? type->toChars() : "null"); 669 675 670 676 type->checkDeprecated(loc, sc); … … 736 742 } 737 743 738 if (storage_class & STCfinal && !init && !fd)739 { // Initialize by constructor only740 storage_class |= STCctorinit;741 }742 743 744 Lagain: 744 if (isConst()) 745 { 746 /* Rewrite things like: 747 * const string s; 748 * to: 749 * invariant string s; 750 */ 751 if (type->nextOf() && type->nextOf()->isInvariant()) 752 { storage_class |= STCinvariant; 753 storage_class &= ~STCconst; 754 goto Lagain; 755 } 756 type = type->constOf(); 757 if (isParameter()) 758 { storage_class |= STCfinal; 759 storage_class &= ~STCconst; 760 } 761 } 762 else if (storage_class & STCinvariant) 745 if (storage_class & STCinvariant) 763 746 { 764 747 type = type->invariantOf(); 765 if (isParameter()) 766 { storage_class |= STCfinal; 767 storage_class &= ~STCinvariant; 768 }769 } 770 type = type->toCanonConst();771 772 if (storage_class & (STC const | STCinvariant | STCstatic))748 } 749 else if (storage_class & (STCconst | STCin)) 750 { 751 if (!type->isInvariant()) 752 type = type->constOf(); 753 } 754 755 if (storage_class & (STCstatic | STCextern)) 773 756 { 774 757 } … … 794 777 aad = parent->isAggregateDeclaration(); 795 778 if (aad) 796 { assert(!(storage_class & (STCconst | STCinvariant | STCstatic))); 797 aad->addField(sc, this); 779 { assert(!(storage_class & (STCextern | STCstatic))); 780 781 if (storage_class & (STCconst | STCinvariant) && init) 782 { 783 if (!type->toBasetype()->isTypeBasic()) 784 storage_class |= STCstatic; 785 } 786 else 787 aad->addField(sc, this); 798 788 } 799 789 … … 804 794 } 805 795 796 /* Templates cannot add fields to aggregates 797 */ 806 798 TemplateInstance *ti = parent->isTemplateInstance(); 807 799 if (ti) … … 839 831 } 840 832 841 if (!init && !sc->inunion && !isStatic() && !isConst() && fd && 842 !(storage_class & (STCfield | STCin | STCforeach)) && 833 if ((isConst() || isInvariant()) && !init && !fd) 834 { // Initialize by constructor only 835 storage_class |= STCctorinit; 836 } 837 838 if (init) 839 storage_class |= STCinit; // remember we had an explicit initializer 840 841 if (!init && !sc->inunion && !isStatic() && fd && 842 (!(storage_class & (STCfield | STCin | STCforeach | STCparameter)) || (storage_class & STCout)) && 843 843 type->size() != 0) 844 844 { … … 906 906 // If local variable, use AssignExp to handle all the various 907 907 // possibilities. 908 if (fd && !isStatic() && !isConst() && !isInvariant() &&908 if (fd && !isStatic() && 909 909 !init->isVoidInitializer()) 910 910 { … … 967 967 { 968 968 init = init->semantic(sc, type); 969 if (fd && (isConst() || isInvariant()) && !isStatic()) 970 { // Make it static 971 storage_class |= STCstatic; 972 } 973 } 974 } 975 else if (isConst() || isInvariant() || isFinal()) 969 } 970 } 971 else if (storage_class & (STCconst | STCinvariant) || 972 type->isConst() || type->isInvariant()) 976 973 { 977 974 /* Because we may need the results of a const declaration in a … … 1014 1011 else if (ei) 1015 1012 { 1016 e = e->optimize(WANTvalue | WANTinterpret); 1013 if (isDataseg()) 1014 /* static const/invariant does CTFE 1015 */ 1016 e = e->optimize(WANTvalue | WANTinterpret); 1017 else 1018 e = e->optimize(WANTvalue); 1017 1019 if (e->op == TOKint64 || e->op == TOKstring) 1018 1020 { … … 1034 1036 } 1035 1037 1036 ExpInitializer *VarDeclaration::getExpInitializer()1037 {1038 ExpInitializer *ei;1039 1040 if (init)1041 ei = init->isExpInitializer();1042 else1043 {1044 Expression *e = type->defaultInit();1045 if (e)1046 ei = new ExpInitializer(loc, e);1047 else1048 ei = NULL;1049 }1050 return ei;1051 }1052 1053 1038 void VarDeclaration::semantic2(Scope *sc) 1054 1039 { … … 1084 1069 void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 1085 1070 { 1071 if (storage_class & STCstatic) 1072 buf->writestring("static "); 1086 1073 if (storage_class & STCconst) 1087 1074 buf->writestring("const "); 1088 if (storage_class & STCstatic) 1089 buf->writestring("static "); 1075 if (storage_class & STCinvariant) 1076 buf->writestring("invariant "); 1077 1090 1078 if (type) 1091 1079 type->toCBuffer(buf, ident, hgs); … … 1108 1096 int VarDeclaration::isImportedSymbol() 1109 1097 { 1110 if (protection == PROTexport && !init && (isStatic() || isConst() || parent->isModule())) 1098 if (protection == PROTexport && !init && 1099 (storage_class & STCstatic || parent->isModule())) 1111 1100 return TRUE; 1112 1101 return FALSE; … … 1160 1149 } 1161 1150 1151 /**************************** 1152 * Get ExpInitializer for a variable, if there is one. 1153 */ 1154 1155 ExpInitializer *VarDeclaration::getExpInitializer() 1156 { 1157 ExpInitializer *ei; 1158 1159 if (init) 1160 ei = init->isExpInitializer(); 1161 else 1162 { 1163 Expression *e = type->defaultInit(); 1164 if (e) 1165 ei = new ExpInitializer(loc, e); 1166 else 1167 ei = NULL; 1168 } 1169 return ei; 1170 } 1171 1172 /******************************************* 1173 * If variable has a constant expression initializer, get it. 1174 * Otherwise, return NULL. 1175 */ 1176 1177 Expression *VarDeclaration::getConstInitializer() 1178 { 1179 if ((isConst() || isInvariant()) && 1180 storage_class & STCinit) 1181 { 1182 ExpInitializer *ei = getExpInitializer(); 1183 if (ei) 1184 return ei->exp; 1185 } 1186 1187 return NULL; 1188 } 1189 1190 /************************************* 1191 * Return !=0 if we can take the address of this variable. 1192 */ 1193 1194 int VarDeclaration::canTakeAddressOf() 1195 { 1196 /* Global variables and struct/class fields of the form: 1197 * const int x = 3; 1198 * are not stored and hence cannot have their address taken. 1199 */ 1200 if ((isConst() || isInvariant()) && 1201 storage_class & STCinit && 1202 (!(storage_class & (STCstatic | STCextern)) || (storage_class & STCfield)) && 1203 (!parent || toParent()->isModule() || toParent()->isTemplateInstance()) && 1204 type->toBasetype()->isTypeBasic() 1205 ) 1206 { 1207 return 0; 1208 } 1209 return 1; 1210 } 1162 1211 1163 1212 /******************************* 1164 1213 * Does symbol go into data segment? 1214 * Includes extern variables. 1165 1215 */ 1166 1216 … … 1173 1223 #endif 1174 1224 Dsymbol *parent = this->toParent(); 1175 if (!parent && !(storage_class & (STCstatic | STCconst)))1225 if (!parent && !(storage_class & STCstatic)) 1176 1226 { //error("forward referenced"); 1177 halt();1178 1227 type = Type::terror; 1179 1228 return 0; 1180 1229 } 1181 return (storage_class & (STCstatic | STCconst) || 1182 parent->isModule() || 1183 parent->isTemplateInstance()); 1230 return canTakeAddressOf() && 1231 (storage_class & (STCstatic | STCextern) || 1232 toParent()->isModule() || 1233 toParent()->isTemplateInstance()); 1184 1234 } 1185 1235 trunk/rebuild/declaration.h
r840 r847 64 64 STCinvariant = 0x100000, 65 65 STCref = 0x200000, 66 STCinit = 0x400000, // has explicit initializer 66 67 }; 67 68 … … 75 76 }; 76 77 77 void overloadResolveX(Match *m, FuncDeclaration *f, Expressions *arguments); 78 void overloadResolveX(Match *m, FuncDeclaration *f, 79 Expression *ethis, Expressions *arguments); 78 80 int overloadApply(FuncDeclaration *fstart, 79 81 int (*fp)(void *, FuncDeclaration *), … … 85 87 { 86 88 Type *type; 89 Type *originalType; // before semantic analysis 87 90 unsigned storage_class; 88 91 enum PROT protection; … … 237 240 int isDataseg(); 238 241 int hasPointers(); 242 int canTakeAddressOf(); 239 243 Expression *callAutoDtor(); 240 244 ExpInitializer *getExpInitializer(); 245 Expression *getConstInitializer(); 241 246 void checkCtorConstInit(); 242 247 void checkNestedReference(Scope *sc, Loc loc); … … 475 480 int overloadInsert(Dsymbol *s); 476 481 FuncDeclaration *overloadExactMatch(Type *t); 477 FuncDeclaration *overloadResolve(Loc loc, Expression s *arguments, int flags = 0);482 FuncDeclaration *overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, int flags = 0); 478 483 LabelDsymbol *searchLabel(Identifier *ident); 479 484 AggregateDeclaration *isThis(); trunk/rebuild/doc.c
r785 r847 270 270 271 271 buf.printf("$(DDOC_COMMENT Generated by Ddoc from %s)\n", srcfile->toChars()); 272 273 272 if (isDocFile) 274 273 { … … 284 283 else 285 284 { 286 287 285 dc->writeSections(sc, this, sc->docbuf); 288 286 emitMemberComments(sc); … … 655 653 if (d->isConst()) 656 654 buf->writestring("const "); 655 #if V2 656 if (d->isInvariant()) 657 buf->writestring("invariant "); 658 #endif 657 659 if (d->isFinal()) 658 660 buf->writestring("final "); … … 664 666 void Declaration::toDocBuffer(OutBuffer *buf) 665 667 { 666 //printf("Declaration::toDocbuffer() %s \n", toChars());668 //printf("Declaration::toDocbuffer() %s, originalType = %p\n", toChars(), originalType); 667 669 if (ident) 668 670 { … … 672 674 { HdrGenState hgs; 673 675 hgs.ddoc = 1; 674 type->toCBuffer(buf, ident, &hgs); 676 if (originalType) 677 { //originalType->print(); 678 originalType->toCBuffer(buf, ident, &hgs); 679 } 680 else 681 type->toCBuffer(buf, ident, &hgs); 675 682 } 676 683 else trunk/rebuild/dsymbol.c
r840 r847 934 934 Expression *e = new IntegerExp(0, td->objects->dim, Type::tsize_t); 935 935 v->init = new ExpInitializer(0, e); 936 v->storage_class |= STC const;936 v->storage_class |= STCstatic | STCconst; 937 937 v->semantic(sc); 938 938 return v; … … 944 944 Expression *e = new IntegerExp(0, type->arguments->dim, Type::tsize_t); 945 945 v->init = new ExpInitializer(0, e); 946 v->storage_class |= STC const;946 v->storage_class |= STCstatic | STCconst; 947 947 v->semantic(sc); 948 948 return v; … … 990 990 Expression *e = new IntegerExp(0, ((StringExp *)ce)->len, Type::tsize_t); 991 991 v->init = new ExpInitializer(0, e); 992 v->storage_class |= STC const;992 v->storage_class |= STCstatic | STCconst; 993 993 } 994 994 else if (ce->op == TOKarrayliteral) … … 998 998 Expression *e = new IntegerExp(0, ((ArrayLiteralExp *)ce)->elements->dim, Type::tsize_t); 999 999 v->init = new ExpInitializer(0, e); 1000 v->storage_class |= STC const;1000 v->storage_class |= STCstatic | STCconst; 1001 1001 } 1002 1002 else if (ce->op == TOKtuple) … … 1006 1006 Expression *e = new IntegerExp(0, ((TupleExp *)ce)->exps->dim, Type::tsize_t); 1007 1007 v->init = new ExpInitializer(0, e); 1008 v->storage_class |= STC const;1008 v->storage_class |= STCstatic | STCconst; 1009 1009 } 1010 1010 *pvar = v; trunk/rebuild/expression.c
r840 r847 833 833 Expression *Expression::modifiableLvalue(Scope *sc, Expression *e) 834 834 { 835 //printf("Expression::modifiableLvalue() %s \n",toChars());835 //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars()); 836 836 837 837 // See if this expression is a modifiable lvalue (i.e. not const) … … 1050 1050 if (this == o || 1051 1051 (((Expression *)o)->op == TOKint64 && 1052 ((ne = (IntegerExp *)o), type-> equals(ne->type)) &&1052 ((ne = (IntegerExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 1053 1053 value == ne->value)) 1054 1054 return 1; … … 1291 1291 char *RealExp::toChars() 1292 1292 { 1293 staticchar buffer[sizeof(value) * 3 + 8 + 1 + 1];1293 char buffer[sizeof(value) * 3 + 8 + 1 + 1]; 1294 1294 1295 1295 #ifdef IN_GCC … … 1301 1301 #endif 1302 1302 assert(strlen(buffer) < sizeof(buffer)); 1303 return buffer;1303 return mem.strdup(buffer); 1304 1304 } 1305 1305 … … 1361 1361 if (this == o || 1362 1362 (((Expression *)o)->op == TOKfloat64 && 1363 ((ne = (RealExp *)o), type-> equals(ne->type)) &&1363 ((ne = (RealExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 1364 1364 RealEquals(value, ne->value) 1365 1365 ) … … 1505 1505 char *ComplexExp::toChars() 1506 1506 { 1507 staticchar buffer[sizeof(value) * 3 + 8 + 1];1507 char buffer[sizeof(value) * 3 + 8 + 1]; 1508 1508 1509 1509 #ifdef IN_GCC … … 1517 1517 assert(strlen(buffer) < sizeof(buffer)); 1518 1518 #endif 1519 return buffer;1519 return mem.strdup(buffer); 1520 1520 } 1521 1521 … … 1558 1558 if (this == o || 1559 1559 (((Expression *)o)->op == TOKcomplex80 && 1560 ((ne = (ComplexExp *)o), type-> equals(ne->type)) &&1560 ((ne = (ComplexExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 1561 1561 RealEquals(creall(value), creall(ne->value)) && 1562 1562 RealEquals(cimagl(value), cimagl(ne->value)) … … 3133 3133 error("cannot create instance of interface %s", cd->toChars()); 3134 3134 else if (cd->isAbstract()) 3135 error("cannot create instance of abstract class %s", cd->toChars()); */ 3135 { error("cannot create instance of abstract class %s", cd->toChars()); 3136 for (int i = 0; i < cd->vtbl.dim; i++) 3137 { FuncDeclaration *fd = ((Dsymbol *)cd->vtbl.data[i])->isFuncDeclaration(); 3138 if (fd && fd->isAbstract()) 3139 error("function %s is abstract", fd->toChars()); 3140 } 3141 } */ 3136 3142 checkDeprecated(sc, cd); 3137 3143 if (cd->isNested()) … … 3210 3216 { 3211 3217 assert(f); 3212 f = f->overloadResolve(loc, arguments);3218 f = f->overloadResolve(loc, NULL, arguments); 3213 3219 checkDeprecated(sc, f); 3214 3220 member = f->isCtorDeclaration(); … … 3241 3247 newargs->shift(e); 3242 3248 3243 f = f->overloadResolve(loc, newargs);3249 f = f->overloadResolve(loc, NULL, newargs); 3244 3250 allocator = f->isNewDeclaration(); 3245 3251 assert(allocator); … … 3275 3281 newargs->shift(e); 3276 3282 3277 f = f->overloadResolve(loc, newargs);3283 f = f->overloadResolve(loc, NULL, newargs); 3278 3284 allocator = f->isNewDeclaration(); 3279 3285 assert(allocator); … … 3304 3310 arg = resolveProperties(sc, arg); 3305 3311 arg = arg->implicitCastTo(sc, Type::tsize_t); 3306 /*if (arg->op == TOKint64 && (long long)arg->toInteger() < 0) 3312 arg = arg->optimize(WANTvalue); 3313 /* if (arg->op == TOKint64 && (long long)arg->toInteger() < 0) 3307 3314 error("negative array index %s", arg->toChars()); */ 3308 3315 arguments->data[i] = (void *) arg; … … 3502 3509 if (this == o || 3503 3510 (((Expression *)o)->op == TOKvar && 3504 ((ne = (VarExp *)o), type-> equals(ne->type)) &&3511 ((ne = (VarExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 3505 3512 var == ne->var)) 3506 3513 return 1; … … 4119 4126 tded = targ; 4120 4127 break; 4128 4129 #if V2 4130 case TOKconst: 4131 if (!targ->isConst()) 4132 goto Lno; 4133 tded = targ; 4134 break; 4135 4136 case TOKinvariant: 4137 if (!targ->isInvariant()) 4138 goto Lno; 4139 tded = targ; 4140 break; 4141 #endif 4121 4142 4122 4143 case TOKsuper: … … 5599 5620 AggregateDeclaration *ad; 5600 5621 UnaExp *ue = (UnaExp *)(e1); 5601 5622 5602 5623 if (e1->op == TOKdotvar) 5603 5624 { // Do overload resolution … … 5606 5627 f = dve->var->isFuncDeclaration(); 5607 5628 assert(f); 5608 f = f->overloadResolve(loc, arguments);5629 f = f->overloadResolve(loc, ue->e1, arguments); 5609 5630 5610 5631 ad = f->toParent()->isAggregateDeclaration(); … … 5615 5636 assert(td); 5616 5637 if (!arguments) 5617 // Should fix deduce () so it works on NULL argument5638 // Should fix deduceFunctionTemplate() so it works on NULL argument 5618 5639 arguments = new Expressions(); 5619 f = td->deduce (sc, loc, NULL, arguments);5640 f = td->deduceFunctionTemplate(sc, loc, NULL, ue->e1, arguments); 5620 5641 if (!f) 5621 5642 { type = Type::terror; … … 5683 5704 #endif 5684 5705 // Const member function can take const/invariant/mutable this 5685 if (!(f-> storage_class & STCconst))5706 if (!(f->type->isConst())) 5686 5707 { 5687 5708 // Check for const/invariant compatibility … … 5689 5710 if (tthis->ty == Tpointer) 5690 5711 tthis = tthis->nextOf()->toBasetype(); 5691 if (f-> storage_class & STCinvariant)5712 if (f->type->isInvariant()) 5692 5713 { 5693 5714 /* if (tthis->mod != MODinvariant) … … 5697 5718 { 5698 5719 /* if (tthis->mod != 0) 5699 error("%s can only be called on a mutable object", e1->toChars()); */ 5720 { //printf("test1: mod = %x\n", tthis->mod); 5721 error("%s can only be called on a mutable object, not %s", e1->toChars(), tthis->toChars()); 5722 } */ 5700 5723 } 5701 5724 … … 5755 5778 sc->callSuper |= CSXany_ctor | CSXsuper_ctor; 5756 5779 5757 f = f->overloadResolve(loc, arguments);5780 f = f->overloadResolve(loc, NULL, arguments); 5758 5781 checkDeprecated(sc, f); 5759 5782 e1 = new DotVarExp(e1->loc, e1, f); … … 5789 5812 5790 5813 f = cd->ctor; 5791 f = f->overloadResolve(loc, arguments);5814 f = f->overloadResolve(loc, NULL, arguments); 5792 5815 checkDeprecated(sc, f); 5793 5816 e1 = new DotVarExp(e1->loc, e1, f); … … 5810 5833 if (f2) 5811 5834 { 5812 f2 = f2->overloadResolve(loc, arguments, 1);5835 f2 = f2->overloadResolve(loc, NULL, arguments, 1); 5813 5836 } 5814 5837 else 5815 5838 { TemplateDeclaration *td = s->isTemplateDeclaration(); 5816 5839 assert(td); 5817 f2 = td->deduce (sc, loc, NULL, arguments, 1);5840 f2 = td->deduceFunctionTemplate(sc, loc, NULL, NULL, arguments, 1); 5818 5841 } 5819 5842 if (f2) … … 5861 5884 { 5862 5885 TemplateExp *te = (TemplateExp *)e1; 5863 f = te->td->deduce (sc, loc, NULL, arguments);5886 f = te->td->deduceFunctionTemplate(sc, loc, NULL, NULL, arguments); 5864 5887 if (!f) 5865 5888 { type = Type::terror; … … 5893 5916 5894 5917 if (ve->hasOverloads) 5895 f = f->overloadResolve(loc, arguments);5918 f = f->overloadResolve(loc, NULL, arguments); 5896 5919 checkDeprecated(sc, f); 5897 5920 … … 5992 6015 { 5993 6016 DotVarExp *dve = (DotVarExp *)e1; 5994 if (dve->var->isFinal())5995 type = e1->type->constOf()->pointerTo();5996 6017 5997 6018 FuncDeclaration *f = dve->var->isFuncDeclaration(); … … 6009 6030 { 6010 6031 VarExp *ve = (VarExp *)e1; 6011 if (ve->var->isFinal()) 6012 type = e1->type->constOf()->pointerTo(); 6032 6033 VarDeclaration *v = ve->var->isVarDeclaration(); 6034 if (v && !v->canTakeAddressOf()) 6035 error("cannot take address of %s", e1->toChars()); 6013 6036 6014 6037 FuncDeclaration *f = ve->var->isFuncDeclaration(); … … 6098 6121 Expression *PtrExp::modifiableLvalue(Scope *sc, Expression *e) 6099 6122 { 6100 //printf("PtrExp::modifiableLvalue() %s \n",toChars());6123 //printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type->toChars()); 6101 6124 6102 6125 if (e1->op == TOKsymoff) 6103 6126 { SymOffExp *se = (SymOffExp *)e1; 6104 6127 se->var->checkModify(loc, sc); 6105 return toLvalue(sc, e);6128 //return toLvalue(sc, e); 6106 6129 } 6107 6130 … … 7080 7103 7081 7104 #if LOGSEMANTIC 7082 //printf("AssignExp::semantic('%s')\n", toChars());7105 printf("AssignExp::semantic('%s')\n", toChars()); 7083 7106 #endif 7084 7107 //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op)); … … 7245 7268 { // Try to do a decent error message with the expression 7246 7269 // before it got constant folded 7247 e1 = e1->optimize(WANTvalue); 7270 if (e1->op != TOKvar) 7271 e1 = e1->optimize(WANTvalue); 7248 7272 e1 = e1->modifiableLvalue(sc, e1old); 7249 7273 } … … 7948 7972 7949 7973 typeCombine(sc); 7950 //type->print(); 7951 type = type->mutableOf(); 7952 //printf("test1\n"); 7953 //type->print(); 7974 type = type->toHeadMutable(); 7954 7975 7955 7976 Type *tb = type->toBasetype(); 7956 7977 if (tb->ty == Tsarray) 7957 7978 type = tb->nextOf()->arrayOf(); 7958 //printf("test2\n");7959 //type->print();7960 7979 if (type->ty == Tarray && tb1->nextOf()->mod != tb2->nextOf()->mod) 7961 type = type->nextOf()->toCanonConst()->arrayOf(); 7962 //printf("test3\n"); 7963 //type->print(); 7980 type = type->nextOf()->toHeadMutable()->arrayOf(); 7964 7981 #if 0 7965 7982 e1->type->print(); … … 8791 8808 break; 8792 8809 } 8810 if (type->toBasetype()->ty == Tarray) 8811 { 8812 e1 = e1->castTo(sc, type); 8813 e2 = e2->castTo(sc, type); 8814 } 8793 8815 } 8794 8816 #if 0 trunk/rebuild/func.c
r840 r847 111 111 #endif 112 112 113 if (type->nextOf()) 113 storage_class |= sc->stc; 114 //printf("function storage_class = x%x\n", storage_class); 115 116 if (!originalType) 117 originalType = type; 118 if (!type->deco && type->nextOf()) 119 { 120 #if 1 121 /* Apply const and invariant storage class 122 * to the function type 123 */ 114 124 type = type->semantic(loc, sc); 125 if (storage_class & STCinvariant) 126 { // Don't use toInvariant(), as that will do a merge() 127 type = type->makeInvariant(); 128 type->deco = type->merge()->deco; 129 } 130 else if (storage_class & STCconst) 131 { 132 if (!type->isInvariant()) 133 { // Don't use toConst(), as that will do a merge() 134 type = type->makeConst(); 135 type->deco = type->merge()->deco; 136 } 137 } 138 #else 139 if (storage_class & (STCconst | STCinvariant)) 140 { 141 /* Apply const and invariant storage class 142 * to the function's return type 143 */ 144 Type *tn = type->nextOf(); 145 if (storage_class & STCconst) 146 tn = tn->makeConst(); 147 if (storage_class & STCinvariant) 148 tn = tn->makeInvariant(); 149 ((TypeNext *)type)->next = tn; 150 } 151 152 type = type->semantic(loc, sc); 153 #endif 154 } 115 155 //type->print(); 116 156 if (type->ty != Tfunction) … … 120 160 } 121 161 f = (TypeFunction *)(type); 162 122 163 size_t nparams = Argument::dim(f->parameters); 123 164 … … 129 170 } 130 171 protection = sc->protection; 131 storage_class |= sc->stc;132 //printf("function storage_class = x%x\n", storage_class);133 172 Dsymbol *parent = toParent(); 134 173 … … 138 177 /*if (isAbstract() && !isVirtual()) 139 178 error("non-virtual functions cannot be abstract"); */ 179 180 if ((f->isConst() || f->isInvariant()) && !isThis()) 181 error("without 'this' cannot be const/invariant"); 182 183 if (isAbstract() && isFinal()) 184 error("cannot be both final and abstract"); 140 185 #if 0 141 186 if (isAbstract() && fbody) … … 682 727 #if BREAKABI 683 728 v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL); 684 v_arguments->storage_class = STCparameter | STCin;729 v_arguments->storage_class = STCparameter; 685 730 v_arguments->semantic(sc2); 686 731 sc2->insert(v_arguments); 687 732 v_arguments->parent = this; 688 733 734 //t = Type::typeinfo->type->constOf()->arrayOf(); 689 735 t = Type::typeinfo->type->arrayOf(); 690 736 _arguments = new VarDeclaration(0, t, Id::_arguments, NULL); … … 1111 1157 Expression *e1 = new VarExp(0, _arguments); 1112 1158 e = new AssignExp(0, e1, e); 1159 e->op = TOKconstruct; 1113 1160 e = e->semantic(sc); 1114 1161 a->push(new ExpStatement(0, e)); … … 1302 1349 if (type && f->type && // can be NULL for overloaded constructors 1303 1350 f->type->covariant(type) && 1351 f->type->mod == type->mod && 1304 1352 !isFuncAliasDeclaration()) 1305 1353 { … … 1449 1497 { 1450 1498 Match *m; 1499 Expression *ethis; 1451 1500 Expressions *arguments; 1452 1501 }; … … 1464 1513 m->anyf = f; 1465 1514 tf = (TypeFunction *)f->type; 1466 match = (MATCH) tf->callMatch( arguments);1515 match = (MATCH) tf->callMatch(f->needThis() ? p->ethis : NULL, arguments); 1467 1516 //printf("match = %d\n", match); 1468 1517 if (match != MATCHnomatch) … … 1499 1548 } 1500 1549 1501 void overloadResolveX(Match *m, FuncDeclaration *fstart, Expressions *arguments) 1550 void overloadResolveX(Match *m, FuncDeclaration *fstart, 1551 Expression *ethis, Expressions *arguments) 1502 1552 { 1503 1553 Param2 p; 1504 1554 p.m = m; 1555 p.ethis = ethis; 1505 1556 p.arguments = arguments; 1506 1557 overloadApply(fstart, &fp2, &p); … … 1508 1559 1509 1560 1510 FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression s *arguments, int flags)1561 FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, int flags) 1511 1562 { 1512 1563 TypeFunction *tf; … … 1531 1582 m
