Mercurial > projects > ldc
comparison dmd2/expression.c @ 1577:e4f7b5d9c68a
DMD 2.032 Merge.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Tue, 08 Sep 2009 10:07:56 +0100 |
parents | 54b3c1394d62 |
children |
comparison
equal
deleted
inserted
replaced
1576:4551475bc6b6 | 1577:e4f7b5d9c68a |
---|---|
3233 if (!e->type) | 3233 if (!e->type) |
3234 error("%s has no value", e->toChars()); | 3234 error("%s has no value", e->toChars()); |
3235 e = resolveProperties(sc, e); | 3235 e = resolveProperties(sc, e); |
3236 if (i >= nfields) | 3236 if (i >= nfields) |
3237 { error("more initializers than fields of %s", sd->toChars()); | 3237 { error("more initializers than fields of %s", sd->toChars()); |
3238 break; | 3238 return new ErrorExp(); |
3239 } | 3239 } |
3240 Dsymbol *s = (Dsymbol *)sd->fields.data[i]; | 3240 Dsymbol *s = (Dsymbol *)sd->fields.data[i]; |
3241 VarDeclaration *v = s->isVarDeclaration(); | 3241 VarDeclaration *v = s->isVarDeclaration(); |
3242 assert(v); | 3242 assert(v); |
3243 if (v->offset < offset) | 3243 if (v->offset < offset) |
4427 { | 4427 { |
4428 } | 4428 } |
4429 else | 4429 else |
4430 { | 4430 { |
4431 fd->semantic2(sc); | 4431 fd->semantic2(sc); |
4432 if (!global.errors) | 4432 if (!global.errors || |
4433 // need to infer return type | |
4434 (fd->type && fd->type->ty == Tfunction && !fd->type->nextOf())) | |
4433 { | 4435 { |
4434 fd->semantic3(sc); | 4436 fd->semantic3(sc); |
4435 | 4437 |
4436 if (!global.errors && global.params.useInline) | 4438 if (!global.errors && global.params.useInline) |
4437 fd->inlineScan(); | 4439 fd->inlineScan(); |
4438 } | 4440 } |
4439 } | 4441 } |
4442 | |
4443 // need to infer return type | |
4444 if (global.errors && fd->type && fd->type->ty == Tfunction && !fd->type->nextOf()) | |
4445 ((TypeFunction *)fd->type)->next = Type::terror; | |
4440 | 4446 |
4441 // Type is a "delegate to" or "pointer to" the function literal | 4447 // Type is a "delegate to" or "pointer to" the function literal |
4442 if (fd->isNested()) | 4448 if (fd->isNested()) |
4443 { | 4449 { |
4444 type = new TypeDelegate(fd->type); | 4450 type = new TypeDelegate(fd->type); |
4783 break; | 4789 break; |
4784 | 4790 |
4785 case TOKinvariant: | 4791 case TOKinvariant: |
4786 case TOKimmutable: | 4792 case TOKimmutable: |
4787 if (!targ->isInvariant()) | 4793 if (!targ->isInvariant()) |
4794 goto Lno; | |
4795 tded = targ; | |
4796 break; | |
4797 | |
4798 case TOKshared: | |
4799 if (!targ->isShared()) | |
4788 goto Lno; | 4800 goto Lno; |
4789 tded = targ; | 4801 tded = targ; |
4790 break; | 4802 break; |
4791 #endif | 4803 #endif |
4792 | 4804 |
5291 { error("file %s cannot be found, check -Jpath", se->toChars()); | 5303 { error("file %s cannot be found, check -Jpath", se->toChars()); |
5292 goto Lerror; | 5304 goto Lerror; |
5293 } | 5305 } |
5294 | 5306 |
5295 if (global.params.verbose) | 5307 if (global.params.verbose) |
5296 printf("file %s\t(%s)\n", (char*)se->string, name); | 5308 printf("file %s\t(%s)\n", (char *)se->string, name); |
5297 | 5309 |
5298 { File f(name); | 5310 { File f(name); |
5299 if (f.read()) | 5311 if (f.read()) |
5300 { error("cannot read file %s", f.toChars()); | 5312 { error("cannot read file %s", f.toChars()); |
5301 goto Lerror; | 5313 goto Lerror; |
6217 #endif | 6229 #endif |
6218 } | 6230 } |
6219 } | 6231 } |
6220 } | 6232 } |
6221 | 6233 |
6222 #if DMDV2 | 6234 #if 1 |
6223 /* This recognizes: | 6235 /* This recognizes: |
6224 * foo!(tiargs)(funcargs) | 6236 * foo!(tiargs)(funcargs) |
6225 */ | 6237 */ |
6226 if (e1->op == TOKimport && !e1->type) | 6238 if (e1->op == TOKimport && !e1->type) |
6227 { ScopeExp *se = (ScopeExp *)e1; | 6239 { ScopeExp *se = (ScopeExp *)e1; |
6344 { AggregateDeclaration *ad; | 6356 { AggregateDeclaration *ad; |
6345 | 6357 |
6346 if (t1->ty == Tstruct) | 6358 if (t1->ty == Tstruct) |
6347 { | 6359 { |
6348 ad = ((TypeStruct *)t1)->sym; | 6360 ad = ((TypeStruct *)t1)->sym; |
6349 | 6361 #if DMDV2 |
6350 // First look for constructor | 6362 // First look for constructor |
6351 if (ad->ctor && arguments && arguments->dim) | 6363 if (ad->ctor && arguments && arguments->dim) |
6352 { | 6364 { |
6353 // Create variable that will get constructed | 6365 // Create variable that will get constructed |
6354 Identifier *idtmp = Lexer::uniqueId("__ctmp"); | 6366 Identifier *idtmp = Lexer::uniqueId("__ctmp"); |
6372 e = new PtrExp(loc, e); | 6384 e = new PtrExp(loc, e); |
6373 #endif | 6385 #endif |
6374 e = e->semantic(sc); | 6386 e = e->semantic(sc); |
6375 return e; | 6387 return e; |
6376 } | 6388 } |
6377 | 6389 #endif |
6378 // No constructor, look for overload of opCall | 6390 // No constructor, look for overload of opCall |
6379 if (search_function(ad, Id::call)) | 6391 if (search_function(ad, Id::call)) |
6380 goto L1; // overload of opCall, therefore it's a call | 6392 goto L1; // overload of opCall, therefore it's a call |
6381 | 6393 |
6382 if (e1->op != TOKtype) | 6394 if (e1->op != TOKtype) |
6447 if (sc->func && sc->func->isInvariantDeclaration() && | 6459 if (sc->func && sc->func->isInvariantDeclaration() && |
6448 ue->e1->op == TOKthis && | 6460 ue->e1->op == TOKthis && |
6449 f->addPostInvariant() | 6461 f->addPostInvariant() |
6450 ) | 6462 ) |
6451 { | 6463 { |
6452 error("cannot call public/export function %s from immutable", f->toChars()); | 6464 error("cannot call public/export function %s from invariant", f->toChars()); |
6453 } | 6465 } |
6454 | 6466 |
6455 checkDeprecated(sc, f); | 6467 checkDeprecated(sc, f); |
6456 #if DMDV2 | 6468 #if DMDV2 |
6457 checkPurity(sc, f); | 6469 checkPurity(sc, f); |
6482 { | 6494 { |
6483 // Check for const/immutable compatibility | 6495 // Check for const/immutable compatibility |
6484 Type *tthis = ue->e1->type->toBasetype(); | 6496 Type *tthis = ue->e1->type->toBasetype(); |
6485 if (tthis->ty == Tpointer) | 6497 if (tthis->ty == Tpointer) |
6486 tthis = tthis->nextOf()->toBasetype(); | 6498 tthis = tthis->nextOf()->toBasetype(); |
6499 #if 0 // this checking should have been already done | |
6487 if (f->type->isInvariant()) | 6500 if (f->type->isInvariant()) |
6488 { | 6501 { |
6489 if (tthis->mod != MODinvariant) | 6502 if (tthis->mod != MODinvariant) |
6490 error("%s can only be called on an invariant object", e1->toChars()); | 6503 error("%s can only be called with an immutable object", e1->toChars()); |
6504 } | |
6505 else if (f->type->isShared()) | |
6506 { | |
6507 if (tthis->mod != MODinvariant && | |
6508 tthis->mod != MODshared && | |
6509 tthis->mod != (MODshared | MODconst)) | |
6510 error("shared %s can only be called with a shared or immutable object", e1->toChars()); | |
6491 } | 6511 } |
6492 else | 6512 else |
6493 { | 6513 { |
6494 if (tthis->mod != 0) | 6514 if (tthis->mod != 0) |
6495 { //printf("mod = %x\n", tthis->mod); | 6515 { //printf("mod = %x\n", tthis->mod); |
6496 error("%s can only be called on a mutable object, not %s", e1->toChars(), tthis->toChars()); | 6516 error("%s can only be called with a mutable object, not %s", e1->toChars(), tthis->toChars()); |
6497 } | 6517 } |
6498 } | 6518 } |
6499 | 6519 #endif |
6500 /* Cannot call mutable method on a final struct | 6520 /* Cannot call mutable method on a final struct |
6501 */ | 6521 */ |
6502 if (tthis->ty == Tstruct && | 6522 if (tthis->ty == Tstruct && |
6503 ue->e1->op == TOKvar) | 6523 ue->e1->op == TOKvar) |
6504 { VarExp *v = (VarExp *)ue->e1; | 6524 { VarExp *v = (VarExp *)ue->e1; |
7584 } | 7604 } |
7585 } | 7605 } |
7586 else | 7606 else |
7587 goto Lerror; | 7607 goto Lerror; |
7588 | 7608 |
7609 { | |
7610 Scope *sc2 = sc; | |
7589 if (t->ty == Tsarray || t->ty == Tarray || t->ty == Ttuple) | 7611 if (t->ty == Tsarray || t->ty == Tarray || t->ty == Ttuple) |
7590 { | 7612 { |
7591 sym = new ArrayScopeSymbol(sc, this); | 7613 sym = new ArrayScopeSymbol(sc, this); |
7592 sym->loc = loc; | 7614 sym->loc = loc; |
7593 sym->parent = sc->scopesym; | 7615 sym->parent = sc->scopesym; |
7594 sc = sc->push(sym); | 7616 sc2 = sc->push(sym); |
7595 } | 7617 } |
7596 | 7618 |
7597 if (lwr) | 7619 if (lwr) |
7598 { lwr = lwr->semantic(sc); | 7620 { lwr = lwr->semantic(sc2); |
7599 lwr = resolveProperties(sc, lwr); | 7621 lwr = resolveProperties(sc2, lwr); |
7600 lwr = lwr->implicitCastTo(sc, Type::tsize_t); | 7622 lwr = lwr->implicitCastTo(sc2, Type::tsize_t); |
7601 } | 7623 } |
7602 if (upr) | 7624 if (upr) |
7603 { upr = upr->semantic(sc); | 7625 { upr = upr->semantic(sc2); |
7604 upr = resolveProperties(sc, upr); | 7626 upr = resolveProperties(sc2, upr); |
7605 upr = upr->implicitCastTo(sc, Type::tsize_t); | 7627 upr = upr->implicitCastTo(sc2, Type::tsize_t); |
7606 } | 7628 } |
7607 | 7629 |
7608 if (t->ty == Tsarray || t->ty == Tarray || t->ty == Ttuple) | 7630 if (sc2 != sc) |
7609 sc->pop(); | 7631 sc2->pop(); |
7632 } | |
7610 | 7633 |
7611 if (t->ty == Ttuple) | 7634 if (t->ty == Ttuple) |
7612 { | 7635 { |
7613 lwr = lwr->optimize(WANTvalue); | 7636 lwr = lwr->optimize(WANTvalue); |
7614 upr = upr->optimize(WANTvalue); | 7637 upr = upr->optimize(WANTvalue); |
8290 e = e->semantic(sc); | 8313 e = e->semantic(sc); |
8291 return e; | 8314 return e; |
8292 } | 8315 } |
8293 } | 8316 } |
8294 | 8317 |
8318 // Determine if this is an initialization of a reference | |
8319 int refinit = 0; | |
8320 if (op == TOKconstruct && e1->op == TOKvar) | |
8321 { VarExp *ve = (VarExp *)e1; | |
8322 VarDeclaration *v = ve->var->isVarDeclaration(); | |
8323 if (v->storage_class & (STCout | STCref)) | |
8324 refinit = 1; | |
8325 } | |
8326 | |
8295 Type *t1 = e1->type->toBasetype(); | 8327 Type *t1 = e1->type->toBasetype(); |
8296 | 8328 |
8297 if (t1->ty == Tfunction) | 8329 if (t1->ty == Tfunction) |
8298 { // Rewrite f=value to f(value) | 8330 { // Rewrite f=value to f(value) |
8299 Expression *e = new CallExp(loc, e1, e2); | 8331 Expression *e = new CallExp(loc, e1, e2); |
8311 { | 8343 { |
8312 Expression *e = op_overload(sc); | 8344 Expression *e = op_overload(sc); |
8313 if (e) | 8345 if (e) |
8314 return e; | 8346 return e; |
8315 } | 8347 } |
8316 else if (op == TOKconstruct) | 8348 else if (op == TOKconstruct && !refinit) |
8317 { Type *t2 = e2->type->toBasetype(); | 8349 { Type *t2 = e2->type->toBasetype(); |
8318 if (t2->ty == Tstruct && | 8350 if (t2->ty == Tstruct && |
8319 sd == ((TypeStruct *)t2)->sym && | 8351 sd == ((TypeStruct *)t2)->sym && |
8320 sd->cpctor) | 8352 sd->cpctor) |
8321 { /* We have a copy constructor for this | 8353 { /* We have a copy constructor for this |
8322 */ | 8354 */ |
8323 if (e2->op == TOKvar || e2->op == TOKstar) | 8355 if (e2->op == TOKquestion) |
8324 { /* Write as: | |
8325 * e1.cpctor(e2); | |
8326 */ | |
8327 Expression *e = new DotVarExp(loc, e1, sd->cpctor, 0); | |
8328 e = new CallExp(loc, e, e2); | |
8329 return e->semantic(sc); | |
8330 } | |
8331 else if (e2->op == TOKquestion) | |
8332 { /* Write as: | 8356 { /* Write as: |
8333 * a ? e1 = b : e1 = c; | 8357 * a ? e1 = b : e1 = c; |
8334 */ | 8358 */ |
8335 CondExp *ec = (CondExp *)e2; | 8359 CondExp *ec = (CondExp *)e2; |
8336 AssignExp *ea1 = new AssignExp(ec->e1->loc, e1, ec->e1); | 8360 AssignExp *ea1 = new AssignExp(ec->e1->loc, e1, ec->e1); |
8338 AssignExp *ea2 = new AssignExp(ec->e1->loc, e1, ec->e2); | 8362 AssignExp *ea2 = new AssignExp(ec->e1->loc, e1, ec->e2); |
8339 ea2->op = op; | 8363 ea2->op = op; |
8340 Expression *e = new CondExp(loc, ec->econd, ea1, ea2); | 8364 Expression *e = new CondExp(loc, ec->econd, ea1, ea2); |
8341 return e->semantic(sc); | 8365 return e->semantic(sc); |
8342 } | 8366 } |
8367 else if (e2->op == TOKvar || | |
8368 e2->op == TOKdotvar || | |
8369 e2->op == TOKstar || | |
8370 e2->op == TOKindex) | |
8371 { /* Write as: | |
8372 * e1.cpctor(e2); | |
8373 */ | |
8374 Expression *e = new DotVarExp(loc, e1, sd->cpctor, 0); | |
8375 e = new CallExp(loc, e, e2); | |
8376 return e->semantic(sc); | |
8377 } | |
8343 } | 8378 } |
8344 } | 8379 } |
8345 } | 8380 } |
8346 else if (t1->ty == Tclass) | 8381 else if (t1->ty == Tclass) |
8347 { // Disallow assignment operator overloads for same type | 8382 { // Disallow assignment operator overloads for same type |
8351 if (e) | 8386 if (e) |
8352 return e; | 8387 return e; |
8353 } | 8388 } |
8354 } | 8389 } |
8355 | 8390 |
8356 if (t1->ty == Tsarray) | 8391 if (t1->ty == Tsarray && !refinit) |
8357 { // Convert e1 to e1[] | 8392 { // Convert e1 to e1[] |
8358 Expression *e = new SliceExp(e1->loc, e1, NULL, NULL); | 8393 Expression *e = new SliceExp(e1->loc, e1, NULL, NULL); |
8359 e1 = e->semantic(sc); | 8394 e1 = e->semantic(sc); |
8360 t1 = e1->type->toBasetype(); | 8395 t1 = e1->type->toBasetype(); |
8361 } | 8396 } |
8396 } | 8431 } |
8397 else if (t1->ty == Tsarray) | 8432 else if (t1->ty == Tsarray) |
8398 { | 8433 { |
8399 /* Should have already converted e1 => e1[] | 8434 /* Should have already converted e1 => e1[] |
8400 */ | 8435 */ |
8401 assert(0); | 8436 assert(op == TOKconstruct); |
8402 //error("cannot assign to static array %s", e1->toChars()); | 8437 //error("cannot assign to static array %s", e1->toChars()); |
8403 } | 8438 } |
8404 else if (e1->op == TOKslice) | 8439 else if (e1->op == TOKslice) |
8405 { | 8440 { |
8406 e2 = e2->implicitCastTo(sc, e1->type->constOf()); | 8441 e2 = e2->implicitCastTo(sc, e1->type->constOf()); |