Changeset 900
- Timestamp:
- 06/29/08 18:26:21 (3 months ago)
- Files:
-
- branches/dmdfe-2.0/aggregate.h (modified) (1 diff)
- branches/dmdfe-2.0/attrib.c (modified) (5 diffs)
- branches/dmdfe-2.0/cast.c (modified) (5 diffs)
- branches/dmdfe-2.0/class.c (modified) (8 diffs)
- branches/dmdfe-2.0/declaration.c (modified) (5 diffs)
- branches/dmdfe-2.0/declaration.h (modified) (3 diffs)
- branches/dmdfe-2.0/e2ir.c (modified) (3 diffs)
- branches/dmdfe-2.0/expression.c (modified) (6 diffs)
- branches/dmdfe-2.0/expression.h (modified) (2 diffs)
- branches/dmdfe-2.0/func.c (modified) (14 diffs)
- branches/dmdfe-2.0/idgen.c (modified) (1 diff)
- branches/dmdfe-2.0/interpret.c (modified) (4 diffs)
- branches/dmdfe-2.0/lexer.c (modified) (3 diffs)
- branches/dmdfe-2.0/lexer.h (modified) (1 diff)
- branches/dmdfe-2.0/mars.c (modified) (4 diffs)
- branches/dmdfe-2.0/mars.h (modified) (1 diff)
- branches/dmdfe-2.0/module.c (modified) (1 diff)
- branches/dmdfe-2.0/mtype.c (modified) (27 diffs)
- branches/dmdfe-2.0/mtype.h (modified) (1 diff)
- branches/dmdfe-2.0/opover.c (modified) (2 diffs)
- branches/dmdfe-2.0/optimize.c (modified) (7 diffs)
- branches/dmdfe-2.0/parse.c (modified) (14 diffs)
- branches/dmdfe-2.0/parse.h (modified) (1 diff)
- branches/dmdfe-2.0/statement.c (modified) (5 diffs)
- branches/dmdfe-2.0/statement.h (modified) (1 diff)
- branches/dmdfe-2.0/struct.c (modified) (1 diff)
- branches/dmdfe-2.0/template.c (modified) (17 diffs)
- branches/dmdfe-2.0/template.h (modified) (6 diffs)
- branches/dmdfe-2.0/tocsym.c (modified) (1 diff)
- branches/dmdfe-2.0/todt.c (modified) (1 diff)
- branches/dmdfe-2.0/toir.c (modified) (1 diff)
- branches/dmdfe-2.0/toobj.c (modified) (2 diffs)
- branches/dmdfe-2.0/traits.c (modified) (1 diff)
- branches/dmdfe-2.0/typinf.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmdfe-2.0/aggregate.h
r882 r900 200 200 VarDeclaration *vthis; // 'this' parameter if this class is nested 201 201 202 int inuse; // to prevent recursive attempts 203 202 204 ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses); 203 205 Dsymbol *syntaxCopy(Dsymbol *s); branches/dmdfe-2.0/attrib.c
r882 r900 288 288 if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest)) 289 289 sc->stc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest); 290 if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest)) 291 sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest); 290 292 if (stc & (STCconst | STCinvariant | STCmanifest)) 291 293 sc->stc &= ~(STCconst | STCinvariant | STCmanifest); … … 324 326 { STCdeprecated, TOKdeprecated }, 325 327 { STCoverride, TOKoverride }, 328 { STCnothrow, TOKnothrow }, 329 { STCpure, TOKpure }, 330 { STCtls, TOKtls }, 326 331 }; 327 332 … … 588 593 sc = sc->push(); 589 594 sc->anonAgg = &aad; 590 sc->stc &= ~(STCauto | STCscope | STCstatic );595 sc->stc &= ~(STCauto | STCscope | STCstatic | STCtls); 591 596 sc->inunion = isunion; 592 597 sc->offset = 0; … … 818 823 goto Lnodecl; 819 824 } 825 else if (global.params.ignoreUnsupportedPragmas) 826 { 827 if (global.params.verbose) 828 { 829 /* Print unrecognized pragmas 830 */ 831 printf("pragma %s", ident->toChars()); 832 if (args) 833 { 834 for (size_t i = 0; i < args->dim; i++) 835 { 836 Expression *e = (Expression *)args->data[i]; 837 e = e->semantic(sc); 838 e = e->optimize(WANTvalue | WANTinterpret); 839 if (i == 0) 840 printf(" ("); 841 else 842 printf(","); 843 printf("%s", e->toChars()); 844 } 845 if (args->dim) 846 printf(")"); 847 } 848 printf("\n"); 849 } 850 goto Lnodecl; 851 } 820 852 else 821 853 error("unrecognized pragma(%s)", ident->toChars()); … … 850 882 void PragmaDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 851 883 { 852 buf->printf("pragma(%s", ident->toChars()); 853 if (args) 854 { 855 for (size_t i = 0; i < args->dim; i++) 856 { 857 Expression *e = (Expression *)args->data[i]; 858 859 buf->writestring(", "); 860 e->toCBuffer(buf, hgs); 861 } 862 } 863 buf->writestring(")"); 884 buf->printf("pragma (%s", ident->toChars()); 885 if (args && args->dim) 886 { 887 buf->writestring(", "); 888 argsToCBuffer(buf, args, hgs); 889 } 890 buf->writeByte(')'); 864 891 AttribDeclaration::toCBuffer(buf, hgs); 865 892 } branches/dmdfe-2.0/cast.c
r883 r900 1 1 2 // Copyright (c) 1999-200 7by Digital Mars2 // Copyright (c) 1999-2008 by Digital Mars 3 3 // All Rights Reserved 4 4 // written by Walter Bright … … 32 32 Expression *Expression::implicitCastTo(Scope *sc, Type *t) 33 33 { 34 //printf("Expression::implicitCastTo(%s) => %s\n", type->toChars(), t->toChars()); 35 //printf("%s\n", toChars()); 34 //printf("Expression::implicitCastTo(%s of type %s) => %s\n", toChars(), type->toChars(), t->toChars()); 36 35 37 36 MATCH match = implicitConvTo(t); … … 104 103 toChars(), type->toChars(), t->toChars()); 105 104 #endif 106 //static int nest; if (++nest == 50) halt();105 //static int nest; if (++nest == 10) halt(); 107 106 if (!type) 108 107 { error("%s is not an expression", toChars()); … … 1087 1086 { 1088 1087 #if 0 1089 printf("ArrayLiteralExp::castTo(this=%s, type=%s, t=%s)\n",1088 printf("ArrayLiteralExp::castTo(this=%s, type=%s, => %s)\n", 1090 1089 toChars(), type->toChars(), t->toChars()); 1091 1090 #endif … … 1097 1096 if ((tb->ty == Tarray || tb->ty == Tsarray) && 1098 1097 (typeb->ty == Tarray || typeb->ty == Tsarray) && 1099 tb->nextOf()->toBasetype()->ty != Tvoid) 1098 // Not trying to convert non-void[] to void[] 1099 !(tb->nextOf()->toBasetype()->ty == Tvoid && typeb->nextOf()->toBasetype()->ty != Tvoid)) 1100 1100 { 1101 1101 if (tb->ty == Tsarray) branches/dmdfe-2.0/class.c
r882 r900 187 187 isnested = 0; 188 188 vthis = NULL; 189 inuse = 0; 189 190 } 190 191 … … 530 531 sc = sc->push(this); 531 532 sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 532 STCabstract | STCdeprecated | STCconst | STCinvariant );533 STCabstract | STCdeprecated | STCconst | STCinvariant | STCtls); 533 534 sc->stc |= storage_class & (STCconst | STCinvariant); 534 535 sc->parent = this; … … 575 576 scope->module->addDeferredSemantic(this); 576 577 577 //printf("\tsemantic('%s') failed \n", toChars());578 //printf("\tsemantic('%s') failed due to forward references\n", toChars()); 578 579 return; 579 580 } … … 1014 1015 1015 1016 //printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type); 1017 if (inuse) 1018 return; 1016 1019 if (!scope) 1017 1020 { type = type->semantic(loc, sc); … … 1101 1104 continue; 1102 1105 } 1103 if (!b->base->symtab || b->base->scope )1106 if (!b->base->symtab || b->base->scope || b->base->inuse) 1104 1107 { 1105 1108 //error("forward reference of base class %s", baseClass->toChars()); … … 1168 1171 sc = sc->push(this); 1169 1172 sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | 1170 STCabstract | STCdeprecated | STCconst | STCinvariant );1173 STCabstract | STCdeprecated | STCconst | STCinvariant | STCtls); 1171 1174 sc->stc |= storage_class & (STCconst | STCinvariant); 1172 1175 sc->parent = this; … … 1178 1181 structalign = sc->structalign; 1179 1182 sc->offset = 8; 1183 inuse++; 1180 1184 for (i = 0; i < members->dim; i++) 1181 1185 { … … 1183 1187 s->semantic(sc); 1184 1188 } 1189 inuse--; 1185 1190 //members->print(); 1186 1191 sc->pop(); branches/dmdfe-2.0/declaration.c
r883 r900 803 803 } 804 804 805 if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter ))805 if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls)) 806 806 { 807 807 } … … 812 812 aad = parent->isAggregateDeclaration(); 813 813 if (aad) 814 { assert(!(storage_class & (STCextern | STCstatic )));814 { assert(!(storage_class & (STCextern | STCstatic | STCtls))); 815 815 816 816 if (storage_class & (STCconst | STCinvariant) && init) … … 854 854 if (type->isauto() && !noauto) 855 855 { 856 if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest ) || !fd)856 if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls) || !fd) 857 857 { 858 858 error("globals, statics, fields, manifest constants, ref and out parameters cannot be auto"); … … 1113 1113 if (storage_class & STCstatic) 1114 1114 buf->writestring("static "); 1115 if (storage_class & STCtls) 1116 buf->writestring("__tls "); 1115 1117 if (storage_class & STCconst) 1116 1118 buf->writestring("const "); … … 1284 1286 } 1285 1287 return canTakeAddressOf() && 1286 (storage_class & (STCstatic | STCextern ) ||1288 (storage_class & (STCstatic | STCextern | STCtls) || 1287 1289 toParent()->isModule() || 1288 1290 toParent()->isTemplateInstance()); branches/dmdfe-2.0/declaration.h
r883 r900 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 … … 68 68 STCnodtor = 0x1000000, // don't run destructor 69 69 STCnothrow = 0x2000000, // never throws exceptions 70 STCpure = 0x4000000, // pure function 71 STCtls = 0x8000000, // thread local 70 72 }; 71 73 … … 483 485 void bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs); 484 486 int overrides(FuncDeclaration *fd); 487 int findVtblIndex(Array *vtbl, int dim); 485 488 int overloadInsert(Dsymbol *s); 486 489 FuncDeclaration *overloadExactMatch(Type *t); 487 490 FuncDeclaration *overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, int flags = 0); 491 MATCH leastAsSpecialized(FuncDeclaration *g); 488 492 LabelDsymbol *searchLabel(Identifier *ident); 489 493 AggregateDeclaration *isThis(); branches/dmdfe-2.0/e2ir.c
r883 r900 4115 4115 { 4116 4116 // set to: 4117 // *aaGet(aa, keyti, valuesize, value);4117 // *aaGet(aa, keyti, valuesize, index); 4118 4118 4119 4119 TypeAArray *taa = (TypeAArray *)t1; … … 4124 4124 Symbol *s; 4125 4125 4126 // n2 becomes the index, also known as the key 4126 4127 n2 = e2->toElem(irs); 4127 if (n2->Ety == TYstruct )4128 if (n2->Ety == TYstruct || n2->Ety == TYarray) 4128 4129 { 4129 4130 n2 = el_una(OPstrpar, TYstruct, n2); 4130 4131 n2->Enumbytes = n2->E1->Enumbytes; 4132 //printf("numbytes = %d\n", n2->Enumbytes); 4131 4133 assert(n2->Enumbytes); 4132 4134 } 4133 4135 valuesize = el_long(TYuint, vsize); // BUG: should be TYsize_t 4136 //printf("valuesize: "); elem_print(valuesize); 4134 4137 if (modifiable) 4135 4138 { … … 4141 4144 s = taa->aaGetSymbol("GetRvalue", 1); 4142 4145 } 4143 //printf("taa-> key = %s\n", taa->key->toChars());4146 //printf("taa->index = %s\n", taa->index->toChars()); 4144 4147 keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs); 4148 //keyti = taa->index->getTypeInfo(NULL)->toElem(irs); 4145 4149 //printf("keyti:\n"); 4146 4150 //elem_print(keyti); branches/dmdfe-2.0/expression.c
r883 r900 112 112 precedence[TOKfunction] = PREC_primary; 113 113 precedence[TOKvar] = PREC_primary; 114 precedence[TOKdefault] = PREC_primary; 114 115 115 116 // post … … 478 479 break; 479 480 } 480 arg = p->defaultArg->copy(); 481 arg = p->defaultArg; 482 if (arg->op == TOKdefault) 483 { DefaultInitExp *de = (DefaultInitExp *)arg; 484 arg = de->resolve(loc, sc); 485 } 486 else 487 arg = arg->copy(); 481 488 arguments->push(arg); 482 489 nargs++; … … 2056 2063 2057 2064 Lerr: 2058 error("'this' is only allowed in non-static member functions, not %s", sc->parent->toChars());2059 type = Type::t int32;2065 error("'this' is only defined in non-static member functions, not %s", sc->parent->toChars()); 2066 type = Type::terror; 2060 2067 return this; 2061 2068 } … … 5236 5243 e1->type = s->isClassDeclaration()->type; 5237 5244 5245 e1 = e1->semantic(sc); // get corrected nested refs 5238 5246 goto L1; 5239 5247 } … … 5241 5249 printf("2: "); 5242 5250 #endif 5243 error(" this for %s needs to be type %s not type %s",5244 var->toChars(), ad->toChars(), t->toChars());5251 error("%s for %s needs to be type %s not type %s", 5252 e1->toChars(), var->toChars(), ad->toChars(), t->toChars()); 5245 5253 } 5246 5254 } … … 9231 9239 9232 9240 9241 /****************************************************************/ 9242 9243 DefaultInitExp::DefaultInitExp(Loc loc, enum TOK subop, int size) 9244 : Expression(loc, TOKdefault, size) 9245 { 9246 this->subop = subop; 9247 } 9248 9249 void DefaultInitExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 9250 { 9251 buf->writestring(Token::toChars(subop)); 9252 } 9253 9254 /****************************************************************/ 9255 9256 FileInitExp::FileInitExp(Loc loc) 9257 : DefaultInitExp(loc, TOKfile, sizeof(FileInitExp)) 9258 { 9259 } 9260 9261 Expression *FileInitExp::semantic(Scope *sc) 9262 { 9263 //printf("FileInitExp::semantic()\n"); 9264 type = Type::tchar->invariantOf()->arrayOf(); 9265 return this; 9266 } 9267 9268 Expression *FileInitExp::resolve(Loc loc, Scope *sc) 9269 { 9270 //printf("FileInitExp::resolve() %s\n", toChars()); 9271 char *s = loc.filename ? loc.filename : sc->module->ident->toChars(); 9272 Expression *e = new StringExp(loc, s); 9273 e = e->semantic(sc); 9274 e = e->castTo(sc, type); 9275 return e; 9276 } 9277 9278 /****************************************************************/ 9279 9280 LineInitExp::LineInitExp(Loc loc) 9281 : DefaultInitExp(loc, TOKline, sizeof(LineInitExp)) 9282 { 9283 } 9284 9285 Expression *LineInitExp::semantic(Scope *sc) 9286 { 9287 type = Type::tint32; 9288 return this; 9289 } 9290 9291 Expression *LineInitExp::resolve(Loc loc, Scope *sc) 9292 { 9293 Expression *e = new IntegerExp(loc, loc.linnum, Type::tint32); 9294 e = e->castTo(sc, type); 9295 return e; 9296 } 9297 9298 branches/dmdfe-2.0/expression.h
r882 r900 62 62 Expression *resolveProperties(Scope *sc, Expression *e); 63 63 void accessCheck(Loc loc, Scope *sc, Expression *e, Declaration *d); 64 Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg, Identifier *id); 64 65 Dsymbol *search_function(ScopeDsymbol *ad, Identifier *funcid); 65 66 void inferApplyArgTypes(enum TOK op, Arguments *arguments, Expression *aggr); … … 1325 1326 /****************************************************************/ 1326 1327 1328 struct DefaultInitExp : Expression 1329 { 1330 enum TOK subop; // which of the derived classes this is 1331 1332 DefaultInitExp(Loc loc, enum TOK subop, int size); 1333 virtual Expression *resolve(Loc loc, Scope *sc) = 0; 1334 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 1335 }; 1336 1337 struct FileInitExp : DefaultInitExp 1338 { 1339 FileInitExp(Loc loc); 1340 Expression *semantic(Scope *sc); 1341 Expression *resolve(Loc loc, Scope *sc); 1342 }; 1343 1344 struct LineInitExp : DefaultInitExp 1345 { 1346 LineInitExp(Loc loc); 1347 Expression *semantic(Scope *sc); 1348 Expression *resolve(Loc loc, Scope *sc); 1349 }; 1350 1351 /****************************************************************/ 1352 1327 1353 /* Special values used by the interpreter 1328 1354 */ branches/dmdfe-2.0/func.c
r883 r900 36 36 : Declaration(id) 37 37 { 38 //printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type); 38 39 this->storage_class = storage_class; 39 40 this->type = type; … … 108 109 printf("\tFuncLiteralDeclaration()\n"); 109 110 printf("sc->parent = %s\n", sc->parent->toChars()); 110 printf("type: % s\n", type->toChars());111 printf("type: %p, %s\n", type, type->toChars()); 111 112 #endif 112 113 … … 305 306 306 307 // Find index of existing function in vtbl[] to override 307 if (cd->baseClass) 308 { 309 for (vi = 0; vi < cd->baseClass->vtbl.dim; vi++) 310 { 311 FuncDeclaration *fdv = ((Dsymbol *)cd->vtbl.data[vi])->isFuncDeclaration(); 312 313 // BUG: should give error if argument types match, 314 // but return type does not? 315 316 //printf("\tvtbl[%d] = '%s'\n", vi, fdv ? fdv->ident->toChars() : ""); 317 if (fdv && fdv->ident == ident) 318 { 319 int cov = type->covariant(fdv->type); 320 //printf("\tbaseclass cov = %d\n", cov); 321 if (cov == 2) 308 vi = findVtblIndex(&cd->vtbl, cd->baseClass ? cd->baseClass->vtbl.dim : 0); 309 switch (vi) 310 { 311 case -1: 312 /* Didn't find one, so 313 * This is an 'introducing' function which gets a new 314 * slot in the vtbl[]. 315 */ 316 317 // Verify this doesn't override previous final function 318 if (cd->baseClass) 319 { Dsymbol *s = cd->baseClass->search(loc, ident, 0); 320 if (s) 322 321 { 323 //type->print(); 324 //fdv->type->print(); 325 //printf("%s %s\n", type->deco, fdv->type->deco); 326 error("of type %s overrides but is not covariant with %s of type %s", 327 type->toChars(), fdv->toPrettyChars(), fdv->type->toChars()); 328 } 329 if (cov == 1) 330 { 331 if (fdv->isFinal()) 332 error("cannot override final function %s", fdv->toPrettyChars()); 333 334 if (!isOverride() && global.params.warnings) 335 error("overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars()); 336 337 if (fdv->toParent() == parent) 338 { 339 // If both are mixins, then error. 340 // If either is not, the one that is not overrides 341 // the other. 342 if (fdv->parent->isClassDeclaration()) 343 goto L1; 344 if (!this->parent->isClassDeclaration() 345 #if !BREAKABI 346 && !isDtorDeclaration() 347 #endif 348 && !isPostBlitDeclaration() 349 ) 350 error("multiple overrides of same function"); 351 } 352 cd->vtbl.data[vi] = (void *)this; 353 vtblIndex = vi; 354 355 /* This works by whenever this function is called, 356 * it actually returns tintro, which gets dynamically 357 * cast to type. But we know that tintro is a base 358 * of type, so we could optimize it by not doing a 359 * dynamic cast, but just subtracting the isBaseOf() 360 * offset if the value is != null. 361 */ 362 363 if (fdv->tintro) 364 tintro = fdv->tintro; 365 else if (!type->equals(fdv->type)) 366 { 367 /* Only need to have a tintro if the vptr 368 * offsets differ 369 */ 370 int offset; 371 if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset)) 372 { 373 tintro = fdv->type; 374 } 375 } 376 goto L1; 377 } 378 if (cov == 3) 379 { 380 cd->sizeok = 2; // can't finish due to forward reference 381 return; 322 FuncDeclaration *f = s->isFuncDeclaration(); 323 f = f->overloadExactMatch(type); 324 if (f && f->isFinal() && f->prot() != PROTprivate) 325 error("cannot override final function %s", f->toPrettyChars()); 382 326 } 383 327 } 384 } 385 } 386 387 // This is an 'introducing' function. 388 389 // Verify this doesn't override previous final function 390 if (cd->baseClass) 391 { Dsymbol *s = cd->baseClass->search(loc, ident, 0); 392 if (s) 393 { 394 FuncDeclaration *f = s->isFuncDeclaration(); 395 f = f->overloadExactMatch(type); 396 if (f && f->isFinal() && f->prot() != PROTprivate) 397 error("cannot override final function %s", f->toPrettyChars()); 398 } 399 } 400 401 if (isFinal()) 402 { 403 cd->vtblFinal.push(this); 404 } 405 else 406 { 407 // Append to end of vtbl[] 408 //printf("\tintroducing function\n"); 409 introducing = 1; 410 vi = cd->vtbl.dim; 411 cd->vtbl.push(this); 412 vtblIndex = vi; 413 } 414 415 L1: ; 328 329 if (isFinal()) 330 { 331 cd->vtblFinal.push(this); 332 } 333 else 334 { 335 // Append to end of vtbl[] 336 //printf("\tintroducing function\n"); 337 introducing = 1; 338 vi = cd->vtbl.dim; 339 cd->vtbl.push(this); 340 vtblIndex = vi; 341 } 342 343 break; 344 345 case -2: // can't determine because of fwd refs 346 cd->sizeok = 2; // can't finish due to forward reference 347 return; 348 349 default: 350 { FuncDeclaration *fdv = (FuncDeclaration *)cd->vtbl.data[vi]; 351 // This function is covariant with fdv 352 if (fdv->isFinal()) 353 error("cannot override final function %s", fdv->toPrettyChars()); 354 355 if (!isOverride() && global.params.warnings) 356 error("overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars()); 357 358 if (fdv->toParent() == parent) 359 { 360 // If both are mixins, then error. 361 // If either is not, the one that is not overrides 362 // the other. 363 if (fdv->parent->isClassDeclaration()) 364 break; 365 if (!this->parent->isClassDeclaration() 366 #if !BREAKABI 367 && !isDtorDeclaration() 368 #endif 369 && !isPostBlitDeclaration() 370 ) 371 error("multiple overrides of same function"); 372 } 373 cd->vtbl.data[vi] = (void *)this; 374 vtblIndex = vi; 375 376 /* This works by whenever this function is called, 377 * it actually returns tintro, which gets dynamically 378 * cast to type. But we know that tintro is a base 379 * of type, so we could optimize it by not doing a 380 * dynamic cast, but just subtracting the isBaseOf() 381 * offset if the value is != null. 382 */ 383 384 if (fdv->tintro) 385 tintro = fdv->tintro; 386 else if (!type->equals(fdv->type)) 387 { 388 /* Only need to have a tintro if the vptr 389 * offsets differ 390 */ 391 int offset; 392 if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset)) 393 { 394 tintro = fdv->type; 395 } 396 } 397 break; 398 } 399 } 416 400 417 401 /* Go through all the interface bases. … … 422 406 { 423 407 BaseClass *b = cd->interfaces[i]; 424 for (vi = 0; vi < b->base->vtbl.dim; vi++) 408 vi = findVtblIndex(&b->base->vtbl, b->base->vtbl.dim); 409 switch (vi) 425 410 { 426 Dsymbol *s = (Dsymbol *)b->base->vtbl.data[vi]; 427 //printf("interface %d vtbl[%d] %p %s\n", i, vi, s, s->toChars()); 428 FuncDeclaration *fdv = s->isFuncDeclaration(); 429 if (fdv && fdv->ident == ident) 430 { 431 int cov = type->covariant(fdv->type); 432 //printf("\tcov = %d\n", cov); 433 if (cov == 2) 411 case -1: 412 break; 413 414 case -2: 415 cd->sizeok = 2; // can't finish due to forward reference 416 return; 417 418 default: 419 { FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.data[vi]; 420 Type *ti = NULL; 421 422 if (fdv->tintro) 423 ti = fdv->tintro; 424 else if (!type->equals(fdv->type)) 434 425 { 435 //type->print(); 436 //fdv->type->print(); 437 //printf("%s %s\n", type->deco, fdv->type->deco); 438 error("of type %s overrides but is not covariant with %s of type %s", 439 type->toChars(), fdv->toPrettyChars(), fdv->type->toChars()); 426 /* Only need to have a tintro if the vptr 427 * offsets differ 428 */ 429 int offset; 430 if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset)) 431 { 432 ti = fdv->type; 433 #if 0 434 if (offset) 435 ti = fdv->type; 436 else if (type->nextOf()->ty == Tclass) 437 { ClassDeclaration *cdn = ((TypeClass *)type->nextOf())->sym; 438 if (cdn && cdn->sizeok != 1) 439 ti = fdv->type; 440 } 441 #endif 442 } 440 443 } 441 if (cov == 1) 442 { Type *ti = NULL; 443 444 if (fdv->tintro) 445 ti = fdv->tintro; 446 else if (!type->equals(fdv->type)) 444 if (ti) 445 { 446 if (tintro && !tintro->equals(ti)) 447 447 { 448 /* Only need to have a tintro if the vptr 449 * offsets differ 450 */ 451 int offset; 452 if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset)) 453 { 454 ti = fdv->type; 455 #if 0 456 if (offset) 457 ti = fdv->type; 458 else if (type->nextOf()->ty == Tclass) 459 { ClassDeclaration *cdn = ((TypeClass *)type->nextOf())->sym; 460 if (cdn && cdn->sizeok != 1) 461 ti = fdv->type; 462 } 463 #endif 464 } 448 error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars()); 465 449 } 466 if (ti) 467 { 468 if (tintro && !tintro->equals(ti)) 469 { 470 error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars()); 471 } 472 tintro = ti; 473 } 474 goto L2; 450 tintro = ti; 475 451 } 476 if (cov == 3) 477 { 478 cd->sizeok = 2; // can't finish due to forward reference 479 return; 480 } 452 goto L2; 481 453 } 482 454 } … … 660 632 sc2->fes = fes; 661 633 sc2->linkage = LINKd; 662 sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STCconst | STCfinal | STCinvariant );634 sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STCconst | STCfinal | STCinvariant | STCtls); 663 635 sc2->protection = PROTpublic; 664 636 sc2->explicitProtection = 0; … … 683 655 assert(ad->handle); 684 656 Type *thandle = ad->handle; 685 if (storage_class & STCconst )657 if (storage_class & STCconst || type->isConst()) 686 658 { 687 659 if (thandle->ty == Tclass) … … 692 664 } 693 665 } 694 else if (storage_class & STCinvariant )666 else if (storage_class & STCinvariant || type->isInvariant()) 695 667 { 696 668 if (thandle->ty == Tclass) … … 1362 1334 } 1363 1335 1336 /************************************************* 1337 * Find index of function in vtbl[0..dim] that 1338 * this function overrides. 1339 * Returns: 1340 * -1 didn't find one 1341 * -2 can't determine because of forward references 1342 */ 1343 1344 int FuncDeclaration::findVtblIndex(Array *vtbl, int dim) 1345 { 1346 for (int vi = 0; vi < dim; vi++) 1347 { 1348 FuncDeclaration *fdv = ((Dsymbol *)vtbl->data[vi])->isFuncDeclaration(); 1349 if (fdv && fdv->ident == ident) 1350 { 1351 int cov = type->covariant(fdv->type); 1352 //printf("\tbaseclass cov = %d\n", cov); 1353 switch (cov) 1354 { 1355 case 0: // types are distinct 1356 break; 1357 1358 case 1: 1359 return vi; 1360 1361 case 2: 1362 //type->print(); 1363 //fdv->type->print(); 1364 //printf("%s %s\n", type->deco, fdv->type->deco); 1365 error("of type %s overrides but is not covariant with %s of type %s", 1366 type->toChars(), fdv->toPrettyChars(), fdv->type->toChars()); 1367 break; 1368 1369 case 3: 1370 return -2; // forward references 1371 1372 default: 1373 assert(0); 1374 } 1375 } 1376 } 1377 return -1; 1378 } 1379 1364 1380 /**************************************************** 1365 1381 * Overload this FuncDeclaration with the new one f. … … 1564 1580 if (f != m->lastf) // skip duplicates 1565 1581 { 1566 TypeFunction *tf;1567 1568 1582 m->anyf = f; 1569 tf = (TypeFunction *)f->type;1583 TypeFunction *tf = (TypeFunction *)f->type; 1570 1584 match = (MATCH) tf->callMatch(f->needThis() ? p->ethis : NULL, arguments); 1571 1585 //printf("match = %d\n", match); … … 1584 1598 else if (f->overrides(m->lastf)) 1585 1599 goto LfIsBetter; 1600 1601 /* Try to disambiguate using template-style partial ordering rules. 1602 * In essence, if f() and g() are ambiguous, if f() can call g(), 1603 * but g() cannot call f(), then pick f(). 1604 * This is because f() is "more specialized." 1605 */ 1606 { 1607 MATCH c1 = f->leastAsSpecialized(m->lastf); 1608 MATCH c2 = m->lastf->leastAsSpecialized(f); 1609 if (c1 > c2) 1610 goto LfIsBetter; 1611 if (c1 < c2) 1612 goto LlastIsBetter; 1613 } 1586 1614 1587 1615 Lambiguous: … … 1686 1714 } 1687 1715 } 1716 } 1717 1718 /************************************* 1719 * Determine partial specialization order of 'this' vs g. 1720 * This is very similar to TemplateDeclaration::leastAsSpecialized(). 1721 * Returns: 1722 * match 'this' is at least as specialized as g 1723 * 0 g is more specialized than 'this' 1724 */ 1725 1726 MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g) 1727 { 1728 #define LOG_LEASTAS 0 1729 1730 #if LOG_LEASTAS 1731 printf("%s.leastAsSpecialized(%s)\n", toChars(), g->toChars()); 1732 #endif 1733 1734 /* This works by calling g() with f()'s parameters, and 1735 * if that is possible, then f() is at least as specialized 1736 * as g() is. 1737 */ 1738 1739 TypeFunction *tf = (TypeFunction *)type; 1740 TypeFunction *tg = (TypeFunction *)g->type; 1741 size_t nfparams = Argument::dim(tf->parameters); 1742 size_t ngparams = Argument::dim(tg->parameters); 1743 MATCH match = MATCHexact; 1744 1745 /* If both functions have a 'this' pointer, and the mods are not 1746 * the same and g's is not const, then this is less specialized. 1747 */ 1748 if (needThis() && g->needThis()) 1749 { 1750 if (tf->mod != tg->mod) 1751 { 1752 if (tg->mod == MODconst) 1753 match = MATCHconst; 1754 else 1755 return MATCHnomatch; 1756 } 1757 } 1758 1759 /* Create a dummy array of arguments out of the parameters to f() 1760 */ 1761 Expressions args; 1762 args.setDim(nfparams); 1763 for (int u = 0; u < nfparams; u++) 1764 { 1765 Argument *p = Argument::getNth(tf->parameters, u); 1766 Expression *e = p->type->defaultInit(); 1767 args.data[u] = e; 1768 } 1769 1770 MATCH m = (MATCH) tg->callMatch(NULL, &args); 1771 if (m) 1772 { 1773 /* A variadic template is less specialized than a 1774 * non-variadic one. 1775 */
