comparison gen/toir.cpp @ 133:44a95ac7368a trunk

[svn r137] Many fixes towards tango.io.Console working, but not quite there yet... In particular, assertions has been fixed to include file/line info, and much more!
author lindquist
date Mon, 14 Jan 2008 05:11:54 +0100
parents 1700239cab2e
children 0e28624814e8
comparison
equal deleted inserted replaced
132:1700239cab2e 133:44a95ac7368a
177 Logger::println("TypeInfoDeclaration"); 177 Logger::println("TypeInfoDeclaration");
178 DtoForceDeclareDsymbol(tid); 178 DtoForceDeclareDsymbol(tid);
179 assert(tid->llvmValue); 179 assert(tid->llvmValue);
180 const llvm::Type* vartype = DtoType(type); 180 const llvm::Type* vartype = DtoType(type);
181 llvm::Value* m; 181 llvm::Value* m;
182 if (tid->llvmValue->getType() != llvm::PointerType::get(vartype)) 182 if (tid->llvmValue->getType() != getPtrToType(vartype))
183 m = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp"); 183 m = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp");
184 else 184 else
185 m = tid->llvmValue; 185 m = tid->llvmValue;
186 return new DVarValue(vd, m, true); 186 return new DVarValue(vd, m, true);
187 } 187 }
276 DtoForceDeclareDsymbol(ti); 276 DtoForceDeclareDsymbol(ti);
277 assert(ti->llvmValue); 277 assert(ti->llvmValue);
278 const llvm::Type* vartype = DtoType(type); 278 const llvm::Type* vartype = DtoType(type);
279 llvm::Constant* m = isaConstant(ti->llvmValue); 279 llvm::Constant* m = isaConstant(ti->llvmValue);
280 assert(m); 280 assert(m);
281 if (ti->llvmValue->getType() != llvm::PointerType::get(vartype)) 281 if (ti->llvmValue->getType() != getPtrToType(vartype))
282 m = llvm::ConstantExpr::getBitCast(m, vartype); 282 m = llvm::ConstantExpr::getBitCast(m, vartype);
283 return m; 283 return m;
284 } 284 }
285 assert(0 && "Unsupported const VarExp kind"); 285 assert(0 && "Unsupported const VarExp kind");
286 return NULL; 286 return NULL;
401 401
402 Type* dtype = DtoDType(type); 402 Type* dtype = DtoDType(type);
403 Type* cty = DtoDType(dtype->next); 403 Type* cty = DtoDType(dtype->next);
404 404
405 const llvm::Type* ct = DtoType(cty); 405 const llvm::Type* ct = DtoType(cty);
406 if (ct == llvm::Type::VoidTy)
407 ct = llvm::Type::Int8Ty;
406 //printf("ct = %s\n", type->next->toChars()); 408 //printf("ct = %s\n", type->next->toChars());
407 const llvm::ArrayType* at = llvm::ArrayType::get(ct,len+1); 409 const llvm::ArrayType* at = llvm::ArrayType::get(ct,len+1);
408 410
409 llvm::Constant* _init; 411 llvm::Constant* _init;
410 if (cty->ty == Tchar) { 412 if (cty->ty == Tchar || cty->ty == Tvoid) {
411 uint8_t* str = (uint8_t*)string; 413 uint8_t* str = (uint8_t*)string;
412 std::string cont((char*)str, len); 414 std::string cont((char*)str, len);
413 _init = llvm::ConstantArray::get(cont,true); 415 _init = llvm::ConstantArray::get(cont,true);
414 } 416 }
415 else if (cty->ty == Twchar) { 417 else if (cty->ty == Twchar) {
432 } 434 }
433 else 435 else
434 assert(0); 436 assert(0);
435 437
436 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; 438 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage;
439 Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n';
437 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,"stringliteral",gIR->module); 440 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,"stringliteral",gIR->module);
438 441
439 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 442 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
440 llvm::Constant* idxs[2] = { zero, zero }; 443 llvm::Constant* idxs[2] = { zero, zero };
441 llvm::Constant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); 444 llvm::Constant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
459 } 462 }
460 } 463 }
461 assert(0); 464 assert(0);
462 } 465 }
463 else if (dtype->ty == Tsarray) { 466 else if (dtype->ty == Tsarray) {
464 const llvm::Type* dstType = llvm::PointerType::get(llvm::ArrayType::get(ct, len)); 467 const llvm::Type* dstType = getPtrToType(llvm::ArrayType::get(ct, len));
465 llvm::Value* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType); 468 llvm::Value* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType);
466 return new DVarValue(type, emem, true); 469 return new DVarValue(type, emem, true);
467 } 470 }
468 else if (dtype->ty == Tpointer) { 471 else if (dtype->ty == Tpointer) {
469 return new DImValue(type, arrptr); 472 return new DImValue(type, arrptr);
875 Expression* exp = (Expression*)arguments->data[0]; 878 Expression* exp = (Expression*)arguments->data[0];
876 DValue* expelem = exp->toElem(p); 879 DValue* expelem = exp->toElem(p);
877 Type* t = DtoDType(type); 880 Type* t = DtoDType(type);
878 const llvm::Type* llt = DtoType(type); 881 const llvm::Type* llt = DtoType(type);
879 if (DtoIsPassedByRef(t)) 882 if (DtoIsPassedByRef(t))
880 llt = llvm::PointerType::get(llt); 883 llt = getPtrToType(llt);
881 // TODO 884 // TODO
882 if (strcmp(global.params.llvmArch, "x86") != 0) { 885 if (strcmp(global.params.llvmArch, "x86") != 0) {
883 warning("%s: va_arg for C variadic functions is broken for anything but x86", loc.toChars()); 886 warning("%s: va_arg for C variadic functions is broken for anything but x86", loc.toChars());
884 } 887 }
885 return new DImValue(type, p->ir->CreateVAArg(expelem->getLVal(),llt,"tmp")); 888 return new DImValue(type, p->ir->CreateVAArg(expelem->getLVal(),llt,"tmp"));
970 else { 973 else {
971 llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint()); 974 llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint());
972 } 975 }
973 976
974 if (dfn && dfn->func && dfn->func->llvmRunTimeHack) { 977 if (dfn && dfn->func && dfn->func->llvmRunTimeHack) {
975 const llvm::Type* rettype = llvm::PointerType::get(DtoType(type)); 978 const llvm::Type* rettype = getPtrToType(DtoType(type));
976 if (llargs[j]->getType() != llfnty->getParamType(j)) { 979 if (llargs[j]->getType() != llfnty->getParamType(j)) {
977 Logger::println("llvmRunTimeHack==true - force casting return value param"); 980 Logger::println("llvmRunTimeHack==true - force casting return value param");
978 Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n'; 981 Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n';
979 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j)); 982 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j));
980 } 983 }
984 ++argiter; 987 ++argiter;
985 } 988 }
986 989
987 // this arguments 990 // this arguments
988 if (dfn && dfn->vthis) { 991 if (dfn && dfn->vthis) {
989 Logger::println("This Call"); 992 Logger::cout() << "This Call func val:" << *funcval << '\n';
990 if (dfn->vthis->getType() != argiter->get()) { 993 if (dfn->vthis->getType() != argiter->get()) {
991 //Logger::cout() << *fn->thisparam << '|' << *argiter->get() << '\n'; 994 //Logger::cout() << "value: " << *dfn->vthis << " totype: " << *argiter->get() << '\n';
992 llargs[j] = DtoBitCast(dfn->vthis, argiter->get()); 995 llargs[j] = DtoBitCast(dfn->vthis, argiter->get());
993 } 996 }
994 else { 997 else {
995 llargs[j] = dfn->vthis; 998 llargs[j] = dfn->vthis;
996 } 999 }
1008 // nested call 1011 // nested call
1009 else if (dfn && dfn->func && dfn->func->isNested()) { 1012 else if (dfn && dfn->func && dfn->func->isNested()) {
1010 Logger::println("Nested Call"); 1013 Logger::println("Nested Call");
1011 llvm::Value* contextptr = DtoNestedContext(dfn->func->toParent2()->isFuncDeclaration()); 1014 llvm::Value* contextptr = DtoNestedContext(dfn->func->toParent2()->isFuncDeclaration());
1012 if (!contextptr) 1015 if (!contextptr)
1013 contextptr = llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); 1016 contextptr = llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty));
1014 llargs[j] = DtoBitCast(contextptr, llvm::PointerType::get(llvm::Type::Int8Ty)); 1017 llargs[j] = DtoBitCast(contextptr, getPtrToType(llvm::Type::Int8Ty));
1015 ++j; 1018 ++j;
1016 ++argiter; 1019 ++argiter;
1017 } 1020 }
1018 1021
1019 // va arg function special argument passing 1022 // va arg function special argument passing
1023 for (int i=0; i<n; i++,j++) 1026 for (int i=0; i<n; i++,j++)
1024 { 1027 {
1025 Argument* fnarg = Argument::getNth(tf->parameters, i); 1028 Argument* fnarg = Argument::getNth(tf->parameters, i);
1026 Expression* exp = (Expression*)arguments->data[i]; 1029 Expression* exp = (Expression*)arguments->data[i];
1027 DValue* expelem = exp->toElem(p); 1030 DValue* expelem = exp->toElem(p);
1028 llargs[j] = DtoBitCast(expelem->getLVal(), llvm::PointerType::get(llvm::Type::Int8Ty)); 1031 llargs[j] = DtoBitCast(expelem->getLVal(), getPtrToType(llvm::Type::Int8Ty));
1029 } 1032 }
1030 } 1033 }
1031 // regular arguments 1034 // regular arguments
1032 else 1035 else
1033 { 1036 {
1060 DtoVariadicArgument(argexp, DtoGEPi(mem,0,i,"tmp")); 1063 DtoVariadicArgument(argexp, DtoGEPi(mem,0,i,"tmp"));
1061 } 1064 }
1062 1065
1063 // build type info array 1066 // build type info array
1064 assert(Type::typeinfo->llvmConstInit); 1067 assert(Type::typeinfo->llvmConstInit);
1065 const llvm::Type* typeinfotype = llvm::PointerType::get(Type::typeinfo->llvmConstInit->getType()); 1068 const llvm::Type* typeinfotype = getPtrToType(Type::typeinfo->llvmConstInit->getType());
1066 Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n'; 1069 Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n';
1067 const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements()); 1070 const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements());
1068 1071
1069 llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint()); 1072 llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint());
1070 for (int i=0; i<arguments->dim; i++) 1073 for (int i=0; i<arguments->dim; i++)
1079 } 1082 }
1080 1083
1081 // put data in d-array 1084 // put data in d-array
1082 llvm::Value* typeinfoarrayparam = new llvm::AllocaInst(llfnty->getParamType(j)->getContainedType(0),"_arguments_array",p->topallocapoint()); 1085 llvm::Value* typeinfoarrayparam = new llvm::AllocaInst(llfnty->getParamType(j)->getContainedType(0),"_arguments_array",p->topallocapoint());
1083 p->ir->CreateStore(DtoConstSize_t(vtype->getNumElements()), DtoGEPi(typeinfoarrayparam,0,0,"tmp")); 1086 p->ir->CreateStore(DtoConstSize_t(vtype->getNumElements()), DtoGEPi(typeinfoarrayparam,0,0,"tmp"));
1084 llvm::Value* casttypeinfomem = p->ir->CreateBitCast(typeinfomem, llvm::PointerType::get(typeinfotype), "tmp"); 1087 llvm::Value* casttypeinfomem = p->ir->CreateBitCast(typeinfomem, getPtrToType(typeinfotype), "tmp");
1085 p->ir->CreateStore(casttypeinfomem, DtoGEPi(typeinfoarrayparam,0,1,"tmp")); 1088 p->ir->CreateStore(casttypeinfomem, DtoGEPi(typeinfoarrayparam,0,1,"tmp"));
1086 1089
1087 // specify arguments 1090 // specify arguments
1088 llargs[j] = typeinfoarrayparam;; 1091 llargs[j] = typeinfoarrayparam;;
1089 j++; 1092 j++;
1090 llargs[j] = p->ir->CreateBitCast(mem, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp"); 1093 llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp");
1091 j++; 1094 j++;
1092 llargs.resize(nimplicit+2); 1095 llargs.resize(nimplicit+2);
1093 } 1096 }
1094 // normal function 1097 // normal function
1095 else { 1098 else {
1126 // void returns cannot not be named 1129 // void returns cannot not be named
1127 const char* varname = ""; 1130 const char* varname = "";
1128 if (llfnty->getReturnType() != llvm::Type::VoidTy) 1131 if (llfnty->getReturnType() != llvm::Type::VoidTy)
1129 varname = "tmp"; 1132 varname = "tmp";
1130 1133
1131 Logger::cout() << "Calling: " << *funcval << '\n'; 1134 //Logger::cout() << "Calling: " << *funcval << '\n';
1132 1135
1133 // call the function 1136 // call the function
1134 llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb()); 1137 llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb());
1135 llvm::Value* retllval = (retinptr) ? llargs[0] : call; 1138 llvm::Value* retllval = (retinptr) ? llargs[0] : call;
1136 1139
1137 if (retinptr && dfn && dfn->func && dfn->func->llvmRunTimeHack) { 1140 if (retinptr && dfn && dfn->func && dfn->func->llvmRunTimeHack) {
1138 const llvm::Type* rettype = llvm::PointerType::get(DtoType(type)); 1141 const llvm::Type* rettype = getPtrToType(DtoType(type));
1139 if (retllval->getType() != rettype) { 1142 if (retllval->getType() != rettype) {
1140 Logger::println("llvmRunTimeHack==true - force casting return value"); 1143 Logger::println("llvmRunTimeHack==true - force casting return value");
1141 Logger::cout() << "from: " << *retllval->getType() << " to: " << *rettype << '\n'; 1144 Logger::cout() << "from: " << *retllval->getType() << " to: " << *rettype << '\n';
1142 retllval = DtoBitCast(retllval, rettype); 1145 retllval = DtoBitCast(retllval, rettype);
1143 } 1146 }
1241 if (offset == 0) { 1244 if (offset == 0) {
1242 varmem = llvalue; 1245 varmem = llvalue;
1243 } 1246 }
1244 else { 1247 else {
1245 const llvm::Type* elemtype = llvalue->getType()->getContainedType(0)->getContainedType(0); 1248 const llvm::Type* elemtype = llvalue->getType()->getContainedType(0)->getContainedType(0);
1246 size_t elemsz = gTargetData->getTypeSize(elemtype); 1249 size_t elemsz = getABITypeSize(elemtype);
1247 varmem = DtoGEPi(llvalue, 0, offset / elemsz, "tmp"); 1250 varmem = DtoGEPi(llvalue, 0, offset / elemsz, "tmp");
1248 } 1251 }
1249 } 1252 }
1250 else if (offset == 0) { 1253 else if (offset == 0) {
1251 Logger::println("normal symoff"); 1254 Logger::println("normal symoff");
1386 } 1389 }
1387 llvm::Value* vthis = l->getRVal(); 1390 llvm::Value* vthis = l->getRVal();
1388 if (!vthis2) vthis2 = vthis; 1391 if (!vthis2) vthis2 = vthis;
1389 //unsigned cc = (unsigned)-1; 1392 //unsigned cc = (unsigned)-1;
1390 1393
1391 // virtual call 1394 // super call
1392 if (!fdecl->isFinal() && fdecl->isVirtual()) { 1395 if (e1->op == TOKsuper) {
1396 DtoForceDeclareDsymbol(fdecl);
1397 funcval = fdecl->llvmValue;
1398 assert(funcval);
1399 }
1400 // normal virtual call
1401 else if (fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())) {
1393 assert(fdecl->vtblIndex > 0); 1402 assert(fdecl->vtblIndex > 0);
1394 assert(e1type->ty == Tclass); 1403 assert(e1type->ty == Tclass);
1395 1404
1396 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 1405 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
1397 llvm::Value* vtblidx = llvm::ConstantInt::get(llvm::Type::Int32Ty, (size_t)fdecl->vtblIndex, false); 1406 llvm::Value* vtblidx = llvm::ConstantInt::get(llvm::Type::Int32Ty, (size_t)fdecl->vtblIndex, false);
1426 { 1435 {
1427 Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars()); 1436 Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars());
1428 LOG_SCOPE; 1437 LOG_SCOPE;
1429 1438
1430 if (VarDeclaration* vd = var->isVarDeclaration()) { 1439 if (VarDeclaration* vd = var->isVarDeclaration()) {
1431 llvm::Value* v = p->func()->decl->llvmThisVar; 1440 llvm::Value* v;
1441 v = p->func()->decl->llvmThisVar;
1432 if (llvm::isa<llvm::AllocaInst>(v)) 1442 if (llvm::isa<llvm::AllocaInst>(v))
1433 v = new llvm::LoadInst(v, "tmp", p->scopebb()); 1443 v = new llvm::LoadInst(v, "tmp", p->scopebb());
1434 return new DThisValue(vd, v); 1444 return new DThisValue(vd, v);
1435 } 1445 }
1436 1446
1816 post = new llvm::GetElementPtrInst(val, whichone, "tmp", p->scopebb()); 1826 post = new llvm::GetElementPtrInst(val, whichone, "tmp", p->scopebb());
1817 } 1827 }
1818 else if (e1type->isfloating()) 1828 else if (e1type->isfloating())
1819 { 1829 {
1820 assert(e2type->isfloating()); 1830 assert(e2type->isfloating());
1821 llvm::Value* one = llvm::ConstantFP::get(val->getType(), 1.0f); 1831 llvm::Value* one = llvm::ConstantFP::get(val->getType(), llvm::APFloat(1.0f));
1822 if (op == TOKplusplus) { 1832 if (op == TOKplusplus) {
1823 post = llvm::BinaryOperator::createAdd(val,one,"tmp",p->scopebb()); 1833 post = llvm::BinaryOperator::createAdd(val,one,"tmp",p->scopebb());
1824 } 1834 }
1825 else if (op == TOKminusminus) { 1835 else if (op == TOKminusminus) {
1826 post = llvm::BinaryOperator::createSub(val,one,"tmp",p->scopebb()); 1836 post = llvm::BinaryOperator::createSub(val,one,"tmp",p->scopebb());
1845 assert(newtype); 1855 assert(newtype);
1846 assert(!allocator && "custom allocators not yet supported"); 1856 assert(!allocator && "custom allocators not yet supported");
1847 1857
1848 Type* ntype = DtoDType(newtype); 1858 Type* ntype = DtoDType(newtype);
1849 1859
1860 if (ntype->ty == Tclass) {
1861 return DtoNewClass((TypeClass*)ntype, this);
1862 }
1863
1850 const llvm::Type* t = DtoType(ntype); 1864 const llvm::Type* t = DtoType(ntype);
1851 1865
1852 llvm::Value* emem = 0; 1866 llvm::Value* emem = 0;
1853 bool inplace = false; 1867 bool inplace = false;
1854 1868
1855 { 1869 if (ntype->ty == Tarray) {
1856 Logger::println("Allocating memory"); 1870 assert(arguments);
1857 LOG_SCOPE; 1871 if (arguments->dim == 1) {
1858 if (onstack) { 1872 DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
1859 assert(ntype->ty == Tclass); 1873 llvm::Value* dimval = sz->getRVal();
1860 emem = new llvm::AllocaInst(t->getContainedType(0),"tmp",p->topallocapoint()); 1874 Type* nnt = DtoDType(ntype->next);
1861 } 1875 if (nnt->ty == Tvoid)
1862 else if (ntype->ty == Tclass) { 1876 nnt = Type::tint8;
1863 emem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb()); 1877
1864 } 1878 if (p->topexp() && p->topexp()->e2 == this) {
1865 else if (ntype->ty == Tarray) { 1879 assert(p->topexp()->v);
1866 assert(arguments); 1880 emem = p->topexp()->v->getLVal();
1867 if (arguments->dim == 1) { 1881 DtoNewDynArray(emem, dimval, nnt);
1868 DValue* sz = ((Expression*)arguments->data[0])->toElem(p); 1882 inplace = true;
1869 llvm::Value* dimval = sz->getRVal();
1870 Type* nnt = DtoDType(ntype->next);
1871 if (nnt->ty == Tvoid)
1872 nnt = Type::tint8;
1873
1874 if (p->topexp() && p->topexp()->e2 == this) {
1875 assert(p->topexp()->v);
1876 emem = p->topexp()->v->getLVal();
1877 DtoNewDynArray(emem, dimval, nnt);
1878 inplace = true;
1879 }
1880 else {
1881 const llvm::Type* restype = DtoType(type);
1882 Logger::cout() << "restype = " << *restype << '\n';
1883 emem = new llvm::AllocaInst(restype,"newstorage",p->topallocapoint());
1884 DtoNewDynArray(emem, dimval, nnt);
1885 return new DVarValue(newtype, emem, true);
1886 }
1887 } 1883 }
1888 else { 1884 else {
1889 assert(0 && "num args to 'new' != 1"); 1885 const llvm::Type* restype = DtoType(type);
1886 Logger::cout() << "restype = " << *restype << '\n';
1887 emem = new llvm::AllocaInst(restype,"newstorage",p->topallocapoint());
1888 DtoNewDynArray(emem, dimval, nnt);
1889 return new DVarValue(newtype, emem, true);
1890 } 1890 }
1891 } 1891 }
1892 else { 1892 else {
1893 emem = new llvm::MallocInst(t,"tmp",p->scopebb()); 1893 assert(0 && "num args to 'new' != 1");
1894 } 1894 }
1895 } 1895 }
1896 1896 else {
1897 if (ntype->ty == Tclass) { 1897 emem = new llvm::MallocInst(t,"tmp",p->scopebb());
1898 // first apply the static initializer 1898 }
1899 TypeClass* tc = (TypeClass*)ntype; 1899
1900 DtoInitClass(tc, emem); 1900 if (ntype->ty == Tstruct) {
1901
1902 // set the this var for nested classes
1903 if (thisexp) {
1904 Logger::println("Resolving 'this' expression");
1905 LOG_SCOPE;
1906 DValue* thisval = thisexp->toElem(p);
1907 size_t idx = 2;
1908 idx += tc->sym->llvmIRStruct->interfaces.size();
1909 llvm::Value* dst = thisval->getRVal();
1910 llvm::Value* src = DtoGEPi(emem,0,idx,"tmp");
1911 Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
1912 DtoStore(dst, src);
1913 }
1914 else if (tc->sym->isNested())
1915 {
1916 Logger::println("Resolving nested context");
1917 LOG_SCOPE;
1918 size_t idx = 2;
1919 idx += tc->sym->llvmIRStruct->interfaces.size();
1920 llvm::Value* nest = p->func()->decl->llvmNested;
1921 if (!nest)
1922 nest = p->func()->decl->llvmThisVar;
1923 assert(nest);
1924 llvm::Value* gep = DtoGEPi(emem,0,idx,"tmp");
1925 nest = DtoBitCast(nest, gep->getType()->getContainedType(0));
1926 DtoStore(nest, gep);
1927 }
1928
1929 // then call constructor
1930 if (arguments) {
1931 Logger::println("Calling constructor");
1932 LOG_SCOPE;
1933 assert(member);
1934 assert(member->llvmValue);
1935 llvm::Function* fn = llvm::cast<llvm::Function>(member->llvmValue);
1936 TypeFunction* tf = (TypeFunction*)DtoDType(member->type);
1937
1938 std::vector<llvm::Value*> ctorargs;
1939 ctorargs.push_back(emem);
1940 for (size_t i=0; i<arguments->dim; ++i)
1941 {
1942 Expression* ex = (Expression*)arguments->data[i];
1943 Argument* fnarg = Argument::getNth(tf->parameters, i);
1944 DValue* argval = DtoArgument(fnarg, ex);
1945 llvm::Value* a = argval->getRVal();
1946 const llvm::Type* aty = fn->getFunctionType()->getParamType(i+1);
1947 if (a->getType() != aty) // this param might have type mismatch
1948 a = DtoBitCast(a, aty);
1949 ctorargs.push_back(a);
1950 }
1951 llvm::CallInst* call = new llvm::CallInst(fn, ctorargs.begin(), ctorargs.end(), "tmp", p->scopebb());
1952 call->setCallingConv(DtoCallingConv(LINKd));
1953 emem = call;
1954 }
1955 }
1956 else if (ntype->ty == Tstruct) {
1957 TypeStruct* ts = (TypeStruct*)ntype; 1901 TypeStruct* ts = (TypeStruct*)ntype;
1958 if (ts->isZeroInit()) { 1902 if (ts->isZeroInit()) {
1959 DtoStructZeroInit(emem); 1903 DtoStructZeroInit(emem);
1960 } 1904 }
1961 else { 1905 else {
2051 DValue* AssertExp::toElem(IRState* p) 1995 DValue* AssertExp::toElem(IRState* p)
2052 { 1996 {
2053 Logger::print("AssertExp::toElem: %s | %s\n", toChars(), type->toChars()); 1997 Logger::print("AssertExp::toElem: %s | %s\n", toChars(), type->toChars());
2054 LOG_SCOPE; 1998 LOG_SCOPE;
2055 1999
2056 DValue* u = e1->toElem(p); 2000 // condition
2057 DValue* m = msg ? msg->toElem(p) : NULL; 2001 DValue* cond = e1->toElem(p);
2058 2002
2059 DtoAssert(u->getRVal(), &loc, m); 2003 // create basic blocks
2060 2004 llvm::BasicBlock* oldend = p->scopeend();
2061 return 0; 2005 llvm::BasicBlock* assertbb = new llvm::BasicBlock("assert", p->topfunc(), oldend);
2006 llvm::BasicBlock* endbb = new llvm::BasicBlock("endassert", p->topfunc(), oldend);
2007
2008 // test condition
2009 llvm::Value* condval = cond->getRVal();
2010 condval = DtoBoolean(condval);
2011
2012 // branch
2013 new llvm::BranchInst(endbb, assertbb, condval, p->scopebb());
2014
2015 // call assert runtime functions
2016 p->scope() = IRScope(assertbb,endbb);
2017 DtoAssert(&loc, msg ? msg->toElem(p) : NULL);
2018
2019 if (!gIR->scopereturned())
2020 new llvm::BranchInst(endbb, p->scopebb());
2021
2022 // rewrite the scope
2023 p->scope() = IRScope(endbb,oldend);
2024
2025 // no meaningful return value
2026 return NULL;
2062 } 2027 }
2063 2028
2064 ////////////////////////////////////////////////////////////////////////////////////////// 2029 //////////////////////////////////////////////////////////////////////////////////////////
2065 2030
2066 DValue* NotExp::toElem(IRState* p) 2031 DValue* NotExp::toElem(IRState* p)
2190 DValue* HaltExp::toElem(IRState* p) 2155 DValue* HaltExp::toElem(IRState* p)
2191 { 2156 {
2192 Logger::print("HaltExp::toElem: %s | %s\n", toChars(), type->toChars()); 2157 Logger::print("HaltExp::toElem: %s | %s\n", toChars(), type->toChars());
2193 LOG_SCOPE; 2158 LOG_SCOPE;
2194 2159
2195 DtoAssert(DtoConstBool(false), &loc, NULL); 2160 DtoAssert(&loc, NULL);
2196 2161
2197 new llvm::UnreachableInst(p->scopebb()); 2162 new llvm::UnreachableInst(p->scopebb());
2198 return 0; 2163 return 0;
2199 } 2164 }
2200 2165
2205 Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars()); 2170 Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars());
2206 LOG_SCOPE; 2171 LOG_SCOPE;
2207 2172
2208 DValue* u = e1->toElem(p); 2173 DValue* u = e1->toElem(p);
2209 2174
2210 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 2175 const llvm::PointerType* int8ptrty = getPtrToType(llvm::Type::Int8Ty);
2211 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
2212
2213 const llvm::Type* int8ptrty = llvm::PointerType::get(llvm::Type::Int8Ty);
2214 2176
2215 llvm::Value* lval; 2177 llvm::Value* lval;
2216 if (p->topexp() && p->topexp()->e2 == this) { 2178 if (p->topexp() && p->topexp()->e2 == this) {
2217 assert(p->topexp()->v); 2179 assert(p->topexp()->v);
2218 lval = p->topexp()->v->getLVal(); 2180 lval = p->topexp()->v->getLVal();
2227 //uval = f->vthis; 2189 //uval = f->vthis;
2228 llvm::Value* nestvar = p->func()->decl->llvmNested; 2190 llvm::Value* nestvar = p->func()->decl->llvmNested;
2229 if (nestvar) 2191 if (nestvar)
2230 uval = nestvar; 2192 uval = nestvar;
2231 else 2193 else
2232 uval = llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); 2194 uval = llvm::ConstantPointerNull::get(int8ptrty);
2233 } 2195 }
2234 else { 2196 else {
2235 uval = u->getRVal(); 2197 uval = u->getRVal();
2236 } 2198 }
2237 2199
2238 llvm::Value* context = DtoGEP(lval,zero,zero,"tmp",p->scopebb()); 2200 llvm::Value* context = DtoGEPi(lval,0,0,"tmp");
2239 llvm::Value* castcontext = DtoBitCast(uval,int8ptrty); 2201 llvm::Value* castcontext = DtoBitCast(uval, int8ptrty);
2240 new llvm::StoreInst(castcontext, context, p->scopebb()); 2202 DtoStore(castcontext, context);
2241 2203
2242 llvm::Value* fptr = DtoGEP(lval,zero,one,"tmp",p->scopebb()); 2204 llvm::Value* fptr = DtoGEPi(lval,0,1,"tmp");
2243 2205
2244 assert(func->llvmValue); 2206 Logger::println("func: '%s'", func->toPrettyChars());
2245 llvm::Value* castfptr = DtoBitCast(func->llvmValue,fptr->getType()->getContainedType(0)); 2207
2246 new llvm::StoreInst(castfptr, fptr, p->scopebb()); 2208 llvm::Value* castfptr;
2209 if (func->isVirtual())
2210 castfptr = DtoVirtualFunctionPointer(u, func);
2211 else if (func->isAbstract())
2212 assert(0 && "TODO delegate to abstract method");
2213 else if (func->toParent()->isInterfaceDeclaration())
2214 assert(0 && "TODO delegate to interface method");
2215 else
2216 castfptr = func->llvmValue;
2217
2218 castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0));
2219 DtoStore(castfptr, fptr);
2247 2220
2248 return new DVarValue(type, lval, true); 2221 return new DVarValue(type, lval, true);
2249 } 2222 }
2250 2223
2251 ////////////////////////////////////////////////////////////////////////////////////////// 2224 //////////////////////////////////////////////////////////////////////////////////////////
2277 else { 2250 else {
2278 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; 2251 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
2279 if (t1->ty == Tpointer && v->isNull() && l->getType() != r->getType()) { 2252 if (t1->ty == Tpointer && v->isNull() && l->getType() != r->getType()) {
2280 r = llvm::ConstantPointerNull::get(isaPointer(l->getType())); 2253 r = llvm::ConstantPointerNull::get(isaPointer(l->getType()));
2281 } 2254 }
2282 Logger::cout() << "l = " << *l << " r = " << *r << '\n'; 2255 //Logger::cout() << "l = " << *l << " r = " << *r << '\n';
2283 eval = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb()); 2256 eval = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb());
2284 } 2257 }
2285 return new DImValue(type, eval); 2258 return new DImValue(type, eval);
2286 } 2259 }
2287 2260
2366 llvm::Value* zero = 0; 2339 llvm::Value* zero = 0;
2367 if (t->isintegral()) 2340 if (t->isintegral())
2368 zero = llvm::ConstantInt::get(val->getType(), 0, true); 2341 zero = llvm::ConstantInt::get(val->getType(), 0, true);
2369 else if (t->isfloating()) { 2342 else if (t->isfloating()) {
2370 if (t->ty == Tfloat32 || t->ty == Timaginary32) 2343 if (t->ty == Tfloat32 || t->ty == Timaginary32)
2371 zero = llvm::ConstantFP::get(val->getType(), float(0)); 2344 zero = llvm::ConstantFP::get(val->getType(), llvm::APFloat(0.0f));
2372 else if (t->ty == Tfloat64 || t->ty == Tfloat80 || t->ty == Timaginary64 || t->ty == Timaginary80) 2345 else if (t->ty == Tfloat64 || t->ty == Tfloat80 || t->ty == Timaginary64 || t->ty == Timaginary80)
2373 zero = llvm::ConstantFP::get(val->getType(), double(0)); 2346 zero = llvm::ConstantFP::get(val->getType(), llvm::APFloat(0.0));
2374 else 2347 else
2375 assert(0); 2348 assert(0);
2376 } 2349 }
2377 else 2350 else
2378 assert(0); 2351 assert(0);
2617 if (!vx) continue; 2590 if (!vx) continue;
2618 tys.push_back(DtoType(vx->type)); 2591 tys.push_back(DtoType(vx->type));
2619 } 2592 }
2620 const llvm::StructType* t = llvm::StructType::get(tys); 2593 const llvm::StructType* t = llvm::StructType::get(tys);
2621 if (t != llt) { 2594 if (t != llt) {
2622 if (gTargetData->getTypeSize(t) != gTargetData->getTypeSize(llt)) { 2595 if (getABITypeSize(t) != getABITypeSize(llt)) {
2623 Logger::cout() << "got size " << gTargetData->getTypeSize(t) << ", expected " << gTargetData->getTypeSize(llt) << '\n'; 2596 Logger::cout() << "got size " << getABITypeSize(t) << ", expected " << getABITypeSize(llt) << '\n';
2624 assert(0 && "type size mismatch"); 2597 assert(0 && "type size mismatch");
2625 } 2598 }
2626 sptr = p->ir->CreateBitCast(sptr, llvm::PointerType::get(t), "tmp"); 2599 sptr = DtoBitCast(sptr, getPtrToType(t));
2627 Logger::cout() << "sptr type is now: " << *t << '\n'; 2600 Logger::cout() << "sptr type is now: " << *t << '\n';
2628 } 2601 }
2629 } 2602 }
2630 2603
2631 // build 2604 // build