comparison gen/classes.cpp @ 1148:3d1b16dabd25

Eliminated the need for resolve, declare, const-init and define lists to drive code generation.
author Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
date Fri, 27 Mar 2009 21:50:32 +0100
parents dbe4af57b240
children 5ebe8224988b
comparison
equal deleted inserted replaced
1147:dbe4af57b240 1148:3d1b16dabd25
122 } 122 }
123 } 123 }
124 124
125 ////////////////////////////////////////////////////////////////////////////////////////// 125 //////////////////////////////////////////////////////////////////////////////////////////
126 126
127 static void DtoDeclareInterface(InterfaceDeclaration* cd);
128 static void DtoConstInitInterface(InterfaceDeclaration* cd);
129 static void DtoDefineInterface(InterfaceDeclaration* cd);
130
127 static void DtoResolveInterface(InterfaceDeclaration* cd) 131 static void DtoResolveInterface(InterfaceDeclaration* cd)
128 { 132 {
129 if (cd->ir.resolved) return; 133 if (cd->ir.resolved) return;
130 cd->ir.resolved = true; 134 cd->ir.resolved = true;
131 135
154 158
155 InterfaceDeclaration* id = bc->base->isInterfaceDeclaration(); 159 InterfaceDeclaration* id = bc->base->isInterfaceDeclaration();
156 assert(id); 160 assert(id);
157 161
158 DtoResolveInterface(id); 162 DtoResolveInterface(id);
159 163
160 // add to interfaceInfos 164 // add to interfaceInfos
161 IrInterface* iri = new IrInterface(bc); 165 IrInterface* iri = new IrInterface(bc);
162 irstruct->interfaceVec.push_back(iri); 166 irstruct->interfaceVec.push_back(iri);
163 irstruct->classInfoInterfaces.push_back(iri); 167 irstruct->classInfoInterfaces.push_back(iri);
164 } 168 }
168 const LLType* t = LLArrayType::get(getVoidPtrType(), cd->vtbl.dim); 172 const LLType* t = LLArrayType::get(getVoidPtrType(), cd->vtbl.dim);
169 assert(!ts->ir.type); 173 assert(!ts->ir.type);
170 ts->ir.type = new LLPATypeHolder(getPtrToType(t)); 174 ts->ir.type = new LLPATypeHolder(getPtrToType(t));
171 175
172 // request declaration 176 // request declaration
173 gIR->declareList.push_back(cd); 177 DtoDeclareInterface(cd);
174 178
175 // handle members 179 // handle members
176 // like "nested" interfaces 180 // like "nested" interfaces
177 Array* arr = cd->members; 181 Array* arr = cd->members;
178 for (int k=0; k < arr->dim; k++) { 182 for (int k=0; k < arr->dim; k++) {
191 { 195 {
192 DtoResolveInterface(id); 196 DtoResolveInterface(id);
193 return; 197 return;
194 } 198 }
195 199
200 // make sure the base classes are processed first
201 if (cd->baseClass)
202 cd->baseClass->codegen(Type::sir);
203
196 if (cd->ir.resolved) return; 204 if (cd->ir.resolved) return;
197 cd->ir.resolved = true; 205 cd->ir.resolved = true;
198 206
199 Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 207 Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
200 LOG_SCOPE; 208 LOG_SCOPE;
201
202 //printf("resolve class: %s\n", cd->toPrettyChars());
203 209
204 // get the TypeClass 210 // get the TypeClass
205 assert(cd->type->ty == Tclass); 211 assert(cd->type->ty == Tclass);
206 TypeClass* ts = (TypeClass*)cd->type; 212 TypeClass* ts = (TypeClass*)cd->type;
207 213
219 // just name the type 225 // just name the type
220 gIR->module->addTypeName(cd->mangle(), ts->ir.type->get()); 226 gIR->module->addTypeName(cd->mangle(), ts->ir.type->get());
221 return; 227 return;
222 } 228 }
223 229
224 // resolve the base class 230 // create the symbols we're going to need
225 if (cd->baseClass) { 231 // avoids chicken egg problems
226 DtoResolveClass(cd->baseClass); 232 llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(cd);
227 } 233
234 // there is always a vtbl symbol
235 std::string varname("_D");
236 varname.append(cd->mangle());
237 varname.append("6__vtblZ");
238 irstruct->vtbl = new llvm::GlobalVariable(irstruct->vtblInitTy.get(), true, _linkage, NULL, varname, gIR->module);
239
240 // ... and initZ
241 std::string initname("_D");
242 initname.append(cd->mangle());
243 initname.append("6__initZ");
244 irstruct->init = new llvm::GlobalVariable(irstruct->initOpaque.get(), true, _linkage, NULL, initname, gIR->module);
228 245
229 // push state 246 // push state
230 gIR->structs.push_back(irstruct); 247 gIR->structs.push_back(irstruct);
231 248
232 // add vtable 249 // add vtable
250 267
251 // refine abstract types for stuff like: class C {C next;} 268 // refine abstract types for stuff like: class C {C next;}
252 llvm::PATypeHolder* spa = ts->ir.type; 269 llvm::PATypeHolder* spa = ts->ir.type;
253 llvm::cast<llvm::OpaqueType>(spa->get())->refineAbstractTypeTo(structtype); 270 llvm::cast<llvm::OpaqueType>(spa->get())->refineAbstractTypeTo(structtype);
254 structtype = isaStruct(spa->get()); 271 structtype = isaStruct(spa->get());
272 assert(structtype);
255 273
256 // name the type 274 // name the type
257 gIR->module->addTypeName(cd->mangle(), ts->ir.type->get()); 275 gIR->module->addTypeName(cd->mangle(), ts->ir.type->get());
258 276
259 // refine vtable type 277 // refine vtable type
267 285
268 // pop state 286 // pop state
269 gIR->structs.pop_back(); 287 gIR->structs.pop_back();
270 288
271 // queue declare 289 // queue declare
272 gIR->declareList.push_back(cd); 290 DtoDeclareClass(cd);
273 } 291 }
274 292
275 ////////////////////////////////////////////////////////////////////////////////////////// 293 //////////////////////////////////////////////////////////////////////////////////////////
276 294
277 static void DtoDeclareInterface(InterfaceDeclaration* cd) 295 static void DtoDeclareInterface(InterfaceDeclaration* cd)
278 { 296 {
297 DtoResolveInterface(cd);
298
279 if (cd->ir.declared) return; 299 if (cd->ir.declared) return;
280 cd->ir.declared = true; 300 cd->ir.declared = true;
281 301
282 Logger::println("DtoDeclareInterface(%s): %s", cd->toPrettyChars(), cd->locToChars()); 302 Logger::println("DtoDeclareInterface(%s): %s", cd->toPrettyChars(), cd->locToChars());
283 LOG_SCOPE; 303 LOG_SCOPE;
319 339
320 // declare the classinfo 340 // declare the classinfo
321 DtoDeclareClassInfo(cd); 341 DtoDeclareClassInfo(cd);
322 342
323 // request const init 343 // request const init
324 gIR->constInitList.push_back(cd); 344 DtoConstInitInterface(cd);
325 345
326 // emit typeinfo and request definition 346 // emit typeinfo and request definition
327 if (mustDefineSymbol(cd)) 347 if (mustDefineSymbol(cd))
328 { 348 {
329 gIR->defineList.push_back(cd); 349 DtoDefineInterface(cd);
330 DtoTypeInfoOf(cd->type, false); 350 DtoTypeInfoOf(cd->type, false);
331 } 351 }
332 } 352 }
333 353
334 ////////////////////////////////////////////////////////////////////////////////////////// 354 //////////////////////////////////////////////////////////////////////////////////////////
340 if (InterfaceDeclaration* id = cd->isInterfaceDeclaration()) 360 if (InterfaceDeclaration* id = cd->isInterfaceDeclaration())
341 { 361 {
342 DtoDeclareInterface(id); 362 DtoDeclareInterface(id);
343 return; 363 return;
344 } 364 }
365
366 DtoResolveClass(cd);
345 367
346 if (cd->ir.declared) return; 368 if (cd->ir.declared) return;
347 cd->ir.declared = true; 369 cd->ir.declared = true;
348 370
349 Logger::println("DtoDeclareClass(%s): %s", cd->toPrettyChars(), cd->locToChars()); 371 Logger::println("DtoDeclareClass(%s): %s", cd->toPrettyChars(), cd->locToChars());
363 if (mustDefineSymbol(cd)) { 385 if (mustDefineSymbol(cd)) {
364 needs_definition = true; 386 needs_definition = true;
365 } 387 }
366 388
367 llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(cd); 389 llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(cd);
368
369 // create vtbl symbol
370 std::string varname("_D");
371 varname.append(cd->mangle());
372 varname.append("6__vtblZ");
373 irstruct->vtbl = new llvm::GlobalVariable(irstruct->vtblInitTy.get(), true, _linkage, 0, varname, gIR->module);
374 390
375 // get interface info type 391 // get interface info type
376 const llvm::StructType* infoTy = DtoInterfaceInfoType(); 392 const llvm::StructType* infoTy = DtoInterfaceInfoType();
377 393
378 // interface info array 394 // interface info array
408 LLConstant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)}; 424 LLConstant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)};
409 iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2); 425 iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2);
410 idx++; 426 idx++;
411 } 427 }
412 428
413 // initZ init
414 std::string initname("_D");
415 initname.append(cd->mangle());
416 initname.append("6__initZ");
417
418 // initZ global
419 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(irstruct->initOpaque.get(), true, _linkage, NULL, initname, gIR->module);
420 irstruct->init = initvar;
421
422 gIR->structs.pop_back(); 429 gIR->structs.pop_back();
423 430
424 // request const init 431 // request const init
425 gIR->constInitList.push_back(cd); 432 DtoConstInitClass(cd);
426 433
427 // define ? (set initializers) 434 // define ? (set initializers)
428 if (needs_definition) 435 if (needs_definition)
429 gIR->defineList.push_back(cd); 436 DtoDefineClass(cd);
430 437
431 // classinfo 438 // classinfo
432 DtoDeclareClassInfo(cd); 439 DtoDeclareClassInfo(cd);
433 440
434 // do typeinfo ? 441 // do typeinfo ?
542 ////////////////////////////////////////////////////////////////////////////// 549 //////////////////////////////////////////////////////////////////////////////
543 550
544 // build the vtable initializer for class cd 551 // build the vtable initializer for class cd
545 static void init_class_vtbl_initializer(ClassDeclaration* cd) 552 static void init_class_vtbl_initializer(ClassDeclaration* cd)
546 { 553 {
554 cd->codegen(Type::sir);
555
547 // generate vtable initializer 556 // generate vtable initializer
548 std::vector<LLConstant*> sinits(cd->vtbl.dim, NULL); 557 std::vector<LLConstant*> sinits(cd->vtbl.dim, NULL);
549 558
550 IrStruct* irstruct = cd->ir.irStruct; 559 IrStruct* irstruct = cd->ir.irStruct;
551 560
552 assert(cd->vtbl.dim > 1); 561 assert(cd->vtbl.dim > 1);
562
563 DtoDeclareClassInfo(cd);
553 564
554 // first entry always classinfo 565 // first entry always classinfo
555 assert(irstruct->classInfo); 566 assert(irstruct->classInfo);
556 sinits[0] = DtoBitCast(irstruct->classInfo, DtoType(ClassDeclaration::classinfo->type)); 567 sinits[0] = DtoBitCast(irstruct->classInfo, DtoType(ClassDeclaration::classinfo->type));
557 568
573 { 584 {
574 sinits[k] = getNullPtr(getVoidPtrType()); 585 sinits[k] = getNullPtr(getVoidPtrType());
575 } 586 }
576 else 587 else
577 { 588 {
578 DtoForceDeclareDsymbol(fd); 589 fd->codegen(Type::sir);
590 Logger::println("F = %s", fd->toPrettyChars());
591 assert(fd->ir.irFunc);
579 assert(fd->ir.irFunc->func); 592 assert(fd->ir.irFunc->func);
580 sinits[k] = fd->ir.irFunc->func; 593 sinits[k] = fd->ir.irFunc->func;
581 } 594 }
582 595
583 // if (Logger::enabled()) 596 // if (Logger::enabled())
643 656
644 if (fd->isAbstract()) 657 if (fd->isAbstract())
645 inits[j] = getNullPtr(getVoidPtrType()); 658 inits[j] = getNullPtr(getVoidPtrType());
646 else 659 else
647 { 660 {
648 DtoForceDeclareDsymbol(fd); 661 fd->codegen(Type::sir);
649 662
650 assert(fd->ir.irFunc->func); 663 assert(fd->ir.irFunc->func);
651 inits[j] = fd->ir.irFunc->func; 664 inits[j] = fd->ir.irFunc->func;
652 } 665 }
653 666
660 } 673 }
661 674
662 // build the interface info for ClassInfo 675 // build the interface info for ClassInfo
663 // generate interface info initializer 676 // generate interface info initializer
664 677
665 DtoForceDeclareDsymbol(iri->decl); 678 iri->decl->codegen(Type::sir);
666 679
667 // classinfo 680 // classinfo
668 IrStruct* iris = iri->decl->ir.irStruct; 681 IrStruct* iris = iri->decl->ir.irStruct;
669 assert(iris); 682 assert(iris);
670 assert(iris->classInfo); 683 assert(iris->classInfo);
696 709
697 ////////////////////////////////////////////////////////////////////////////// 710 //////////////////////////////////////////////////////////////////////////////
698 711
699 static void DtoConstInitInterface(InterfaceDeclaration* cd) 712 static void DtoConstInitInterface(InterfaceDeclaration* cd)
700 { 713 {
714 DtoDeclareInterface(cd);
715
701 if (cd->ir.initialized) return; 716 if (cd->ir.initialized) return;
702 cd->ir.initialized = true; 717 cd->ir.initialized = true;
703 718
704 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 719 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
705 LOG_SCOPE; 720 LOG_SCOPE;
715 { 730 {
716 DtoConstInitInterface(it); 731 DtoConstInitInterface(it);
717 return; 732 return;
718 } 733 }
719 734
735 DtoDeclareClass(cd);
736
720 if (cd->ir.initialized) return; 737 if (cd->ir.initialized) return;
721 cd->ir.initialized = true; 738 cd->ir.initialized = true;
722 739
723 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 740 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
724 LOG_SCOPE; 741 LOG_SCOPE;
725
726 assert(!cd->isInterfaceDeclaration());
727
728 // make sure the baseclass is const initialized
729 if (cd->baseClass)
730 DtoForceConstInitDsymbol(cd->baseClass);
731 742
732 // get IrStruct 743 // get IrStruct
733 IrStruct* irstruct = cd->ir.irStruct; 744 IrStruct* irstruct = cd->ir.irStruct;
734 gIR->structs.push_back(irstruct); 745 gIR->structs.push_back(irstruct);
735 746
809 820
810 ////////////////////////////////////////////////////////////////////////////////////////// 821 //////////////////////////////////////////////////////////////////////////////////////////
811 822
812 static void DtoDefineInterface(InterfaceDeclaration* cd) 823 static void DtoDefineInterface(InterfaceDeclaration* cd)
813 { 824 {
825 DtoConstInitInterface(cd);
826
814 if (cd->ir.defined) return; 827 if (cd->ir.defined) return;
815 cd->ir.defined = true; 828 cd->ir.defined = true;
816 829
817 Logger::println("DtoDefineClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 830 Logger::println("DtoDefineClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
818 LOG_SCOPE; 831 LOG_SCOPE;
836 if (InterfaceDeclaration* id = cd->isInterfaceDeclaration()) 849 if (InterfaceDeclaration* id = cd->isInterfaceDeclaration())
837 { 850 {
838 DtoDefineInterface(id); 851 DtoDefineInterface(id);
839 return; 852 return;
840 } 853 }
854
855 DtoConstInitClass(cd);
841 856
842 if (cd->ir.defined) return; 857 if (cd->ir.defined) return;
843 cd->ir.defined = true; 858 cd->ir.defined = true;
844 859
845 Logger::println("DtoDefineClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 860 Logger::println("DtoDefineClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
896 ////////////////////////////////////////////////////////////////////////////////////////// 911 //////////////////////////////////////////////////////////////////////////////////////////
897 912
898 DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp) 913 DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp)
899 { 914 {
900 // resolve type 915 // resolve type
901 DtoForceDeclareDsymbol(tc->sym); 916 tc->sym->codegen(Type::sir);
902 917
903 // allocate 918 // allocate
904 LLValue* mem; 919 LLValue* mem;
905 if (newexp->onstack) 920 if (newexp->onstack)
906 { 921 {
907 mem = DtoAlloca(DtoType(tc)->getContainedType(0), ".newclass_alloca"); 922 mem = DtoAlloca(DtoType(tc)->getContainedType(0), ".newclass_alloca");
908 } 923 }
909 // custom allocator 924 // custom allocator
910 else if (newexp->allocator) 925 else if (newexp->allocator)
911 { 926 {
912 DtoForceDeclareDsymbol(newexp->allocator); 927 newexp->allocator->codegen(Type::sir);
913 DFuncValue dfn(newexp->allocator, newexp->allocator->ir.irFunc->func); 928 DFuncValue dfn(newexp->allocator, newexp->allocator->ir.irFunc->func);
914 DValue* res = DtoCallFunction(newexp->loc, NULL, &dfn, newexp->newargs); 929 DValue* res = DtoCallFunction(newexp->loc, NULL, &dfn, newexp->newargs);
915 mem = DtoBitCast(res->getRVal(), DtoType(tc), ".newclass_custom"); 930 mem = DtoBitCast(res->getRVal(), DtoType(tc), ".newclass_custom");
916 } 931 }
917 // default allocator 932 // default allocator
957 // call constructor 972 // call constructor
958 if (newexp->member) 973 if (newexp->member)
959 { 974 {
960 Logger::println("Calling constructor"); 975 Logger::println("Calling constructor");
961 assert(newexp->arguments != NULL); 976 assert(newexp->arguments != NULL);
962 DtoForceDeclareDsymbol(newexp->member); 977 newexp->member->codegen(Type::sir);
963 DFuncValue dfn(newexp->member, newexp->member->ir.irFunc->func, mem); 978 DFuncValue dfn(newexp->member, newexp->member->ir.irFunc->func, mem);
964 return DtoCallFunction(newexp->loc, tc, &dfn, newexp->arguments); 979 return DtoCallFunction(newexp->loc, tc, &dfn, newexp->arguments);
965 } 980 }
966 981
967 // return default constructed class 982 // return default constructed class
970 985
971 ////////////////////////////////////////////////////////////////////////////////////////// 986 //////////////////////////////////////////////////////////////////////////////////////////
972 987
973 void DtoInitClass(TypeClass* tc, LLValue* dst) 988 void DtoInitClass(TypeClass* tc, LLValue* dst)
974 { 989 {
975 DtoForceConstInitDsymbol(tc->sym); 990 tc->sym->codegen(Type::sir);
976 991
977 size_t presz = 2*getTypePaddedSize(DtoSize_t()); 992 size_t presz = 2*getTypePaddedSize(DtoSize_t());
978 uint64_t n = getTypePaddedSize(tc->ir.type->get()) - presz; 993 uint64_t n = getTypePaddedSize(tc->ir.type->get()) - presz;
979 994
980 // set vtable field seperately, this might give better optimization 995 // set vtable field seperately, this might give better optimization
1120 DValue* DtoDynamicCastObject(DValue* val, Type* _to) 1135 DValue* DtoDynamicCastObject(DValue* val, Type* _to)
1121 { 1136 {
1122 // call: 1137 // call:
1123 // Object _d_dynamic_cast(Object o, ClassInfo c) 1138 // Object _d_dynamic_cast(Object o, ClassInfo c)
1124 1139
1125 DtoForceDeclareDsymbol(ClassDeclaration::object); 1140 ClassDeclaration::object->codegen(Type::sir);
1126 DtoForceDeclareDsymbol(ClassDeclaration::classinfo); 1141 ClassDeclaration::classinfo->codegen(Type::sir);
1127 1142
1128 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_dynamic_cast"); 1143 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_dynamic_cast");
1129 const llvm::FunctionType* funcTy = func->getFunctionType(); 1144 const llvm::FunctionType* funcTy = func->getFunctionType();
1130 1145
1131 std::vector<LLValue*> args; 1146 std::vector<LLValue*> args;
1135 obj = DtoBitCast(obj, funcTy->getParamType(0)); 1150 obj = DtoBitCast(obj, funcTy->getParamType(0));
1136 assert(funcTy->getParamType(0) == obj->getType()); 1151 assert(funcTy->getParamType(0) == obj->getType());
1137 1152
1138 // ClassInfo c 1153 // ClassInfo c
1139 TypeClass* to = (TypeClass*)_to->toBasetype(); 1154 TypeClass* to = (TypeClass*)_to->toBasetype();
1140 DtoForceDeclareDsymbol(to->sym); 1155 to->sym->codegen(Type::sir);
1141 assert(to->sym->ir.irStruct->classInfo); 1156 assert(to->sym->ir.irStruct->classInfo);
1142 LLValue* cinfo = to->sym->ir.irStruct->classInfo; 1157 LLValue* cinfo = to->sym->ir.irStruct->classInfo;
1143 // unfortunately this is needed as the implementation of object differs somehow from the declaration 1158 // unfortunately this is needed as the implementation of object differs somehow from the declaration
1144 // this could happen in user code as well :/ 1159 // this could happen in user code as well :/
1145 cinfo = DtoBitCast(cinfo, funcTy->getParamType(1)); 1160 cinfo = DtoBitCast(cinfo, funcTy->getParamType(1));
1185 DValue* DtoDynamicCastInterface(DValue* val, Type* _to) 1200 DValue* DtoDynamicCastInterface(DValue* val, Type* _to)
1186 { 1201 {
1187 // call: 1202 // call:
1188 // Object _d_interface_cast(void* p, ClassInfo c) 1203 // Object _d_interface_cast(void* p, ClassInfo c)
1189 1204
1190 DtoForceDeclareDsymbol(ClassDeclaration::object); 1205 ClassDeclaration::object->codegen(Type::sir);
1191 DtoForceDeclareDsymbol(ClassDeclaration::classinfo); 1206 ClassDeclaration::classinfo->codegen(Type::sir);
1192 1207
1193 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_interface_cast"); 1208 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_interface_cast");
1194 const llvm::FunctionType* funcTy = func->getFunctionType(); 1209 const llvm::FunctionType* funcTy = func->getFunctionType();
1195 1210
1196 std::vector<LLValue*> args; 1211 std::vector<LLValue*> args;
1199 LLValue* ptr = val->getRVal(); 1214 LLValue* ptr = val->getRVal();
1200 ptr = DtoBitCast(ptr, funcTy->getParamType(0)); 1215 ptr = DtoBitCast(ptr, funcTy->getParamType(0));
1201 1216
1202 // ClassInfo c 1217 // ClassInfo c
1203 TypeClass* to = (TypeClass*)_to->toBasetype(); 1218 TypeClass* to = (TypeClass*)_to->toBasetype();
1204 DtoForceDeclareDsymbol(to->sym); 1219 to->sym->codegen(Type::sir);
1205 assert(to->sym->ir.irStruct->classInfo); 1220 assert(to->sym->ir.irStruct->classInfo);
1206 LLValue* cinfo = to->sym->ir.irStruct->classInfo; 1221 LLValue* cinfo = to->sym->ir.irStruct->classInfo;
1207 // unfortunately this is needed as the implementation of object differs somehow from the declaration 1222 // unfortunately this is needed as the implementation of object differs somehow from the declaration
1208 // this could happen in user code as well :/ 1223 // this could happen in user code as well :/
1209 cinfo = DtoBitCast(cinfo, funcTy->getParamType(1)); 1224 cinfo = DtoBitCast(cinfo, funcTy->getParamType(1));
1402 1417
1403 // if no destructor emit a null 1418 // if no destructor emit a null
1404 if (!dtor) 1419 if (!dtor)
1405 return getNullPtr(getVoidPtrType()); 1420 return getNullPtr(getVoidPtrType());
1406 1421
1407 DtoForceDeclareDsymbol(dtor); 1422 dtor->codegen(Type::sir);
1408 return llvm::ConstantExpr::getBitCast(dtor->ir.irFunc->func, getPtrToType(LLType::Int8Ty)); 1423 return llvm::ConstantExpr::getBitCast(dtor->ir.irFunc->func, getPtrToType(LLType::Int8Ty));
1409 } 1424 }
1410 1425
1411 static unsigned build_classinfo_flags(ClassDeclaration* cd) 1426 static unsigned build_classinfo_flags(ClassDeclaration* cd)
1412 { 1427 {
1478 1493
1479 // holds the list of initializers for llvm 1494 // holds the list of initializers for llvm
1480 std::vector<LLConstant*> inits; 1495 std::vector<LLConstant*> inits;
1481 1496
1482 ClassDeclaration* cinfo = ClassDeclaration::classinfo; 1497 ClassDeclaration* cinfo = ClassDeclaration::classinfo;
1483 DtoForceConstInitDsymbol(cinfo); 1498 cinfo->codegen(Type::sir);
1484 1499
1485 LLConstant* c; 1500 LLConstant* c;
1486 1501
1487 const LLType* voidPtr = getVoidPtrType(); 1502 const LLType* voidPtr = getVoidPtrType();
1488 const LLType* voidPtrPtr = getPtrToType(voidPtr); 1503 const LLType* voidPtrPtr = getPtrToType(voidPtr);
1573 // invariant 1588 // invariant
1574 VarDeclaration* invVar = (VarDeclaration*)cinfo->fields.data[6]; 1589 VarDeclaration* invVar = (VarDeclaration*)cinfo->fields.data[6];
1575 const LLType* invTy = DtoType(invVar->type); 1590 const LLType* invTy = DtoType(invVar->type);
1576 if (cd->inv) 1591 if (cd->inv)
1577 { 1592 {
1578 DtoForceDeclareDsymbol(cd->inv); 1593 cd->inv->codegen(Type::sir);
1579 c = cd->inv->ir.irFunc->func; 1594 c = cd->inv->ir.irFunc->func;
1580 c = DtoBitCast(c, invTy); 1595 c = DtoBitCast(c, invTy);
1581 } 1596 }
1582 else 1597 else
1583 c = LLConstant::getNullValue(invTy); 1598 c = LLConstant::getNullValue(invTy);
1593 inits.push_back(c); 1608 inits.push_back(c);
1594 1609
1595 // deallocator 1610 // deallocator
1596 if (cd->aggDelete) 1611 if (cd->aggDelete)
1597 { 1612 {
1598 DtoForceDeclareDsymbol(cd->aggDelete); 1613 cd->aggDelete->codegen(Type::sir);
1599 c = cd->aggDelete->ir.irFunc->func; 1614 c = cd->aggDelete->ir.irFunc->func;
1600 c = DtoBitCast(c, voidPtr); 1615 c = DtoBitCast(c, voidPtr);
1601 } 1616 }
1602 else 1617 else
1603 c = LLConstant::getNullValue(voidPtr); 1618 c = LLConstant::getNullValue(voidPtr);
1623 inits.push_back(c); 1638 inits.push_back(c);
1624 1639
1625 // default constructor 1640 // default constructor
1626 if (cd->defaultCtor) 1641 if (cd->defaultCtor)
1627 { 1642 {
1628 DtoForceDeclareDsymbol(cd->defaultCtor); 1643 cd->defaultCtor->codegen(Type::sir);
1629 c = isaConstant(cd->defaultCtor->ir.irFunc->func); 1644 c = isaConstant(cd->defaultCtor->ir.irFunc->func);
1630 c = DtoBitCast(c, voidPtr); 1645 c = DtoBitCast(c, voidPtr);
1631 } 1646 }
1632 else 1647 else
1633 c = LLConstant::getNullValue(voidPtr); 1648 c = LLConstant::getNullValue(voidPtr);