Changeset 812
- Timestamp:
- 12/23/10 04:52:15 (14 years ago)
- Files:
-
- trunk/src/e2ir.c (modified) (2 diffs)
- trunk/src/expression.c (modified) (4 diffs)
- trunk/src/func.c (modified) (2 diffs)
- trunk/src/imphint.c (modified) (1 diff)
- trunk/src/mtype.c (modified) (1 diff)
- trunk/src/toir.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/e2ir.c
r775 r812 2450 2450 else 2451 2451 e = toElemBin(irs, eop); 2452 2452 2453 2453 return e; 2454 2454 } 2455 2455 2456 2456 2457 2457 /*************************************** 2458 2458 */ 2459 2459 2460 2460 elem *InExp::toElem(IRState *irs) 2461 2461 { elem *e; 2462 2462 elem *key = e1->toElem(irs); 2463 2463 elem *aa = e2->toElem(irs); 2464 2464 elem *ep; 2465 2465 elem *keyti; 2466 2466 TypeAArray *taa = (TypeAArray *)e2->type->toBasetype(); 2467 2467 2468 2468 2469 2469 // set to: 2470 // aaIn(aa, keyti, key); 2471 2472 if (tybasic(key->Ety) == TYstruct) 2473 { 2474 key = el_una(OPstrpar, TYstruct, key); 2475 key->ET = key->E1->ET; 2476 } 2477 else if (tybasic(key->Ety) == TYarray && taa->index->ty == Tsarray) 2478 { // e2->elem() turns string literals into a TYarray, so the 2479 // length is lost. Restore it. 2480 key = el_una(OPstrpar, TYstruct, key); 2481 assert(e1->type->size() == taa->index->size()); 2482 key->ET = taa->index->toCtype(); 2483 } 2484 2485 Symbol *s = taa->aaGetSymbol("In", 0); 2470 Symbol *s; 2471 if (I64) 2472 { 2473 // aaInX(aa, keyti, key); 2474 key = addressElem(key, e1->type); 2475 s = taa->aaGetSymbol("InX", 0); 2476 } 2477 else 2478 { 2479 // aaIn(aa, keyti, key); 2480 if (tybasic(key->Ety) == TYstruct) 2481 { 2482 key = el_una(OPstrpar, TYstruct, key); 2483 key->ET = key->E1->ET; 2484 } 2485 else if (tybasic(key->Ety) == TYarray && taa->index->ty == Tsarray) 2486 { // e2->elem() turns string literals into a TYarray, so the 2487 // length is lost. Restore it. 2488 key = el_una(OPstrpar, TYstruct, key); 2489 assert(e1->type->size() == taa->index->size()); 2490 key->ET = taa->index->toCtype(); 2491 } 2492 2493 s = taa->aaGetSymbol("In", 0); 2494 } 2486 2495 keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs); 2487 2496 ep = el_params(key, keyti, aa, NULL); 2488 2497 e = el_bin(OPcall, type->totym(), el_var(s), ep); 2489 2498 2490 2499 el_setLoc(e,loc); 2491 2500 return e; 2492 2501 } 2493 2502 2494 2503 /*************************************** 2495 2504 */ 2496 2505 2497 2506 elem *RemoveExp::toElem(IRState *irs) 2498 2507 { elem *e; 2499 2508 Type *tb = e1->type->toBasetype(); 2500 2509 assert(tb->ty == Taarray); 2501 2510 TypeAArray *taa = (TypeAArray *)tb; 2502 2511 elem *ea = e1->toElem(irs); 2503 2512 elem *ekey = e2->toElem(irs); 2504 2513 elem *ep; 2505 2514 elem *keyti; 2506 2515 2507 if (tybasic(ekey->Ety) == TYstruct || tybasic(ekey->Ety) == TYarray) 2508 { 2509 ekey = el_una(OPstrpar, TYstruct, ekey); 2510 ekey->ET = ekey->E1->ET; 2511 } 2512 2513 Symbol *s = taa->aaGetSymbol("Del", 0); 2516 Symbol *s; 2517 if (I64) 2518 { 2519 ekey = addressElem(ekey, e1->type); 2520 s = taa->aaGetSymbol("DelX", 0); 2521 } 2522 else 2523 { 2524 if (tybasic(ekey->Ety) == TYstruct || tybasic(ekey->Ety) == TYarray) 2525 { 2526 ekey = el_una(OPstrpar, TYstruct, ekey); 2527 ekey->ET = ekey->E1->ET; 2528 } 2529 2530 s = taa->aaGetSymbol("Del", 0); 2531 } 2514 2532 keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs); 2515 2533 ep = el_params(ekey, keyti, ea, NULL); 2516 2534 e = el_bin(OPcall, TYnptr, el_var(s), ep); 2517 2535 2518 2536 el_setLoc(e,loc); 2519 2537 return e; 2520 2538 } 2521 2539 2522 2540 /*************************************** 2523 2541 */ 2524 2542 2525 2543 elem *AssignExp::toElem(IRState *irs) 2526 2544 { 2527 2545 //printf("AssignExp::toElem('%s')\n", toChars()); 2528 2546 Type *t1b = e1->type->toBasetype(); 2529 2547 2530 2548 // Look for array.length = n 2531 2549 if (e1->op == TOKarraylength) 2532 2550 { 2533 2551 // Generate: … … 4367 4385 e = el_combine(einit, e); 4368 4386 } 4369 4387 else if (t1->ty == Tsarray) 4370 4388 { 4371 4389 e = sarray_toDarray(loc, t1, NULL, e); 4372 4390 } 4373 4391 el_setLoc(e,loc); 4374 4392 return e; 4375 4393 } 4376 4394 4377 4395 elem *IndexExp::toElem(IRState *irs) 4378 4396 { elem *e; 4379 4397 elem *n1 = e1->toElem(irs); 4380 4398 elem *eb = NULL; 4381 4399 4382 4400 //printf("IndexExp::toElem() %s\n", toChars()); 4383 4401 Type *t1 = e1->type->toBasetype(); 4384 4402 if (t1->ty == Taarray) 4385 4403 { 4386 4404 // set to: 4387 // *aaGet (aa, keyti, valuesize, index);4405 // *aaGetX(aa, keyti, valuesize, &key); 4388 4406 4389 4407 TypeAArray *taa = (TypeAArray *)t1; 4390 elem *keyti;4391 elem *ep;4392 4408 int vsize = taa->next->size(); 4393 4409 Symbol *s; 4394 4410 4395 4411 // n2 becomes the index, also known as the key 4396 4412 elem *n2 = e2->toElem(irs); 4397 if (tybasic(n2->Ety) == TYstruct || tybasic(n2->Ety) == TYarray) 4398 { 4399 n2 = el_una(OPstrpar, TYstruct, n2); 4400 n2->ET = n2->E1->ET; 4401 if (taa->index->ty == Tsarray) 4402 { 4403 assert(e2->type->size() == taa->index->size()); 4404 } 4405 //printf("numbytes = %d\n", n2->Enumbytes); 4406 } 4407 elem *valuesize = el_long(TYuint, vsize); // BUG: should be TYsize_t 4413 4414 if (I64) 4415 { 4416 /* Turn n2 into a pointer to the index. If it's an lvalue, 4417 * take the address of it. If not, copy it to a temp and 4418 * take the address of that. 4419 */ 4420 n2 = addressElem(n2, taa->index); 4421 } 4422 else 4423 { 4424 if (tybasic(n2->Ety) == TYstruct || tybasic(n2->Ety) == TYarray) 4425 { 4426 n2 = el_una(OPstrpar, TYstruct, n2); 4427 n2->ET = n2->E1->ET; 4428 if (taa->index->ty == Tsarray) 4429 { 4430 assert(e2->type->size() == taa->index->size()); 4431 } 4432 //printf("numbytes = %d\n", n2->Enumbytes); 4433 } 4434 } 4435 4436 elem *valuesize = el_long(TYsize_t, vsize); 4408 4437 //printf("valuesize: "); elem_print(valuesize); 4409 4438 if (modifiable) 4410 4439 { 4411 4440 n1 = el_una(OPaddr, TYnptr, n1); 4412 s = taa->aaGetSymbol( "Get", 1);4441 s = taa->aaGetSymbol(I64 ? "GetX" : "Get", 1); 4413 4442 } 4414 4443 else 4415 4444 { 4416 s = taa->aaGetSymbol( "GetRvalue", 1);4445 s = taa->aaGetSymbol(I64 ? "GetRvalueX" : "GetRvalue", 1); 4417 4446 } 4418 4447 //printf("taa->index = %s\n", taa->index->toChars()); 4419 keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs);4448 elem* keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs); 4420 4449 //keyti = taa->index->getTypeInfo(NULL)->toElem(irs); 4421 4450 //printf("keyti:\n"); 4422 4451 //elem_print(keyti); 4423 e p = el_params(n2, valuesize, keyti, n1, NULL);4452 elem* ep = el_params(n2, valuesize, keyti, n1, NULL); 4424 4453 e = el_bin(OPcall, TYnptr, el_var(s), ep); 4425 4454 if (irs->arrayBoundsCheck()) 4426 4455 { 4427 4456 elem *ea; 4428 4457 4429 4458 elem *n = el_same(&e); 4430 4459 4431 4460 // Construct: ((e || ModuleAssert(line)),n) 4432 4461 Symbol *sassert = irs->blx->module->toModuleArray(); 4433 4462 ea = el_bin(OPcall,TYvoid,el_var(sassert), 4434 4463 el_long(TYint, loc.linnum)); 4435 4464 e = el_bin(OPoror,TYvoid,e,ea); 4436 4465 e = el_bin(OPcomma, TYnptr, e, n); 4437 4466 } 4438 4467 e = el_una(OPind, type->totym(), e); 4439 4468 if (tybasic(e->Ety) == TYstruct) 4440 4469 e->ET = type->toCtype(); 4441 4470 } 4442 4471 else 4443 4472 { trunk/src/expression.c
r798 r812 5322 5322 } 5323 5323 5324 5324 Expression *BinExp::semantic(Scope *sc) 5325 5325 { 5326 5326 #if LOGSEMANTIC 5327 5327 printf("BinExp::semantic('%s')\n", toChars()); 5328 5328 #endif 5329 5329 e1 = e1->semantic(sc); 5330 5330 if (!e1->type && 5331 5331 !(op == TOKassign && e1->op == TOKdottd)) // a.template = e2 5332 5332 { 5333 5333 error("%s has no value", e1->toChars()); 5334 5334 return new ErrorExp(); 5335 5335 } 5336 5336 e2 = e2->semantic(sc); 5337 5337 if (!e2->type) 5338 5338 { 5339 5339 error("%s has no value", e2->toChars()); 5340 5340 return new ErrorExp(); 5341 5341 } 5342 if (e1->op == TOKerror || e2->op == TOKerror) 5343 return new ErrorExp(); 5342 5344 return this; 5343 5345 } 5344 5346 5345 5347 Expression *BinExp::semanticp(Scope *sc) 5346 5348 { 5347 5349 BinExp::semantic(sc); 5348 5350 e1 = resolveProperties(sc, e1); 5349 5351 e2 = resolveProperties(sc, e2); 5350 5352 return this; 5351 5353 } 5352 5354 5353 5355 int BinExp::checkSideEffect(int flag) 5354 5356 { 5355 5357 if (op == TOKplusplus || 5356 5358 op == TOKminusminus || 5357 5359 op == TOKassign || 5358 5360 op == TOKconstruct || 5359 5361 op == TOKblit || 5360 5362 op == TOKaddass || 5361 5363 op == TOKminass || … … 8528 8530 //printf("IndexExp::IndexExp('%s')\n", toChars()); 8529 8531 lengthVar = NULL; 8530 8532 modifiable = 0; // assume it is an rvalue 8531 8533 } 8532 8534 8533 8535 Expression *IndexExp::semantic(Scope *sc) 8534 8536 { Expression *e; 8535 8537 BinExp *b; 8536 8538 UnaExp *u; 8537 8539 Type *t1; 8538 8540 ScopeDsymbol *sym; 8539 8541 8540 8542 #if LOGSEMANTIC 8541 8543 printf("IndexExp::semantic('%s')\n", toChars()); 8542 8544 #endif 8543 8545 if (type) 8544 8546 return this; 8545 8547 if (!e1->type) 8546 8548 e1 = e1->semantic(sc); 8547 8549 assert(e1->type); // semantic() should already be run on it 8550 if (e1->op == TOKerror) 8551 goto Lerr; 8548 8552 e = this; 8549 8553 8550 8554 // Note that unlike C we do not implement the int[ptr] 8551 8555 8552 8556 t1 = e1->type->toBasetype(); 8553 8557 8554 8558 if (t1->ty == Tsarray || t1->ty == Tarray || t1->ty == Ttuple) 8555 8559 { // Create scope for 'length' variable 8556 8560 sym = new ArrayScopeSymbol(sc, this); 8557 8561 sym->loc = loc; 8558 8562 sym->parent = sc->scopesym; 8559 8563 sc = sc->push(sym); 8560 8564 } 8561 8565 8562 8566 e2 = e2->semantic(sc); 8563 8567 if (!e2->type) 8564 8568 { 8565 8569 error("%s has no value", e2->toChars()); 8566 8570 goto Lerr; 8567 8571 } … … 8637 8641 assert(0); 8638 8642 8639 8643 if (index < length) 8640 8644 { 8641 8645 8642 8646 if (e1->op == TOKtuple) 8643 8647 e = (Expression *)te->exps->data[(size_t)index]; 8644 8648 else 8645 8649 e = new TypeExp(e1->loc, Parameter::getNth(tup->arguments, (size_t)index)->type); 8646 8650 } 8647 8651 else 8648 8652 { 8649 8653 error("array index [%ju] is outside array bounds [0 .. %zu]", 8650 8654 index, length); 8651 8655 e = e1; 8652 8656 } 8653 8657 break; 8654 8658 } 8655 8659 8656 8660 default: 8661 if (e1->op == TOKerror) 8662 goto Lerr; 8657 8663 error("%s must be an array or pointer type, not %s", 8658 8664 e1->toChars(), e1->type->toChars()); 8659 8665 case Terror: 8660 8666 goto Lerr; 8661 8667 } 8662 8668 return e; 8663 8669 8664 8670 Lerr: 8665 8671 return new ErrorExp(); 8666 8672 } 8667 8673 8668 8674 #if DMDV2 8669 8675 int IndexExp::isLvalue() 8670 8676 { 8671 8677 return 1; 8672 8678 } 8673 8679 #endif 8674 8680 8675 8681 Expression *IndexExp::toLvalue(Scope *sc, Expression *e) 8676 8682 { … … 8924 8930 // Rewrite (a[i..j] = value) to (a.opSliceAssign(value, i, j)) 8925 8931 if (search_function(ad, Id::sliceass)) 8926 8932 { Expression *e = new DotIdExp(loc, ae->e1, Id::sliceass); 8927 8933 Expressions *a = new Expressions(); 8928 8934 8929 8935 a->push(e2); 8930 8936 if (ae->lwr) 8931 8937 { a->push(ae->lwr); 8932 8938 assert(ae->upr); 8933 8939 a->push(ae->upr); 8934 8940 } 8935 8941 else 8936 8942 assert(!ae->upr); 8937 8943 e = new CallExp(loc, e, a); 8938 8944 e = e->semantic(sc); 8939 8945 return e; 8940 8946 } 8941 8947 } 8942 8948 } 8943 8949 8944 BinExp::semantic(sc); 8950 Expression *e = BinExp::semantic(sc); 8951 if (e->op == TOKerror) 8952 return e; 8945 8953 8946 8954 if (e1->op == TOKdottd) 8947 8955 { // Rewrite a.b=e2, when b is a template, as a.b(e2) 8948 8956 Expression *e = new CallExp(loc, e1, e2); 8949 8957 e = e->semantic(sc); 8950 8958 return e; 8951 8959 } 8952 8960 8953 8961 e2 = resolveProperties(sc, e2); 8954 8962 assert(e1->type); 8955 8963 8956 8964 /* Rewrite tuple assignment as a tuple of assignments. 8957 8965 */ 8958 8966 if (e1->op == TOKtuple && e2->op == TOKtuple) 8959 8967 { TupleExp *tup1 = (TupleExp *)e1; 8960 8968 TupleExp *tup2 = (TupleExp *)e2; 8961 8969 size_t dim = tup1->exps->dim; 8962 8970 if (dim != tup2->exps->dim) 8963 8971 { 8964 8972 error("mismatched tuple lengths, %d and %d", (int)dim, (int)tup2->exps->dim); trunk/src/func.c
r809 r812 912 912 { 913 913 /* The 'this' for a nested function is the link to the 914 914 * enclosing function's stack frame. 915 915 * Note that nested functions and member functions are disjoint. 916 916 */ 917 917 VarDeclaration *v = new ThisDeclaration(loc, Type::tvoid->pointerTo()); 918 918 v->storage_class |= STCparameter; 919 919 v->semantic(sc2); 920 920 if (!sc2->insert(v)) 921 921 assert(0); 922 922 v->parent = this; 923 923 vthis = v; 924 924 } 925 925 926 926 // Declare hidden variable _arguments[] and _argptr 927 927 if (f->varargs == 1) 928 928 { 929 929 #if TARGET_NET 930 930 varArgs(sc2, f, argptr, _arguments); 931 931 #else 932 Type *t; 932 Type *t; 933 934 if (global.params.isX86_64) 935 { // Declare save area for varargs registers 936 Type *t = new TypeIdentifier(loc, Id::va_argsave_t); 937 t = t->semantic(loc, sc); 938 if (t == Type::terror) 939 error("must import core.vararg to use variadic functions"); 940 else 941 { 942 v_argsave = new VarDeclaration(loc, t, Id::va_argsave, NULL); 943 v_argsave->semantic(sc2); 944 sc2->insert(v_argsave); 945 v_argsave->parent = this; 946 } 947 } 933 948 934 949 if (f->linkage == LINKd) 935 950 { // Declare _arguments[] 936 951 #if BREAKABI 937 952 v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL); 938 953 v_arguments->storage_class = STCparameter; 939 954 v_arguments->semantic(sc2); 940 955 sc2->insert(v_arguments); 941 956 v_arguments->parent = this; 942 957 943 958 //t = Type::typeinfo->type->constOf()->arrayOf(); 944 959 t = Type::typeinfo->type->arrayOf(); 945 960 _arguments = new VarDeclaration(0, t, Id::_arguments, NULL); 946 961 _arguments->semantic(sc2); 947 962 sc2->insert(_arguments); 948 963 _arguments->parent = this; 949 964 #else 950 965 t = Type::typeinfo->type->arrayOf(); 951 966 v_arguments = new VarDeclaration(0, t, Id::_arguments, NULL); 952 967 v_arguments->storage_class = STCparameter | STCin; 953 968 v_arguments->semantic(sc2); 954 969 sc2->insert(v_arguments); 955 970 v_arguments->parent = this; 956 971 #endif 957 972 } 958 973 if (f->linkage == LINKd || (parameters && parameters->dim)) 959 974 { // Declare _argptr 960 975 #if IN_GCC 961 976 t = d_gcc_builtin_va_list_d_type; 962 977 #else 963 978 t = Type::tvoid->pointerTo(); 964 979 #endif 965 980 argptr = new VarDeclaration(0, t, Id::_argptr, NULL); 966 981 argptr->semantic(sc2); 967 982 sc2->insert(argptr); 968 983 argptr->parent = this; 969 984 } 970 985 #endif 971 }972 if (global.params.isX86_64 && f->varargs && f->linkage == LINKc)973 { // Declare save area for varargs registers974 Type *t = new TypeIdentifier(loc, Id::va_argsave_t);975 t = t->semantic(loc, sc);976 if (t == Type::terror)977 error("must import std.c.stdarg to use variadic functions");978 else979 {980 v_argsave = new VarDeclaration(loc, t, Id::va_argsave, NULL);981 v_argsave->semantic(sc2);982 sc2->insert(v_argsave);983 v_argsave->parent = this;984 }985 986 } 986 987 987 988 #if 0 988 989 // Propagate storage class from tuple parameters to their element-parameters. 989 990 if (f->parameters) 990 991 { 991 992 for (size_t i = 0; i < f->parameters->dim; i++) 992 993 { Parameter *arg = (Parameter *)f->parameters->data[i]; 993 994 994 995 //printf("[%d] arg->type->ty = %d %s\n", i, arg->type->ty, arg->type->toChars()); 995 996 if (arg->type->ty == Ttuple) 996 997 { TypeTuple *t = (TypeTuple *)arg->type; 997 998 size_t dim = Parameter::dim(t->arguments); 998 999 for (size_t j = 0; j < dim; j++) 999 1000 { Parameter *narg = Parameter::getNth(t->arguments, j); 1000 1001 narg->storageClass = arg->storageClass; 1001 1002 } 1002 1003 } 1003 1004 } 1004 1005 } … … 1367 1368 Statements *a = new Statements(); 1368 1369 1369 1370 // Merge in initialization of 'out' parameters 1370 1371 if (parameters) 1371 1372 { for (size_t i = 0; i < parameters->dim; i++) 1372 1373 { 1373 1374 VarDeclaration *v = (VarDeclaration *)parameters->data[i]; 1374 1375 if (v->storage_class & STCout) 1375 1376 { 1376 1377 assert(v->init); 1377 1378 ExpInitializer *ie = v->init->isExpInitializer(); 1378 1379 assert(ie); 1379 1380 if (ie->exp->op == TOKconstruct) 1380 1381 ie->exp->op = TOKassign; // construction occured in parameter processing 1381 1382 a->push(new ExpStatement(0, ie->exp)); 1382 1383 } 1383 1384 } 1384 1385 } 1385 1386 1386 1387 if (argptr) 1387 { // Initialize _argptr to point past non-variadic arg1388 { // Initialize _argptr 1388 1389 #if IN_GCC 1389 1390 // Handled in FuncDeclaration::toObjFile 1390 1391 v_argptr = argptr; 1391 1392 v_argptr->init = new VoidInitializer(loc); 1392 1393 #else 1393 1394 Type *t = argptr->type; 1394 VarDeclaration *p; 1395 unsigned offset = 0; 1396 1397 Expression *e1 = new VarExp(0, argptr); 1398 // Find the last non-ref parameter 1399 if (parameters && parameters->dim) 1400 { 1401 int lastNonref = parameters->dim -1; 1402 p = (VarDeclaration *)parameters->data[lastNonref]; 1403 /* The trouble with out and ref parameters is that taking 1404 * the address of it doesn't work, because later processing 1405 * adds in an extra level of indirection. So we skip over them. 1406 */ 1407 while (p->storage_class & (STCout | STCref)) 1408 { 1409 --lastNonref; 1410 offset += PTRSIZE; 1411 if (lastNonref < 0) 1412 { 1413 p = v_arguments; 1414 break; 1415 } 1416 p = (VarDeclaration *)parameters->data[lastNonref]; 1417 } 1395 if (global.params.isX86_64) 1396 { // Initialize _argptr to point to v_argsave 1397 Expression *e1 = new VarExp(0, argptr); 1398 Expression *e = new SymOffExp(0, v_argsave, 6*8 + 8*16); 1399 e->type = argptr->type; 1400 e = new AssignExp(0, e1, e); 1401 e = e->semantic(sc); 1402 a->push(new ExpStatement(0, e)); 1418 1403 } 1419 1404 else 1420 p = v_arguments; // last parameter is _arguments[] 1421 if (p->storage_class & STClazy) 1422 // If the last parameter is lazy, it's the size of a delegate 1423 offset += PTRSIZE * 2; 1424 else 1425 offset += p->type->size(); 1426 offset = (offset + PTRSIZE - 1) & ~(PTRSIZE - 1); // assume stack aligns on pointer size 1427 Expression *e = new SymOffExp(0, p, offset); 1428 e->type = Type::tvoidptr; 1429 //e = e->semantic(sc); 1430 e = new AssignExp(0, e1, e); 1431 e->type = t; 1432 a->push(new ExpStatement(0, e)); 1433 p->isargptr = TRUE; 1405 { // Initialize _argptr to point past non-variadic arg 1406 VarDeclaration *p; 1407 unsigned offset = 0; 1408 1409 Expression *e1 = new VarExp(0, argptr); 1410 // Find the last non-ref parameter 1411 if (parameters && parameters->dim) 1412 { 1413 int lastNonref = parameters->dim -1; 1414 p = (VarDeclaration *)parameters->data[lastNonref]; 1415 /* The trouble with out and ref parameters is that taking 1416 * the address of it doesn't work, because later processing 1417 * adds in an extra level of indirection. So we skip over them. 1418 */ 1419 while (p->storage_class & (STCout | STCref)) 1420 { 1421 --lastNonref; 1422 offset += PTRSIZE; 1423 if (lastNonref < 0) 1424 { 1425 p = v_arguments; 1426 break; 1427 } 1428 p = (VarDeclaration *)parameters->data[lastNonref]; 1429 } 1430 } 1431 else 1432 p = v_arguments; // last parameter is _arguments[] 1433 if (p->storage_class & STClazy) 1434 // If the last parameter is lazy, it's the size of a delegate 1435 offset += PTRSIZE * 2; 1436 else 1437 offset += p->type->size(); 1438 offset = (offset + PTRSIZE - 1) & ~(PTRSIZE - 1); // assume stack aligns on pointer size 1439 Expression *e = new SymOffExp(0, p, offset); 1440 e->type = Type::tvoidptr; 1441 //e = e->semantic(sc); 1442 e = new AssignExp(0, e1, e); 1443 e->type = t; 1444 a->push(new ExpStatement(0, e)); 1445 p->isargptr = TRUE; 1446 } 1434 1447 #endif 1435 1448 } 1436 1449 1437 1450 if (_arguments) 1438 1451 { 1439 1452 /* Advance to elements[] member of TypeInfo_Tuple with: 1440 1453 * _arguments = v_arguments.elements; 1441 1454 */ 1442 1455 Expression *e = new VarExp(0, v_arguments); 1443 1456 e = new DotIdExp(0, e, Id::elements); 1444 1457 Expression *e1 = new VarExp(0, _arguments); 1445 1458 e = new ConstructExp(0, e1, e); 1446 1459 e = e->semantic(sc2); 1447 1460 a->push(new ExpStatement(0, e)); 1448 1461 } 1449 1462 1450 1463 // Merge contracts together with body into one compound statement 1451 1464 1452 1465 #ifdef _DH 1453 1466 if (frequire && global.params.useIn) trunk/src/imphint.c
r767 r812 29 29 { 30 30 #if DMDV1 31 31 static const char *modules[] = 32 32 { "std.c.stdio", 33 33 "std.stdio", 34 34 "std.math", 35 35 "std.c.stdarg", 36 36 }; 37 37 static const char *names[] = 38 38 { 39 39 "printf", NULL, 40 40 "writefln", NULL, 41 41 "sin", "cos", "sqrt", "fabs", NULL, 42 42 "__va_argsave_t", NULL, 43 43 }; 44 44 #else 45 45 static const char *modules[] = 46 46 { "core.stdc.stdio", 47 47 "std.stdio", 48 48 "std.math", 49 " std.c.stdarg",49 "core.vararg", 50 50 }; 51 51 static const char *names[] = 52 52 { 53 53 "printf", NULL, 54 54 "writeln", NULL, 55 55 "sin", "cos", "sqrt", "fabs", NULL, 56 56 "__va_argsave_t", NULL, 57 57 }; 58 58 #endif 59 59 int m = 0; 60 60 for (int n = 0; n < sizeof(names)/sizeof(names[0]); n++) 61 61 { 62 62 const char *p = names[n]; 63 63 if (p == NULL) 64 64 { m++; 65 65 continue; 66 66 } 67 67 assert(m < sizeof(modules)/sizeof(modules[0])); 68 68 if (strcmp(s, p) == 0) 69 69 return modules[m]; trunk/src/mtype.c
r809 r812 1703 1703 } 1704 1704 else 1705 1705 s = deco; 1706 1706 e = new StringExp(loc, (char *)s, strlen(s), 'c'); 1707 1707 Scope sc; 1708 1708 e = e->semantic(&sc); 1709 1709 } 1710 1710 else if (ident == Id::stringof) 1711 1711 { char *s = toChars(); 1712 1712 e = new StringExp(loc, s, strlen(s), 'c'); 1713 1713 Scope sc; 1714 1714 e = e->semantic(&sc); 1715 1715 } 1716 1716 else 1717 1717 { 1718 1718 Dsymbol *s = NULL; 1719 1719 if (ty == Tstruct || ty == Tclass || ty == Tenum || ty == Ttypedef) 1720 1720 s = toDsymbol(NULL); 1721 1721 if (s) 1722 1722 s = s->search_correct(ident); 1723 if (s) 1724 error(loc, "no property '%s' for type '%s', did you mean '%s'?", ident->toChars(), toChars(), s->toChars()); 1725 else 1726 error(loc, "no property '%s' for type '%s'", ident->toChars(), toChars()); 1723 if (this != Type::terror) 1724 { 1725 if (s) 1726 error(loc, "no property '%s' for type '%s', did you mean '%s'?", ident->toChars(), toChars(), s->toChars()); 1727 else 1728 error(loc, "no property '%s' for type '%s'", ident->toChars(), toChars()); 1729 } 1727 1730 e = new ErrorExp(); 1728 1731 } 1729 1732 return e; 1730 1733 } 1731 1734 1732 1735 Expression *Type::dotExp(Scope *sc, Expression *e, Identifier *ident) 1733 1736 { VarDeclaration *v = NULL; 1734 1737 1735 1738 #if LOGDOTEXP 1736 1739 printf("Type::dotExp(e = '%s', ident = '%s')\n", e->toChars(), ident->toChars()); 1737 1740 #endif 1738 1741 if (e->op == TOKdotvar) 1739 1742 { 1740 1743 DotVarExp *dv = (DotVarExp *)e; 1741 1744 v = dv->var->isVarDeclaration(); 1742 1745 } 1743 1746 else if (e->op == TOKvar) 1744 1747 { 1745 1748 VarExp *ve = (VarExp *)e; 1746 1749 v = ve->var->isVarDeclaration(); trunk/src/toir.c
r767 r812 424 424 "9intrinsic4outpFkhZh", 425 425 "9intrinsic5bswapFkZk", 426 426 "9intrinsic5outplFkkZk", 427 427 "9intrinsic5outpwFktZt", 428 428 #elif DMDV2 429 429 /* The names are mangled differently because of the pure and 430 430 * nothrow attributes. 431 431 */ 432 432 "4math3cosFNaNbNfeZe", 433 433 "4math3sinFNaNbNfeZe", 434 434 "4math4fabsFNaNbNfeZe", 435 435 "4math4rintFNaNbNfeZe", 436 436 "4math4sqrtFNaNbNfdZd", 437 437 "4math4sqrtFNaNbNfeZe", 438 438 "4math4sqrtFNaNbNffZf", 439 439 "4math4yl2xFNaNbNfeeZe", 440 440 "4math5ldexpFNaNbNfeiZe", 441 441 "4math6rndtolFNaNbNfeZl", 442 442 "4math6yl2xp1FNaNbNfeeZe", 443 443 444 "9intrinsic2btFNaNbxP kkZi",445 "9intrinsic3bsfFNaNb kZi",446 "9intrinsic3bsrFNaNb kZi",444 "9intrinsic2btFNaNbxPmmZi", 445 "9intrinsic3bsfFNaNbmZi", 446 "9intrinsic3bsrFNaNbmZi", 447 447 "9intrinsic3btcFNbPmmZi", 448 448 "9intrinsic3btrFNbPmmZi", 449 449 "9intrinsic3btsFNbPmmZi", 450 450 "9intrinsic3inpFNbkZh", 451 451 "9intrinsic4inplFNbkZk", 452 452 "9intrinsic4inpwFNbkZt", 453 453 "9intrinsic4outpFNbkhZh", 454 454 "9intrinsic5bswapFNaNbkZk", 455 455 "9intrinsic5outplFNbkkZk", 456 456 "9intrinsic5outpwFNbktZt", 457 457 #endif 458 458 }; 459 459 static unsigned char ioptab[] = 460 460 { 461 461 OPcos, 462 462 OPsin, 463 463 OPabs, 464 464 OPrint, 465 465 OPsqrt, 466 466 OPsqrt,
