Changeset 603
- Timestamp:
- 08/06/10 06:09:13 (14 years ago)
- Files:
-
- branches/dmd-1.x/src/func.c (modified) (1 diff)
- trunk/src/func.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmd-1.x/src/func.c
r567 r603 1199 1199 if (v->storage_class & STCout) 1200 1200 { 1201 1201 assert(v->init); 1202 1202 ExpInitializer *ie = v->init->isExpInitializer(); 1203 1203 assert(ie); 1204 1204 ie->exp->op = TOKassign; // construction occurred in parameter processing 1205 1205 a->push(new ExpStatement(0, ie->exp)); 1206 1206 } 1207 1207 } 1208 1208 } 1209 1209 1210 1210 if (argptr) 1211 1211 { // Initialize _argptr to point past non-variadic arg 1212 1212 #if IN_GCC 1213 1213 // Handled in FuncDeclaration::toObjFile 1214 1214 v_argptr = argptr; 1215 1215 v_argptr->init = new VoidInitializer(loc); 1216 1216 #else 1217 1217 Type *t = argptr->type; 1218 1218 VarDeclaration *p; 1219 unsigned offset ;1219 unsigned offset = 0; 1220 1220 1221 1221 Expression *e1 = new VarExp(0, argptr); 1222 // Find the last non-ref parameter 1222 1223 if (parameters && parameters->dim) 1223 p = (VarDeclaration *)parameters->data[parameters->dim - 1]; 1224 { 1225 int lastNonref = parameters->dim -1; 1226 p = (VarDeclaration *)parameters->data[lastNonref]; 1227 /* The trouble with out and ref parameters is that taking 1228 * the address of it doesn't work, because later processing 1229 * adds in an extra level of indirection. So we skip over them. 1230 */ 1231 while (p->storage_class & (STCout | STCref)) 1232 { 1233 --lastNonref; 1234 offset += PTRSIZE; 1235 if (lastNonref < 0) 1236 { 1237 p = v_arguments; 1238 break; 1239 } 1240 p = (VarDeclaration *)parameters->data[lastNonref]; 1241 } 1242 } 1224 1243 else 1225 1244 p = v_arguments; // last parameter is _arguments[] 1226 1245 if (p->storage_class & STClazy) 1227 1246 // If the last parameter is lazy, it's the size of a delegate 1228 offset = PTRSIZE * 2;1247 offset += PTRSIZE * 2; 1229 1248 else 1230 offset = p->type->size();1231 offset = (offset + 3) & ~3; // assume stack aligns on 41249 offset += p->type->size(); 1250 offset = (offset + PTRSIZE - 1) & ~(PTRSIZE - 1); // assume stack aligns on pointer size 1232 1251 Expression *e = new SymOffExp(0, p, offset); 1233 1252 e->type = Type::tvoidptr; 1234 1253 //e = e->semantic(sc); 1235 1254 e = new AssignExp(0, e1, e); 1236 1255 e->type = t; 1237 1256 a->push(new ExpStatement(0, e)); 1238 1257 #endif 1239 1258 } 1240 1259 1241 1260 if (_arguments) 1242 1261 { 1243 1262 /* Advance to elements[] member of TypeInfo_Tuple with: 1244 1263 * _arguments = v_arguments.elements; 1245 1264 */ 1246 1265 Expression *e = new VarExp(0, v_arguments); 1247 1266 e = new DotIdExp(0, e, Id::elements); 1248 1267 Expression *e1 = new VarExp(0, _arguments); 1249 1268 e = new AssignExp(0, e1, e); 1250 1269 e->op = TOKconstruct; 1251 1270 e = e->semantic(sc2); trunk/src/func.c
r567 r603 1350 1350 { 1351 1351 assert(v->init); 1352 1352 ExpInitializer *ie = v->init->isExpInitializer(); 1353 1353 assert(ie); 1354 1354 if (ie->exp->op == TOKconstruct) 1355 1355 ie->exp->op = TOKassign; // construction occured in parameter processing 1356 1356 a->push(new ExpStatement(0, ie->exp)); 1357 1357 } 1358 1358 } 1359 1359 } 1360 1360 1361 1361 if (argptr) 1362 1362 { // Initialize _argptr to point past non-variadic arg 1363 1363 #if IN_GCC 1364 1364 // Handled in FuncDeclaration::toObjFile 1365 1365 v_argptr = argptr; 1366 1366 v_argptr->init = new VoidInitializer(loc); 1367 1367 #else 1368 1368 Type *t = argptr->type; 1369 1369 VarDeclaration *p; 1370 unsigned offset ;1370 unsigned offset = 0; 1371 1371 1372 1372 Expression *e1 = new VarExp(0, argptr); 1373 // Find the last non-ref parameter 1373 1374 if (parameters && parameters->dim) 1374 p = (VarDeclaration *)parameters->data[parameters->dim - 1]; 1375 { 1376 int lastNonref = parameters->dim -1; 1377 p = (VarDeclaration *)parameters->data[lastNonref]; 1378 /* The trouble with out and ref parameters is that taking 1379 * the address of it doesn't work, because later processing 1380 * adds in an extra level of indirection. So we skip over them. 1381 */ 1382 while (p->storage_class & (STCout | STCref)) 1383 { 1384 --lastNonref; 1385 offset += PTRSIZE; 1386 if (lastNonref < 0) 1387 { 1388 p = v_arguments; 1389 break; 1390 } 1391 p = (VarDeclaration *)parameters->data[lastNonref]; 1392 } 1393 } 1375 1394 else 1376 1395 p = v_arguments; // last parameter is _arguments[] 1377 1396 if (p->storage_class & STClazy) 1378 1397 // If the last parameter is lazy, it's the size of a delegate 1379 offset = PTRSIZE * 2;1398 offset += PTRSIZE * 2; 1380 1399 else 1381 offset = p->type->size();1382 offset = (offset + 3) & ~3; // assume stack aligns on 41400 offset += p->type->size(); 1401 offset = (offset + PTRSIZE - 1) & ~(PTRSIZE - 1); // assume stack aligns on pointer size 1383 1402 Expression *e = new SymOffExp(0, p, offset); 1384 1403 e->type = Type::tvoidptr; 1385 1404 //e = e->semantic(sc); 1386 1405 e = new AssignExp(0, e1, e); 1387 1406 e->type = t; 1388 1407 a->push(new ExpStatement(0, e)); 1389 1408 p->isargptr = TRUE; 1390 1409 #endif 1391 1410 } 1392 1411 1393 1412 if (_arguments) 1394 1413 { 1395 1414 /* Advance to elements[] member of TypeInfo_Tuple with: 1396 1415 * _arguments = v_arguments.elements; 1397 1416 */ 1398 1417 Expression *e = new VarExp(0, v_arguments); 1399 1418 e = new DotIdExp(0, e, Id::elements); 1400 1419 Expression *e1 = new VarExp(0, _arguments); 1401 1420 e = new ConstructExp(0, e1, e); 1402 1421 e = e->semantic(sc2);
