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 //////////////////////////////////////////////////////////////////////////////////////////