Mercurial > projects > ldc
comparison gen/classes.cpp @ 284:70c370e97944 trunk
[svn r305] Started support for custom class allocators/deallocators. Allocators with more than one argument still need to be fixed.
Removed the LLVM stacktrace code from mars.c.
Moved the LLVM based default target detection code from mars.c to llvmhelpers.cpp.
author | lindquist |
---|---|
date | Sat, 21 Jun 2008 02:48:53 +0200 |
parents | 665b81613475 |
children | 297690b5d4a5 |
comparison
equal
deleted
inserted
replaced
283:9bb48fb57a7d | 284:70c370e97944 |
---|---|
792 LLValue* mem; | 792 LLValue* mem; |
793 if (newexp->onstack) | 793 if (newexp->onstack) |
794 { | 794 { |
795 mem = new llvm::AllocaInst(DtoType(tc)->getContainedType(0), "newclass_alloca", gIR->topallocapoint()); | 795 mem = new llvm::AllocaInst(DtoType(tc)->getContainedType(0), "newclass_alloca", gIR->topallocapoint()); |
796 } | 796 } |
797 // custom allocator | |
798 else if (newexp->allocator) | |
799 { | |
800 DtoForceDeclareDsymbol(newexp->allocator); | |
801 assert(newexp->newargs); | |
802 assert(newexp->newargs->dim == 1); | |
803 | |
804 llvm::Function* fn = newexp->allocator->ir.irFunc->func; | |
805 assert(fn); | |
806 DValue* arg = ((Expression*)newexp->newargs->data[0])->toElem(gIR); | |
807 mem = gIR->ir->CreateCall(fn, arg->getRVal(), "newclass_custom_alloc"); | |
808 mem = DtoBitCast(mem, DtoType(tc), "newclass_custom"); | |
809 } | |
810 // default allocator | |
797 else | 811 else |
798 { | 812 { |
799 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass"); | 813 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass"); |
800 mem = gIR->ir->CreateCall(fn, tc->sym->ir.irStruct->classInfo, "newclass_gc_alloc"); | 814 mem = gIR->ir->CreateCall(fn, tc->sym->ir.irStruct->classInfo, "newclass_gc_alloc"); |
801 mem = DtoBitCast(mem, DtoType(tc), "newclass_gc"); | 815 mem = DtoBitCast(mem, DtoType(tc), "newclass_gc"); |
1444 | 1458 |
1445 ClassDeclaration* cinfo = ClassDeclaration::classinfo; | 1459 ClassDeclaration* cinfo = ClassDeclaration::classinfo; |
1446 DtoForceConstInitDsymbol(cinfo); | 1460 DtoForceConstInitDsymbol(cinfo); |
1447 assert(cinfo->ir.irStruct->constInit); | 1461 assert(cinfo->ir.irStruct->constInit); |
1448 | 1462 |
1463 // def init constant | |
1464 LLConstant* defc = cinfo->ir.irStruct->constInit; | |
1465 assert(defc); | |
1466 | |
1449 LLConstant* c; | 1467 LLConstant* c; |
1450 | 1468 |
1451 // own vtable | 1469 // own vtable |
1452 c = cinfo->ir.irStruct->constInit->getOperand(0); | 1470 c = defc->getOperand(0); |
1453 assert(c); | 1471 assert(c); |
1454 inits.push_back(c); | 1472 inits.push_back(c); |
1455 | 1473 |
1456 // monitor | 1474 // monitor |
1457 c = cinfo->ir.irStruct->constInit->getOperand(1); | 1475 c = defc->getOperand(1); |
1458 inits.push_back(c); | 1476 inits.push_back(c); |
1459 | 1477 |
1460 // byte[] init | 1478 // byte[] init |
1461 const LLType* byteptrty = getPtrToType(LLType::Int8Ty); | 1479 const LLType* byteptrty = getPtrToType(LLType::Int8Ty); |
1462 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { | 1480 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { |
1463 c = cinfo->ir.irStruct->constInit->getOperand(2); | 1481 c = defc->getOperand(2); |
1464 } | 1482 } |
1465 else { | 1483 else { |
1466 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->init, byteptrty); | 1484 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->init, byteptrty); |
1467 assert(!cd->ir.irStruct->constInit->getType()->isAbstract()); | 1485 assert(!defc->getType()->isAbstract()); |
1468 size_t initsz = getABITypeSize(cd->ir.irStruct->constInit->getType()); | 1486 size_t initsz = getABITypeSize(defc->getType()); |
1469 c = DtoConstSlice(DtoConstSize_t(initsz), c); | 1487 c = DtoConstSlice(DtoConstSize_t(initsz), c); |
1470 } | 1488 } |
1471 inits.push_back(c); | 1489 inits.push_back(c); |
1472 | 1490 |
1473 // class name | 1491 // class name |
1482 c = DtoConstString(name); | 1500 c = DtoConstString(name); |
1483 inits.push_back(c); | 1501 inits.push_back(c); |
1484 | 1502 |
1485 // vtbl array | 1503 // vtbl array |
1486 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { | 1504 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { |
1487 c = cinfo->ir.irStruct->constInit->getOperand(4); | 1505 c = defc->getOperand(4); |
1488 } | 1506 } |
1489 else { | 1507 else { |
1490 const LLType* byteptrptrty = getPtrToType(byteptrty); | 1508 const LLType* byteptrptrty = getPtrToType(byteptrty); |
1491 assert(!cd->ir.irStruct->vtbl->getType()->isAbstract()); | 1509 assert(!cd->ir.irStruct->vtbl->getType()->isAbstract()); |
1492 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->vtbl, byteptrptrty); | 1510 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->vtbl, byteptrptrty); |
1501 inits.push_back(c); | 1519 inits.push_back(c); |
1502 | 1520 |
1503 // interfaces array | 1521 // interfaces array |
1504 IrStruct* irstruct = cd->ir.irStruct; | 1522 IrStruct* irstruct = cd->ir.irStruct; |
1505 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) { | 1523 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) { |
1506 c = cinfo->ir.irStruct->constInit->getOperand(5); | 1524 c = defc->getOperand(5); |
1507 } | 1525 } |
1508 else { | 1526 else { |
1509 const LLType* t = cinfo->ir.irStruct->constInit->getOperand(5)->getType()->getContainedType(1); | 1527 const LLType* t = defc->getOperand(5)->getType()->getContainedType(1); |
1510 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); | 1528 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); |
1511 size_t iisz = irstruct->interfaceInfosTy->getNumElements(); | 1529 size_t iisz = irstruct->interfaceInfosTy->getNumElements(); |
1512 c = DtoConstSlice(DtoConstSize_t(iisz), c); | 1530 c = DtoConstSlice(DtoConstSize_t(iisz), c); |
1513 } | 1531 } |
1514 inits.push_back(c); | 1532 inits.push_back(c); |
1520 assert(c); | 1538 assert(c); |
1521 inits.push_back(c); | 1539 inits.push_back(c); |
1522 } | 1540 } |
1523 else { | 1541 else { |
1524 // null | 1542 // null |
1525 c = cinfo->ir.irStruct->constInit->getOperand(6); | 1543 c = defc->getOperand(6); |
1526 inits.push_back(c); | 1544 inits.push_back(c); |
1527 } | 1545 } |
1528 | 1546 |
1529 // destructor | 1547 // destructor |
1530 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { | 1548 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { |
1531 c = cinfo->ir.irStruct->constInit->getOperand(7); | 1549 c = defc->getOperand(7); |
1532 } | 1550 } |
1533 else { | 1551 else { |
1534 c = build_class_dtor(cd); | 1552 c = build_class_dtor(cd); |
1535 } | 1553 } |
1536 inits.push_back(c); | 1554 inits.push_back(c); |
1537 | 1555 |
1538 // invariant | 1556 // invariant |
1539 // TODO | 1557 // TODO |
1540 c = cinfo->ir.irStruct->constInit->getOperand(8); | 1558 c = defc->getOperand(8); |
1541 inits.push_back(c); | 1559 inits.push_back(c); |
1542 | 1560 |
1543 // uint flags | 1561 // uint flags |
1544 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { | 1562 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { |
1545 c = cinfo->ir.irStruct->constInit->getOperand(9); | 1563 c = defc->getOperand(9); |
1546 } | 1564 } |
1547 else { | 1565 else { |
1548 uint flags = build_classinfo_flags(cd); | 1566 uint flags = build_classinfo_flags(cd); |
1549 c = DtoConstUint(flags); | 1567 c = DtoConstUint(flags); |
1550 } | 1568 } |
1551 inits.push_back(c); | 1569 inits.push_back(c); |
1552 | 1570 |
1553 // allocator | 1571 // deallocator |
1554 // TODO | 1572 if (cd->aggDelete) { |
1555 c = cinfo->ir.irStruct->constInit->getOperand(10); | 1573 DtoForceDeclareDsymbol(cd->aggDelete); |
1574 c = cd->aggDelete->ir.irFunc->func; | |
1575 c = llvm::ConstantExpr::getBitCast(c, defc->getOperand(10)->getType()); | |
1576 } | |
1577 else { | |
1578 c = defc->getOperand(10); | |
1579 } | |
1556 inits.push_back(c); | 1580 inits.push_back(c); |
1557 | 1581 |
1558 // offset typeinfo | 1582 // offset typeinfo |
1559 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { | 1583 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { |
1560 c = cinfo->ir.irStruct->constInit->getOperand(11); | 1584 c = defc->getOperand(11); |
1561 } | 1585 } |
1562 else { | 1586 else { |
1563 c = build_offti_array(cd, cinfo->ir.irStruct->constInit->getOperand(11)); | 1587 c = build_offti_array(cd, defc->getOperand(11)); |
1564 } | 1588 } |
1565 inits.push_back(c); | 1589 inits.push_back(c); |
1566 | 1590 |
1567 // default constructor | 1591 // default constructor |
1568 if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { | 1592 if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { |
1569 DtoForceDeclareDsymbol(cd->defaultCtor); | 1593 DtoForceDeclareDsymbol(cd->defaultCtor); |
1570 c = isaConstant(cd->defaultCtor->ir.irFunc->func); | 1594 c = isaConstant(cd->defaultCtor->ir.irFunc->func); |
1571 const LLType* toTy = cinfo->ir.irStruct->constInit->getOperand(12)->getType(); | 1595 const LLType* toTy = defc->getOperand(12)->getType(); |
1572 c = llvm::ConstantExpr::getBitCast(c, toTy); | 1596 c = llvm::ConstantExpr::getBitCast(c, toTy); |
1573 } | 1597 } |
1574 else { | 1598 else { |
1575 c = cinfo->ir.irStruct->constInit->getOperand(12); | 1599 c = defc->getOperand(12); |
1576 } | 1600 } |
1577 inits.push_back(c); | 1601 inits.push_back(c); |
1578 | 1602 |
1579 /*size_t n = inits.size(); | 1603 /*size_t n = inits.size(); |
1580 for (size_t i=0; i<n; ++i) | 1604 for (size_t i=0; i<n; ++i) |
1581 { | 1605 { |
1582 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; | 1606 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; |
1583 }*/ | 1607 }*/ |
1584 | 1608 |
1585 // build the initializer | 1609 // build the initializer |
1586 const llvm::StructType* st = isaStruct(cinfo->ir.irStruct->constInit->getType()); | 1610 const llvm::StructType* st = isaStruct(defc->getType()); |
1587 LLConstant* finalinit = llvm::ConstantStruct::get(st, inits); | 1611 LLConstant* finalinit = llvm::ConstantStruct::get(st, inits); |
1588 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; | 1612 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; |
1589 | 1613 |
1590 cd->ir.irStruct->constClassInfo = finalinit; | 1614 cd->ir.irStruct->constClassInfo = finalinit; |
1591 cd->ir.irStruct->classInfo->setInitializer(finalinit); | 1615 cd->ir.irStruct->classInfo->setInitializer(finalinit); |