Mercurial > projects > ldc
comparison gen/toir.cpp @ 102:027b8d8b71ec trunk
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
Basically it tries to do the following in order: Resolve types, Declare symbols, Create constant initializers, Apply initializers, Generate functions bodies.
ClassInfo is now has the most useful(biased?) members working.
Probably other stuf...
author | lindquist |
---|---|
date | Sun, 18 Nov 2007 06:52:57 +0100 |
parents | 169fda3a77d4 |
children | 4d1e9eb001e0 |
comparison
equal
deleted
inserted
replaced
101:169fda3a77d4 | 102:027b8d8b71ec |
---|---|
25 #include "gen/tollvm.h" | 25 #include "gen/tollvm.h" |
26 #include "gen/runtime.h" | 26 #include "gen/runtime.h" |
27 #include "gen/arrays.h" | 27 #include "gen/arrays.h" |
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 | 31 |
31 #include "gen/dvalue.h" | 32 #include "gen/dvalue.h" |
32 | 33 |
33 ////////////////////////////////////////////////////////////////////////////////////////// | 34 ////////////////////////////////////////////////////////////////////////////////////////// |
34 | 35 |
43 Logger::println("VarDeclaration"); | 44 Logger::println("VarDeclaration"); |
44 | 45 |
45 // static | 46 // static |
46 if (vd->isDataseg()) | 47 if (vd->isDataseg()) |
47 { | 48 { |
48 vd->toObjFile(); | 49 vd->toObjFile(); // TODO |
49 } | 50 } |
50 else | 51 else |
51 { | 52 { |
52 Logger::println("vdtype = %s", vd->type->toChars()); | 53 Logger::println("vdtype = %s", vd->type->toChars()); |
53 // referenced by nested delegate? | 54 // referenced by nested delegate? |
73 } | 74 } |
74 // struct declaration | 75 // struct declaration |
75 else if (StructDeclaration* s = declaration->isStructDeclaration()) | 76 else if (StructDeclaration* s = declaration->isStructDeclaration()) |
76 { | 77 { |
77 Logger::println("StructDeclaration"); | 78 Logger::println("StructDeclaration"); |
78 s->toObjFile(); | 79 DtoForceConstInitDsymbol(s); |
79 } | 80 } |
80 // function declaration | 81 // function declaration |
81 else if (FuncDeclaration* f = declaration->isFuncDeclaration()) | 82 else if (FuncDeclaration* f = declaration->isFuncDeclaration()) |
82 { | 83 { |
83 Logger::println("FuncDeclaration"); | 84 Logger::println("FuncDeclaration"); |
84 f->toObjFile(); | 85 DtoForceDeclareDsymbol(f); |
85 } | 86 } |
86 // alias declaration | 87 // alias declaration |
87 else if (AliasDeclaration* a = declaration->isAliasDeclaration()) | 88 else if (AliasDeclaration* a = declaration->isAliasDeclaration()) |
88 { | 89 { |
89 Logger::println("AliasDeclaration - no work"); | 90 Logger::println("AliasDeclaration - no work"); |
143 } | 144 } |
144 // typeinfo | 145 // typeinfo |
145 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) | 146 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) |
146 { | 147 { |
147 Logger::println("TypeInfoDeclaration"); | 148 Logger::println("TypeInfoDeclaration"); |
148 tid->toObjFile(); | 149 DtoForceDeclareDsymbol(tid); |
149 assert(tid->llvmValue); | 150 assert(tid->llvmValue); |
150 const llvm::Type* vartype = DtoType(type); | 151 const llvm::Type* vartype = DtoType(type); |
151 llvm::Value* m; | 152 llvm::Value* m; |
152 if (tid->llvmValue->getType() != llvm::PointerType::get(vartype)) | 153 if (tid->llvmValue->getType() != llvm::PointerType::get(vartype)) |
153 m = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp"); | 154 m = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp"); |
157 } | 158 } |
158 // classinfo | 159 // classinfo |
159 else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration()) | 160 else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration()) |
160 { | 161 { |
161 Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars()); | 162 Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars()); |
163 DtoDeclareClassInfo(cid->cd); | |
162 assert(cid->cd->llvmClass); | 164 assert(cid->cd->llvmClass); |
163 return new DVarValue(vd, cid->cd->llvmClass, true); | 165 return new DVarValue(vd, cid->cd->llvmClass, true); |
164 } | 166 } |
165 // nested variable | 167 // nested variable |
166 else if (vd->nestedref) { | 168 else if (vd->nestedref) { |
197 } | 199 } |
198 } | 200 } |
199 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) | 201 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) |
200 { | 202 { |
201 Logger::println("FuncDeclaration"); | 203 Logger::println("FuncDeclaration"); |
202 if (fdecl->llvmInternal != LLVMva_arg)// && fdecl->llvmValue == 0) | 204 if (fdecl->llvmInternal != LLVMva_arg) {// && fdecl->llvmValue == 0) |
203 fdecl->toObjFile(); | 205 DtoForceDeclareDsymbol(fdecl); |
206 } | |
204 return new DFuncValue(fdecl, fdecl->llvmValue); | 207 return new DFuncValue(fdecl, fdecl->llvmValue); |
205 } | 208 } |
206 else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) | 209 else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) |
207 { | 210 { |
208 // this seems to be the static initialiser for structs | 211 // this seems to be the static initialiser for structs |
232 // this seems to be the static initialiser for structs | 235 // this seems to be the static initialiser for structs |
233 Type* sdecltype = DtoDType(sdecl->type); | 236 Type* sdecltype = DtoDType(sdecl->type); |
234 Logger::print("Sym: type=%s\n", sdecltype->toChars()); | 237 Logger::print("Sym: type=%s\n", sdecltype->toChars()); |
235 assert(sdecltype->ty == Tstruct); | 238 assert(sdecltype->ty == Tstruct); |
236 TypeStruct* ts = (TypeStruct*)sdecltype; | 239 TypeStruct* ts = (TypeStruct*)sdecltype; |
237 ts->sym->toObjFile(); | 240 DtoForceConstInitDsymbol(ts->sym); |
238 DtoConstInitStruct(ts->sym); | |
239 assert(ts->sym->llvmInitZ); | 241 assert(ts->sym->llvmInitZ); |
240 return ts->sym->llvmInitZ; | 242 return ts->sym->llvmInitZ; |
241 } | 243 } |
242 assert(0 && "Only supported const VarExp is of a SymbolDeclaration"); | 244 assert(0 && "Only supported const VarExp is of a SymbolDeclaration"); |
243 return NULL; | 245 return NULL; |
1061 Type* e1type = DtoDType(e1->type); | 1063 Type* e1type = DtoDType(e1->type); |
1062 | 1064 |
1063 bool delegateCall = false; | 1065 bool delegateCall = false; |
1064 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false); | 1066 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false); |
1065 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty,1,false); | 1067 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty,1,false); |
1066 LINK dlink = LINKdefault; | 1068 LINK dlink = LINKd; |
1067 | 1069 |
1068 // hidden struct return parameter handling | 1070 // hidden struct return parameter handling |
1069 bool retinptr = false; | 1071 bool retinptr = false; |
1070 | 1072 |
1071 // regular functions | 1073 // regular functions |
1115 const llvm::Type* llt = DtoType(type); | 1117 const llvm::Type* llt = DtoType(type); |
1116 if (DtoIsPassedByRef(t)) | 1118 if (DtoIsPassedByRef(t)) |
1117 llt = llvm::PointerType::get(llt); | 1119 llt = llvm::PointerType::get(llt); |
1118 // TODO | 1120 // TODO |
1119 if (strcmp(global.params.llvmArch, "x86") != 0) { | 1121 if (strcmp(global.params.llvmArch, "x86") != 0) { |
1120 warning("va_arg for C variadic functions is broken for anything but x86"); | 1122 warning("%s: va_arg for C variadic functions is broken for anything but x86", loc.toChars()); |
1121 } | 1123 } |
1122 return new DImValue(type, p->ir->CreateVAArg(expelem->getLVal(),llt,"tmp")); | 1124 return new DImValue(type, p->ir->CreateVAArg(expelem->getLVal(),llt,"tmp")); |
1123 } | 1125 } |
1124 else if (fndecl->llvmInternal == LLVMalloca) { | 1126 else if (fndecl->llvmInternal == LLVMalloca) { |
1125 //Argument* fnarg = Argument::getNth(tf->parameters, 0); | 1127 //Argument* fnarg = Argument::getNth(tf->parameters, 0); |
1265 Expression* argexp = (Expression*)arguments->data[i]; | 1267 Expression* argexp = (Expression*)arguments->data[i]; |
1266 vvalues.push_back(DtoArgument(NULL, fnarg, argexp)); | 1268 vvalues.push_back(DtoArgument(NULL, fnarg, argexp)); |
1267 vtypes.push_back(vvalues.back()->getType()); | 1269 vtypes.push_back(vvalues.back()->getType()); |
1268 | 1270 |
1269 TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration(); | 1271 TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration(); |
1270 tidecl->toObjFile(); | 1272 DtoForceDeclareDsymbol(tidecl); |
1271 assert(tidecl->llvmValue); | 1273 assert(tidecl->llvmValue); |
1272 vtypeinfos.push_back(tidecl->llvmValue); | 1274 vtypeinfos.push_back(tidecl->llvmValue); |
1273 } | 1275 } |
1274 | 1276 |
1275 const llvm::StructType* vtype = llvm::StructType::get(vtypes); | 1277 const llvm::StructType* vtype = llvm::StructType::get(vtypes); |
1304 for (int i=0; i<arguments->dim; i++,j++) { | 1306 for (int i=0; i<arguments->dim; i++,j++) { |
1305 Argument* fnarg = Argument::getNth(tf->parameters, i); | 1307 Argument* fnarg = Argument::getNth(tf->parameters, i); |
1306 llargs[j] = DtoArgument(llfnty->getParamType(j), fnarg, (Expression*)arguments->data[i]); | 1308 llargs[j] = DtoArgument(llfnty->getParamType(j), fnarg, (Expression*)arguments->data[i]); |
1307 // this hack is necessary :/ | 1309 // this hack is necessary :/ |
1308 if (dfn && dfn->func && dfn->func->llvmRunTimeHack) { | 1310 if (dfn && dfn->func && dfn->func->llvmRunTimeHack) { |
1309 if (llargs[j]->getType() != llfnty->getParamType(j)) | 1311 Logger::println("llvmRunTimeHack==true"); |
1312 if (llargs[j]->getType() != llfnty->getParamType(j)) { | |
1310 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j)); | 1313 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j)); |
1314 } | |
1311 } | 1315 } |
1312 } | 1316 } |
1313 Logger::println("%d params passed", n); | 1317 Logger::println("%d params passed", n); |
1314 for (int i=0; i<n; ++i) { | 1318 for (int i=0; i<n; ++i) { |
1315 assert(llargs[i]); | 1319 assert(llargs[i]); |
1334 int li = dfn->func->llvmInternal; | 1338 int li = dfn->func->llvmInternal; |
1335 if (li != LLVMintrinsic && li != LLVMva_start && li != LLVMva_intrinsic) { | 1339 if (li != LLVMintrinsic && li != LLVMva_start && li != LLVMva_intrinsic) { |
1336 call->setCallingConv(DtoCallingConv(dlink)); | 1340 call->setCallingConv(DtoCallingConv(dlink)); |
1337 } | 1341 } |
1338 } | 1342 } |
1339 else if (delegateCall) { | 1343 /*else if (delegateCall) { |
1340 call->setCallingConv(DtoCallingConv(dlink)); | 1344 call->setCallingConv(DtoCallingConv(dlink)); |
1341 } | 1345 }*/ |
1342 else if (dfn && dfn->cc != (unsigned)-1) { | 1346 else if (dfn && dfn->cc != (unsigned)-1) { |
1343 call->setCallingConv(dfn->cc); | 1347 call->setCallingConv(dfn->cc); |
1344 } | 1348 } |
1345 else if (llvm::isa<llvm::LoadInst>(funcval)) { | 1349 else { |
1346 call->setCallingConv(DtoCallingConv(dlink)); | 1350 call->setCallingConv(DtoCallingConv(dlink)); |
1347 } | 1351 } |
1348 | 1352 |
1349 return new DImValue(type, retllval, isInPlace); | 1353 return new DImValue(type, retllval, isInPlace); |
1350 } | 1354 } |
1383 assert(0 && "SymOffExp::toElem should no longer be called :/"); | 1387 assert(0 && "SymOffExp::toElem should no longer be called :/"); |
1384 | 1388 |
1385 if (VarDeclaration* vd = var->isVarDeclaration()) | 1389 if (VarDeclaration* vd = var->isVarDeclaration()) |
1386 { | 1390 { |
1387 Logger::println("VarDeclaration"); | 1391 Logger::println("VarDeclaration"); |
1388 if (!vd->llvmTouched && vd->isDataseg()) | 1392 |
1389 vd->toObjFile(); | 1393 // handle forward reference |
1394 if (!vd->llvmDeclared && vd->isDataseg()) { | |
1395 vd->toObjFile(); // TODO | |
1396 } | |
1390 | 1397 |
1391 assert(vd->llvmValue); | 1398 assert(vd->llvmValue); |
1392 Type* t = DtoDType(type); | 1399 Type* t = DtoDType(type); |
1393 Type* tnext = DtoDType(t->next); | 1400 Type* tnext = DtoDType(t->next); |
1394 Type* vdtype = DtoDType(vd->type); | 1401 Type* vdtype = DtoDType(vd->type); |
1463 else if (DFuncValue* fv = v->isFunc()) { | 1470 else if (DFuncValue* fv = v->isFunc()) { |
1464 //Logger::println("FuncDeclaration"); | 1471 //Logger::println("FuncDeclaration"); |
1465 FuncDeclaration* fd = fv->func; | 1472 FuncDeclaration* fd = fv->func; |
1466 assert(fd); | 1473 assert(fd); |
1467 if (fd->llvmValue == 0) | 1474 if (fd->llvmValue == 0) |
1468 fd->toObjFile(); | 1475 DtoForceDeclareDsymbol(fd); |
1469 return new DFuncValue(fd, fd->llvmValue); | 1476 return new DFuncValue(fd, fd->llvmValue); |
1470 } | 1477 } |
1471 else if (DImValue* im = v->isIm()) { | 1478 else if (DImValue* im = v->isIm()) { |
1472 return v; | 1479 return v; |
1473 } | 1480 } |
1537 } | 1544 } |
1538 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) | 1545 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) |
1539 { | 1546 { |
1540 if (fdecl->llvmValue == 0) | 1547 if (fdecl->llvmValue == 0) |
1541 { | 1548 { |
1542 fdecl->toObjFile(); | 1549 DtoForceDeclareDsymbol(fdecl); |
1543 } | 1550 } |
1544 | 1551 |
1545 llvm::Value* funcval = fdecl->llvmValue; | 1552 llvm::Value* funcval = fdecl->llvmValue; |
1546 llvm::Value* vthis = l->getRVal(); | 1553 llvm::Value* vthis = l->getRVal(); |
1547 unsigned cc = (unsigned)-1; | 1554 unsigned cc = (unsigned)-1; |
2097 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 2104 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
2098 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | 2105 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); |
2099 llvm::Value* ptr = DtoGEP(val,zero,one,"tmp",p->scopebb()); | 2106 llvm::Value* ptr = DtoGEP(val,zero,one,"tmp",p->scopebb()); |
2100 ptr = new llvm::LoadInst(ptr,"tmp",p->scopebb()); | 2107 ptr = new llvm::LoadInst(ptr,"tmp",p->scopebb()); |
2101 new llvm::FreeInst(ptr, p->scopebb()); | 2108 new llvm::FreeInst(ptr, p->scopebb()); |
2102 DtoNullArray(val); | 2109 DtoSetArrayToNull(val); |
2103 } | 2110 } |
2104 else { | 2111 else { |
2105 assert(0); | 2112 assert(0); |
2106 } | 2113 } |
2107 | 2114 |
2505 assert(fd); | 2512 assert(fd); |
2506 | 2513 |
2507 if (fd->isNested()) Logger::println("nested"); | 2514 if (fd->isNested()) Logger::println("nested"); |
2508 Logger::println("kind = %s\n", fd->kind()); | 2515 Logger::println("kind = %s\n", fd->kind()); |
2509 | 2516 |
2510 fd->toObjFile(); | 2517 DtoForceDeclareDsymbol(fd); |
2511 | 2518 |
2512 bool temp = false; | 2519 bool temp = false; |
2513 llvm::Value* lval = NULL; | 2520 llvm::Value* lval = NULL; |
2514 if (p->topexp() && p->topexp()->e2 == this) { | 2521 if (p->topexp() && p->topexp()->e2 == this) { |
2515 assert(p->topexp()->v); | 2522 assert(p->topexp()->v); |