Mercurial > projects > ldc
comparison gen/toir.cpp @ 244:a95056b3c996 trunk
[svn r261] Fixed debug info for integer and floating local variables, can now be inspected in GDB.
Did a lot of smaller cleans up here and there.
Replaced more llvm::Foo with LLFoo for common stuff.
Split up tollvm.cpp.
author | lindquist |
---|---|
date | Mon, 09 Jun 2008 09:37:08 +0200 |
parents | 4d006f7b2ada |
children | d61ce72c39ab |
comparison
equal
deleted
inserted
replaced
243:4d006f7b2ada | 244:a95056b3c996 |
---|---|
22 #include "port.h" | 22 #include "port.h" |
23 | 23 |
24 #include "gen/irstate.h" | 24 #include "gen/irstate.h" |
25 #include "gen/logger.h" | 25 #include "gen/logger.h" |
26 #include "gen/tollvm.h" | 26 #include "gen/tollvm.h" |
27 #include "gen/llvmhelpers.h" | |
27 #include "gen/runtime.h" | 28 #include "gen/runtime.h" |
28 #include "gen/arrays.h" | 29 #include "gen/arrays.h" |
29 #include "gen/structs.h" | 30 #include "gen/structs.h" |
30 #include "gen/classes.h" | 31 #include "gen/classes.h" |
31 #include "gen/typeinf.h" | 32 #include "gen/typeinf.h" |
32 #include "gen/complex.h" | 33 #include "gen/complex.h" |
33 #include "gen/dvalue.h" | 34 #include "gen/dvalue.h" |
34 #include "gen/aa.h" | 35 #include "gen/aa.h" |
35 #include "gen/functions.h" | 36 #include "gen/functions.h" |
37 #include "gen/todebug.h" | |
36 | 38 |
37 ////////////////////////////////////////////////////////////////////////////////////////// | 39 ////////////////////////////////////////////////////////////////////////////////////////// |
38 | 40 |
39 DValue* DeclarationExp::toElem(IRState* p) | 41 DValue* DeclarationExp::toElem(IRState* p) |
40 { | 42 { |
73 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); | 75 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); |
74 //allocainst->setAlignment(vd->type->alignsize()); // TODO | 76 //allocainst->setAlignment(vd->type->alignsize()); // TODO |
75 assert(!vd->ir.irLocal); | 77 assert(!vd->ir.irLocal); |
76 vd->ir.irLocal = new IrLocal(vd); | 78 vd->ir.irLocal = new IrLocal(vd); |
77 vd->ir.irLocal->value = allocainst; | 79 vd->ir.irLocal->value = allocainst; |
80 | |
81 if (global.params.symdebug && (vd->type->isintegral() || vd->type->isfloating())) | |
82 { | |
83 LLGlobalVariable* cu = DtoDwarfCompileUnit(vd->getModule()); | |
84 LLGlobalVariable* bt = DtoDwarfBasicType(vd->type, cu); | |
85 LLGlobalVariable* vdesc = DtoDwarfVariable(vd, bt); | |
86 DtoDwarfDeclare(allocainst, vdesc); | |
87 } | |
78 } | 88 } |
79 | 89 |
80 Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n'; | 90 Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n'; |
81 DValue* ie = DtoInitializer(vd->init); | 91 DValue* ie = DtoInitializer(vd->init); |
82 } | 92 } |
313 if (isaPointer(t)) { | 323 if (isaPointer(t)) { |
314 Logger::println("pointer"); | 324 Logger::println("pointer"); |
315 LLConstant* i = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)value,false); | 325 LLConstant* i = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)value,false); |
316 return llvm::ConstantExpr::getIntToPtr(i, t); | 326 return llvm::ConstantExpr::getIntToPtr(i, t); |
317 } | 327 } |
318 assert(llvm::isa<llvm::IntegerType>(t)); | 328 assert(llvm::isa<LLIntegerType>(t)); |
319 LLConstant* c = llvm::ConstantInt::get(t,(uint64_t)value,!type->isunsigned()); | 329 LLConstant* c = llvm::ConstantInt::get(t,(uint64_t)value,!type->isunsigned()); |
320 assert(c); | 330 assert(c); |
321 Logger::cout() << "value = " << *c << '\n'; | 331 Logger::cout() << "value = " << *c << '\n'; |
322 return c; | 332 return c; |
323 } | 333 } |
408 | 418 |
409 Type* dtype = DtoDType(type); | 419 Type* dtype = DtoDType(type); |
410 Type* cty = DtoDType(dtype->next); | 420 Type* cty = DtoDType(dtype->next); |
411 | 421 |
412 const LLType* ct = DtoType(cty); | 422 const LLType* ct = DtoType(cty); |
413 if (ct == llvm::Type::VoidTy) | 423 if (ct == LLType::VoidTy) |
414 ct = llvm::Type::Int8Ty; | 424 ct = LLType::Int8Ty; |
415 //printf("ct = %s\n", type->next->toChars()); | 425 //printf("ct = %s\n", type->next->toChars()); |
416 const llvm::ArrayType* at = llvm::ArrayType::get(ct,len+1); | 426 const LLArrayType* at = LLArrayType::get(ct,len+1); |
417 | 427 |
418 LLConstant* _init; | 428 LLConstant* _init; |
419 if (cty->size() == 1) { | 429 if (cty->size() == 1) { |
420 uint8_t* str = (uint8_t*)string; | 430 uint8_t* str = (uint8_t*)string; |
421 std::string cont((char*)str, len); | 431 std::string cont((char*)str, len); |
444 | 454 |
445 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; | 455 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; |
446 Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n'; | 456 Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n'; |
447 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,".stringliteral",gIR->module); | 457 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,".stringliteral",gIR->module); |
448 | 458 |
449 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 459 llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false); |
450 LLConstant* idxs[2] = { zero, zero }; | 460 LLConstant* idxs[2] = { zero, zero }; |
451 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); | 461 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); |
452 | 462 |
453 if (dtype->ty == Tarray) { | 463 if (dtype->ty == Tarray) { |
454 LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false); | 464 LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false); |
469 } | 479 } |
470 } | 480 } |
471 assert(0); | 481 assert(0); |
472 } | 482 } |
473 else if (dtype->ty == Tsarray) { | 483 else if (dtype->ty == Tsarray) { |
474 const LLType* dstType = getPtrToType(llvm::ArrayType::get(ct, len)); | 484 const LLType* dstType = getPtrToType(LLArrayType::get(ct, len)); |
475 LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType); | 485 LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType); |
476 return new DVarValue(type, emem, true); | 486 return new DVarValue(type, emem, true); |
477 } | 487 } |
478 else if (dtype->ty == Tpointer) { | 488 else if (dtype->ty == Tpointer) { |
479 return new DImValue(type, arrptr); | 489 return new DImValue(type, arrptr); |
495 | 505 |
496 bool nullterm = (t->ty != Tsarray); | 506 bool nullterm = (t->ty != Tsarray); |
497 size_t endlen = nullterm ? len+1 : len; | 507 size_t endlen = nullterm ? len+1 : len; |
498 | 508 |
499 const LLType* ct = DtoType(cty); | 509 const LLType* ct = DtoType(cty); |
500 const llvm::ArrayType* at = llvm::ArrayType::get(ct,endlen); | 510 const LLArrayType* at = LLArrayType::get(ct,endlen); |
501 | 511 |
502 LLConstant* _init; | 512 LLConstant* _init; |
503 if (cty->size() == 1) { | 513 if (cty->size() == 1) { |
504 uint8_t* str = (uint8_t*)string; | 514 uint8_t* str = (uint8_t*)string; |
505 std::string cont((char*)str, len); | 515 std::string cont((char*)str, len); |
534 } | 544 } |
535 | 545 |
536 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; | 546 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; |
537 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,".stringliteral",gIR->module); | 547 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,".stringliteral",gIR->module); |
538 | 548 |
539 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 549 llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false); |
540 LLConstant* idxs[2] = { zero, zero }; | 550 LLConstant* idxs[2] = { zero, zero }; |
541 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); | 551 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); |
542 | 552 |
543 if (t->ty == Tpointer) { | 553 if (t->ty == Tpointer) { |
544 return arrptr; | 554 return arrptr; |
878 | 888 |
879 TypeFunction* tf = 0; | 889 TypeFunction* tf = 0; |
880 Type* e1type = DtoDType(e1->type); | 890 Type* e1type = DtoDType(e1->type); |
881 | 891 |
882 bool delegateCall = false; | 892 bool delegateCall = false; |
883 LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false); | |
884 LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty,1,false); | |
885 LINK dlink = LINKd; | 893 LINK dlink = LINKd; |
886 | 894 |
887 // hidden struct return parameter handling | 895 // hidden struct return parameter handling |
888 bool retinptr = false; | 896 bool retinptr = false; |
889 | 897 |
950 //Argument* fnarg = Argument::getNth(tf->parameters, 0); | 958 //Argument* fnarg = Argument::getNth(tf->parameters, 0); |
951 Expression* exp = (Expression*)arguments->data[0]; | 959 Expression* exp = (Expression*)arguments->data[0]; |
952 DValue* expv = exp->toElem(p); | 960 DValue* expv = exp->toElem(p); |
953 if (expv->getType()->toBasetype()->ty != Tint32) | 961 if (expv->getType()->toBasetype()->ty != Tint32) |
954 expv = DtoCast(expv, Type::tint32); | 962 expv = DtoCast(expv, Type::tint32); |
955 LLValue* alloc = new llvm::AllocaInst(llvm::Type::Int8Ty, expv->getRVal(), "alloca", p->scopebb()); | 963 LLValue* alloc = new llvm::AllocaInst(LLType::Int8Ty, expv->getRVal(), "alloca", p->scopebb()); |
956 // done | 964 // done |
957 return new DImValue(type, alloc); | 965 return new DImValue(type, alloc); |
958 } | 966 } |
959 } | 967 } |
960 | 968 |
970 | 978 |
971 LLValue* funcval = fn->getRVal(); | 979 LLValue* funcval = fn->getRVal(); |
972 assert(funcval != 0); | 980 assert(funcval != 0); |
973 std::vector<LLValue*> llargs(n, 0); | 981 std::vector<LLValue*> llargs(n, 0); |
974 | 982 |
975 const llvm::FunctionType* llfnty = 0; | 983 const LLFunctionType* llfnty = 0; |
976 | 984 |
977 // TODO: review the stuff below, using the llvm type to choose seem like a bad idea. the D type should be used. | 985 // TODO: review the stuff below, using the llvm type to choose seem like a bad idea. the D type should be used. |
978 // | 986 // |
979 // normal function call | 987 // normal function call |
980 if (llvm::isa<llvm::FunctionType>(funcval->getType())) { | 988 if (llvm::isa<LLFunctionType>(funcval->getType())) { |
981 llfnty = llvm::cast<llvm::FunctionType>(funcval->getType()); | 989 llfnty = llvm::cast<LLFunctionType>(funcval->getType()); |
982 } | 990 } |
983 // pointer to something | 991 // pointer to something |
984 else if (isaPointer(funcval->getType())) { | 992 else if (isaPointer(funcval->getType())) { |
985 // pointer to function pointer - I think this not really supposed to happen, but does :/ | 993 // pointer to function pointer - I think this not really supposed to happen, but does :/ |
986 // seems like sometimes we get a func* other times a func** | 994 // seems like sometimes we get a func* other times a func** |
987 if (isaPointer(funcval->getType()->getContainedType(0))) { | 995 if (isaPointer(funcval->getType()->getContainedType(0))) { |
988 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); | 996 funcval = DtoLoad(funcval); |
989 } | 997 } |
990 // function pointer | 998 // function pointer |
991 if (llvm::isa<llvm::FunctionType>(funcval->getType()->getContainedType(0))) { | 999 if (llvm::isa<LLFunctionType>(funcval->getType()->getContainedType(0))) { |
992 //Logger::cout() << "function pointer type:\n" << *funcval << '\n'; | 1000 //Logger::cout() << "function pointer type:\n" << *funcval << '\n'; |
993 llfnty = llvm::cast<llvm::FunctionType>(funcval->getType()->getContainedType(0)); | 1001 llfnty = llvm::cast<LLFunctionType>(funcval->getType()->getContainedType(0)); |
994 } | 1002 } |
995 // struct pointer - delegate | 1003 // struct pointer - delegate |
996 else if (isaStruct(funcval->getType()->getContainedType(0))) { | 1004 else if (isaStruct(funcval->getType()->getContainedType(0))) { |
997 funcval = DtoGEP(funcval,zero,one,"tmp",p->scopebb()); | 1005 funcval = DtoGEPi(funcval,0,1); |
998 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); | 1006 funcval = DtoLoad(funcval); |
999 const LLType* ty = funcval->getType()->getContainedType(0); | 1007 const LLType* ty = funcval->getType()->getContainedType(0); |
1000 llfnty = llvm::cast<llvm::FunctionType>(ty); | 1008 llfnty = llvm::cast<LLFunctionType>(ty); |
1001 } | 1009 } |
1002 // unknown | 1010 // unknown |
1003 else { | 1011 else { |
1004 Logger::cout() << "what kind of pointer are we calling? : " << *funcval->getType() << '\n'; | 1012 Logger::cout() << "what kind of pointer are we calling? : " << *funcval->getType() << '\n'; |
1005 } | 1013 } |
1009 } | 1017 } |
1010 assert(llfnty); | 1018 assert(llfnty); |
1011 //Logger::cout() << "Function LLVM type: " << *llfnty << '\n'; | 1019 //Logger::cout() << "Function LLVM type: " << *llfnty << '\n'; |
1012 | 1020 |
1013 // argument handling | 1021 // argument handling |
1014 llvm::FunctionType::param_iterator argiter = llfnty->param_begin(); | 1022 LLFunctionType::param_iterator argiter = llfnty->param_begin(); |
1015 int j = 0; | 1023 int j = 0; |
1016 | 1024 |
1017 IRExp* topexp = p->topexp(); | 1025 IRExp* topexp = p->topexp(); |
1018 | 1026 |
1019 bool isInPlace = false; | 1027 bool isInPlace = false; |
1067 ++argiter; | 1075 ++argiter; |
1068 } | 1076 } |
1069 // delegate context arguments | 1077 // delegate context arguments |
1070 else if (delegateCall) { | 1078 else if (delegateCall) { |
1071 Logger::println("Delegate Call"); | 1079 Logger::println("Delegate Call"); |
1072 LLValue* contextptr = DtoGEP(fn->getRVal(),zero,zero,"tmp",p->scopebb()); | 1080 LLValue* contextptr = DtoGEPi(fn->getRVal(),0,0); |
1073 llargs[j] = new llvm::LoadInst(contextptr,"tmp",p->scopebb()); | 1081 llargs[j] = DtoLoad(contextptr); |
1074 ++j; | 1082 ++j; |
1075 ++argiter; | 1083 ++argiter; |
1076 } | 1084 } |
1077 // nested call | 1085 // nested call |
1078 else if (dfn && dfn->func && dfn->func->isNested()) { | 1086 else if (dfn && dfn->func && dfn->func->isNested()) { |
1079 Logger::println("Nested Call"); | 1087 Logger::println("Nested Call"); |
1080 LLValue* contextptr = DtoNestedContext(dfn->func->toParent2()->isFuncDeclaration()); | 1088 LLValue* contextptr = DtoNestedContext(dfn->func->toParent2()->isFuncDeclaration()); |
1081 if (!contextptr) | 1089 if (!contextptr) |
1082 contextptr = llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)); | 1090 contextptr = llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)); |
1083 llargs[j] = DtoBitCast(contextptr, getPtrToType(llvm::Type::Int8Ty)); | 1091 llargs[j] = DtoBitCast(contextptr, getPtrToType(LLType::Int8Ty)); |
1084 ++j; | 1092 ++j; |
1085 ++argiter; | 1093 ++argiter; |
1086 } | 1094 } |
1087 | 1095 |
1088 // va arg function special argument passing | 1096 // va arg function special argument passing |
1092 for (int i=0; i<n; i++,j++) | 1100 for (int i=0; i<n; i++,j++) |
1093 { | 1101 { |
1094 Argument* fnarg = Argument::getNth(tf->parameters, i); | 1102 Argument* fnarg = Argument::getNth(tf->parameters, i); |
1095 Expression* exp = (Expression*)arguments->data[i]; | 1103 Expression* exp = (Expression*)arguments->data[i]; |
1096 DValue* expelem = exp->toElem(p); | 1104 DValue* expelem = exp->toElem(p); |
1097 llargs[j] = DtoBitCast(expelem->getLVal(), getPtrToType(llvm::Type::Int8Ty)); | 1105 llargs[j] = DtoBitCast(expelem->getLVal(), getPtrToType(LLType::Int8Ty)); |
1098 } | 1106 } |
1099 } | 1107 } |
1100 // d variadic function | 1108 // d variadic function |
1101 else if (tf->linkage == LINKd && tf->varargs == 1) | 1109 else if (tf->linkage == LINKd && tf->varargs == 1) |
1102 { | 1110 { |
1115 { | 1123 { |
1116 Argument* argu = Argument::getNth(tf->parameters, i); | 1124 Argument* argu = Argument::getNth(tf->parameters, i); |
1117 Expression* argexp = (Expression*)arguments->data[i]; | 1125 Expression* argexp = (Expression*)arguments->data[i]; |
1118 vtypes.push_back(DtoType(argexp->type)); | 1126 vtypes.push_back(DtoType(argexp->type)); |
1119 } | 1127 } |
1120 const llvm::StructType* vtype = llvm::StructType::get(vtypes); | 1128 const LLStructType* vtype = LLStructType::get(vtypes); |
1121 Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n'; | 1129 Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n'; |
1122 LLValue* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint()); | 1130 LLValue* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint()); |
1123 | 1131 |
1124 // store arguments in the struct | 1132 // store arguments in the struct |
1125 for (int i=begin,k=0; i<arguments->dim; i++,k++) | 1133 for (int i=begin,k=0; i<arguments->dim; i++,k++) |
1131 } | 1139 } |
1132 | 1140 |
1133 // build type info array | 1141 // build type info array |
1134 assert(Type::typeinfo->ir.irStruct->constInit); | 1142 assert(Type::typeinfo->ir.irStruct->constInit); |
1135 const LLType* typeinfotype = DtoType(Type::typeinfo->type); | 1143 const LLType* typeinfotype = DtoType(Type::typeinfo->type); |
1136 const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements()); | 1144 const LLArrayType* typeinfoarraytype = LLArrayType::get(typeinfotype,vtype->getNumElements()); |
1137 | 1145 |
1138 llvm::GlobalVariable* typeinfomem = | 1146 llvm::GlobalVariable* typeinfomem = |
1139 new llvm::GlobalVariable(typeinfoarraytype, true, llvm::GlobalValue::InternalLinkage, NULL, "._arguments.storage", gIR->module); | 1147 new llvm::GlobalVariable(typeinfoarraytype, true, llvm::GlobalValue::InternalLinkage, NULL, "._arguments.storage", gIR->module); |
1140 Logger::cout() << "_arguments storage: " << *typeinfomem << '\n'; | 1148 Logger::cout() << "_arguments storage: " << *typeinfomem << '\n'; |
1141 | 1149 |
1160 true, llvm::GlobalValue::InternalLinkage, tiinits, "._arguments.array", gIR->module); | 1168 true, llvm::GlobalValue::InternalLinkage, tiinits, "._arguments.array", gIR->module); |
1161 | 1169 |
1162 // specify arguments | 1170 // specify arguments |
1163 llargs[j] = typeinfoarrayparam;; | 1171 llargs[j] = typeinfoarrayparam;; |
1164 j++; | 1172 j++; |
1165 llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp"); | 1173 llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(LLType::Int8Ty), "tmp"); |
1166 j++; | 1174 j++; |
1167 | 1175 |
1168 // pass non variadic args | 1176 // pass non variadic args |
1169 for (int i=0; i<begin; i++) | 1177 for (int i=0; i<begin; i++) |
1170 { | 1178 { |
1226 } | 1234 } |
1227 #endif | 1235 #endif |
1228 | 1236 |
1229 // void returns cannot not be named | 1237 // void returns cannot not be named |
1230 const char* varname = ""; | 1238 const char* varname = ""; |
1231 if (llfnty->getReturnType() != llvm::Type::VoidTy) | 1239 if (llfnty->getReturnType() != LLType::VoidTy) |
1232 varname = "tmp"; | 1240 varname = "tmp"; |
1233 | 1241 |
1234 //Logger::cout() << "Calling: " << *funcval << '\n'; | 1242 //Logger::cout() << "Calling: " << *funcval << '\n'; |
1235 | 1243 |
1236 // call the function | 1244 // call the function |
1423 // normal virtual call | 1431 // normal virtual call |
1424 else if (fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())) { | 1432 else if (fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())) { |
1425 assert(fdecl->vtblIndex > 0); | 1433 assert(fdecl->vtblIndex > 0); |
1426 assert(e1type->ty == Tclass); | 1434 assert(e1type->ty == Tclass); |
1427 | 1435 |
1428 LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1436 LLValue* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false); |
1429 LLValue* vtblidx = llvm::ConstantInt::get(llvm::Type::Int32Ty, (size_t)fdecl->vtblIndex, false); | 1437 LLValue* vtblidx = llvm::ConstantInt::get(LLType::Int32Ty, (size_t)fdecl->vtblIndex, false); |
1430 //Logger::cout() << "vthis: " << *vthis << '\n'; | 1438 //Logger::cout() << "vthis: " << *vthis << '\n'; |
1431 funcval = DtoGEP(vthis, zero, zero, "tmp", p->scopebb()); | 1439 funcval = DtoGEP(vthis, zero, zero); |
1432 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); | 1440 funcval = DtoLoad(funcval); |
1433 funcval = DtoGEP(funcval, zero, vtblidx, toChars(), p->scopebb()); | 1441 funcval = DtoGEP(funcval, zero, vtblidx, toChars()); |
1434 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); | 1442 funcval = DtoLoad(funcval); |
1435 #if OPAQUE_VTBLS | 1443 #if OPAQUE_VTBLS |
1436 funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type))); | 1444 funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type))); |
1437 Logger::cout() << "funcval casted: " << *funcval << '\n'; | 1445 Logger::cout() << "funcval casted: " << *funcval << '\n'; |
1438 #endif | 1446 #endif |
1439 } | 1447 } |
1463 | 1471 |
1464 if (VarDeclaration* vd = var->isVarDeclaration()) { | 1472 if (VarDeclaration* vd = var->isVarDeclaration()) { |
1465 LLValue* v; | 1473 LLValue* v; |
1466 v = p->func()->decl->ir.irFunc->thisVar; | 1474 v = p->func()->decl->ir.irFunc->thisVar; |
1467 if (llvm::isa<llvm::AllocaInst>(v)) | 1475 if (llvm::isa<llvm::AllocaInst>(v)) |
1468 v = new llvm::LoadInst(v, "tmp", p->scopebb()); | 1476 v = DtoLoad(v); |
1469 const LLType* t = DtoType(type); | 1477 const LLType* t = DtoType(type); |
1470 if (v->getType() != t) | 1478 if (v->getType() != t) |
1471 v = DtoBitCast(v, t, "tmp"); | 1479 v = DtoBitCast(v, t); |
1472 return new DThisValue(vd, v); | 1480 return new DThisValue(vd, v); |
1473 } | 1481 } |
1474 | 1482 |
1475 assert(0); | 1483 assert(0); |
1476 return 0; | 1484 return 0; |
1489 | 1497 |
1490 p->arrays.push_back(l); // if $ is used it must be an array so this is fine. | 1498 p->arrays.push_back(l); // if $ is used it must be an array so this is fine. |
1491 DValue* r = e2->toElem(p); | 1499 DValue* r = e2->toElem(p); |
1492 p->arrays.pop_back(); | 1500 p->arrays.pop_back(); |
1493 | 1501 |
1494 LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1502 LLValue* zero = DtoConstUint(0); |
1495 LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | 1503 LLValue* one = DtoConstUint(1); |
1496 | 1504 |
1497 LLValue* arrptr = 0; | 1505 LLValue* arrptr = 0; |
1498 if (e1type->ty == Tpointer) { | 1506 if (e1type->ty == Tpointer) { |
1499 arrptr = llvm::GetElementPtrInst::Create(l->getRVal(),r->getRVal(),"tmp",p->scopebb()); | 1507 arrptr = DtoGEP1(l->getRVal(),r->getRVal()); |
1500 } | 1508 } |
1501 else if (e1type->ty == Tsarray) { | 1509 else if (e1type->ty == Tsarray) { |
1502 arrptr = DtoGEP(l->getRVal(), zero, r->getRVal(),"tmp",p->scopebb()); | 1510 arrptr = DtoGEP(l->getRVal(), zero, r->getRVal()); |
1503 } | 1511 } |
1504 else if (e1type->ty == Tarray) { | 1512 else if (e1type->ty == Tarray) { |
1505 arrptr = DtoGEP(l->getRVal(),zero,one,"tmp",p->scopebb()); | 1513 arrptr = DtoGEP(l->getRVal(),zero,one); |
1506 arrptr = new llvm::LoadInst(arrptr,"tmp",p->scopebb()); | 1514 arrptr = DtoLoad(arrptr); |
1507 arrptr = llvm::GetElementPtrInst::Create(arrptr,r->getRVal(),"tmp",p->scopebb()); | 1515 arrptr = DtoGEP1(arrptr,r->getRVal()); |
1508 } | 1516 } |
1509 else if (e1type->ty == Taarray) { | 1517 else if (e1type->ty == Taarray) { |
1510 return DtoAAIndex(type, l, r); | 1518 return DtoAAIndex(type, l, r); |
1511 } | 1519 } |
1512 else { | 1520 else { |
1528 | 1536 |
1529 DValue* v = e1->toElem(p); | 1537 DValue* v = e1->toElem(p); |
1530 LLValue* vmem = v->getRVal(); | 1538 LLValue* vmem = v->getRVal(); |
1531 assert(vmem); | 1539 assert(vmem); |
1532 | 1540 |
1533 LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1541 LLValue* zero = DtoConstUint(0); |
1534 LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | 1542 LLValue* one = DtoConstUint(1); |
1535 | 1543 |
1536 LLValue* emem = 0; | 1544 LLValue* emem = 0; |
1537 LLValue* earg = 0; | 1545 LLValue* earg = 0; |
1538 | 1546 |
1539 // partial slice | 1547 // partial slice |
1550 | 1558 |
1551 if (e1type->ty == Tpointer) { | 1559 if (e1type->ty == Tpointer) { |
1552 emem = v->getRVal(); | 1560 emem = v->getRVal(); |
1553 } | 1561 } |
1554 else if (e1type->ty == Tarray) { | 1562 else if (e1type->ty == Tarray) { |
1555 LLValue* tmp = DtoGEP(vmem,zero,one,"tmp",p->scopebb()); | 1563 LLValue* tmp = DtoGEP(vmem,zero,one); |
1556 emem = new llvm::LoadInst(tmp,"tmp",p->scopebb()); | 1564 emem = DtoLoad(tmp); |
1557 } | 1565 } |
1558 else if (e1type->ty == Tsarray) { | 1566 else if (e1type->ty == Tsarray) { |
1559 emem = DtoGEP(vmem,zero,zero,"tmp",p->scopebb()); | 1567 emem = DtoGEP(vmem,zero,zero); |
1560 } | 1568 } |
1561 else | 1569 else |
1562 assert(emem); | 1570 assert(emem); |
1563 | 1571 |
1564 llvm::ConstantInt* c = llvm::cast<llvm::ConstantInt>(cv->c); | 1572 llvm::ConstantInt* c = llvm::cast<llvm::ConstantInt>(cv->c); |
1565 if (!(lwr_is_zero = c->isZero())) { | 1573 if (!(lwr_is_zero = c->isZero())) { |
1566 emem = llvm::GetElementPtrInst::Create(emem,cv->c,"tmp",p->scopebb()); | 1574 emem = DtoGEP1(emem,cv->c); |
1567 } | 1575 } |
1568 } | 1576 } |
1569 else | 1577 else |
1570 { | 1578 { |
1571 if (e1type->ty == Tarray) { | 1579 if (e1type->ty == Tarray) { |
1572 LLValue* tmp = DtoGEP(vmem,zero,one,"tmp",p->scopebb()); | 1580 LLValue* tmp = DtoGEP(vmem,zero,one); |
1573 tmp = new llvm::LoadInst(tmp,"tmp",p->scopebb()); | 1581 tmp = DtoLoad(tmp); |
1574 emem = llvm::GetElementPtrInst::Create(tmp,lo->getRVal(),"tmp",p->scopebb()); | 1582 emem = DtoGEP1(tmp,lo->getRVal()); |
1575 } | 1583 } |
1576 else if (e1type->ty == Tsarray) { | 1584 else if (e1type->ty == Tsarray) { |
1577 emem = DtoGEP(vmem,zero,lo->getRVal(),"tmp",p->scopebb()); | 1585 emem = DtoGEP(vmem,zero,lo->getRVal()); |
1578 } | 1586 } |
1579 else if (e1type->ty == Tpointer) { | 1587 else if (e1type->ty == Tpointer) { |
1580 emem = llvm::GetElementPtrInst::Create(v->getRVal(),lo->getRVal(),"tmp",p->scopebb()); | 1588 emem = DtoGEP1(v->getRVal(),lo->getRVal()); |
1581 } | 1589 } |
1582 else { | 1590 else { |
1583 Logger::println("type = %s", e1type->toChars()); | 1591 Logger::println("type = %s", e1type->toChars()); |
1584 assert(0); | 1592 assert(0); |
1585 } | 1593 } |
1913 // allocate | 1921 // allocate |
1914 LLValue* mem = DtoNew(newtype); | 1922 LLValue* mem = DtoNew(newtype); |
1915 // init | 1923 // init |
1916 TypeStruct* ts = (TypeStruct*)ntype; | 1924 TypeStruct* ts = (TypeStruct*)ntype; |
1917 if (ts->isZeroInit()) { | 1925 if (ts->isZeroInit()) { |
1918 DtoStructZeroInit(mem); | 1926 DtoAggrZeroInit(mem); |
1919 } | 1927 } |
1920 else { | 1928 else { |
1921 assert(ts->sym); | 1929 assert(ts->sym); |
1922 DtoStructCopy(mem,ts->sym->ir.irStruct->init); | 1930 DtoAggrCopy(mem,ts->sym->ir.irStruct->init); |
1923 } | 1931 } |
1924 return new DImValue(type, mem, false); | 1932 return new DImValue(type, mem, false); |
1925 } | 1933 } |
1926 // new basic type | 1934 // new basic type |
1927 else | 1935 else |
2069 | 2077 |
2070 DValue* u = e1->toElem(p); | 2078 DValue* u = e1->toElem(p); |
2071 | 2079 |
2072 LLValue* b = DtoBoolean(u->getRVal()); | 2080 LLValue* b = DtoBoolean(u->getRVal()); |
2073 | 2081 |
2074 LLConstant* zero = llvm::ConstantInt::get(llvm::Type::Int1Ty, 0, true); | 2082 LLConstant* zero = llvm::ConstantInt::get(LLType::Int1Ty, 0, true); |
2075 b = p->ir->CreateICmpEQ(b,zero); | 2083 b = p->ir->CreateICmpEQ(b,zero); |
2076 | 2084 |
2077 return new DImValue(type, b); | 2085 return new DImValue(type, b); |
2078 } | 2086 } |
2079 | 2087 |
2085 LOG_SCOPE; | 2093 LOG_SCOPE; |
2086 | 2094 |
2087 // allocate a temporary for the final result. failed to come up with a better way :/ | 2095 // allocate a temporary for the final result. failed to come up with a better way :/ |
2088 LLValue* resval = 0; | 2096 LLValue* resval = 0; |
2089 llvm::BasicBlock* entryblock = &p->topfunc()->front(); | 2097 llvm::BasicBlock* entryblock = &p->topfunc()->front(); |
2090 resval = new llvm::AllocaInst(llvm::Type::Int1Ty,"andandtmp",p->topallocapoint()); | 2098 resval = new llvm::AllocaInst(LLType::Int1Ty,"andandtmp",p->topallocapoint()); |
2091 | 2099 |
2092 DValue* u = e1->toElem(p); | 2100 DValue* u = e1->toElem(p); |
2093 | 2101 |
2094 llvm::BasicBlock* oldend = p->scopeend(); | 2102 llvm::BasicBlock* oldend = p->scopeend(); |
2095 llvm::BasicBlock* andand = llvm::BasicBlock::Create("andand", gIR->topfunc(), oldend); | 2103 llvm::BasicBlock* andand = llvm::BasicBlock::Create("andand", gIR->topfunc(), oldend); |
2096 llvm::BasicBlock* andandend = llvm::BasicBlock::Create("andandend", gIR->topfunc(), oldend); | 2104 llvm::BasicBlock* andandend = llvm::BasicBlock::Create("andandend", gIR->topfunc(), oldend); |
2097 | 2105 |
2098 LLValue* ubool = DtoBoolean(u->getRVal()); | 2106 LLValue* ubool = DtoBoolean(u->getRVal()); |
2099 new llvm::StoreInst(ubool,resval,p->scopebb()); | 2107 DtoStore(ubool,resval); |
2100 llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb()); | 2108 llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb()); |
2101 | 2109 |
2102 p->scope() = IRScope(andand, andandend); | 2110 p->scope() = IRScope(andand, andandend); |
2103 DValue* v = e2->toElem(p); | 2111 DValue* v = e2->toElem(p); |
2104 | 2112 |
2105 LLValue* vbool = DtoBoolean(v->getRVal()); | 2113 LLValue* vbool = DtoBoolean(v->getRVal()); |
2106 LLValue* uandvbool = llvm::BinaryOperator::create(llvm::BinaryOperator::And, ubool, vbool,"tmp",p->scopebb()); | 2114 LLValue* uandvbool = llvm::BinaryOperator::create(llvm::BinaryOperator::And, ubool, vbool,"tmp",p->scopebb()); |
2107 new llvm::StoreInst(uandvbool,resval,p->scopebb()); | 2115 DtoStore(uandvbool,resval); |
2108 llvm::BranchInst::Create(andandend,p->scopebb()); | 2116 llvm::BranchInst::Create(andandend,p->scopebb()); |
2109 | 2117 |
2110 p->scope() = IRScope(andandend, oldend); | 2118 p->scope() = IRScope(andandend, oldend); |
2111 | 2119 |
2112 resval = new llvm::LoadInst(resval,"tmp",p->scopebb()); | 2120 resval = DtoLoad(resval); |
2113 return new DImValue(type, resval); | 2121 return new DImValue(type, resval); |
2114 } | 2122 } |
2115 | 2123 |
2116 ////////////////////////////////////////////////////////////////////////////////////////// | 2124 ////////////////////////////////////////////////////////////////////////////////////////// |
2117 | 2125 |
2121 LOG_SCOPE; | 2129 LOG_SCOPE; |
2122 | 2130 |
2123 // allocate a temporary for the final result. failed to come up with a better way :/ | 2131 // allocate a temporary for the final result. failed to come up with a better way :/ |
2124 LLValue* resval = 0; | 2132 LLValue* resval = 0; |
2125 llvm::BasicBlock* entryblock = &p->topfunc()->front(); | 2133 llvm::BasicBlock* entryblock = &p->topfunc()->front(); |
2126 resval = new llvm::AllocaInst(llvm::Type::Int1Ty,"orortmp",p->topallocapoint()); | 2134 resval = new llvm::AllocaInst(LLType::Int1Ty,"orortmp",p->topallocapoint()); |
2127 | 2135 |
2128 DValue* u = e1->toElem(p); | 2136 DValue* u = e1->toElem(p); |
2129 | 2137 |
2130 llvm::BasicBlock* oldend = p->scopeend(); | 2138 llvm::BasicBlock* oldend = p->scopeend(); |
2131 llvm::BasicBlock* oror = llvm::BasicBlock::Create("oror", gIR->topfunc(), oldend); | 2139 llvm::BasicBlock* oror = llvm::BasicBlock::Create("oror", gIR->topfunc(), oldend); |
2132 llvm::BasicBlock* ororend = llvm::BasicBlock::Create("ororend", gIR->topfunc(), oldend); | 2140 llvm::BasicBlock* ororend = llvm::BasicBlock::Create("ororend", gIR->topfunc(), oldend); |
2133 | 2141 |
2134 LLValue* ubool = DtoBoolean(u->getRVal()); | 2142 LLValue* ubool = DtoBoolean(u->getRVal()); |
2135 new llvm::StoreInst(ubool,resval,p->scopebb()); | 2143 DtoStore(ubool,resval); |
2136 llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb()); | 2144 llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb()); |
2137 | 2145 |
2138 p->scope() = IRScope(oror, ororend); | 2146 p->scope() = IRScope(oror, ororend); |
2139 DValue* v = e2->toElem(p); | 2147 DValue* v = e2->toElem(p); |
2140 | 2148 |
2141 LLValue* vbool = DtoBoolean(v->getRVal()); | 2149 LLValue* vbool = DtoBoolean(v->getRVal()); |
2142 new llvm::StoreInst(vbool,resval,p->scopebb()); | 2150 DtoStore(vbool,resval); |
2143 llvm::BranchInst::Create(ororend,p->scopebb()); | 2151 llvm::BranchInst::Create(ororend,p->scopebb()); |
2144 | 2152 |
2145 p->scope() = IRScope(ororend, oldend); | 2153 p->scope() = IRScope(ororend, oldend); |
2146 | 2154 |
2147 resval = new llvm::LoadInst(resval,"tmp",p->scopebb()); | 2155 resval = new llvm::LoadInst(resval,"tmp",p->scopebb()); |
2171 DValue* v = e2->toElem(p); \ | 2179 DValue* v = e2->toElem(p); \ |
2172 p->exps.pop_back(); \ | 2180 p->exps.pop_back(); \ |
2173 LLValue* uval = u->getRVal(); \ | 2181 LLValue* uval = u->getRVal(); \ |
2174 LLValue* vval = v->getRVal(); \ | 2182 LLValue* vval = v->getRVal(); \ |
2175 LLValue* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \ | 2183 LLValue* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \ |
2176 new llvm::StoreInst(DtoPointedType(u->getLVal(), tmp), u->getLVal(), p->scopebb()); \ | 2184 DtoStore(DtoPointedType(u->getLVal(), tmp), u->getLVal()); \ |
2177 return u; \ | 2185 return u; \ |
2178 } | 2186 } |
2179 | 2187 |
2180 BinBitExp(And,And); | 2188 BinBitExp(And,And); |
2181 BinBitExp(Or,Or); | 2189 BinBitExp(Or,Or); |
2203 DValue* DelegateExp::toElem(IRState* p) | 2211 DValue* DelegateExp::toElem(IRState* p) |
2204 { | 2212 { |
2205 Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2213 Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2206 LOG_SCOPE; | 2214 LOG_SCOPE; |
2207 | 2215 |
2208 const llvm::PointerType* int8ptrty = getPtrToType(llvm::Type::Int8Ty); | 2216 const LLPointerType* int8ptrty = getPtrToType(LLType::Int8Ty); |
2209 | 2217 |
2210 LLValue* lval; | 2218 LLValue* lval; |
2211 bool inplace = false; | 2219 bool inplace = false; |
2212 if (p->topexp() && p->topexp()->e2 == this) { | 2220 if (p->topexp() && p->topexp()->e2 == this) { |
2213 assert(p->topexp()->v); | 2221 assert(p->topexp()->v); |
2243 uval = src->getRVal(); | 2251 uval = src->getRVal(); |
2244 } | 2252 } |
2245 | 2253 |
2246 Logger::cout() << "context = " << *uval << '\n'; | 2254 Logger::cout() << "context = " << *uval << '\n'; |
2247 | 2255 |
2248 LLValue* context = DtoGEPi(lval,0,0,"tmp"); | 2256 LLValue* context = DtoGEPi(lval,0,0); |
2249 LLValue* castcontext = DtoBitCast(uval, int8ptrty); | 2257 LLValue* castcontext = DtoBitCast(uval, int8ptrty); |
2250 DtoStore(castcontext, context); | 2258 DtoStore(castcontext, context); |
2251 | 2259 |
2252 LLValue* fptr = DtoGEPi(lval,0,1,"tmp"); | 2260 LLValue* fptr = DtoGEPi(lval,0,1); |
2253 | 2261 |
2254 Logger::println("func: '%s'", func->toPrettyChars()); | 2262 Logger::println("func: '%s'", func->toPrettyChars()); |
2255 | 2263 |
2256 LLValue* castfptr; | 2264 LLValue* castfptr; |
2257 if (func->isVirtual()) | 2265 if (func->isVirtual()) |
2316 { | 2324 { |
2317 if (l->getType() != r->getType()) { | 2325 if (l->getType() != r->getType()) { |
2318 if (v->isNull()) | 2326 if (v->isNull()) |
2319 r = llvm::ConstantPointerNull::get(isaPointer(l->getType())); | 2327 r = llvm::ConstantPointerNull::get(isaPointer(l->getType())); |
2320 else | 2328 else |
2321 r = DtoBitCast(r, l->getType(), "tmp"); | 2329 r = DtoBitCast(r, l->getType()); |
2322 } | 2330 } |
2323 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; | 2331 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; |
2324 eval = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb()); | 2332 eval = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb()); |
2325 } | 2333 } |
2326 else { | 2334 else { |
2526 Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n'; | 2534 Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n'; |
2527 lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint()); | 2535 lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint()); |
2528 temp = true; | 2536 temp = true; |
2529 } | 2537 } |
2530 | 2538 |
2531 LLValue* context = DtoGEPi(lval,0,0,"tmp",p->scopebb()); | 2539 LLValue* context = DtoGEPi(lval,0,0); |
2532 const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0)); | 2540 const LLPointerType* pty = isaPointer(context->getType()->getContainedType(0)); |
2533 LLValue* llvmNested = p->func()->decl->ir.irFunc->nestedVar; | 2541 LLValue* llvmNested = p->func()->decl->ir.irFunc->nestedVar; |
2534 if (llvmNested == NULL) { | 2542 if (llvmNested == NULL) { |
2535 LLValue* nullcontext = llvm::ConstantPointerNull::get(pty); | 2543 LLValue* nullcontext = llvm::ConstantPointerNull::get(pty); |
2536 p->ir->CreateStore(nullcontext, context); | 2544 DtoStore(nullcontext, context); |
2537 } | 2545 } |
2538 else { | 2546 else { |
2539 LLValue* nestedcontext = p->ir->CreateBitCast(llvmNested, pty, "tmp"); | 2547 LLValue* nestedcontext = DtoBitCast(llvmNested, pty); |
2540 p->ir->CreateStore(nestedcontext, context); | 2548 DtoStore(nestedcontext, context); |
2541 } | 2549 } |
2542 | 2550 |
2543 LLValue* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb()); | 2551 LLValue* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb()); |
2544 | 2552 |
2545 assert(fd->ir.irFunc->func); | 2553 assert(fd->ir.irFunc->func); |
2546 LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func,fptr->getType()->getContainedType(0)); | 2554 LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, fptr->getType()->getContainedType(0)); |
2547 new llvm::StoreInst(castfptr, fptr, p->scopebb()); | 2555 DtoStore(castfptr, fptr); |
2548 | 2556 |
2549 if (temp) | 2557 if (temp) |
2550 return new DVarValue(type, lval, true); | 2558 return new DVarValue(type, lval, true); |
2551 else | 2559 else |
2552 return new DImValue(type, lval, true); | 2560 return new DImValue(type, lval, true); |
2573 // llvm target type | 2581 // llvm target type |
2574 const LLType* llType = DtoType(arrayType); | 2582 const LLType* llType = DtoType(arrayType); |
2575 Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n"; | 2583 Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n"; |
2576 | 2584 |
2577 // llvm storage type | 2585 // llvm storage type |
2578 const LLType* llStoType = llvm::ArrayType::get(DtoType(elemType), len); | 2586 const LLType* llStoType = LLArrayType::get(DtoType(elemType), len); |
2579 Logger::cout() << "llvm storage type: '" << *llStoType << "'\n"; | 2587 Logger::cout() << "llvm storage type: '" << *llStoType << "'\n"; |
2580 | 2588 |
2581 // dst pointer | 2589 // dst pointer |
2582 LLValue* dstMem = 0; | 2590 LLValue* dstMem = 0; |
2583 | 2591 |
2639 LOG_SCOPE; | 2647 LOG_SCOPE; |
2640 | 2648 |
2641 const LLType* t = DtoType(type); | 2649 const LLType* t = DtoType(type); |
2642 Logger::cout() << "array literal has llvm type: " << *t << '\n'; | 2650 Logger::cout() << "array literal has llvm type: " << *t << '\n'; |
2643 assert(isaArray(t)); | 2651 assert(isaArray(t)); |
2644 const llvm::ArrayType* arrtype = isaArray(t); | 2652 const LLArrayType* arrtype = isaArray(t); |
2645 | 2653 |
2646 assert(arrtype->getNumElements() == elements->dim); | 2654 assert(arrtype->getNumElements() == elements->dim); |
2647 std::vector<LLConstant*> vals(elements->dim, NULL); | 2655 std::vector<LLConstant*> vals(elements->dim, NULL); |
2648 for (unsigned i=0; i<elements->dim; ++i) | 2656 for (unsigned i=0; i<elements->dim; ++i) |
2649 { | 2657 { |
2690 for (unsigned i=0; i<n; ++i) { | 2698 for (unsigned i=0; i<n; ++i) { |
2691 Expression* vx = (Expression*)elements->data[i]; | 2699 Expression* vx = (Expression*)elements->data[i]; |
2692 if (!vx) continue; | 2700 if (!vx) continue; |
2693 tys.push_back(DtoType(vx->type)); | 2701 tys.push_back(DtoType(vx->type)); |
2694 } | 2702 } |
2695 const llvm::StructType* t = llvm::StructType::get(tys); | 2703 const LLStructType* t = LLStructType::get(tys); |
2696 if (t != llt) { | 2704 if (t != llt) { |
2697 if (getABITypeSize(t) != getABITypeSize(llt)) { | 2705 if (getABITypeSize(t) != getABITypeSize(llt)) { |
2698 Logger::cout() << "got size " << getABITypeSize(t) << ", expected " << getABITypeSize(llt) << '\n'; | 2706 Logger::cout() << "got size " << getABITypeSize(t) << ", expected " << getABITypeSize(llt) << '\n'; |
2699 assert(0 && "type size mismatch"); | 2707 assert(0 && "type size mismatch"); |
2700 } | 2708 } |
2709 { | 2717 { |
2710 Expression* vx = (Expression*)elements->data[i]; | 2718 Expression* vx = (Expression*)elements->data[i]; |
2711 if (!vx) continue; | 2719 if (!vx) continue; |
2712 | 2720 |
2713 Logger::cout() << "getting index " << j << " of " << *sptr << '\n'; | 2721 Logger::cout() << "getting index " << j << " of " << *sptr << '\n'; |
2714 LLValue* arrptr = DtoGEPi(sptr,0,j,"tmp",p->scopebb()); | 2722 LLValue* arrptr = DtoGEPi(sptr,0,j); |
2715 DValue* darrptr = new DVarValue(vx->type, arrptr, true); | 2723 DValue* darrptr = new DVarValue(vx->type, arrptr, true); |
2716 | 2724 |
2717 p->exps.push_back(IRExp(NULL,vx,darrptr)); | 2725 p->exps.push_back(IRExp(NULL,vx,darrptr)); |
2718 DValue* ve = vx->toElem(p); | 2726 DValue* ve = vx->toElem(p); |
2719 p->exps.pop_back(); | 2727 p->exps.pop_back(); |
2743 vals[i] = vx->toConstElem(p); | 2751 vals[i] = vx->toConstElem(p); |
2744 } | 2752 } |
2745 | 2753 |
2746 assert(DtoDType(type)->ty == Tstruct); | 2754 assert(DtoDType(type)->ty == Tstruct); |
2747 const LLType* t = DtoType(type); | 2755 const LLType* t = DtoType(type); |
2748 const llvm::StructType* st = isaStruct(t); | 2756 const LLStructType* st = isaStruct(t); |
2749 return llvm::ConstantStruct::get(st,vals); | 2757 return llvm::ConstantStruct::get(st,vals); |
2750 } | 2758 } |
2751 | 2759 |
2752 ////////////////////////////////////////////////////////////////////////////////////////// | 2760 ////////////////////////////////////////////////////////////////////////////////////////// |
2753 | 2761 |