Mercurial > projects > ldc
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); |