Changeset 797:340acf1535d0
- Timestamp:
- 11/29/08 15:25:43 (1 month ago)
- Children:
- Files:
-
- dmd/aggregate.h (modified) (2 diffs)
- dmd/attrib.c (modified) (2 diffs)
- dmd/attrib.h (modified) (2 diffs)
- dmd/declaration.c (modified) (1 diff)
- dmd/declaration.h (modified) (1 diff)
- dmd/expression.h (modified) (1 diff)
- dmd/mars.c (modified) (1 diff)
- dmd/mars.h (modified) (1 diff)
- dmd/mtype.c (modified) (1 diff)
- dmd/mtype.h (modified) (1 diff)
- dmd2/aggregate.h (modified) (2 diffs)
- dmd2/attrib.c (modified) (2 diffs)
- dmd2/attrib.h (modified) (1 diff)
- dmd2/declaration.c (modified) (1 diff)
- dmd2/declaration.h (modified) (1 diff)
- dmd2/expression.h (modified) (1 diff)
- dmd2/mars.c (modified) (1 diff)
- dmd2/mars.h (modified) (1 diff)
- dmd2/mtype.c (modified) (1 diff)
- dmd2/mtype.h (modified) (1 diff)
- gen/arrays.cpp (modified) (6 diffs)
- gen/arrays.h (modified) (1 diff)
- gen/classes.cpp (modified) (38 diffs)
- gen/functions.cpp (modified) (12 diffs)
- gen/irstate.h (modified) (2 diffs)
- gen/llvmhelpers.cpp (modified) (15 diffs)
- gen/llvmhelpers.h (modified) (2 diffs)
- gen/runtime.cpp (modified) (3 diffs)
- gen/statements.cpp (modified) (1 diff)
- gen/structs.cpp (modified) (9 diffs)
- gen/structs.h (modified) (1 diff)
- gen/tocall.cpp (modified) (2 diffs)
- gen/todebug.cpp (modified) (1 diff)
- gen/toir.cpp (modified) (9 diffs)
- gen/tollvm.cpp (modified) (4 diffs)
- gen/tollvm.h (modified) (2 diffs)
- gen/toobj.cpp (modified) (10 diffs)
- gen/typinf.cpp (modified) (27 diffs)
- ir/irstruct.cpp (modified) (4 diffs)
- ir/irstruct.h (modified) (2 diffs)
- ir/irtype.cpp (modified) (2 diffs)
- ir/irtype.h (modified) (1 diff)
- ir/irvar.cpp (modified) (2 diffs)
- ir/irvar.h (modified) (1 diff)
- llvmdc.kdevelop (deleted)
- llvmdc.kdevelop.filelist (deleted)
- tests/mini/interface3.d (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
dmd/aggregate.h
r336 r797 46 46 class GlobalVariable; 47 47 } 48 struct DUnion;49 48 50 49 struct AggregateDeclaration : ScopeDsymbol … … 259 258 Symbol *vtblsym; 260 259 261 // llvm262 void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result);263 264 260 ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } 265 261 }; dmd/attrib.c
r794 r797 617 617 aad.structalign = sc->structalign; 618 618 aad.parent = ad; 619 620 619 for (unsigned i = 0; i < decl->dim; i++) 621 620 { … … 672 671 { 673 672 VarDeclaration *v = (VarDeclaration *)aad.fields.data[i]; 673 674 // LDC 675 v->offset2 = sc->offset; 674 676 675 677 v->offset += sc->offset; dmd/attrib.h
r710 r797 51 51 AttribDeclaration *isAttribDeclaration() { return this; } 52 52 53 v oid toObjFile(int multiobj); // compile to .obj file53 virtual void toObjFile(int multiobj); // compile to .obj file 54 54 int cvMember(unsigned char *p); 55 55 }; … … 108 108 void toCBuffer(OutBuffer *buf, HdrGenState *hgs); 109 109 const char *kind(); 110 111 // LDC 112 void toObjFile(int multiobj); // compile to .obj file 110 113 }; 111 114 dmd/declaration.c
r737 r797 625 625 // LDC 626 626 anonDecl = NULL; 627 offset2 = 0; 627 628 } 628 629 dmd/declaration.h
r751 r797 274 274 // LDC 275 275 AnonDeclaration* anonDecl; 276 unsigned offset2; 276 277 }; 277 278 dmd/expression.h
r664 r797 629 629 //Expression *doInline(InlineDoState *ids); 630 630 //Expression *inlineScan(InlineScanState *iss); 631 632 // LDC 633 virtual llvm::Constant *toConstElem(IRState *irs); 631 634 }; 632 635 dmd/mars.c
r788 r797 1197 1197 } 1198 1198 } 1199 #endif 1199 1200 if (global.errors) 1200 1201 fatal(); 1201 #endif1202 1202 1203 1203 // Generate output files dmd/mars.h
r735 r797 346 346 347 347 /*** Where to send error messages ***/ 348 #if IN_GCC 348 #if IN_GCC || IN_LLVM 349 349 #define stdmsg stderr 350 350 #else dmd/mtype.c
r780 r797 3185 3185 { 3186 3186 return PTRSIZE * 2; 3187 } 3188 3189 // LDC added, no reason to align to 2*PTRSIZE 3190 unsigned TypeDelegate::alignsize() 3191 { 3192 // A Delegate consists of two ptr values, so align it on pointer size 3193 // boundary 3194 return PTRSIZE; 3187 3195 } 3188 3196 dmd/mtype.h
r758 r797 452 452 Type *semantic(Loc loc, Scope *sc); 453 453 d_uns64 size(Loc loc); 454 unsigned alignsize(); // added in LDC 454 455 void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 455 456 Expression *defaultInit(Loc loc); dmd2/aggregate.h
r758 r797 46 46 class GlobalVariable; 47 47 } 48 struct DUnion;49 48 50 49 struct AggregateDeclaration : ScopeDsymbol … … 265 264 Symbol *vtblsym; 266 265 267 // llvm268 void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result);269 270 266 ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } 271 267 }; dmd2/attrib.c
r758 r797 630 630 aad.structalign = sc->structalign; 631 631 aad.parent = ad; 632 633 632 for (unsigned i = 0; i < decl->dim; i++) 634 633 { … … 685 684 { 686 685 VarDeclaration *v = (VarDeclaration *)aad.fields.data[i]; 686 687 // LDC 688 v->offset2 = sc->offset; 687 689 688 690 v->offset += sc->offset; dmd2/attrib.h
r758 r797 51 51 AttribDeclaration *isAttribDeclaration() { return this; } 52 52 53 v oid toObjFile(int multiobj); // compile to .obj file53 virtual void toObjFile(int multiobj); // compile to .obj file 54 54 int cvMember(unsigned char *p); 55 55 }; dmd2/declaration.c
r758 r797 619 619 // LDC 620 620 anonDecl = NULL; 621 offset2 = 0; 621 622 } 622 623 dmd2/declaration.h
r758 r797 280 280 // LDC 281 281 AnonDeclaration* anonDecl; 282 unsigned offset2; 282 283 }; 283 284 dmd2/expression.h
r758 r797 654 654 //Expression *doInline(InlineDoState *ids); 655 655 //Expression *inlineScan(InlineScanState *iss); 656 657 // LDC 658 virtual llvm::Constant *toConstElem(IRState *irs); 656 659 }; 657 660 dmd2/mars.c
r789 r797 1221 1221 } 1222 1222 } 1223 #endif 1223 1224 if (global.errors) 1224 1225 fatal(); 1225 #endif1226 1226 1227 1227 // Generate output files dmd2/mars.h
r758 r797 351 351 352 352 /*** Where to send error messages ***/ 353 #if IN_GCC 353 #if IN_GCC || IN_LLVM 354 354 #define stdmsg stderr 355 355 #else dmd2/mtype.c
r771 r797 3695 3695 } 3696 3696 3697 // LDC added, no reason to align to 2*PTRSIZE 3698 unsigned TypeDelegate::alignsize() 3699 { 3700 // A Delegate consists of two ptr values, so align it on pointer size 3701 // boundary 3702 return PTRSIZE; 3703 } 3704 3697 3705 void TypeDelegate::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 3698 3706 { dmd2/mtype.h
r758 r797 517 517 Type *semantic(Loc loc, Scope *sc); 518 518 d_uns64 size(Loc loc); 519 unsigned alignsize(); // added in LDC 519 520 void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 520 521 Expression *defaultInit(Loc loc); gen/arrays.cpp
r796 r797 209 209 210 210 ////////////////////////////////////////////////////////////////////////////////////////// 211 212 // FIXME: this looks like it could use a cleanup 213 211 214 LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit) 212 215 { … … 241 244 Type* arrnext = arrinittype->nextOf(); 242 245 const LLType* elemty = DtoType(arrinittype->nextOf()); 246 247 // true if there is a mismatch with one of the initializers 248 bool mismatch = false; 243 249 244 250 assert(arrinit->index.dim == arrinit->value.dim); … … 293 299 assert(v); 294 300 301 // global arrays of unions might have type mismatch for each element 302 // if there is any mismatch at all, we need to use a struct instead :/ 303 if (v->getType() != elemty) 304 mismatch = true; 305 295 306 inits[i] = v; 296 307 if (Logger::enabled()) … … 299 310 300 311 Logger::println("building constant array"); 312 313 LLConstant* constarr; 301 314 const LLArrayType* arrty = LLArrayType::get(elemty,tdim); 302 LLConstant* constarr = LLConstantArray::get(arrty, inits); 315 316 if (mismatch) 317 { 318 constarr = LLConstantStruct::get(inits); 319 } 320 else 321 { 322 constarr = LLConstantArray::get(arrty, inits); 323 } 324 325 #if 0 326 if (Logger::enabled()) 327 { 328 Logger::cout() << "array type: " << *arrty << '\n'; 329 size_t n = inits.size(); 330 for (size_t i=0; i<n; i++) 331 Logger::cout() << " init " << i << " = " << *inits[i] << '\n'; 332 } 333 #endif 303 334 304 335 if (arrinittype->ty == Tsarray) … … 307 338 assert(arrinittype->ty == Tarray); 308 339 309 LLGlobalVariable* gvar = new LLGlobalVariable( arrty,true,LLGlobalValue::InternalLinkage,constarr,".constarray",gIR->module);340 LLGlobalVariable* gvar = new LLGlobalVariable(constarr->getType(),true,LLGlobalValue::InternalLinkage,constarr,".constarray",gIR->module); 310 341 LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; 342 311 343 LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); 344 gep = llvm::ConstantExpr::getBitCast(gvar, getPtrToType(elemty)); 345 312 346 return DtoConstSlice(DtoConstSize_t(tdim),gep); 313 347 } … … 793 827 // return result 794 828 return (op == TOKnotidentity) ? gIR->ir->CreateNot(res) : res; 795 }796 797 //////////////////////////////////////////////////////////////////////////////////////////798 LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c)799 {800 const LLArrayType* at = isaArray(t);801 assert(at);802 803 if (isaArray(at->getElementType()))804 {805 c = DtoConstStaticArray(at->getElementType(), c);806 }807 else {808 assert(at->getElementType() == c->getType());809 }810 std::vector<LLConstant*> initvals;811 initvals.resize(at->getNumElements(), c);812 return llvm::ConstantArray::get(at, initvals);813 829 } 814 830 gen/arrays.h
r591 r797 10 10 LLConstant* DtoConstArrayInitializer(ArrayInitializer* si); 11 11 LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr); 12 LLConstant* DtoConstStaticArray(const LLType* t, LLConstant* c);13 12 14 13 void DtoArrayCopySlices(DSliceValue* dst, DSliceValue* src); gen/classes.cpp
r796 r797 22 22 ////////////////////////////////////////////////////////////////////////////////////////// 23 23 24 static void LLVM_AddBaseClassInterfaces(ClassDeclaration* target, BaseClasses* bcs) 25 { 26 // add base class data members first 27 for (int j=0; j<bcs->dim; j++) 28 { 29 BaseClass* bc = (BaseClass*)(bcs->data[j]); 30 31 // base *classes* might add more interfaces? 32 DtoResolveClass(bc->base); 33 LLVM_AddBaseClassInterfaces(target, &bc->base->baseclasses); 34 35 // resolve interfaces while we're at it 36 if (bc->base->isInterfaceDeclaration()) 24 // adds interface b to target, if newinstance != 0, then target must provide all 25 // functions required to implement b (it reimplements b) 26 static void add_interface(ClassDeclaration* target, BaseClass* b, int newinstance) 27 { 28 Logger::println("adding interface: %s", b->base->toChars()); 29 LOG_SCOPE; 30 31 InterfaceDeclaration* inter = b->base->isInterfaceDeclaration(); 32 DtoResolveClass(inter); 33 34 assert(inter); 35 IrStruct* irstruct = target->ir.irStruct; 36 assert(irstruct); 37 38 // add interface to map/list 39 // if it's already inserted in the map, it's because another interface has it as baseclass 40 // but if it appears here, it's because we're reimplementing it, so we overwrite the IrInterface entry 41 IrInterface* iri; 42 bool overwrite = false; 43 if (irstruct->interfaceMap.find(inter) != irstruct->interfaceMap.end()) 44 { 45 overwrite = true; 46 } 47 48 iri = new IrInterface(b); 49 // add to map 50 if (overwrite) 51 irstruct->interfaceMap[b->base] = iri; 52 else 53 irstruct->interfaceMap.insert(std::make_pair(b->base, iri)); 54 // add to ordered list 55 irstruct->interfaceVec.push_back(iri); 56 57 // assign this iri to all base interfaces of this one 58 for (unsigned j = 0; j < b->baseInterfaces_dim; j++) 59 { 60 BaseClass *bc = &b->baseInterfaces[j]; 61 // add to map 62 if (irstruct->interfaceMap.find(bc->base) == irstruct->interfaceMap.end()) 37 63 { 38 // don't add twice 39 if (target->ir.irStruct->interfaceMap.find(bc->base) == target->ir.irStruct->interfaceMap.end()) 40 { 41 Logger::println("adding interface '%s'", bc->base->toPrettyChars()); 42 IrInterface* iri = new IrInterface(bc); 43 44 // add to map 45 target->ir.irStruct->interfaceMap.insert(std::make_pair(bc->base, iri)); 46 // add to ordered list 47 target->ir.irStruct->interfaceVec.push_back(iri); 48 49 // Fill in vtbl[] 50 if (!target->isAbstract()) { 51 bc->fillVtbl(target, &bc->vtbl, 0); 52 } 53 } 64 irstruct->interfaceMap.insert(std::make_pair(bc->base, iri)); 54 65 } 55 66 } 56 } 57 58 ////////////////////////////////////////////////////////////////////////////////////////// 59 60 static void LLVM_AddBaseClassData(IrStruct* irstruct, BaseClasses* bcs) 61 { 62 // add base class data members first 63 for (int j=0; j<bcs->dim; j++) 64 { 65 BaseClass* bc = (BaseClass*)(bcs->data[j]); 66 67 // interfaces never add data fields 68 if (bc->base->isInterfaceDeclaration()) 69 continue; 70 71 // recursively add baseclass data 72 LLVM_AddBaseClassData(irstruct, &bc->base->baseclasses); 73 74 Array* arr = &bc->base->fields; 75 if (arr->dim == 0) 76 continue; 77 78 Logger::println("Adding base class members of %s", bc->base->toChars()); 79 LOG_SCOPE; 80 81 for (int k=0; k < arr->dim; k++) { 82 VarDeclaration* v = (VarDeclaration*)(arr->data[k]); 83 Logger::println("Adding field: %s %s", v->type->toChars(), v->toChars()); 84 // init fields, used to happen in VarDeclaration::toObjFile 85 irstruct->addField(v); 67 68 // build the interface vtable 69 b->fillVtbl(target, &b->vtbl, newinstance); 70 71 // add the vtable type 72 assert(inter->type->ir.type); 73 irstruct->types.push_back( inter->type->ir.type->get() ); 74 // set and increment index 75 iri->index = irstruct->index++; 76 } 77 78 static void add_class_data(ClassDeclaration* target, ClassDeclaration* cd) 79 { 80 Logger::println("Adding data from class: %s", cd->toChars()); 81 LOG_SCOPE; 82 83 // recurse into baseClasses 84 if (cd->baseClass) 85 { 86 add_class_data(target, cd->baseClass); 87 //offset = baseClass->structsize; 88 } 89 90 // add members 91 Array* arr = cd->members; 92 for (int k=0; k < arr->dim; k++) { 93 Dsymbol* s = (Dsymbol*)arr->data[k]; 94 s->toObjFile(0); 95 } 96 97 // add interfaces 98 if (cd->vtblInterfaces) 99 { 100 Logger::println("num vtbl interfaces: %u", cd->vtblInterfaces->dim); 101 for (int i = 0; i < cd->vtblInterfaces->dim; i++) 102 { 103 BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i]; 104 assert(b); 105 // create new instances only for explicitly derived interfaces 106 add_interface(target, b, (cd == target)); 86 107 } 87 108 } … … 90 111 ////////////////////////////////////////////////////////////////////////////////////////// 91 112 92 void DtoResolveClass(ClassDeclaration* cd)113 static void DtoResolveInterface(InterfaceDeclaration* cd) 93 114 { 94 115 if (cd->ir.resolved) return; 95 116 cd->ir.resolved = true; 96 117 97 Logger::println("DtoResolve Class(%s): %s", cd->toPrettyChars(), cd->loc.toChars());118 Logger::println("DtoResolveInterface(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 98 119 LOG_SCOPE; 99 100 //printf("resolve class: %s\n", cd->toPrettyChars());101 120 102 121 // get the TypeClass … … 104 123 TypeClass* ts = (TypeClass*)cd->type; 105 124 106 // make sure the IrStruct is created 107 IrStruct* irstruct = cd->ir.irStruct; 108 if (!irstruct) { 109 irstruct = new IrStruct(ts); 110 cd->ir.irStruct = irstruct; 125 // create the IrStruct, we need somewhere to store the classInfo 126 assert(!cd->ir.irStruct); 127 IrStruct* irstruct = new IrStruct(cd); 128 cd->ir.irStruct = irstruct; 129 130 // handle base interfaces 131 if (cd->baseclasses.dim) 132 { 133 Logger::println("num baseclasses: %u", cd->baseclasses.dim); 134 LOG_SCOPE; 135 136 for (int i=0; i<cd->baseclasses.dim; i++) 137 { 138 BaseClass* bc = (BaseClass*)cd->baseclasses.data[i]; 139 Logger::println("baseclass %d: %s", i, bc->base->toChars()); 140 141 InterfaceDeclaration* id = bc->base->isInterfaceDeclaration(); 142 assert(id); 143 144 DtoResolveInterface(id); 145 146 // add to interfaceInfos 147 IrInterface* iri = new IrInterface(bc); 148 irstruct->interfaceVec.push_back(iri); 149 } 150 } 151 152 // create the type 153 const LLType* t = LLArrayType::get(getVoidPtrType(), cd->vtbl.dim); 154 assert(!ts->ir.type); 155 ts->ir.type = new LLPATypeHolder(getPtrToType(t)); 156 157 // request declaration 158 gIR->declareList.push_back(cd); 159 160 // handle members 161 // like "nested" interfaces 162 Array* arr = cd->members; 163 for (int k=0; k < arr->dim; k++) { 164 Dsymbol* s = (Dsymbol*)arr->data[k]; 165 s->toObjFile(0); 166 } 167 } 168 169 ////////////////////////////////////////////////////////////////////////////////////////// 170 171 // FIXME: this needs to be cleaned up 172 173 void DtoResolveClass(ClassDeclaration* cd) 174 { 175 if (InterfaceDeclaration* id = cd->isInterfaceDeclaration()) 176 { 177 DtoResolveInterface(id); 178 return; 179 } 180 181 if (cd->ir.resolved) return; 182 cd->ir.resolved = true; 183 184 Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 185 LOG_SCOPE; 186 187 //printf("resolve class: %s\n", cd->toPrettyChars()); 188 189 // get the TypeClass 190 assert(cd->type->ty == Tclass); 191 TypeClass* ts = (TypeClass*)cd->type; 192 193 // create the IrStruct 194 assert(!cd->ir.irStruct); 195 IrStruct* irstruct = new IrStruct(cd); 196 cd->ir.irStruct = irstruct; 197 198 // create the type 199 ts->ir.type = new LLPATypeHolder(llvm::OpaqueType::get()); 200 201 // if it just a forward declaration? 202 if (cd->sizeok != 1) 203 { 204 // just name the type 205 gIR->module->addTypeName(cd->mangle(), ts->ir.type->get()); 206 return; 111 207 } 112 208 … … 116 212 } 117 213 118 // resolve interface vtables119 /*if (cd->vtblInterfaces) {120 Logger::println("Vtbl interfaces for '%s'", cd->toPrettyChars());121 LOG_SCOPE;122 for (int i=0; i < cd->vtblInterfaces->dim; i++) {123 BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i];124 ClassDeclaration *id = b->base;125 Logger::println("Vtbl interface: '%s'", id->toPrettyChars());126 DtoResolveClass(id);127 // Fill in vtbl[]128 b->fillVtbl(cd, &b->vtbl, 1);129 }130 }*/131 132 214 // push state 133 215 gIR->structs.push_back(irstruct); 134 gIR->classes.push_back(cd);135 136 // vector holding the field types137 std::vector<const LLType*> fieldtypes;138 216 139 217 // add vtable 140 ts->ir.vtblType = new llvm::PATypeHolder(llvm::OpaqueType::get()); 141 const LLType* vtabty = getPtrToType(ts->ir.vtblType->get()); 142 fieldtypes.push_back(vtabty); 218 irstruct->types.push_back(getPtrToType(irstruct->vtblTy.get())); 219 irstruct->index++; 143 220 144 221 // add monitor 145 fieldtypes.push_back(getVoidPtrType()); 146 147 // add base class data fields first 148 LLVM_AddBaseClassData(irstruct, &cd->baseclasses); 149 150 // add own fields 151 Array* fields = &cd->fields; 152 for (int k=0; k < fields->dim; k++) 153 { 154 VarDeclaration* v = (VarDeclaration*)fields->data[k]; 155 Logger::println("Adding field: %s %s", v->type->toChars(), v->toChars()); 156 // init fields, used to happen in VarDeclaration::toObjFile 157 irstruct->addField(v); 158 } 159 160 // then add other members of us, if any 161 if(cd->members) { 162 for (int k=0; k < cd->members->dim; k++) { 163 Dsymbol* dsym = (Dsymbol*)(cd->members->data[k]); 164 dsym->toObjFile(0); // TODO: multiobj 165 } 166 } 167 168 // resolve class data fields (possibly unions) 169 Logger::println("doing class fields"); 170 171 if (irstruct->offsets.empty()) 172 { 173 Logger::println("has no fields"); 174 } 175 else 176 { 177 Logger::println("has fields"); 178 unsigned prevsize = (unsigned)-1; 179 unsigned lastoffset = (unsigned)-1; 180 const LLType* fieldtype = NULL; 181 VarDeclaration* fieldinit = NULL; 182 size_t fieldpad = 0; 183 int idx = 0; 184 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { 185 // first iteration 186 if (lastoffset == (unsigned)-1) { 187 lastoffset = i->first; 188 fieldtype = i->second.type; 189 fieldinit = i->second.var; 190 prevsize = getABITypeSize(fieldtype); 191 i->second.var->ir.irField->index = idx; 192 } 193 // colliding offset? 194 else if (lastoffset == i->first) { 195 size_t s = getABITypeSize(i->second.type); 196 if (s > prevsize) { 197 fieldpad += s - prevsize; 198 prevsize = s; 199 } 200 cd->ir.irStruct->hasUnions = true; 201 i->second.var->ir.irField->index = idx; 202 } 203 // intersecting offset? 204 else if (i->first < (lastoffset + prevsize)) { 205 size_t s = getABITypeSize(i->second.type); 206 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size 207 cd->ir.irStruct->hasUnions = true; 208 i->second.var->ir.irField->index = idx; 209 i->second.var->ir.irField->indexOffset = (i->first - lastoffset) / s; 210 } 211 // fresh offset 212 else { 213 // commit the field 214 fieldtypes.push_back(fieldtype); 215 irstruct->defaultFields.push_back(fieldinit); 216 if (fieldpad) { 217 fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad)); 218 irstruct->defaultFields.push_back(NULL); 219 idx++; 220 } 221 222 idx++; 223 224 // start new 225 lastoffset = i->first; 226 fieldtype = i->second.type; 227 fieldinit = i->second.var; 228 prevsize = getABITypeSize(fieldtype); 229 i->second.var->ir.irField->index = idx; 230 fieldpad = 0; 231 } 232 } 233 fieldtypes.push_back(fieldtype); 234 irstruct->defaultFields.push_back(fieldinit); 235 if (fieldpad) { 236 fieldtypes.push_back(llvm::ArrayType::get(LLType::Int8Ty, fieldpad)); 237 irstruct->defaultFields.push_back(NULL); 238 } 239 } 240 241 // populate interface map 242 { 243 Logger::println("Adding interfaces to '%s'", cd->toPrettyChars()); 244 LOG_SCOPE; 245 LLVM_AddBaseClassInterfaces(cd, &cd->baseclasses); 246 Logger::println("%d interfaces added", cd->ir.irStruct->interfaceVec.size()); 247 assert(cd->ir.irStruct->interfaceVec.size() == cd->ir.irStruct->interfaceMap.size()); 248 } 249 250 // add interface vtables at the end 251 int interIdx = (int)fieldtypes.size(); 252 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) 253 { 254 IrInterface* iri = *i; 255 ClassDeclaration* id = iri->decl; 256 257 // set vtbl type 258 TypeClass* itc = (TypeClass*)id->type; 259 const LLType* ivtblTy = itc->ir.vtblType->get(); 260 assert(ivtblTy); 261 if (Logger::enabled()) 262 Logger::cout() << "interface vtbl type: " << *ivtblTy << '\n'; 263 fieldtypes.push_back(getPtrToType(ivtblTy)); 264 265 // fix the interface vtable type 266 assert(iri->vtblTy == NULL); 267 iri->vtblTy = new llvm::PATypeHolder(ivtblTy); 268 269 // set index 270 iri->index = interIdx++; 271 } 272 Logger::println("%d interface vtables added", cd->ir.irStruct->interfaceVec.size()); 273 assert(cd->ir.irStruct->interfaceVec.size() == cd->ir.irStruct->interfaceMap.size()); 222 irstruct->types.push_back(getVoidPtrType()); 223 irstruct->index++; 224 225 // add class data fields and interface vtables recursively 226 add_class_data(cd, cd); 227 228 // check if errors occured while building interface vtables 229 if (global.errors) 230 fatal(); 274 231 275 232 // create type 276 const llvm::StructType* structtype = llvm::StructType::get(fieldtypes); 233 assert(irstruct->index == irstruct->types.size()); 234 const LLType* structtype = irstruct->build(); 277 235 278 236 // refine abstract types for stuff like: class C {C next;} 279 assert(irstruct->recty != 0); 280 llvm::PATypeHolder& spa = irstruct->recty; 281 llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype); 282 structtype = isaStruct(spa.get()); 283 284 // make it official 285 if (!ts->ir.type) 286 ts->ir.type = new llvm::PATypeHolder(structtype); 287 else 288 *ts->ir.type = structtype; 289 spa = *ts->ir.type; 237 llvm::PATypeHolder* spa = ts->ir.type; 238 llvm::cast<llvm::OpaqueType>(spa->get())->refineAbstractTypeTo(structtype); 239 structtype = isaStruct(spa->get()); 290 240 291 241 // name the type 292 242 gIR->module->addTypeName(cd->mangle(), ts->ir.type->get()); 293 243 294 // create vtable type 295 llvm::GlobalVariable* svtblVar = 0; 296 #if OPAQUE_VTBLS 244 // refine vtable type 245 297 246 // void*[vtbl.dim] 298 const llvm::ArrayType* svtbl_ty 299 = llvm::ArrayType::get(getVoidPtrType(), cd->vtbl.dim); 300 301 #else 302 std::vector<const LLType*> sinits_ty; 303 304 for (int k=0; k < cd->vtbl.dim; k++) 305 { 306 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k]; 307 assert(dsym); 308 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n'; 309 310 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { 311 DtoResolveFunction(fd); 312 //assert(fd->type->ty == Tfunction); 313 //TypeFunction* tf = (TypeFunction*)fd->type; 314 //const LLType* fpty = getPtrToType(tf->ir.type->get()); 315 const llvm::FunctionType* vfty = DtoBaseFunctionType(fd); 316 const LLType* vfpty = getPtrToType(vfty); 317 sinits_ty.push_back(vfpty); 318 } 319 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { 320 Logger::println("*** ClassDeclaration in vtable: %s", cd2->toChars()); 321 const LLType* cinfoty; 322 if (cd->isInterfaceDeclaration()) { 323 cinfoty = DtoInterfaceInfoType(); 324 } 325 else if (cd != ClassDeclaration::classinfo) { 326 cinfoty = ClassDeclaration::classinfo->type->ir.type->get(); 327 } 328 else { 329 // this is the ClassInfo class, the type is this type 330 cinfoty = ts->ir.type->get(); 331 } 332 const LLType* cty = getPtrToType(cinfoty); 333 sinits_ty.push_back(cty); 334 } 335 else 336 assert(0); 337 } 338 339 // get type 340 assert(!sinits_ty.empty()); 341 const llvm::StructType* svtbl_ty = llvm::StructType::get(sinits_ty); 342 #endif 343 344 // refine for final vtable type 345 llvm::cast<llvm::OpaqueType>(ts->ir.vtblType->get())->refineAbstractTypeTo(svtbl_ty); 346 347 #if !OPAQUE_VTBLS 348 // name vtbl type 349 std::string styname(cd->mangle()); 350 styname.append("__vtblType"); 351 gIR->module->addTypeName(styname, svtbl_ty); 352 #endif 247 llvm::cast<llvm::OpaqueType>(irstruct->vtblTy.get())->refineAbstractTypeTo(LLArrayType::get(getVoidPtrType(), cd->vtbl.dim)); 353 248 354 249 // log 355 //Logger::cout() << "final class type: " << *ts->ir.type->get() << '\n';250 Logger::cout() << "final class type: " << *ts->ir.type->get() << '\n'; 356 251 357 252 // pop state 358 gIR->classes.pop_back();359 253 gIR->structs.pop_back(); 360 254 … … 365 259 ////////////////////////////////////////////////////////////////////////////////////////// 366 260 367 void DtoDeclareClass(ClassDeclaration* cd)261 static void DtoDeclareInterface(InterfaceDeclaration* cd) 368 262 { 369 263 if (cd->ir.declared) return; 370 264 cd->ir.declared = true; 371 265 372 Logger::println("DtoDeclareClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 266 Logger::println("DtoDeclareInterface(%s): %s", cd->toPrettyChars(), cd->locToChars()); 267 LOG_SCOPE; 268 269 assert(cd->ir.irStruct); 270 IrStruct* irstruct = cd->ir.irStruct; 271 272 // get interface info type 273 const llvm::StructType* infoTy = DtoInterfaceInfoType(); 274 275 // interface info array 276 if (!irstruct->interfaceVec.empty()) { 277 // symbol name 278 std::string nam = "_D"; 279 nam.append(cd->mangle()); 280 nam.append("16__interfaceInfosZ"); 281 282 llvm::GlobalValue::LinkageTypes linkage = DtoLinkage(cd); 283 284 // resolve array type 285 const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, irstruct->interfaceVec.size()); 286 &
