comparison gen/toir.cpp @ 109:5ab8e92611f9 trunk

[svn r113] Added initial support for associative arrays (AAs). Fixed some problems with the string runtime support functions. Fixed initialization of array of structs. Fixed slice assignment where LHS is slice but RHS is dynamic array. Fixed problems with result of assignment expressions. Fixed foreach problems with key type mismatches.
author lindquist
date Wed, 21 Nov 2007 04:13:15 +0100
parents 288fe1029e1f
children 27b9f749d9fe
comparison
equal deleted inserted replaced
108:288fe1029e1f 109:5ab8e92611f9
28 #include "gen/structs.h" 28 #include "gen/structs.h"
29 #include "gen/classes.h" 29 #include "gen/classes.h"
30 #include "gen/typeinf.h" 30 #include "gen/typeinf.h"
31 #include "gen/complex.h" 31 #include "gen/complex.h"
32 #include "gen/dvalue.h" 32 #include "gen/dvalue.h"
33 #include "gen/aa.h"
33 34
34 ////////////////////////////////////////////////////////////////////////////////////////// 35 //////////////////////////////////////////////////////////////////////////////////////////
35 36
36 DValue* DeclarationExp::toElem(IRState* p) 37 DValue* DeclarationExp::toElem(IRState* p)
37 { 38 {
64 const llvm::Type* lltype = DtoType(vd->type); 65 const llvm::Type* lltype = DtoType(vd->type);
65 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); 66 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint());
66 //allocainst->setAlignment(vd->type->alignsize()); // TODO 67 //allocainst->setAlignment(vd->type->alignsize()); // TODO
67 vd->llvmValue = allocainst; 68 vd->llvmValue = allocainst;
68 } 69 }
70
69 Logger::cout() << "llvm value for decl: " << *vd->llvmValue << '\n'; 71 Logger::cout() << "llvm value for decl: " << *vd->llvmValue << '\n';
70 DValue* ie = DtoInitializer(vd->init); 72 DValue* ie = DtoInitializer(vd->init);
71 } 73 }
72 74
73 return new DVarValue(vd, vd->llvmValue, true); 75 return new DVarValue(vd, vd->llvmValue, true);
407 return new DVarValue(type, tmpmem, true); 409 return new DVarValue(type, tmpmem, true);
408 } 410 }
409 else if (p->topexp()->e2 == this) { 411 else if (p->topexp()->e2 == this) {
410 DValue* arr = p->topexp()->v; 412 DValue* arr = p->topexp()->v;
411 assert(arr); 413 assert(arr);
412 DtoSetArray(arr->getLVal(), clen, arrptr); 414 if (arr->isSlice()) {
413 return new DImValue(type, arr->getLVal(), true); 415 return new DSliceValue(type, clen, arrptr);
416 }
417 else {
418 DtoSetArray(arr->getRVal(), clen, arrptr);
419 return new DImValue(type, arr->getLVal(), true);
420 }
414 } 421 }
415 assert(0); 422 assert(0);
416 } 423 }
417 else if (dtype->ty == Tsarray) { 424 else if (dtype->ty == Tsarray) {
418 const llvm::Type* dstType = llvm::PointerType::get(llvm::ArrayType::get(ct, len)); 425 const llvm::Type* dstType = llvm::PointerType::get(llvm::ArrayType::get(ct, len));
488 DtoAssign(l, r); 495 DtoAssign(l, r);
489 } 496 }
490 497
491 if (l->isSlice() || l->isComplex()) 498 if (l->isSlice() || l->isComplex())
492 return l; 499 return l;
493 return new DImValue(type, l->getRVal()); 500
501 llvm::Value* v;
502 if (l->isVar() && l->isVar()->lval)
503 v = l->getLVal();
504 else
505 v = l->getRVal();
506
507 return new DVarValue(type, v, true);
494 } 508 }
495 509
496 ////////////////////////////////////////////////////////////////////////////////////////// 510 //////////////////////////////////////////////////////////////////////////////////////////
497 511
498 DValue* AddExp::toElem(IRState* p) 512 DValue* AddExp::toElem(IRState* p)
891 if (topexp && topexp->e2 == this) { 905 if (topexp && topexp->e2 == this) {
892 assert(topexp->v); 906 assert(topexp->v);
893 llvm::Value* tlv = topexp->v->getLVal(); 907 llvm::Value* tlv = topexp->v->getLVal();
894 assert(isaStruct(tlv->getType()->getContainedType(0))); 908 assert(isaStruct(tlv->getType()->getContainedType(0)));
895 llargs[j] = tlv; 909 llargs[j] = tlv;
896 if (DtoIsPassedByRef(tf->next)) { 910 isInPlace = true;
911 /*if (DtoIsPassedByRef(tf->next)) {
897 isInPlace = true; 912 isInPlace = true;
898 } 913 }
899 else 914 else
900 assert(0); 915 assert(0);*/
901 } 916 }
902 else { 917 else {
903 llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint()); 918 llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint());
904 } 919 }
920
921 if (dfn && dfn->func && dfn->func->llvmRunTimeHack) {
922 const llvm::Type* rettype = llvm::PointerType::get(DtoType(type));
923 if (llargs[j]->getType() != llfnty->getParamType(j)) {
924 Logger::println("llvmRunTimeHack==true - force casting return value param");
925 Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n';
926 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j));
927 }
928 }
929
905 ++j; 930 ++j;
906 ++argiter; 931 ++argiter;
907 } 932 }
908 933
909 // this arguments 934 // this arguments
1002 for (int i=0; i<arguments->dim; i++,j++) { 1027 for (int i=0; i<arguments->dim; i++,j++) {
1003 Argument* fnarg = Argument::getNth(tf->parameters, i); 1028 Argument* fnarg = Argument::getNth(tf->parameters, i);
1004 llargs[j] = DtoArgument(llfnty->getParamType(j), fnarg, (Expression*)arguments->data[i]); 1029 llargs[j] = DtoArgument(llfnty->getParamType(j), fnarg, (Expression*)arguments->data[i]);
1005 // this hack is necessary :/ 1030 // this hack is necessary :/
1006 if (dfn && dfn->func && dfn->func->llvmRunTimeHack) { 1031 if (dfn && dfn->func && dfn->func->llvmRunTimeHack) {
1007 Logger::println("llvmRunTimeHack==true - force casting argument"); 1032 if (llfnty->getParamType(j) != NULL) {
1008 if (llargs[j]->getType() != llfnty->getParamType(j)) { 1033 if (llargs[j]->getType() != llfnty->getParamType(j)) {
1009 Logger::cout() << "from: " << *llargs[j]->getType() << " to: " << *llfnty->getParamType(j); 1034 Logger::println("llvmRunTimeHack==true - force casting argument");
1010 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j)); 1035 Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n';
1036 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j));
1037 }
1011 } 1038 }
1012 } 1039 }
1013 } 1040 }
1014 Logger::println("%d params passed", n); 1041 Logger::println("%d params passed", n);
1015 for (int i=0; i<n; ++i) { 1042 for (int i=0; i<n; ++i) {
1022 // void returns cannot not be named 1049 // void returns cannot not be named
1023 const char* varname = ""; 1050 const char* varname = "";
1024 if (llfnty->getReturnType() != llvm::Type::VoidTy) 1051 if (llfnty->getReturnType() != llvm::Type::VoidTy)
1025 varname = "tmp"; 1052 varname = "tmp";
1026 1053
1027 Logger::cout() << "Calling: " << *funcval->getType() << '\n'; 1054 Logger::cout() << "Calling: " << *funcval << '\n';
1028 1055
1029 // call the function 1056 // call the function
1030 llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb()); 1057 llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb());
1031 llvm::Value* retllval = (retinptr) ? llargs[0] : call; 1058 llvm::Value* retllval = (retinptr) ? llargs[0] : call;
1059
1060 if (retinptr && dfn && dfn->func && dfn->func->llvmRunTimeHack) {
1061 const llvm::Type* rettype = llvm::PointerType::get(DtoType(type));
1062 if (retllval->getType() != rettype) {
1063 Logger::println("llvmRunTimeHack==true - force casting return value");
1064 Logger::cout() << "from: " << *retllval->getType() << " to: " << *rettype << '\n';
1065 retllval = DtoBitCast(retllval, rettype);
1066 }
1067 }
1032 1068
1033 // set calling convention 1069 // set calling convention
1034 if (dfn && dfn->func) { 1070 if (dfn && dfn->func) {
1035 int li = dfn->func->llvmInternal; 1071 int li = dfn->func->llvmInternal;
1036 if (li != LLVMintrinsic && li != LLVMva_start && li != LLVMva_intrinsic) { 1072 if (li != LLVMintrinsic && li != LLVMva_start && li != LLVMva_intrinsic) {
1326 else if (e1type->ty == Tarray) { 1362 else if (e1type->ty == Tarray) {
1327 arrptr = DtoGEP(l->getLVal(),zero,one,"tmp",p->scopebb()); 1363 arrptr = DtoGEP(l->getLVal(),zero,one,"tmp",p->scopebb());
1328 arrptr = new llvm::LoadInst(arrptr,"tmp",p->scopebb()); 1364 arrptr = new llvm::LoadInst(arrptr,"tmp",p->scopebb());
1329 arrptr = new llvm::GetElementPtrInst(arrptr,r->getRVal(),"tmp",p->scopebb()); 1365 arrptr = new llvm::GetElementPtrInst(arrptr,r->getRVal(),"tmp",p->scopebb());
1330 } 1366 }
1331 assert(arrptr); 1367 else if (e1type->ty == Taarray) {
1368 return DtoAAIndex(type, l, r);
1369 }
1370 else {
1371 Logger::println("invalid index exp! e1type: %s", e1type->toChars());
1372 assert(0);
1373 }
1332 return new DVarValue(type, arrptr, true); 1374 return new DVarValue(type, arrptr, true);
1333 } 1375 }
1334 1376
1335 ////////////////////////////////////////////////////////////////////////////////////////// 1377 //////////////////////////////////////////////////////////////////////////////////////////
1336 1378
2450 return llvm::ConstantStruct::get(st,vals); 2492 return llvm::ConstantStruct::get(st,vals);
2451 } 2493 }
2452 2494
2453 ////////////////////////////////////////////////////////////////////////////////////////// 2495 //////////////////////////////////////////////////////////////////////////////////////////
2454 2496
2497 DValue* InExp::toElem(IRState* p)
2498 {
2499 Logger::print("InExp::toElem: %s | %s\n", toChars(), type->toChars());
2500 LOG_SCOPE;
2501
2502 DValue* key = e1->toElem(p);
2503 DValue* aa = e2->toElem(p);
2504
2505 return DtoAAIn(type, aa, key);
2506 }
2507
2508 //////////////////////////////////////////////////////////////////////////////////////////
2509
2455 #define STUB(x) DValue *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; } 2510 #define STUB(x) DValue *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; }
2456 //STUB(IdentityExp); 2511 //STUB(IdentityExp);
2457 //STUB(CondExp); 2512 //STUB(CondExp);
2458 //STUB(EqualExp); 2513 //STUB(EqualExp);
2459 STUB(InExp); 2514 //STUB(InExp);
2460 //STUB(CmpExp); 2515 //STUB(CmpExp);
2461 //STUB(AndAndExp); 2516 //STUB(AndAndExp);
2462 //STUB(OrOrExp); 2517 //STUB(OrOrExp);
2463 //STUB(AndExp); 2518 //STUB(AndExp);
2464 //STUB(AndAssignExp); 2519 //STUB(AndAssignExp);