Changeset 846
- Timestamp:
- 12/20/07 16:13:06 (10 months ago)
- Files:
-
- branches/dmdfe-2.0/attrib.c (modified) (2 diffs)
- branches/dmdfe-2.0/cast.c (modified) (1 diff)
- branches/dmdfe-2.0/class.c (modified) (6 diffs)
- branches/dmdfe-2.0/declaration.c (modified) (17 diffs)
- branches/dmdfe-2.0/declaration.h (modified) (5 diffs)
- branches/dmdfe-2.0/doc.c (modified) (5 diffs)
- branches/dmdfe-2.0/dsymbol.c (modified) (5 diffs)
- branches/dmdfe-2.0/expression.c (modified) (33 diffs)
- branches/dmdfe-2.0/func.c (modified) (13 diffs)
- branches/dmdfe-2.0/init.c (modified) (1 diff)
- branches/dmdfe-2.0/inline.c (modified) (1 diff)
- branches/dmdfe-2.0/interpret.c (modified) (2 diffs)
- branches/dmdfe-2.0/mars.c (modified) (1 diff)
- branches/dmdfe-2.0/module.c (modified) (1 diff)
- branches/dmdfe-2.0/module.h (modified) (1 diff)
- branches/dmdfe-2.0/mtype.c (modified) (29 diffs)
- branches/dmdfe-2.0/mtype.h (modified) (7 diffs)
- branches/dmdfe-2.0/opover.c (modified) (6 diffs)
- branches/dmdfe-2.0/optimize.c (modified) (4 diffs)
- branches/dmdfe-2.0/parse.c (modified) (17 diffs)
- branches/dmdfe-2.0/parse.h (modified) (3 diffs)
- branches/dmdfe-2.0/statement.c (modified) (1 diff)
- branches/dmdfe-2.0/struct.c (modified) (3 diffs)
- branches/dmdfe-2.0/template.c (modified) (31 diffs)
- branches/dmdfe-2.0/template.h (modified) (9 diffs)
- branches/dmdfe-2.0/tocsym.c (modified) (1 diff)
- branches/dmdfe-2.0/todt.c (modified) (1 diff)
- branches/dmdfe-2.0/toobj.c (modified) (7 diffs)
- branches/dmdfe-2.0/typinf.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmdfe-2.0/attrib.c
r740 r846 283 283 if (stc & (STCauto | STCscope | STCstatic | STCextern)) 284 284 sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern); 285 if (stc & (STCconst | STCinvariant)) 286 sc->stc &= ~(STCconst | STCinvariant); 285 287 sc->stc |= stc; 286 288 for (unsigned i = 0; i < decl->dim; i++) … … 311 313 { STCextern, TOKextern }, 312 314 { STCconst, TOKconst }, 315 { STCinvariant, TOKinvariant }, 313 316 { STCfinal, TOKfinal }, 314 317 { STCabstract, TOKabstract }, branches/dmdfe-2.0/cast.c
r838 r846 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 } branches/dmdfe-2.0/class.c
r837 r846 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()) branches/dmdfe-2.0/declaration.c
r838 r846 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 … … 643 644 { 644 645 //printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); 645 //printf(" type = %s\n", type ->toChars());646 //printf(" stc = x%x\n", sc->stc);646 //printf(" type = %s\n", type ? type->toChars() : "null"); 647 //printf(" stc = x%x\n", sc->stc); 647 648 //printf("linkage = %d\n", sc->linkage); 648 649 //if (strcmp(toChars(), "mul") == 0) halt(); … … 665 666 */ 666 667 storage_class &= ~STCauto; 668 originalType = type; 667 669 } 668 670 else 671 { if (!originalType) 672 originalType = type; 669 673 type = type->semantic(loc, sc); 674 } 675 //printf(" type = %s\n", type ? type->toChars() : "null"); 670 676 671 677 type->checkDeprecated(loc, sc); … … 737 743 } 738 744 739 if (storage_class & STCfinal && !init && !fd)740 { // Initialize by constructor only741 storage_class |= STCctorinit;742 }743 744 745 Lagain: 745 if (isConst()) 746 { 747 /* Rewrite things like: 748 * const string s; 749 * to: 750 * invariant string s; 751 */ 752 if (type->nextOf() && type->nextOf()->isInvariant()) 753 { storage_class |= STCinvariant; 754 storage_class &= ~STCconst; 755 goto Lagain; 756 } 757 type = type->constOf(); 758 if (isParameter()) 759 { storage_class |= STCfinal; 760 storage_class &= ~STCconst; 761 } 762 } 763 else if (storage_class & STCinvariant) 746 if (storage_class & STCinvariant) 764 747 { 765 748 type = type->invariantOf(); 766 if (isParameter()) 767 { storage_class |= STCfinal; 768 storage_class &= ~STCinvariant; 769 }770 } 771 type = type->toCanonConst();772 773 if (storage_class & (STC const | STCinvariant | STCstatic))749 } 750 else if (storage_class & (STCconst | STCin)) 751 { 752 if (!type->isInvariant()) 753 type = type->constOf(); 754 } 755 756 if (storage_class & (STCstatic | STCextern)) 774 757 { 775 758 } … … 795 778 aad = parent->isAggregateDeclaration(); 796 779 if (aad) 797 { assert(!(storage_class & (STCconst | STCinvariant | STCstatic))); 798 aad->addField(sc, this); 780 { assert(!(storage_class & (STCextern | STCstatic))); 781 782 if (storage_class & (STCconst | STCinvariant) && init) 783 { 784 if (!type->toBasetype()->isTypeBasic()) 785 storage_class |= STCstatic; 786 } 787 else 788 aad->addField(sc, this); 799 789 } 800 790 … … 805 795 } 806 796 797 /* Templates cannot add fields to aggregates 798 */ 807 799 TemplateInstance *ti = parent->isTemplateInstance(); 808 800 if (ti) … … 840 832 } 841 833 842 if (!init && !sc->inunion && !isStatic() && !isConst() && fd && 843 !(storage_class & (STCfield | STCin | STCforeach)) && 834 if ((isConst() || isInvariant()) && !init && !fd) 835 { // Initialize by constructor only 836 storage_class |= STCctorinit; 837 } 838 839 if (init) 840 storage_class |= STCinit; // remember we had an explicit initializer 841 842 if (!init && !sc->inunion && !isStatic() && fd && 843 (!(storage_class & (STCfield | STCin | STCforeach | STCparameter)) || (storage_class & STCout)) && 844 844 type->size() != 0) 845 845 { … … 907 907 // If local variable, use AssignExp to handle all the various 908 908 // possibilities. 909 if (fd && !isStatic() && !isConst() && !isInvariant() &&909 if (fd && !isStatic() && 910 910 !init->isVoidInitializer()) 911 911 { … … 968 968 { 969 969 init = init->semantic(sc, type); 970 if (fd && (isConst() || isInvariant()) && !isStatic()) 971 { // Make it static 972 storage_class |= STCstatic; 973 } 974 } 975 } 976 else if (isConst() || isInvariant() || isFinal()) 970 } 971 } 972 else if (storage_class & (STCconst | STCinvariant) || 973 type->isConst() || type->isInvariant()) 977 974 { 978 975 /* Because we may need the results of a const declaration in a … … 1015 1012 else if (ei) 1016 1013 { 1017 e = e->optimize(WANTvalue | WANTinterpret); 1014 if (isDataseg()) 1015 /* static const/invariant does CTFE 1016 */ 1017 e = e->optimize(WANTvalue | WANTinterpret); 1018 else 1019 e = e->optimize(WANTvalue); 1018 1020 if (e->op == TOKint64 || e->op == TOKstring) 1019 1021 { … … 1035 1037 } 1036 1038 1037 ExpInitializer *VarDeclaration::getExpInitializer()1038 {1039 ExpInitializer *ei;1040 1041 if (init)1042 ei = init->isExpInitializer();1043 else1044 {1045 Expression *e = type->defaultInit();1046 if (e)1047 ei = new ExpInitializer(loc, e);1048 else1049 ei = NULL;1050 }1051 return ei;1052 }1053 1054 1039 void VarDeclaration::semantic2(Scope *sc) 1055 1040 { … … 1085 1070 void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 1086 1071 { 1072 if (storage_class & STCstatic) 1073 buf->writestring("static "); 1087 1074 if (storage_class & STCconst) 1088 1075 buf->writestring("const "); 1089 if (storage_class & STCstatic) 1090 buf->writestring("static "); 1076 if (storage_class & STCinvariant) 1077 buf->writestring("invariant "); 1078 1091 1079 if (type) 1092 1080 type->toCBuffer(buf, ident, hgs); … … 1109 1097 int VarDeclaration::isImportedSymbol() 1110 1098 { 1111 if (protection == PROTexport && !init && (isStatic() || isConst() || parent->isModule())) 1099 if (protection == PROTexport && !init && 1100 (storage_class & STCstatic || parent->isModule())) 1112 1101 return TRUE; 1113 1102 return FALSE; … … 1161 1150 } 1162 1151 1152 /**************************** 1153 * Get ExpInitializer for a variable, if there is one. 1154 */ 1155 1156 ExpInitializer *VarDeclaration::getExpInitializer() 1157 { 1158 ExpInitializer *ei; 1159 1160 if (init) 1161 ei = init->isExpInitializer(); 1162 else 1163 { 1164 Expression *e = type->defaultInit(); 1165 if (e) 1166 ei = new ExpInitializer(loc, e); 1167 else 1168 ei = NULL; 1169 } 1170 return ei; 1171 } 1172 1173 /******************************************* 1174 * If variable has a constant expression initializer, get it. 1175 * Otherwise, return NULL. 1176 */ 1177 1178 Expression *VarDeclaration::getConstInitializer() 1179 { 1180 if ((isConst() || isInvariant()) && 1181 storage_class & STCinit) 1182 { 1183 ExpInitializer *ei = getExpInitializer(); 1184 if (ei) 1185 return ei->exp; 1186 } 1187 1188 return NULL; 1189 } 1190 1191 /************************************* 1192 * Return !=0 if we can take the address of this variable. 1193 */ 1194 1195 int VarDeclaration::canTakeAddressOf() 1196 { 1197 /* Global variables and struct/class fields of the form: 1198 * const int x = 3; 1199 * are not stored and hence cannot have their address taken. 1200 */ 1201 if ((isConst() || isInvariant()) && 1202 storage_class & STCinit && 1203 (!(storage_class & (STCstatic | STCextern)) || (storage_class & STCfield)) && 1204 (!parent || toParent()->isModule() || toParent()->isTemplateInstance()) && 1205 type->toBasetype()->isTypeBasic() 1206 ) 1207 { 1208 return 0; 1209 } 1210 return 1; 1211 } 1163 1212 1164 1213 /******************************* 1165 1214 * Does symbol go into data segment? 1215 * Includes extern variables. 1166 1216 */ 1167 1217 … … 1174 1224 #endif 1175 1225 Dsymbol *parent = this->toParent(); 1176 if (!parent && !(storage_class & (STCstatic | STCconst)))1226 if (!parent && !(storage_class & STCstatic)) 1177 1227 { error("forward referenced"); 1178 halt();1179 1228 type = Type::terror; 1180 1229 return 0; 1181 1230 } 1182 return (storage_class & (STCstatic | STCconst) || 1183 parent->isModule() || 1184 parent->isTemplateInstance()); 1231 return canTakeAddressOf() && 1232 (storage_class & (STCstatic | STCextern) || 1233 toParent()->isModule() || 1234 toParent()->isTemplateInstance()); 1185 1235 } 1186 1236 branches/dmdfe-2.0/declaration.h
r838 r846 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(); branches/dmdfe-2.0/doc.c
r783 r846 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 branches/dmdfe-2.0/dsymbol.c
r837 r846 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; branches/dmdfe-2.0/expression.c
r838 r846 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; … … 1290 1290 char *RealExp::toChars() 1291 1291 { 1292 staticchar buffer[sizeof(value) * 3 + 8 + 1 + 1];1292 char buffer[sizeof(value) * 3 + 8 + 1 + 1]; 1293 1293 1294 1294 #ifdef IN_GCC … … 1300 1300 #endif 1301 1301 assert(strlen(buffer) < sizeof(buffer)); 1302 return buffer;1302 return mem.strdup(buffer); 1303 1303 } 1304 1304 … … 1360 1360 if (this == o || 1361 1361 (((Expression *)o)->op == TOKfloat64 && 1362 ((ne = (RealExp *)o), type-> equals(ne->type)) &&1362 ((ne = (RealExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 1363 1363 RealEquals(value, ne->value) 1364 1364 ) … … 1504 1504 char *ComplexExp::toChars() 1505 1505 { 1506 staticchar buffer[sizeof(value) * 3 + 8 + 1];1506 char buffer[sizeof(value) * 3 + 8 + 1]; 1507 1507 1508 1508 #ifdef IN_GCC … … 1516 1516 assert(strlen(buffer) < sizeof(buffer)); 1517 1517 #endif 1518 return buffer;1518 return mem.strdup(buffer); 1519 1519 } 1520 1520 … … 1557 1557 if (this == o || 1558 1558 (((Expression *)o)->op == TOKcomplex80 && 1559 ((ne = (ComplexExp *)o), type-> equals(ne->type)) &&1559 ((ne = (ComplexExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 1560 1560 RealEquals(creall(value), creall(ne->value)) && 1561 1561 RealEquals(cimagl(value), cimagl(ne->value)) … … 3132 3132 error("cannot create instance of interface %s", cd->toChars()); 3133 3133 else if (cd->isAbstract()) 3134 error("cannot create instance of abstract class %s", cd->toChars()); 3134 { error("cannot create instance of abstract class %s", cd->toChars()); 3135 for (int i = 0; i < cd->vtbl.dim; i++) 3136 { FuncDeclaration *fd = ((Dsymbol *)cd->vtbl.data[i])->isFuncDeclaration(); 3137 if (fd && fd->isAbstract()) 3138 error("function %s is abstract", fd->toChars()); 3139 } 3140 } 3135 3141 checkDeprecated(sc, cd); 3136 3142 if (cd->isNested()) … … 3209 3215 { 3210 3216 assert(f); 3211 f = f->overloadResolve(loc, arguments);3217 f = f->overloadResolve(loc, NULL, arguments); 3212 3218 checkDeprecated(sc, f); 3213 3219 member = f->isCtorDeclaration(); … … 3240 3246 newargs->shift(e); 3241 3247 3242 f = f->overloadResolve(loc, newargs);3248 f = f->overloadResolve(loc, NULL, newargs); 3243 3249 allocator = f->isNewDeclaration(); 3244 3250 assert(allocator); … … 3274 3280 newargs->shift(e); 3275 3281 3276 f = f->overloadResolve(loc, newargs);3282 f = f->overloadResolve(loc, NULL, newargs); 3277 3283 allocator = f->isNewDeclaration(); 3278 3284 assert(allocator); … … 3303 3309 arg = resolveProperties(sc, arg); 3304 3310 arg = arg->implicitCastTo(sc, Type::tsize_t); 3311 arg = arg->optimize(WANTvalue); 3305 3312 if (arg->op == TOKint64 && (long long)arg->toInteger() < 0) 3306 3313 error("negative array index %s", arg->toChars()); … … 3501 3508 if (this == o || 3502 3509 (((Expression *)o)->op == TOKvar && 3503 ((ne = (VarExp *)o), type-> equals(ne->type)) &&3510 ((ne = (VarExp *)o), type->toHeadMutable()->equals(ne->type->toHeadMutable())) && 3504 3511 var == ne->var)) 3505 3512 return 1; … … 4118 4125 tded = targ; 4119 4126 break; 4127 4128 #if V2 4129 case TOKconst: 4130 if (!targ->isConst()) 4131 goto Lno; 4132 tded = targ; 4133 break; 4134 4135 case TOKinvariant: 4136 if (!targ->isInvariant()) 4137 goto Lno; 4138 tded = targ; 4139 break; 4140 #endif 4120 4141 4121 4142 case TOKsuper: … … 5598 5619 AggregateDeclaration *ad; 5599 5620 UnaExp *ue = (UnaExp *)(e1); 5600 5621 5601 5622 if (e1->op == TOKdotvar) 5602 5623 { // Do overload resolution … … 5605 5626 f = dve->var->isFuncDeclaration(); 5606 5627 assert(f); 5607 f = f->overloadResolve(loc, arguments);5628 f = f->overloadResolve(loc, ue->e1, arguments); 5608 5629 5609 5630 ad = f->toParent()->isAggregateDeclaration(); … … 5614 5635 assert(td); 5615 5636 if (!arguments) 5616 // Should fix deduce () so it works on NULL argument5637 // Should fix deduceFunctionTemplate() so it works on NULL argument 5617 5638 arguments = new Expressions(); 5618 f = td->deduce (sc, loc, NULL, arguments);5639 f = td->deduceFunctionTemplate(sc, loc, NULL, ue->e1, arguments); 5619 5640 if (!f) 5620 5641 { type = Type::terror; … … 5682 5703 #endif 5683 5704 // Const member function can take const/invariant/mutable this 5684 if (!(f-> storage_class & STCconst))5705 if (!(f->type->isConst())) 5685 5706 { 5686 5707 // Check for const/invariant compatibility … … 5688 5709 if (tthis->ty == Tpointer) 5689 5710 tthis = tthis->nextOf()->toBasetype(); 5690 if (f-> storage_class & STCinvariant)5711 if (f->type->isInvariant()) 5691 5712 { 5692 5713 if (tthis->mod != MODinvariant) … … 5696 5717 { 5697 5718 if (tthis->mod != 0) 5698 error("%s can only be called on a mutable object", e1->toChars()); 5719 { //printf("test1: mod = %x\n", tthis->mod); 5720 error("%s can only be called on a mutable object, not %s", e1->toChars(), tthis->toChars()); 5721 } 5699 5722 } 5700 5723 … … 5754 5777 sc->callSuper |= CSXany_ctor | CSXsuper_ctor; 5755 5778 5756 f = f->overloadResolve(loc, arguments);5779 f = f->overloadResolve(loc, NULL, arguments); 5757 5780 checkDeprecated(sc, f); 5758 5781 e1 = new DotVarExp(e1->loc, e1, f); … … 5788 5811 5789 5812 f = cd->ctor; 5790 f = f->overloadResolve(loc, arguments);5813 f = f->overloadResolve(loc, NULL, arguments); 5791 5814 checkDeprecated(sc, f); 5792 5815 e1 = new DotVarExp(e1->loc, e1, f); … … 5809 5832 if (f2) 5810 5833 { 5811 f2 = f2->overloadResolve(loc, arguments, 1);5834 f2 = f2->overloadResolve(loc, NULL, arguments, 1); 5812 5835 } 5813 5836 else 5814 5837 { TemplateDeclaration *td = s->isTemplateDeclaration(); 5815 5838 assert(td); 5816 f2 = td->deduce (sc, loc, NULL, arguments, 1);5839 f2 = td->deduceFunctionTemplate(sc, loc, NULL, NULL, arguments, 1); 5817 5840 } 5818 5841 if (f2) … … 5860 5883 { 5861 5884 TemplateExp *te = (TemplateExp *)e1; 5862 f = te->td->deduce (sc, loc, NULL, arguments);5885 f = te->td->deduceFunctionTemplate(sc, loc, NULL, NULL, arguments); 5863 5886 if (!f) 5864 5887 { type = Type::terror; … … 5892 5915 5893 5916 if (ve->hasOverloads) 5894 f = f->overloadResolve(loc, arguments);5917 f = f->overloadResolve(loc, NULL, arguments); 5895 5918 checkDeprecated(sc, f); 5896 5919 … … 5991 6014 { 5992 6015 DotVarExp *dve = (DotVarExp *)e1; 5993 if (dve->var->isFinal())5994 type = e1->type->constOf()->pointerTo();5995 6016 5996 6017 FuncDeclaration *f = dve->var->isFuncDeclaration(); … … 6008 6029 { 6009 6030 VarExp *ve = (VarExp *)e1; 6010 if (ve->var->isFinal()) 6011 type = e1->type->constOf()->pointerTo(); 6031 6032 VarDeclaration *v = ve->var->isVarDeclaration(); 6033 if (v && !v->canTakeAddressOf()) 6034 error("cannot take address of %s", e1->toChars()); 6012 6035 6013 6036 FuncDeclaration *f = ve->var->isFuncDeclaration(); … … 6097 6120 Expression *PtrExp::modifiableLvalue(Scope *sc, Expression *e) 6098 6121 { 6099 //printf("PtrExp::modifiableLvalue() %s \n",toChars());6122 //printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type->toChars()); 6100 6123 6101 6124 if (e1->op == TOKsymoff) 6102 6125 { SymOffExp *se = (SymOffExp *)e1; 6103 6126 se->var->checkModify(loc, sc); 6104 return toLvalue(sc, e);6127 //return toLvalue(sc, e); 6105 6128 } 6106 6129 … … 7079 7102 7080 7103 #if LOGSEMANTIC 7081 //printf("AssignExp::semantic('%s')\n", toChars());7104 printf("AssignExp::semantic('%s')\n", toChars()); 7082 7105 #endif 7083 7106 //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op)); … … 7244 7267 { // Try to do a decent error message with the expression 7245 7268 // before it got constant folded 7246 e1 = e1->optimize(WANTvalue); 7269 if (e1->op != TOKvar) 7270 e1 = e1->optimize(WANTvalue); 7247 7271 e1 = e1->modifiableLvalue(sc, e1old); 7248 7272 } … … 7947 7971 7948 7972 typeCombine(sc); 7949 //type->print(); 7950 type = type->mutableOf(); 7951 //printf("test1\n"); 7952 //type->print(); 7973 type = type->toHeadMutable(); 7953 7974 7954 7975 Type *tb = type->toBasetype(); 7955 7976 if (tb->ty == Tsarray) 7956 7977 type = tb->nextOf()->arrayOf(); 7957 //printf("test2\n");7958 //type->print();7959 7978 if (type->ty == Tarray && tb1->nextOf()->mod != tb2->nextOf()->mod) 7960 type = type->nextOf()->toCanonConst()->arrayOf(); 7961 //printf("test3\n"); 7962 //type->print(); 7979 type = type->nextOf()->toHeadMutable()->arrayOf(); 7963 7980 #if 0 7964 7981 e1->type->print(); … … 8790 8807 break; 8791 8808 } 8809 if (type->toBasetype()->ty == Tarray) 8810 { 8811 e1 = e1->castTo(sc, type); 8812 e2 = e2->castTo(sc, type); 8813 } 8792 8814 } 8793 8815 #if 0 branches/dmdfe-2.0/func.c
r838 r846 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) … … 680 725 #if BREAKABI 681 726 v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL); 682 v_arguments->storage_class = STCparameter | STCin;727 v_arguments->storage_class = STCparameter; 683 728 v_arguments->semantic(sc2); 684 729 sc2->insert(v_arguments); 685 730 v_arguments->parent = this; 686 731 732 //t = Type::typeinfo->type->constOf()->arrayOf(); 687 733 t = Type::typeinfo->type->arrayOf(); 688 734 _arguments = new VarDeclaration(0, t, Id::_arguments, NULL); … … 1109 1155 Expression *e1 = new VarExp(0, _arguments); 1110 1156 e = new AssignExp(0, e1, e); 1157 e->op = TOKconstruct; 1111 1158 e = e->semantic(sc); 1112 1159 a->push(new ExpStatement(0, e)); … … 1300 1347 if (type && f->type && // can be NULL for overloaded constructors 1301 1348 f->type->covariant(type) && 1349 f->type->mod == type->mod && 1302 1350 !isFuncAliasDeclaration()) 1303 1351 { … … 1447 1495 { 1448 1496 Match *m; 1497 Expression *ethis; 1449 1498 Expressions *arguments; 1450 1499 }; … … 1462 1511 m->anyf = f; 1463 1512 tf = (TypeFunction *)f->type; 1464 match = (MATCH) tf->callMatch( arguments);1513 match = (MATCH) tf->callMatch(f->needThis() ? p->ethis : NULL, arguments); 1465 1514 //printf("match = %d\n", match); 1466 1515 if (match != MATCHnomatch) … … 1497 1546 } 1498 1547 1499 void overloadResolveX(Match *m, FuncDeclaration *fstart, Expressions *arguments) 1548 void overloadResolveX(Match *m, FuncDeclaration *fstart, 1549 Expression *ethis, Expressions *arguments) 1500 1550 { 1501 1551 Param2 p; 1502 1552 p.m = m; 1553 p.ethis = ethis; 1503 1554 &nb
