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;