Mercurial > projects > ldc
comparison gen/classes.cpp @ 833:482cd74d1c71
Add all base interfaces to interfaceMap, not just direct parents.
Removed some superfluous 'static'.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sun, 07 Dec 2008 16:43:20 +0100 |
parents | a70ddd449e7d |
children | 3afe9f276db7 |
comparison
equal
deleted
inserted
replaced
832:0cc0c6b53372 | 833:482cd74d1c71 |
---|---|
19 | 19 |
20 #include "ir/irstruct.h" | 20 #include "ir/irstruct.h" |
21 | 21 |
22 ////////////////////////////////////////////////////////////////////////////////////////// | 22 ////////////////////////////////////////////////////////////////////////////////////////// |
23 | 23 |
24 // adds the base interfaces of b and the given iri to IrStruct's interfaceMap | |
25 void add_base_interfaces(IrStruct* to, IrInterface* iri, BaseClass* b) | |
26 { | |
27 for (unsigned j = 0; j < b->baseInterfaces_dim; j++) | |
28 { | |
29 BaseClass *bc = &b->baseInterfaces[j]; | |
30 // add to map | |
31 if (to->interfaceMap.find(bc->base) == to->interfaceMap.end()) | |
32 { | |
33 to->interfaceMap.insert(std::make_pair(bc->base, iri)); | |
34 } | |
35 // add base interfaces | |
36 add_base_interfaces(to, iri, bc); | |
37 } | |
38 } | |
39 | |
24 // adds interface b to target, if newinstance != 0, then target must provide all | 40 // adds interface b to target, if newinstance != 0, then target must provide all |
25 // functions required to implement b (it reimplements b) | 41 // functions required to implement b (it reimplements b) |
26 static void add_interface(ClassDeclaration* target, BaseClass* b, int newinstance) | 42 void add_interface(ClassDeclaration* target, BaseClass* b, int newinstance) |
27 { | 43 { |
28 Logger::println("adding interface: %s", b->base->toChars()); | 44 Logger::println("adding interface: %s", b->base->toChars()); |
29 LOG_SCOPE; | 45 LOG_SCOPE; |
30 | 46 |
31 InterfaceDeclaration* inter = b->base->isInterfaceDeclaration(); | 47 InterfaceDeclaration* inter = b->base->isInterfaceDeclaration(); |
57 | 73 |
58 // add to classinfo interfaces | 74 // add to classinfo interfaces |
59 if (newinstance) | 75 if (newinstance) |
60 irstruct->classInfoInterfaces.push_back(iri); | 76 irstruct->classInfoInterfaces.push_back(iri); |
61 | 77 |
62 // assign this iri to all base interfaces of this one | 78 // recursively assign this iri to all base interfaces |
63 for (unsigned j = 0; j < b->baseInterfaces_dim; j++) | 79 add_base_interfaces(irstruct, iri, b); |
64 { | |
65 BaseClass *bc = &b->baseInterfaces[j]; | |
66 // add to map | |
67 if (irstruct->interfaceMap.find(bc->base) == irstruct->interfaceMap.end()) | |
68 { | |
69 irstruct->interfaceMap.insert(std::make_pair(bc->base, iri)); | |
70 } | |
71 } | |
72 | 80 |
73 // build the interface vtable | 81 // build the interface vtable |
74 b->fillVtbl(target, &iri->vtblDecls, newinstance); | 82 b->fillVtbl(target, &iri->vtblDecls, newinstance); |
75 | 83 |
76 // add the vtable type | 84 // add the vtable type |
80 iri->index = irstruct->index++; | 88 iri->index = irstruct->index++; |
81 } | 89 } |
82 | 90 |
83 ////////////////////////////////////////////////////////////////////////////////////////// | 91 ////////////////////////////////////////////////////////////////////////////////////////// |
84 | 92 |
85 static void add_class_data(ClassDeclaration* target, ClassDeclaration* cd) | 93 void add_class_data(ClassDeclaration* target, ClassDeclaration* cd) |
86 { | 94 { |
87 Logger::println("Adding data from class: %s", cd->toChars()); | 95 Logger::println("Adding data from class: %s", cd->toChars()); |
88 LOG_SCOPE; | 96 LOG_SCOPE; |
89 | 97 |
90 // recurse into baseClasses | 98 // recurse into baseClasses |
115 } | 123 } |
116 } | 124 } |
117 | 125 |
118 ////////////////////////////////////////////////////////////////////////////////////////// | 126 ////////////////////////////////////////////////////////////////////////////////////////// |
119 | 127 |
120 static void DtoResolveInterface(InterfaceDeclaration* cd) | 128 void DtoResolveInterface(InterfaceDeclaration* cd) |
121 { | 129 { |
122 if (cd->ir.resolved) return; | 130 if (cd->ir.resolved) return; |
123 cd->ir.resolved = true; | 131 cd->ir.resolved = true; |
124 | 132 |
125 Logger::println("DtoResolveInterface(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); | 133 Logger::println("DtoResolveInterface(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); |
265 gIR->declareList.push_back(cd); | 273 gIR->declareList.push_back(cd); |
266 } | 274 } |
267 | 275 |
268 ////////////////////////////////////////////////////////////////////////////////////////// | 276 ////////////////////////////////////////////////////////////////////////////////////////// |
269 | 277 |
270 static void DtoDeclareInterface(InterfaceDeclaration* cd) | 278 void DtoDeclareInterface(InterfaceDeclaration* cd) |
271 { | 279 { |
272 if (cd->ir.declared) return; | 280 if (cd->ir.declared) return; |
273 cd->ir.declared = true; | 281 cd->ir.declared = true; |
274 | 282 |
275 Logger::println("DtoDeclareInterface(%s): %s", cd->toPrettyChars(), cd->locToChars()); | 283 Logger::println("DtoDeclareInterface(%s): %s", cd->toPrettyChars(), cd->locToChars()); |
430 } | 438 } |
431 | 439 |
432 ////////////////////////////////////////////////////////////////////////////// | 440 ////////////////////////////////////////////////////////////////////////////// |
433 | 441 |
434 // adds data fields and interface vtables to the constant initializer of class cd | 442 // adds data fields and interface vtables to the constant initializer of class cd |
435 static size_t init_class_initializer(std::vector<LLConstant*>& inits, ClassDeclaration* target, ClassDeclaration* cd, size_t offsetbegin) | 443 size_t init_class_initializer(std::vector<LLConstant*>& inits, ClassDeclaration* target, ClassDeclaration* cd, size_t offsetbegin) |
436 { | 444 { |
437 // first do baseclasses | 445 // first do baseclasses |
438 if (cd->baseClass) | 446 if (cd->baseClass) |
439 { | 447 { |
440 offsetbegin = init_class_initializer(inits, target, cd->baseClass, offsetbegin); | 448 offsetbegin = init_class_initializer(inits, target, cd->baseClass, offsetbegin); |
533 } | 541 } |
534 | 542 |
535 ////////////////////////////////////////////////////////////////////////////// | 543 ////////////////////////////////////////////////////////////////////////////// |
536 | 544 |
537 // build the vtable initializer for class cd | 545 // build the vtable initializer for class cd |
538 static void init_class_vtbl_initializer(ClassDeclaration* cd) | 546 void init_class_vtbl_initializer(ClassDeclaration* cd) |
539 { | 547 { |
540 // generate vtable initializer | 548 // generate vtable initializer |
541 std::vector<LLConstant*> sinits(cd->vtbl.dim, NULL); | 549 std::vector<LLConstant*> sinits(cd->vtbl.dim, NULL); |
542 | 550 |
543 IrStruct* irstruct = cd->ir.irStruct; | 551 IrStruct* irstruct = cd->ir.irStruct; |
586 // Logger::cout() << "vtbl initializer: " << *irstruct->constVtbl << std::endl; | 594 // Logger::cout() << "vtbl initializer: " << *irstruct->constVtbl << std::endl; |
587 } | 595 } |
588 | 596 |
589 ////////////////////////////////////////////////////////////////////////////// | 597 ////////////////////////////////////////////////////////////////////////////// |
590 | 598 |
591 static void init_class_interface_vtbl_initializers(ClassDeclaration* cd) | 599 void init_class_interface_vtbl_initializers(ClassDeclaration* cd) |
592 { | 600 { |
593 IrStruct* irstruct = cd->ir.irStruct; | 601 IrStruct* irstruct = cd->ir.irStruct; |
594 | 602 |
595 // don't do anything if list is empty | 603 // don't do anything if list is empty |
596 if (irstruct->interfaceVec.empty()) | 604 if (irstruct->interfaceVec.empty()) |
687 } | 695 } |
688 } | 696 } |
689 | 697 |
690 ////////////////////////////////////////////////////////////////////////////// | 698 ////////////////////////////////////////////////////////////////////////////// |
691 | 699 |
692 static void DtoConstInitInterface(InterfaceDeclaration* cd) | 700 void DtoConstInitInterface(InterfaceDeclaration* cd) |
693 { | 701 { |
694 if (cd->ir.initialized) return; | 702 if (cd->ir.initialized) return; |
695 cd->ir.initialized = true; | 703 cd->ir.initialized = true; |
696 | 704 |
697 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); | 705 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); |
770 gIR->structs.pop_back(); | 778 gIR->structs.pop_back(); |
771 } | 779 } |
772 | 780 |
773 ////////////////////////////////////////////////////////////////////////////////////////// | 781 ////////////////////////////////////////////////////////////////////////////////////////// |
774 | 782 |
775 static void DefineInterfaceInfos(IrStruct* irstruct) | 783 void DefineInterfaceInfos(IrStruct* irstruct) |
776 { | 784 { |
777 // always do interface info array when possible | 785 // always do interface info array when possible |
778 std::vector<LLConstant*> infoInits; | 786 std::vector<LLConstant*> infoInits; |
779 | 787 |
780 size_t n = irstruct->interfaceVec.size(); | 788 size_t n = irstruct->interfaceVec.size(); |
800 } | 808 } |
801 } | 809 } |
802 | 810 |
803 ////////////////////////////////////////////////////////////////////////////////////////// | 811 ////////////////////////////////////////////////////////////////////////////////////////// |
804 | 812 |
805 static void DtoDefineInterface(InterfaceDeclaration* cd) | 813 void DtoDefineInterface(InterfaceDeclaration* cd) |
806 { | 814 { |
807 if (cd->ir.defined) return; | 815 if (cd->ir.defined) return; |
808 cd->ir.defined = true; | 816 cd->ir.defined = true; |
809 | 817 |
810 Logger::println("DtoDefineClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); | 818 Logger::println("DtoDefineClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); |
1046 Logger::println("from interface"); | 1054 Logger::println("from interface"); |
1047 return DtoDynamicCastInterface(val, _to); | 1055 return DtoDynamicCastInterface(val, _to); |
1048 } | 1056 } |
1049 // class -> interface - static cast | 1057 // class -> interface - static cast |
1050 else if (it->isBaseOf(fc->sym,NULL)) { | 1058 else if (it->isBaseOf(fc->sym,NULL)) { |
1051 Logger::println("static down cast)"); | 1059 Logger::println("static down cast"); |
1052 // get the from class | 1060 // get the from class |
1053 ClassDeclaration* cd = fc->sym->isClassDeclaration(); | 1061 ClassDeclaration* cd = fc->sym->isClassDeclaration(); |
1054 IrStruct* irstruct = cd->ir.irStruct; | 1062 IrStruct* irstruct = cd->ir.irStruct; |
1055 // find interface impl | 1063 // find interface impl |
1056 IrStruct::InterfaceMapIter iriter = irstruct->interfaceMap.find(it); | 1064 IrStruct::InterfaceMapIter iriter = irstruct->interfaceMap.find(it); |
1313 ////////////////////////////////////////////////////////////////////////////////////////// | 1321 ////////////////////////////////////////////////////////////////////////////////////////// |
1314 | 1322 |
1315 #if GENERATE_OFFTI | 1323 #if GENERATE_OFFTI |
1316 | 1324 |
1317 // build a single element for the OffsetInfo[] of ClassInfo | 1325 // build a single element for the OffsetInfo[] of ClassInfo |
1318 static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd) | 1326 LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd) |
1319 { | 1327 { |
1320 std::vector<LLConstant*> inits(2); | 1328 std::vector<LLConstant*> inits(2); |
1321 | 1329 |
1322 // size_t offset; | 1330 // size_t offset; |
1323 // | 1331 // |
1338 | 1346 |
1339 // done | 1347 // done |
1340 return llvm::ConstantStruct::get(inits); | 1348 return llvm::ConstantStruct::get(inits); |
1341 } | 1349 } |
1342 | 1350 |
1343 static LLConstant* build_offti_array(ClassDeclaration* cd, const LLType* arrayT) | 1351 LLConstant* build_offti_array(ClassDeclaration* cd, const LLType* arrayT) |
1344 { | 1352 { |
1345 IrStruct* irstruct = cd->ir.irStruct; | 1353 IrStruct* irstruct = cd->ir.irStruct; |
1346 | 1354 |
1347 size_t nvars = irstruct->varDecls.size(); | 1355 size_t nvars = irstruct->varDecls.size(); |
1348 std::vector<LLConstant*> arrayInits(nvars); | 1356 std::vector<LLConstant*> arrayInits(nvars); |
1373 return DtoConstSlice(size, ptr); | 1381 return DtoConstSlice(size, ptr); |
1374 } | 1382 } |
1375 | 1383 |
1376 #endif // GENERATE_OFFTI | 1384 #endif // GENERATE_OFFTI |
1377 | 1385 |
1378 static LLConstant* build_class_dtor(ClassDeclaration* cd) | 1386 LLConstant* build_class_dtor(ClassDeclaration* cd) |
1379 { | 1387 { |
1380 FuncDeclaration* dtor = cd->dtor; | 1388 FuncDeclaration* dtor = cd->dtor; |
1381 | 1389 |
1382 // if no destructor emit a null | 1390 // if no destructor emit a null |
1383 if (!dtor) | 1391 if (!dtor) |
1385 | 1393 |
1386 DtoForceDeclareDsymbol(dtor); | 1394 DtoForceDeclareDsymbol(dtor); |
1387 return llvm::ConstantExpr::getBitCast(dtor->ir.irFunc->func, getPtrToType(LLType::Int8Ty)); | 1395 return llvm::ConstantExpr::getBitCast(dtor->ir.irFunc->func, getPtrToType(LLType::Int8Ty)); |
1388 } | 1396 } |
1389 | 1397 |
1390 static unsigned build_classinfo_flags(ClassDeclaration* cd) | 1398 unsigned build_classinfo_flags(ClassDeclaration* cd) |
1391 { | 1399 { |
1392 // adapted from original dmd code | 1400 // adapted from original dmd code |
1393 unsigned flags = 0; | 1401 unsigned flags = 0; |
1394 //flags |= isCOMclass(); // IUnknown | 1402 //flags |= isCOMclass(); // IUnknown |
1395 bool hasOffTi = false; | 1403 bool hasOffTi = false; |