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));