Mercurial > projects > ldc
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); |