Mercurial > projects > ldc
comparison gen/classes.cpp @ 157:5c17f81fc1c1 trunk
[svn r173] moved IR state previously stored in Type into IrType and a Type->IrType map; fixes #7
author | ChristianK |
---|---|
date | Thu, 01 May 2008 13:32:08 +0200 |
parents | ccd07d9f2ce9 |
children | b77664331d06 |
comparison
equal
deleted
inserted
replaced
156:ccd07d9f2ce9 | 157:5c17f81fc1c1 |
---|---|
126 | 126 |
127 gIR->structs.push_back(irstruct); | 127 gIR->structs.push_back(irstruct); |
128 gIR->classes.push_back(cd); | 128 gIR->classes.push_back(cd); |
129 | 129 |
130 // add vtable | 130 // add vtable |
131 ts->llvmVtblType = new llvm::PATypeHolder(llvm::OpaqueType::get()); | 131 gIR->irType[ts].vtblType = new llvm::PATypeHolder(llvm::OpaqueType::get()); |
132 const llvm::Type* vtabty = getPtrToType(ts->llvmVtblType->get()); | 132 const llvm::Type* vtabty = getPtrToType(gIR->irType[ts].vtblType->get()); |
133 | 133 |
134 std::vector<const llvm::Type*> fieldtypes; | 134 std::vector<const llvm::Type*> fieldtypes; |
135 fieldtypes.push_back(vtabty); | 135 fieldtypes.push_back(vtabty); |
136 | 136 |
137 // add monitor | 137 // add monitor |
235 IrInterface* iri = *i; | 235 IrInterface* iri = *i; |
236 ClassDeclaration* id = iri->decl; | 236 ClassDeclaration* id = iri->decl; |
237 | 237 |
238 // set vtbl type | 238 // set vtbl type |
239 TypeClass* itc = (TypeClass*)id->type; | 239 TypeClass* itc = (TypeClass*)id->type; |
240 const llvm::Type* ivtblTy = getPtrToType(itc->llvmVtblType->get()); | 240 const llvm::Type* ivtblTy = getPtrToType(gIR->irType[itc].vtblType->get()); |
241 fieldtypes.push_back(ivtblTy); | 241 fieldtypes.push_back(ivtblTy); |
242 | 242 |
243 // fix the interface vtable type | 243 // fix the interface vtable type |
244 iri->vtblTy = isaStruct(itc->llvmVtblType->get()); | 244 iri->vtblTy = isaStruct(gIR->irType[itc].vtblType->get()); |
245 | 245 |
246 // set index | 246 // set index |
247 iri->index = interIdx++; | 247 iri->index = interIdx++; |
248 } | 248 } |
249 Logger::println("%d interface vtables added", gIR->irDsymbol[cd].irStruct->interfaceVec.size()); | 249 Logger::println("%d interface vtables added", gIR->irDsymbol[cd].irStruct->interfaceVec.size()); |
257 llvm::PATypeHolder& spa = irstruct->recty; | 257 llvm::PATypeHolder& spa = irstruct->recty; |
258 llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype); | 258 llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype); |
259 structtype = isaStruct(spa.get()); | 259 structtype = isaStruct(spa.get()); |
260 | 260 |
261 // make it official | 261 // make it official |
262 if (!ts->llvmType) | 262 if (!gIR->irType[ts].type) |
263 ts->llvmType = new llvm::PATypeHolder(structtype); | 263 gIR->irType[ts].type = new llvm::PATypeHolder(structtype); |
264 else | 264 else |
265 *ts->llvmType = structtype; | 265 *gIR->irType[ts].type = structtype; |
266 spa = *ts->llvmType; | 266 spa = *gIR->irType[ts].type; |
267 | 267 |
268 // name the type | 268 // name the type |
269 gIR->module->addTypeName(cd->mangle(), ts->llvmType->get()); | 269 gIR->module->addTypeName(cd->mangle(), gIR->irType[ts].type->get()); |
270 | 270 |
271 // get interface info type | 271 // get interface info type |
272 const llvm::StructType* infoTy = DtoInterfaceInfoType(); | 272 const llvm::StructType* infoTy = DtoInterfaceInfoType(); |
273 | 273 |
274 // create vtable type | 274 // create vtable type |
283 | 283 |
284 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { | 284 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { |
285 DtoResolveFunction(fd); | 285 DtoResolveFunction(fd); |
286 //assert(fd->type->ty == Tfunction); | 286 //assert(fd->type->ty == Tfunction); |
287 //TypeFunction* tf = (TypeFunction*)fd->type; | 287 //TypeFunction* tf = (TypeFunction*)fd->type; |
288 //const llvm::Type* fpty = getPtrToType(tf->llvmType->get()); | 288 //const llvm::Type* fpty = getPtrToType(gIR->irType[tf].type->get()); |
289 const llvm::FunctionType* vfty = DtoBaseFunctionType(fd); | 289 const llvm::FunctionType* vfty = DtoBaseFunctionType(fd); |
290 const llvm::Type* vfpty = getPtrToType(vfty); | 290 const llvm::Type* vfpty = getPtrToType(vfty); |
291 sinits_ty.push_back(vfpty); | 291 sinits_ty.push_back(vfpty); |
292 } | 292 } |
293 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { | 293 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { |
295 const llvm::Type* cinfoty; | 295 const llvm::Type* cinfoty; |
296 if (cd->isInterfaceDeclaration()) { | 296 if (cd->isInterfaceDeclaration()) { |
297 cinfoty = infoTy; | 297 cinfoty = infoTy; |
298 } | 298 } |
299 else if (cd != ClassDeclaration::classinfo) { | 299 else if (cd != ClassDeclaration::classinfo) { |
300 cinfoty = ClassDeclaration::classinfo->type->llvmType->get(); | 300 cinfoty = gIR->irType[ClassDeclaration::classinfo->type].type->get(); |
301 } | 301 } |
302 else { | 302 else { |
303 // this is the ClassInfo class, the type is this type | 303 // this is the ClassInfo class, the type is this type |
304 cinfoty = ts->llvmType->get(); | 304 cinfoty = gIR->irType[ts].type->get(); |
305 } | 305 } |
306 const llvm::Type* cty = getPtrToType(cinfoty); | 306 const llvm::Type* cty = getPtrToType(cinfoty); |
307 sinits_ty.push_back(cty); | 307 sinits_ty.push_back(cty); |
308 } | 308 } |
309 else | 309 else |
316 std::string styname(cd->mangle()); | 316 std::string styname(cd->mangle()); |
317 styname.append("__vtblType"); | 317 styname.append("__vtblType"); |
318 gIR->module->addTypeName(styname, svtbl_ty); | 318 gIR->module->addTypeName(styname, svtbl_ty); |
319 | 319 |
320 // refine for final vtable type | 320 // refine for final vtable type |
321 llvm::cast<llvm::OpaqueType>(ts->llvmVtblType->get())->refineAbstractTypeTo(svtbl_ty); | 321 llvm::cast<llvm::OpaqueType>(gIR->irType[ts].vtblType->get())->refineAbstractTypeTo(svtbl_ty); |
322 | 322 |
323 gIR->classes.pop_back(); | 323 gIR->classes.pop_back(); |
324 gIR->structs.pop_back(); | 324 gIR->structs.pop_back(); |
325 | 325 |
326 gIR->declareList.push_back(cd); | 326 gIR->declareList.push_back(cd); |
358 // vtable | 358 // vtable |
359 std::string varname("_D"); | 359 std::string varname("_D"); |
360 varname.append(cd->mangle()); | 360 varname.append(cd->mangle()); |
361 varname.append("6__vtblZ"); | 361 varname.append("6__vtblZ"); |
362 | 362 |
363 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get()); | 363 const llvm::StructType* svtbl_ty = isaStruct(gIR->irType[ts].vtblType->get()); |
364 gIR->irDsymbol[cd].irStruct->vtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module); | 364 gIR->irDsymbol[cd].irStruct->vtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module); |
365 } | 365 } |
366 | 366 |
367 // get interface info type | 367 // get interface info type |
368 const llvm::StructType* infoTy = DtoInterfaceInfoType(); | 368 const llvm::StructType* infoTy = DtoInterfaceInfoType(); |
406 // init | 406 // init |
407 std::string initname("_D"); | 407 std::string initname("_D"); |
408 initname.append(cd->mangle()); | 408 initname.append(cd->mangle()); |
409 initname.append("6__initZ"); | 409 initname.append("6__initZ"); |
410 | 410 |
411 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module); | 411 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(gIR->irType[ts].type->get(), true, _linkage, NULL, initname, gIR->module); |
412 gIR->irDsymbol[cd].irStruct->init = initvar; | 412 gIR->irDsymbol[cd].irStruct->init = initvar; |
413 } | 413 } |
414 | 414 |
415 gIR->classes.pop_back(); | 415 gIR->classes.pop_back(); |
416 gIR->structs.pop_back(); | 416 gIR->structs.pop_back(); |
445 gIR->classes.push_back(cd); | 445 gIR->classes.push_back(cd); |
446 | 446 |
447 // get the struct (class) type | 447 // get the struct (class) type |
448 assert(cd->type->ty == Tclass); | 448 assert(cd->type->ty == Tclass); |
449 TypeClass* ts = (TypeClass*)cd->type; | 449 TypeClass* ts = (TypeClass*)cd->type; |
450 const llvm::StructType* structtype = isaStruct(ts->llvmType->get()); | 450 const llvm::StructType* structtype = isaStruct(gIR->irType[ts].type->get()); |
451 const llvm::StructType* vtbltype = isaStruct(ts->llvmVtblType->get()); | 451 const llvm::StructType* vtbltype = isaStruct(gIR->irType[ts].vtblType->get()); |
452 | 452 |
453 // make sure each offset knows its default initializer | 453 // make sure each offset knows its default initializer |
454 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) | 454 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) |
455 { | 455 { |
456 IrStruct::Offset* so = &i->second; | 456 IrStruct::Offset* so = &i->second; |
466 if (cd->isAbstract()) | 466 if (cd->isAbstract()) |
467 { | 467 { |
468 fieldinits.push_back( | 468 fieldinits.push_back( |
469 llvm::ConstantPointerNull::get( | 469 llvm::ConstantPointerNull::get( |
470 getPtrToType( | 470 getPtrToType( |
471 ts->llvmVtblType->get() | 471 gIR->irType[ts].vtblType->get() |
472 ) | 472 ) |
473 ) | 473 ) |
474 ); | 474 ); |
475 } | 475 } |
476 else | 476 else |
567 } | 567 } |
568 else | 568 else |
569 assert(0); | 569 assert(0); |
570 } | 570 } |
571 | 571 |
572 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get()); | 572 const llvm::StructType* svtbl_ty = isaStruct(gIR->irType[ts].vtblType->get()); |
573 | 573 |
574 #if 0 | 574 #if 0 |
575 for (size_t i=0; i< sinits.size(); ++i) | 575 for (size_t i=0; i< sinits.size(); ++i) |
576 { | 576 { |
577 Logger::cout() << "field[" << i << "] = " << *svtbl_ty->getElementType(i) << '\n'; | 577 Logger::cout() << "field[" << i << "] = " << *svtbl_ty->getElementType(i) << '\n'; |
591 | 591 |
592 ClassDeclaration* id = iri->decl; | 592 ClassDeclaration* id = iri->decl; |
593 assert(id->type->ty == Tclass); | 593 assert(id->type->ty == Tclass); |
594 TypeClass* its = (TypeClass*)id->type; | 594 TypeClass* its = (TypeClass*)id->type; |
595 | 595 |
596 const llvm::StructType* ivtbl_ty = isaStruct(its->llvmVtblType->get()); | 596 const llvm::StructType* ivtbl_ty = isaStruct(gIR->irType[its].vtblType->get()); |
597 | 597 |
598 // generate interface info initializer | 598 // generate interface info initializer |
599 std::vector<llvm::Constant*> infoInits; | 599 std::vector<llvm::Constant*> infoInits; |
600 | 600 |
601 // classinfo | 601 // classinfo |
610 infoInits.push_back(c); | 610 infoInits.push_back(c); |
611 | 611 |
612 // offset | 612 // offset |
613 // generate target independent offset with constGEP | 613 // generate target independent offset with constGEP |
614 /*llvm::Value* cidx = DtoConstInt(iri->index); | 614 /*llvm::Value* cidx = DtoConstInt(iri->index); |
615 Logger::cout() << "offset to interface in class type: " << *cd->type->llvmType->get() << '\n'; | 615 Logger::cout() << "offset to interface in class type: " << *gIR->irType[cd->type].type->get() << '\n'; |
616 size_t ioff = gTargetData->getIndexedOffset(cd->type->llvmType->get(), &cidx, 1); | 616 size_t ioff = gTargetData->getIndexedOffset(gIR->irType[cd->type].type->get(), &cidx, 1); |
617 infoInits.push_back(DtoConstUint(ioff));*/ | 617 infoInits.push_back(DtoConstUint(ioff));*/ |
618 assert(iri->index >= 0); | 618 assert(iri->index >= 0); |
619 size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->llvmType->get()))->getElementOffset(iri->index); | 619 size_t ioff = gTargetData->getStructLayout(isaStruct(gIR->irType[cd->type].type->get()))->getElementOffset(iri->index); |
620 infoInits.push_back(DtoConstUint(ioff)); | 620 infoInits.push_back(DtoConstUint(ioff)); |
621 | 621 |
622 // create interface info initializer constant | 622 // create interface info initializer constant |
623 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits)); | 623 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits)); |
624 | 624 |
803 ////////////////////////////////////////////////////////////////////////////////////////// | 803 ////////////////////////////////////////////////////////////////////////////////////////// |
804 | 804 |
805 void DtoInitClass(TypeClass* tc, llvm::Value* dst) | 805 void DtoInitClass(TypeClass* tc, llvm::Value* dst) |
806 { | 806 { |
807 size_t presz = 2*getABITypeSize(DtoSize_t()); | 807 size_t presz = 2*getABITypeSize(DtoSize_t()); |
808 uint64_t n = getABITypeSize(tc->llvmType->get()) - presz; | 808 uint64_t n = getABITypeSize(gIR->irType[tc].type->get()) - presz; |
809 | 809 |
810 // set vtable field seperately, this might give better optimization | 810 // set vtable field seperately, this might give better optimization |
811 assert(gIR->irDsymbol[tc->sym].irStruct->vtbl); | 811 assert(gIR->irDsymbol[tc->sym].irStruct->vtbl); |
812 DtoStore(gIR->irDsymbol[tc->sym].irStruct->vtbl, DtoGEPi(dst,0,0,"vtbl")); | 812 DtoStore(gIR->irDsymbol[tc->sym].irStruct->vtbl, DtoGEPi(dst,0,0,"vtbl")); |
813 | 813 |
1197 if (!cd->isInterfaceDeclaration()) | 1197 if (!cd->isInterfaceDeclaration()) |
1198 gname.append("7__ClassZ"); | 1198 gname.append("7__ClassZ"); |
1199 else | 1199 else |
1200 gname.append("11__InterfaceZ"); | 1200 gname.append("11__InterfaceZ"); |
1201 | 1201 |
1202 const llvm::Type* st = cinfo->type->llvmType->get(); | 1202 const llvm::Type* st = gIR->irType[cinfo->type].type->get(); |
1203 | 1203 |
1204 gIR->irDsymbol[cd].irStruct->classInfo = new llvm::GlobalVariable(st, true, DtoLinkage(cd), NULL, gname, gIR->module); | 1204 gIR->irDsymbol[cd].irStruct->classInfo = new llvm::GlobalVariable(st, true, DtoLinkage(cd), NULL, gname, gIR->module); |
1205 } | 1205 } |
1206 | 1206 |
1207 static llvm::Constant* build_offti_entry(VarDeclaration* vd) | 1207 static llvm::Constant* build_offti_entry(VarDeclaration* vd) |
1222 vd->type->getTypeInfo(NULL); | 1222 vd->type->getTypeInfo(NULL); |
1223 assert(vd->type->vtinfo); | 1223 assert(vd->type->vtinfo); |
1224 DtoForceDeclareDsymbol(vd->type->vtinfo); | 1224 DtoForceDeclareDsymbol(vd->type->vtinfo); |
1225 llvm::Constant* c = isaConstant(gIR->irDsymbol[vd->type->vtinfo].getIrValue()); | 1225 llvm::Constant* c = isaConstant(gIR->irDsymbol[vd->type->vtinfo].getIrValue()); |
1226 | 1226 |
1227 const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get()); | 1227 const llvm::Type* tiTy = getPtrToType(gIR->irType[Type::typeinfo->type].type->get()); |
1228 //Logger::cout() << "tiTy = " << *tiTy << '\n'; | 1228 //Logger::cout() << "tiTy = " << *tiTy << '\n'; |
1229 | 1229 |
1230 types.push_back(tiTy); | 1230 types.push_back(tiTy); |
1231 inits.push_back(llvm::ConstantExpr::getBitCast(c, tiTy)); | 1231 inits.push_back(llvm::ConstantExpr::getBitCast(c, tiTy)); |
1232 | 1232 |
1263 | 1263 |
1264 if (ninits > 0) { | 1264 if (ninits > 0) { |
1265 // OffsetTypeInfo type | 1265 // OffsetTypeInfo type |
1266 std::vector<const llvm::Type*> elemtypes; | 1266 std::vector<const llvm::Type*> elemtypes; |
1267 elemtypes.push_back(DtoSize_t()); | 1267 elemtypes.push_back(DtoSize_t()); |
1268 const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get()); | 1268 const llvm::Type* tiTy = getPtrToType(gIR->irType[Type::typeinfo->type].type->get()); |
1269 elemtypes.push_back(tiTy); | 1269 elemtypes.push_back(tiTy); |
1270 const llvm::StructType* sTy = llvm::StructType::get(elemtypes); | 1270 const llvm::StructType* sTy = llvm::StructType::get(elemtypes); |
1271 | 1271 |
1272 // array type | 1272 // array type |
1273 const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits); | 1273 const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits); |
1288 | 1288 |
1289 static llvm::Constant* build_class_dtor(ClassDeclaration* cd) | 1289 static llvm::Constant* build_class_dtor(ClassDeclaration* cd) |
1290 { | 1290 { |
1291 // construct the function | 1291 // construct the function |
1292 std::vector<const llvm::Type*> paramTypes; | 1292 std::vector<const llvm::Type*> paramTypes; |
1293 paramTypes.push_back(getPtrToType(cd->type->llvmType->get())); | 1293 paramTypes.push_back(getPtrToType(gIR->irType[cd->type].type->get())); |
1294 | 1294 |
1295 const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy, paramTypes, false); | 1295 const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy, paramTypes, false); |
1296 | 1296 |
1297 if (cd->dtors.dim == 0) { | 1297 if (cd->dtors.dim == 0) { |
1298 return llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)); | 1298 return llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)); |