comparison gen/toir.cpp @ 136:0e28624814e8 trunk

[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
author lindquist
date Thu, 17 Jan 2008 03:15:12 +0100
parents 44a95ac7368a
children ce7b81fb957f
comparison
equal deleted inserted replaced
135:176bd52b3cf5 136:0e28624814e8
55 { 55 {
56 if (global.params.llvmAnnotate) 56 if (global.params.llvmAnnotate)
57 DtoAnnotation(toChars()); 57 DtoAnnotation(toChars());
58 58
59 Logger::println("vdtype = %s", vd->type->toChars()); 59 Logger::println("vdtype = %s", vd->type->toChars());
60
60 // referenced by nested delegate? 61 // referenced by nested delegate?
61 if (vd->nestedref) { 62 if (vd->nestedref) {
62 Logger::println("has nestedref set"); 63 Logger::println("has nestedref set");
63 vd->llvmValue = p->func()->decl->llvmNested; 64 assert(vd->irLocal);
64 assert(vd->llvmValue); 65 vd->irLocal->value = p->func()->decl->irFunc->nestedVar;
65 assert(vd->llvmNestedIndex >= 0); 66 assert(vd->irLocal->value);
67 assert(vd->irLocal->nestedIndex >= 0);
66 } 68 }
67 // normal stack variable 69 // normal stack variable
68 else { 70 else {
69 // allocate storage on the stack 71 // allocate storage on the stack
70 const llvm::Type* lltype = DtoType(vd->type); 72 const llvm::Type* lltype = DtoType(vd->type);
71 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); 73 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint());
72 //allocainst->setAlignment(vd->type->alignsize()); // TODO 74 //allocainst->setAlignment(vd->type->alignsize()); // TODO
73 vd->llvmValue = allocainst; 75 assert(!vd->irLocal);
74 } 76 vd->irLocal = new IrLocal(vd);
75 77 vd->irLocal->value = allocainst;
76 Logger::cout() << "llvm value for decl: " << *vd->llvmValue << '\n'; 78 }
79
80 Logger::cout() << "llvm value for decl: " << *vd->irLocal->value << '\n';
77 DValue* ie = DtoInitializer(vd->init); 81 DValue* ie = DtoInitializer(vd->init);
78 } 82 }
79 83
80 return new DVarValue(vd, vd->llvmValue, true); 84 return new DVarValue(vd, vd->getIrValue(), true);
81 } 85 }
82 // struct declaration 86 // struct declaration
83 else if (StructDeclaration* s = declaration->isStructDeclaration()) 87 else if (StructDeclaration* s = declaration->isStructDeclaration())
84 { 88 {
85 Logger::println("StructDeclaration"); 89 Logger::println("StructDeclaration");
147 151
148 // _arguments 152 // _arguments
149 if (vd->ident == Id::_arguments) 153 if (vd->ident == Id::_arguments)
150 { 154 {
151 Logger::println("Id::_arguments"); 155 Logger::println("Id::_arguments");
152 if (!vd->llvmValue) 156 if (!vd->getIrValue())
153 vd->llvmValue = p->func()->decl->llvmArguments; 157 vd->getIrValue() = p->func()->decl->irFunc->_arguments;
154 assert(vd->llvmValue); 158 assert(vd->getIrValue());
155 return new DVarValue(vd, vd->llvmValue, true); 159 return new DVarValue(vd, vd->getIrValue(), true);
156 } 160 }
157 // _argptr 161 // _argptr
158 else if (vd->ident == Id::_argptr) 162 else if (vd->ident == Id::_argptr)
159 { 163 {
160 Logger::println("Id::_argptr"); 164 Logger::println("Id::_argptr");
161 if (!vd->llvmValue) 165 if (!vd->getIrValue())
162 vd->llvmValue = p->func()->decl->llvmArgPtr; 166 vd->getIrValue() = p->func()->decl->irFunc->_argptr;
163 assert(vd->llvmValue); 167 assert(vd->getIrValue());
164 return new DVarValue(vd, vd->llvmValue, true); 168 return new DVarValue(vd, vd->getIrValue(), true);
165 } 169 }
166 // _dollar 170 // _dollar
167 else if (vd->ident == Id::dollar) 171 else if (vd->ident == Id::dollar)
168 { 172 {
169 Logger::println("Id::dollar"); 173 Logger::println("Id::dollar");
174 // typeinfo 178 // typeinfo
175 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) 179 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
176 { 180 {
177 Logger::println("TypeInfoDeclaration"); 181 Logger::println("TypeInfoDeclaration");
178 DtoForceDeclareDsymbol(tid); 182 DtoForceDeclareDsymbol(tid);
179 assert(tid->llvmValue); 183 assert(tid->getIrValue());
180 const llvm::Type* vartype = DtoType(type); 184 const llvm::Type* vartype = DtoType(type);
181 llvm::Value* m; 185 llvm::Value* m;
182 if (tid->llvmValue->getType() != getPtrToType(vartype)) 186 if (tid->getIrValue()->getType() != getPtrToType(vartype))
183 m = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp"); 187 m = p->ir->CreateBitCast(tid->getIrValue(), vartype, "tmp");
184 else 188 else
185 m = tid->llvmValue; 189 m = tid->getIrValue();
186 return new DVarValue(vd, m, true); 190 return new DVarValue(vd, m, true);
187 } 191 }
188 // classinfo 192 // classinfo
189 else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration()) 193 else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration())
190 { 194 {
199 return new DVarValue(vd, DtoNestedVariable(vd), true); 203 return new DVarValue(vd, DtoNestedVariable(vd), true);
200 } 204 }
201 // function parameter 205 // function parameter
202 else if (vd->isParameter()) { 206 else if (vd->isParameter()) {
203 Logger::println("function param"); 207 Logger::println("function param");
204 if (!vd->llvmValue) { 208 if (!vd->getIrValue()) {
205 // TODO: determine this properly 209 // TODO: determine this properly
206 // this happens when the DMD frontend generates by pointer wrappers for struct opEquals(S) and opCmp(S) 210 // this happens when the DMD frontend generates by pointer wrappers for struct opEquals(S) and opCmp(S)
207 vd->llvmValue = &p->func()->func->getArgumentList().back(); 211 vd->getIrValue() = &p->func()->func->getArgumentList().back();
208 } 212 }
209 if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->llvmValue)) { 213 if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->getIrValue())) {
210 return new DVarValue(vd, vd->llvmValue, true); 214 return new DVarValue(vd, vd->getIrValue(), true);
211 } 215 }
212 else if (llvm::isa<llvm::Argument>(vd->llvmValue)) { 216 else if (llvm::isa<llvm::Argument>(vd->getIrValue())) {
213 return new DImValue(type, vd->llvmValue); 217 return new DImValue(type, vd->getIrValue());
214 } 218 }
215 else assert(0); 219 else assert(0);
216 } 220 }
217 else { 221 else {
218 // take care of forward references of global variables 222 // take care of forward references of global variables
219 if (vd->isDataseg() || (vd->storage_class & STCextern)) { 223 if (vd->isDataseg() || (vd->storage_class & STCextern)) {
220 vd->toObjFile(); 224 vd->toObjFile();
221 DtoConstInitGlobal(vd); 225 DtoConstInitGlobal(vd);
222 } 226 }
223 if (!vd->llvmValue || vd->llvmValue->getType()->isAbstract()) { 227 if (!vd->getIrValue() || vd->getIrValue()->getType()->isAbstract()) {
224 Logger::println("global variable not resolved :/ %s", vd->toChars()); 228 Logger::println("global variable not resolved :/ %s", vd->toChars());
225 assert(0); 229 assert(0);
226 } 230 }
227 return new DVarValue(vd, vd->llvmValue, true); 231 return new DVarValue(vd, vd->getIrValue(), true);
228 } 232 }
229 } 233 }
230 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) 234 else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
231 { 235 {
232 Logger::println("FuncDeclaration"); 236 Logger::println("FuncDeclaration");
233 if (fdecl->llvmInternal != LLVMva_arg) {// && fdecl->llvmValue == 0) 237 if (fdecl->llvmInternal != LLVMva_arg) {// && fdecl->llvmValue == 0)
234 DtoForceDeclareDsymbol(fdecl); 238 DtoForceDeclareDsymbol(fdecl);
235 } 239 }
236 return new DFuncValue(fdecl, fdecl->llvmValue); 240 return new DFuncValue(fdecl, fdecl->irFunc->func);
237 } 241 }
238 else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) 242 else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration())
239 { 243 {
240 // this seems to be the static initialiser for structs 244 // this seems to be the static initialiser for structs
241 Type* sdecltype = DtoDType(sdecl->type); 245 Type* sdecltype = DtoDType(sdecl->type);
272 return ts->sym->llvmConstInit; 276 return ts->sym->llvmConstInit;
273 } 277 }
274 else if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration()) 278 else if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration())
275 { 279 {
276 DtoForceDeclareDsymbol(ti); 280 DtoForceDeclareDsymbol(ti);
277 assert(ti->llvmValue); 281 assert(ti->getIrValue());
278 const llvm::Type* vartype = DtoType(type); 282 const llvm::Type* vartype = DtoType(type);
279 llvm::Constant* m = isaConstant(ti->llvmValue); 283 llvm::Constant* m = isaConstant(ti->getIrValue());
280 assert(m); 284 assert(m);
281 if (ti->llvmValue->getType() != getPtrToType(vartype)) 285 if (ti->getIrValue()->getType() != getPtrToType(vartype))
282 m = llvm::ConstantExpr::getBitCast(m, vartype); 286 m = llvm::ConstantExpr::getBitCast(m, vartype);
283 return m; 287 return m;
284 } 288 }
285 assert(0 && "Unsupported const VarExp kind"); 289 assert(0 && "Unsupported const VarExp kind");
286 return NULL; 290 return NULL;
972 } 976 }
973 else { 977 else {
974 llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint()); 978 llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint());
975 } 979 }
976 980
977 if (dfn && dfn->func && dfn->func->llvmRunTimeHack) { 981 if (dfn && dfn->func && dfn->func->runTimeHack) {
978 const llvm::Type* rettype = getPtrToType(DtoType(type)); 982 const llvm::Type* rettype = getPtrToType(DtoType(type));
979 if (llargs[j]->getType() != llfnty->getParamType(j)) { 983 if (llargs[j]->getType() != llfnty->getParamType(j)) {
980 Logger::println("llvmRunTimeHack==true - force casting return value param"); 984 Logger::println("llvmRunTimeHack==true - force casting return value param");
981 Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n'; 985 Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n';
982 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j)); 986 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j));
1073 for (int i=0; i<arguments->dim; i++) 1077 for (int i=0; i<arguments->dim; i++)
1074 { 1078 {
1075 Expression* argexp = (Expression*)arguments->data[i]; 1079 Expression* argexp = (Expression*)arguments->data[i];
1076 TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration(); 1080 TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration();
1077 DtoForceDeclareDsymbol(tidecl); 1081 DtoForceDeclareDsymbol(tidecl);
1078 assert(tidecl->llvmValue); 1082 assert(tidecl->getIrValue());
1079 vtypeinfos.push_back(tidecl->llvmValue); 1083 vtypeinfos.push_back(tidecl->getIrValue());
1080 llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[i], typeinfotype, "tmp"); 1084 llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[i], typeinfotype, "tmp");
1081 p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,i,"tmp")); 1085 p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,i,"tmp"));
1082 } 1086 }
1083 1087
1084 // put data in d-array 1088 // put data in d-array
1106 if (fnarg && llargs[j]->getType() != llfnty->getParamType(j)) { 1110 if (fnarg && llargs[j]->getType() != llfnty->getParamType(j)) {
1107 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j)); 1111 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j));
1108 } 1112 }
1109 1113
1110 // this hack is necessary :/ 1114 // this hack is necessary :/
1111 if (dfn && dfn->func && dfn->func->llvmRunTimeHack) { 1115 if (dfn && dfn->func && dfn->func->runTimeHack) {
1112 if (llfnty->getParamType(j) != NULL) { 1116 if (llfnty->getParamType(j) != NULL) {
1113 if (llargs[j]->getType() != llfnty->getParamType(j)) { 1117 if (llargs[j]->getType() != llfnty->getParamType(j)) {
1114 Logger::println("llvmRunTimeHack==true - force casting argument"); 1118 Logger::println("llvmRunTimeHack==true - force casting argument");
1115 Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n'; 1119 Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n';
1116 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j)); 1120 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j));
1135 1139
1136 // call the function 1140 // call the function
1137 llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb()); 1141 llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb());
1138 llvm::Value* retllval = (retinptr) ? llargs[0] : call; 1142 llvm::Value* retllval = (retinptr) ? llargs[0] : call;
1139 1143
1140 if (retinptr && dfn && dfn->func && dfn->func->llvmRunTimeHack) { 1144 if (retinptr && dfn && dfn->func && dfn->func->runTimeHack) {
1141 const llvm::Type* rettype = getPtrToType(DtoType(type)); 1145 const llvm::Type* rettype = getPtrToType(DtoType(type));
1142 if (retllval->getType() != rettype) { 1146 if (retllval->getType() != rettype) {
1143 Logger::println("llvmRunTimeHack==true - force casting return value"); 1147 Logger::println("llvmRunTimeHack==true - force casting return value");
1144 Logger::cout() << "from: " << *retllval->getType() << " to: " << *rettype << '\n'; 1148 Logger::cout() << "from: " << *retllval->getType() << " to: " << *rettype << '\n';
1145 retllval = DtoBitCast(retllval, rettype); 1149 retllval = DtoBitCast(retllval, rettype);
1206 // handle forward reference 1210 // handle forward reference
1207 if (!vd->llvmDeclared && vd->isDataseg()) { 1211 if (!vd->llvmDeclared && vd->isDataseg()) {
1208 vd->toObjFile(); // TODO 1212 vd->toObjFile(); // TODO
1209 } 1213 }
1210 1214
1211 assert(vd->llvmValue); 1215 assert(vd->getIrValue());
1212 Type* t = DtoDType(type); 1216 Type* t = DtoDType(type);
1213 Type* tnext = DtoDType(t->next); 1217 Type* tnext = DtoDType(t->next);
1214 Type* vdtype = DtoDType(vd->type); 1218 Type* vdtype = DtoDType(vd->type);
1215 1219
1216 llvm::Value* llvalue = vd->nestedref ? DtoNestedVariable(vd) : vd->llvmValue; 1220 llvm::Value* llvalue = vd->nestedref ? DtoNestedVariable(vd) : vd->getIrValue();
1217 llvm::Value* varmem = 0; 1221 llvm::Value* varmem = 0;
1218 1222
1219 if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) { 1223 if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) {
1220 Logger::println("struct"); 1224 Logger::println("struct");
1221 TypeStruct* vdt = (TypeStruct*)vdtype; 1225 TypeStruct* vdt = (TypeStruct*)vdtype;
1285 else if (DFuncValue* fv = v->isFunc()) { 1289 else if (DFuncValue* fv = v->isFunc()) {
1286 Logger::println("is func"); 1290 Logger::println("is func");
1287 //Logger::println("FuncDeclaration"); 1291 //Logger::println("FuncDeclaration");
1288 FuncDeclaration* fd = fv->func; 1292 FuncDeclaration* fd = fv->func;
1289 assert(fd); 1293 assert(fd);
1290 if (fd->llvmValue == 0) 1294 DtoForceDeclareDsymbol(fd);
1291 DtoForceDeclareDsymbol(fd); 1295 return new DFuncValue(fd, fd->irFunc->func);
1292 return new DFuncValue(fd, fd->llvmValue);
1293 } 1296 }
1294 else if (DImValue* im = v->isIm()) { 1297 else if (DImValue* im = v->isIm()) {
1295 Logger::println("is immediate"); 1298 Logger::println("is immediate");
1296 return v; 1299 return v;
1297 } 1300 }
1392 //unsigned cc = (unsigned)-1; 1395 //unsigned cc = (unsigned)-1;
1393 1396
1394 // super call 1397 // super call
1395 if (e1->op == TOKsuper) { 1398 if (e1->op == TOKsuper) {
1396 DtoForceDeclareDsymbol(fdecl); 1399 DtoForceDeclareDsymbol(fdecl);
1397 funcval = fdecl->llvmValue; 1400 funcval = fdecl->irFunc->func;
1398 assert(funcval); 1401 assert(funcval);
1399 } 1402 }
1400 // normal virtual call 1403 // normal virtual call
1401 else if (fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())) { 1404 else if (fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())) {
1402 assert(fdecl->vtblIndex > 0); 1405 assert(fdecl->vtblIndex > 0);
1413 //cc = DtoCallingConv(fdecl->linkage); 1416 //cc = DtoCallingConv(fdecl->linkage);
1414 } 1417 }
1415 // static call 1418 // static call
1416 else { 1419 else {
1417 DtoForceDeclareDsymbol(fdecl); 1420 DtoForceDeclareDsymbol(fdecl);
1418 funcval = fdecl->llvmValue; 1421 funcval = fdecl->irFunc->func;
1419 assert(funcval); 1422 assert(funcval);
1420 //assert(funcval->getType() == DtoType(fdecl->type)); 1423 //assert(funcval->getType() == DtoType(fdecl->type));
1421 } 1424 }
1422 return new DFuncValue(fdecl, funcval, vthis2); 1425 return new DFuncValue(fdecl, funcval, vthis2);
1423 } 1426 }
1436 Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars()); 1439 Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars());
1437 LOG_SCOPE; 1440 LOG_SCOPE;
1438 1441
1439 if (VarDeclaration* vd = var->isVarDeclaration()) { 1442 if (VarDeclaration* vd = var->isVarDeclaration()) {
1440 llvm::Value* v; 1443 llvm::Value* v;
1441 v = p->func()->decl->llvmThisVar; 1444 v = p->func()->decl->irFunc->thisVar;
1442 if (llvm::isa<llvm::AllocaInst>(v)) 1445 if (llvm::isa<llvm::AllocaInst>(v))
1443 v = new llvm::LoadInst(v, "tmp", p->scopebb()); 1446 v = new llvm::LoadInst(v, "tmp", p->scopebb());
1444 return new DThisValue(vd, v); 1447 return new DThisValue(vd, v);
1445 } 1448 }
1446 1449
2185 2188
2186 llvm::Value* uval; 2189 llvm::Value* uval;
2187 if (DFuncValue* f = u->isFunc()) { 2190 if (DFuncValue* f = u->isFunc()) {
2188 //assert(f->vthis); 2191 //assert(f->vthis);
2189 //uval = f->vthis; 2192 //uval = f->vthis;
2190 llvm::Value* nestvar = p->func()->decl->llvmNested; 2193 llvm::Value* nestvar = p->func()->decl->irFunc->nestedVar;
2191 if (nestvar) 2194 if (nestvar)
2192 uval = nestvar; 2195 uval = nestvar;
2193 else 2196 else
2194 uval = llvm::ConstantPointerNull::get(int8ptrty); 2197 uval = llvm::ConstantPointerNull::get(int8ptrty);
2195 } 2198 }
2211 else if (func->isAbstract()) 2214 else if (func->isAbstract())
2212 assert(0 && "TODO delegate to abstract method"); 2215 assert(0 && "TODO delegate to abstract method");
2213 else if (func->toParent()->isInterfaceDeclaration()) 2216 else if (func->toParent()->isInterfaceDeclaration())
2214 assert(0 && "TODO delegate to interface method"); 2217 assert(0 && "TODO delegate to interface method");
2215 else 2218 else
2216 castfptr = func->llvmValue; 2219 castfptr = func->irFunc->func;
2217 2220
2218 castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0)); 2221 castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0));
2219 DtoStore(castfptr, fptr); 2222 DtoStore(castfptr, fptr);
2220 2223
2221 return new DVarValue(type, lval, true); 2224 return new DVarValue(type, lval, true);
2438 temp = true; 2441 temp = true;
2439 } 2442 }
2440 2443
2441 llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb()); 2444 llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb());
2442 const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0)); 2445 const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0));
2443 llvm::Value* llvmNested = p->func()->decl->llvmNested; 2446 llvm::Value* llvmNested = p->func()->decl->irFunc->nestedVar;
2444 if (llvmNested == NULL) { 2447 if (llvmNested == NULL) {
2445 llvm::Value* nullcontext = llvm::ConstantPointerNull::get(pty); 2448 llvm::Value* nullcontext = llvm::ConstantPointerNull::get(pty);
2446 p->ir->CreateStore(nullcontext, context); 2449 p->ir->CreateStore(nullcontext, context);
2447 } 2450 }
2448 else { 2451 else {
2450 p->ir->CreateStore(nestedcontext, context); 2453 p->ir->CreateStore(nestedcontext, context);
2451 } 2454 }
2452 2455
2453 llvm::Value* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb()); 2456 llvm::Value* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb());
2454 2457
2455 assert(fd->llvmValue); 2458 assert(fd->irFunc->func);
2456 llvm::Value* castfptr = new llvm::BitCastInst(fd->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb()); 2459 llvm::Value* castfptr = new llvm::BitCastInst(fd->irFunc->func,fptr->getType()->getContainedType(0),"tmp",p->scopebb());
2457 new llvm::StoreInst(castfptr, fptr, p->scopebb()); 2460 new llvm::StoreInst(castfptr, fptr, p->scopebb());
2458 2461
2459 if (temp) 2462 if (temp)
2460 return new DVarValue(type, lval, true); 2463 return new DVarValue(type, lval, true);
2461 else 2464 else