Mercurial > projects > ldc
comparison gen/toir.c @ 50:6fcc08a4d406 trunk
[svn r54] Added support for nested delegates referencing parent's stack variables.
Replaced tester.sh with a version written in D.
A few bugfixes.
author | lindquist |
---|---|
date | Mon, 22 Oct 2007 15:40:56 +0200 |
parents | e5c4bece7fa1 |
children | 61bc1b4ad3c4 |
comparison
equal
deleted
inserted
replaced
49:e5c4bece7fa1 | 50:6fcc08a4d406 |
---|---|
39 // variable declaration | 39 // variable declaration |
40 if (VarDeclaration* vd = declaration->isVarDeclaration()) | 40 if (VarDeclaration* vd = declaration->isVarDeclaration()) |
41 { | 41 { |
42 Logger::println("VarDeclaration"); | 42 Logger::println("VarDeclaration"); |
43 | 43 |
44 // static | |
44 if (vd->isDataseg()) | 45 if (vd->isDataseg()) |
45 { | 46 { |
46 vd->toObjFile(); | 47 vd->toObjFile(); |
47 } | 48 } |
48 else | 49 else |
49 { | 50 { |
50 // allocate storage on the stack | |
51 Logger::println("vdtype = %s", vd->type->toChars()); | 51 Logger::println("vdtype = %s", vd->type->toChars()); |
52 const llvm::Type* lltype = LLVM_DtoType(vd->type); | 52 // referenced by nested delegate? |
53 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); | 53 if (vd->nestedref) { |
54 //allocainst->setAlignment(vd->type->alignsize()); // TODO | 54 Logger::println("has nestedref set"); |
55 vd->llvmValue = allocainst; | 55 vd->llvmValue = p->func().decl->llvmNested; |
56 // e->val = really needed?? | 56 assert(vd->llvmValue); |
57 | 57 assert(vd->llvmNestedIndex >= 0); |
58 } | |
59 // normal stack variable | |
60 else { | |
61 // allocate storage on the stack | |
62 const llvm::Type* lltype = LLVM_DtoType(vd->type); | |
63 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); | |
64 //allocainst->setAlignment(vd->type->alignsize()); // TODO | |
65 vd->llvmValue = allocainst; | |
66 } | |
58 LLVM_DtoInitializer(vd->init); | 67 LLVM_DtoInitializer(vd->init); |
59 } | 68 } |
60 } | 69 } |
61 // struct declaration | 70 // struct declaration |
62 else if (StructDeclaration* s = declaration->isStructDeclaration()) | 71 else if (StructDeclaration* s = declaration->isStructDeclaration()) |
95 | 104 |
96 assert(var); | 105 assert(var); |
97 if (VarDeclaration* vd = var->isVarDeclaration()) | 106 if (VarDeclaration* vd = var->isVarDeclaration()) |
98 { | 107 { |
99 Logger::println("VarDeclaration"); | 108 Logger::println("VarDeclaration"); |
100 | 109 |
110 if (vd->nestedref) { | |
111 Logger::println("has nested ref"); | |
112 } | |
113 | |
101 // needed to take care of forward references of global variables | 114 // needed to take care of forward references of global variables |
102 if (!vd->llvmTouched && vd->isDataseg()) | 115 if (!vd->llvmTouched && vd->isDataseg()) |
103 vd->toObjFile(); | 116 vd->toObjFile(); |
104 | 117 |
105 if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) | 118 if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) |
109 | 122 |
110 // this must be a dollar expression or some other magic value | 123 // this must be a dollar expression or some other magic value |
111 // or it could be a forward declaration of a global variable | 124 // or it could be a forward declaration of a global variable |
112 if (!vd->llvmValue) | 125 if (!vd->llvmValue) |
113 { | 126 { |
127 assert(!vd->nestedref); | |
128 Logger::println("special - no llvmValue"); | |
114 // dollar | 129 // dollar |
115 if (!p->arrays.empty()) | 130 if (!p->arrays.empty()) |
116 { | 131 { |
117 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 132 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
118 //llvm::Value* tmp = new llvm::GetElementPtrInst(p->arrays.back(),zero,zero,"tmp",p->scopebb()); | 133 //llvm::Value* tmp = new llvm::GetElementPtrInst(p->arrays.back(),zero,zero,"tmp",p->scopebb()); |
135 return e; | 150 return e; |
136 } | 151 } |
137 | 152 |
138 // function parameter | 153 // function parameter |
139 if (vd->storage_class & STCparameter) { | 154 if (vd->storage_class & STCparameter) { |
155 assert(!vd->nestedref); | |
140 Logger::println("function param"); | 156 Logger::println("function param"); |
141 if (vd->storage_class & (STCref | STCout)) { | 157 if (vd->storage_class & (STCref | STCout)) { |
142 e->mem = vd->llvmValue; | 158 e->mem = vd->llvmValue; |
143 e->type = elem::VAR; | 159 e->type = elem::VAR; |
144 } | 160 } |
161 assert(0); | 177 assert(0); |
162 } | 178 } |
163 } | 179 } |
164 } | 180 } |
165 else { | 181 else { |
166 e->mem = vd->llvmValue; | 182 // nested variable |
167 //e->mem->setName(toChars()); | 183 if (vd->nestedref) { |
184 /* | |
185 FuncDeclaration* fd = vd->toParent()->isFuncDeclaration(); | |
186 assert(fd != NULL); | |
187 llvm::Value* ptr = NULL; | |
188 // inside nested function | |
189 if (fd != p->func().decl) { | |
190 ptr = p->func().decl->llvmThisVar; | |
191 Logger::cout() << "nested var reference:" << '\n' << *ptr << *vd->llvmValue->getType() << '\n'; | |
192 ptr = p->ir->CreateBitCast(ptr, vd->llvmValue->getType(), "tmp"); | |
193 } | |
194 // inside the actual parent function | |
195 else { | |
196 ptr = vd->llvmValue; | |
197 } | |
198 assert(ptr); | |
199 e->mem = LLVM_DtoGEPi(ptr,0,unsigned(vd->llvmNestedIndex),"tmp",p->scopebb()); | |
200 */ | |
201 e->mem = LLVM_DtoNestedVariable(vd); | |
202 } | |
203 // normal local variable | |
204 else { | |
205 e->mem = vd->llvmValue; | |
206 } | |
168 e->vardecl = vd; | 207 e->vardecl = vd; |
169 e->type = elem::VAR; | 208 e->type = elem::VAR; |
170 } | 209 } |
171 } | 210 } |
172 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) | 211 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) |
1281 if (VarDeclaration* vd = var->isVarDeclaration()) | 1320 if (VarDeclaration* vd = var->isVarDeclaration()) |
1282 { | 1321 { |
1283 Logger::println("VarDeclaration"); | 1322 Logger::println("VarDeclaration"); |
1284 assert(vd->llvmValue); | 1323 assert(vd->llvmValue); |
1285 Type* t = LLVM_DtoDType(type); | 1324 Type* t = LLVM_DtoDType(type); |
1286 Type* vdtype = LLVM_DtoDType(vd->type); | 1325 Type* vdtype = LLVM_DtoDType(vd->type); |
1326 | |
1327 llvm::Value* llvalue = vd->nestedref ? LLVM_DtoNestedVariable(vd) : vd->llvmValue; | |
1328 | |
1287 if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) { | 1329 if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) { |
1288 TypeStruct* vdt = (TypeStruct*)vdtype; | 1330 TypeStruct* vdt = (TypeStruct*)vdtype; |
1289 e = new elem; | 1331 e = new elem; |
1290 std::vector<unsigned> dst(1,0); | 1332 std::vector<unsigned> dst(1,0); |
1291 vdt->sym->offsetToIndex(t->next, offset, dst); | 1333 vdt->sym->offsetToIndex(t->next, offset, dst); |
1292 llvm::Value* ptr = vd->llvmValue; | 1334 llvm::Value* ptr = llvalue; |
1293 assert(ptr); | 1335 assert(ptr); |
1294 e->mem = LLVM_DtoGEP(ptr,dst,"tmp",p->scopebb()); | 1336 e->mem = LLVM_DtoGEP(ptr,dst,"tmp",p->scopebb()); |
1295 e->type = elem::VAL; | 1337 e->type = elem::VAL; |
1296 e->field = true; | 1338 e->field = true; |
1297 } | 1339 } |
1300 llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1342 llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1301 e->val = new llvm::GetElementPtrInst(vd->llvmValue,idx0,idx0,"tmp",p->scopebb());*/ | 1343 e->val = new llvm::GetElementPtrInst(vd->llvmValue,idx0,idx0,"tmp",p->scopebb());*/ |
1302 e = new elem; | 1344 e = new elem; |
1303 llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1345 llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1304 //llvm::Value* idx1 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | 1346 //llvm::Value* idx1 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); |
1305 e->mem = LLVM_DtoGEP(vd->llvmValue,idx0,idx0,"tmp",p->scopebb()); | 1347 e->mem = LLVM_DtoGEP(llvalue,idx0,idx0,"tmp",p->scopebb()); |
1306 e->arg = vd->llvmValue; | 1348 e->arg = llvalue; |
1307 e->type = elem::VAL; | 1349 e->type = elem::VAL; |
1308 } | 1350 } |
1309 else if (offset == 0) { | 1351 else if (offset == 0) { |
1310 /*if (!vd->llvmValue) | |
1311 vd->toObjFile();*/ | |
1312 assert(vd->llvmValue); | |
1313 e = new elem; | 1352 e = new elem; |
1314 e->mem = vd->llvmValue; | 1353 assert(llvalue); |
1315 //e->vardecl = vd; | 1354 e->mem = llvalue; |
1316 e->type = elem::VAL; | 1355 e->type = elem::VAL; |
1317 } | 1356 } |
1318 else { | 1357 else { |
1319 assert(0); | 1358 assert(0); |
1320 } | 1359 } |
1324 Logger::println("FuncDeclaration"); | 1363 Logger::println("FuncDeclaration"); |
1325 e = new elem; | 1364 e = new elem; |
1326 if (fd->llvmValue == 0) | 1365 if (fd->llvmValue == 0) |
1327 fd->toObjFile(); | 1366 fd->toObjFile(); |
1328 e->val = fd->llvmValue; | 1367 e->val = fd->llvmValue; |
1329 //e->aspointer = true; | |
1330 e->type = elem::FUNC; | 1368 e->type = elem::FUNC; |
1331 } | 1369 } |
1332 assert(e != 0); | 1370 assert(e != 0); |
1333 assert(e->type != elem::NONE); | 1371 assert(e->type != elem::NONE); |
1334 return e; | 1372 return e; |
2593 if (fd->isNested()) Logger::println("nested"); | 2631 if (fd->isNested()) Logger::println("nested"); |
2594 Logger::println("kind = %s\n", fd->kind()); | 2632 Logger::println("kind = %s\n", fd->kind()); |
2595 | 2633 |
2596 fd->toObjFile(); | 2634 fd->toObjFile(); |
2597 | 2635 |
2598 llvm::Value* lval = p->toplval(); | 2636 llvm::Value* lval = NULL; |
2637 if (p->lvals.empty() || p->toplval() == NULL) { | |
2638 const llvm::Type* dgty = LLVM_DtoType(type); | |
2639 Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n'; | |
2640 lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint()); | |
2641 } | |
2642 else { | |
2643 lval = p->toplval(); | |
2644 } | |
2599 | 2645 |
2600 elem* e = new elem; | 2646 elem* e = new elem; |
2601 | 2647 |
2602 llvm::Value* context = LLVM_DtoGEPi(lval,0,0,"tmp",p->scopebb()); | 2648 llvm::Value* context = LLVM_DtoGEPi(lval,0,0,"tmp",p->scopebb()); |
2603 //llvm::Value* castcontext = llvm::ConstantPointerNull::get(context->getType()); | 2649 const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(context->getType()->getContainedType(0)); |
2604 //new llvm::StoreInst(castcontext, context, p->scopebb()); | 2650 llvm::Value* llvmNested = p->func().decl->llvmNested; |
2651 if (llvmNested == NULL) { | |
2652 llvm::Value* nullcontext = llvm::ConstantPointerNull::get(pty); | |
2653 p->ir->CreateStore(nullcontext, context); | |
2654 } | |
2655 else { | |
2656 llvm::Value* nestedcontext = p->ir->CreateBitCast(llvmNested, pty, "tmp"); | |
2657 p->ir->CreateStore(nestedcontext, context); | |
2658 } | |
2605 | 2659 |
2606 llvm::Value* fptr = LLVM_DtoGEPi(lval,0,1,"tmp",p->scopebb()); | 2660 llvm::Value* fptr = LLVM_DtoGEPi(lval,0,1,"tmp",p->scopebb()); |
2607 | 2661 |
2608 assert(fd->llvmValue); | 2662 assert(fd->llvmValue); |
2609 llvm::Value* castfptr = new llvm::BitCastInst(fd->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb()); | 2663 llvm::Value* castfptr = new llvm::BitCastInst(fd->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb()); |
2610 new llvm::StoreInst(castfptr, fptr, p->scopebb()); | 2664 new llvm::StoreInst(castfptr, fptr, p->scopebb()); |
2611 | 2665 |
2612 e->inplace = true; | 2666 e->inplace = true; |
2667 e->mem = lval; | |
2668 e->type = elem::VAR; | |
2613 | 2669 |
2614 return e; | 2670 return e; |
2615 } | 2671 } |
2616 | 2672 |
2617 ////////////////////////////////////////////////////////////////////////////////////////// | 2673 ////////////////////////////////////////////////////////////////////////////////////////// |