comparison gen/classes.cpp @ 797:340acf1535d0

Removed KDevelop3 project files, CMake can generate them just fine! Fixed function literals in static initializers. Changed alignment of delegates from 2*PTRSIZE to just PTRSIZE. Changed errors to go to stderr instead of stdout. Fairly major rewriting of struct/union/class handling, STILL A BIT BUGGY !!!
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sat, 29 Nov 2008 21:25:43 +0100
parents 6e7a4c3b64d2
children 9f92b6e40fd3 d14e4594c7d7
comparison
equal deleted inserted replaced
796:6e7a4c3b64d2 797:340acf1535d0
19 19
20 #include "ir/irstruct.h" 20 #include "ir/irstruct.h"
21 21
22 ////////////////////////////////////////////////////////////////////////////////////////// 22 //////////////////////////////////////////////////////////////////////////////////////////
23 23
24 static void LLVM_AddBaseClassInterfaces(ClassDeclaration* target, BaseClasses* bcs) 24 // adds interface b to target, if newinstance != 0, then target must provide all
25 { 25 // functions required to implement b (it reimplements b)
26 // add base class data members first 26 static void add_interface(ClassDeclaration* target, BaseClass* b, int newinstance)
27 for (int j=0; j<bcs->dim; j++) 27 {
28 { 28 Logger::println("adding interface: %s", b->base->toChars());
29 BaseClass* bc = (BaseClass*)(bcs->data[j]); 29 LOG_SCOPE;
30 30
31 // base *classes* might add more interfaces? 31 InterfaceDeclaration* inter = b->base->isInterfaceDeclaration();
32 DtoResolveClass(bc->base); 32 DtoResolveClass(inter);
33 LLVM_AddBaseClassInterfaces(target, &bc->base->baseclasses); 33
34 34 assert(inter);
35 // resolve interfaces while we're at it 35 IrStruct* irstruct = target->ir.irStruct;
36 if (bc->base->isInterfaceDeclaration()) 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 64 irstruct->interfaceMap.insert(std::make_pair(bc->base, iri));
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 }
54 } 65 }
55 } 66 }
56 } 67
57 68 // build the interface vtable
58 ////////////////////////////////////////////////////////////////////////////////////////// 69 b->fillVtbl(target, &b->vtbl, newinstance);
59 70
60 static void LLVM_AddBaseClassData(IrStruct* irstruct, BaseClasses* bcs) 71 // add the vtable type
61 { 72 assert(inter->type->ir.type);
62 // add base class data members first 73 irstruct->types.push_back( inter->type->ir.type->get() );
63 for (int j=0; j<bcs->dim; j++) 74 // set and increment index
64 { 75 iri->index = irstruct->index++;
65 BaseClass* bc = (BaseClass*)(bcs->data[j]); 76 }
66 77
67 // interfaces never add data fields 78 static void add_class_data(ClassDeclaration* target, ClassDeclaration* cd)
68 if (bc->base->isInterfaceDeclaration()) 79 {
69 continue; 80 Logger::println("Adding data from class: %s", cd->toChars());
70 81 LOG_SCOPE;
71 // recursively add baseclass data 82
72 LLVM_AddBaseClassData(irstruct, &bc->base->baseclasses); 83 // recurse into baseClasses
73 84 if (cd->baseClass)
74 Array* arr = &bc->base->fields; 85 {
75 if (arr->dim == 0) 86 add_class_data(target, cd->baseClass);
76 continue; 87 //offset = baseClass->structsize;
77 88 }
78 Logger::println("Adding base class members of %s", bc->base->toChars()); 89
79 LOG_SCOPE; 90 // add members
80 91 Array* arr = cd->members;
81 for (int k=0; k < arr->dim; k++) { 92 for (int k=0; k < arr->dim; k++) {
82 VarDeclaration* v = (VarDeclaration*)(arr->data[k]); 93 Dsymbol* s = (Dsymbol*)arr->data[k];
83 Logger::println("Adding field: %s %s", v->type->toChars(), v->toChars()); 94 s->toObjFile(0);
84 // init fields, used to happen in VarDeclaration::toObjFile 95 }
85 irstruct->addField(v); 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 }
88 } 109 }
89 110
90 ////////////////////////////////////////////////////////////////////////////////////////// 111 //////////////////////////////////////////////////////////////////////////////////////////
91 112
92 void DtoResolveClass(ClassDeclaration* cd) 113 static void DtoResolveInterface(InterfaceDeclaration* cd)
93 { 114 {
94 if (cd->ir.resolved) return; 115 if (cd->ir.resolved) return;
95 cd->ir.resolved = true; 116 cd->ir.resolved = true;
96 117
97 Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 118 Logger::println("DtoResolveInterface(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
98 LOG_SCOPE; 119 LOG_SCOPE;
99
100 //printf("resolve class: %s\n", cd->toPrettyChars());
101 120
102 // get the TypeClass 121 // get the TypeClass
103 assert(cd->type->ty == Tclass); 122 assert(cd->type->ty == Tclass);
104 TypeClass* ts = (TypeClass*)cd->type; 123 TypeClass* ts = (TypeClass*)cd->type;
105 124
106 // make sure the IrStruct is created 125 // create the IrStruct, we need somewhere to store the classInfo
107 IrStruct* irstruct = cd->ir.irStruct; 126 assert(!cd->ir.irStruct);
108 if (!irstruct) { 127 IrStruct* irstruct = new IrStruct(cd);
109 irstruct = new IrStruct(ts); 128 cd->ir.irStruct = irstruct;
110 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
113 // resolve the base class 209 // resolve the base class
114 if (cd->baseClass) { 210 if (cd->baseClass) {
115 DtoResolveClass(cd->baseClass); 211 DtoResolveClass(cd->baseClass);
116 } 212 }
117 213
118 // resolve interface vtables
119 /*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 // push state 214 // push state
133 gIR->structs.push_back(irstruct); 215 gIR->structs.push_back(irstruct);
134 gIR->classes.push_back(cd);
135
136 // vector holding the field types
137 std::vector<const LLType*> fieldtypes;
138 216
139 // add vtable 217 // add vtable
140 ts->ir.vtblType = new llvm::PATypeHolder(llvm::OpaqueType::get()); 218 irstruct->types.push_back(getPtrToType(irstruct->vtblTy.get()));
141 const LLType* vtabty = getPtrToType(ts->ir.vtblType->get()); 219 irstruct->index++;
142 fieldtypes.push_back(vtabty);
143 220
144 // add monitor 221 // add monitor
145 fieldtypes.push_back(getVoidPtrType()); 222 irstruct->types.push_back(getVoidPtrType());
146 223 irstruct->index++;
147 // add base class data fields first 224
148 LLVM_AddBaseClassData(irstruct, &cd->baseclasses); 225 // add class data fields and interface vtables recursively
149 226 add_class_data(cd, cd);
150 // add own fields 227
151 Array* fields = &cd->fields; 228 // check if errors occured while building interface vtables
152 for (int k=0; k < fields->dim; k++) 229 if (global.errors)
153 { 230 fatal();
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());
274 231
275 // create type 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 // refine abstract types for stuff like: class C {C next;} 236 // refine abstract types for stuff like: class C {C next;}
279 assert(irstruct->recty != 0); 237 llvm::PATypeHolder* spa = ts->ir.type;
280 llvm::PATypeHolder& spa = irstruct->recty; 238 llvm::cast<llvm::OpaqueType>(spa->get())->refineAbstractTypeTo(structtype);
281 llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype); 239 structtype = isaStruct(spa->get());
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;
290 240
291 // name the type 241 // name the type
292 gIR->module->addTypeName(cd->mangle(), ts->ir.type->get()); 242 gIR->module->addTypeName(cd->mangle(), ts->ir.type->get());
293 243
294 // create vtable type 244 // refine vtable type
295 llvm::GlobalVariable* svtblVar = 0; 245
296 #if OPAQUE_VTBLS
297 // void*[vtbl.dim] 246 // void*[vtbl.dim]
298 const llvm::ArrayType* svtbl_ty 247 llvm::cast<llvm::OpaqueType>(irstruct->vtblTy.get())->refineAbstractTypeTo(LLArrayType::get(getVoidPtrType(), cd->vtbl.dim));
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
353 248
354 // log 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 // pop state 252 // pop state
358 gIR->classes.pop_back();
359 gIR->structs.pop_back(); 253 gIR->structs.pop_back();
360 254
361 // queue declare 255 // queue declare
362 gIR->declareList.push_back(cd); 256 gIR->declareList.push_back(cd);
363 } 257 }
364 258
365 ////////////////////////////////////////////////////////////////////////////////////////// 259 //////////////////////////////////////////////////////////////////////////////////////////
366 260
367 void DtoDeclareClass(ClassDeclaration* cd) 261 static void DtoDeclareInterface(InterfaceDeclaration* cd)
368 { 262 {
369 if (cd->ir.declared) return; 263 if (cd->ir.declared) return;
370 cd->ir.declared = true; 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 // declare global
287 irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, linkage, NULL, nam, gIR->module);
288
289 // do each interface info
290 unsigned idx = 0;
291 size_t n = irstruct->interfaceVec.size();
292 for (size_t i=0; i < n; i++)
293 {
294 IrInterface* iri = irstruct->interfaceVec[i];
295 ClassDeclaration* id = iri->decl;
296
297 // always create interfaceinfos
298 LLConstant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)};
299 iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2);
300 idx++;
301 }
302 }
303
304 // declare the classinfo
305 DtoDeclareClassInfo(cd);
306
307 // request const init
308 gIR->constInitList.push_back(cd);
309
310 // emit typeinfo and request definition
311 if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd))
312 {
313 gIR->defineList.push_back(cd);
314 DtoTypeInfoOf(cd->type, false);
315 }
316 }
317
318 //////////////////////////////////////////////////////////////////////////////////////////
319
320 // FIXME: this needs to be cleaned up
321
322 void DtoDeclareClass(ClassDeclaration* cd)
323 {
324 if (InterfaceDeclaration* id = cd->isInterfaceDeclaration())
325 {
326 DtoDeclareInterface(id);
327 return;
328 }
329
330 if (cd->ir.declared) return;
331 cd->ir.declared = true;
332
333 Logger::println("DtoDeclareClass(%s): %s", cd->toPrettyChars(), cd->locToChars());
373 LOG_SCOPE; 334 LOG_SCOPE;
374 335
375 //printf("declare class: %s\n", cd->toPrettyChars()); 336 //printf("declare class: %s\n", cd->toPrettyChars());
376 337
377 assert(cd->type->ty == Tclass); 338 assert(cd->type->ty == Tclass);
379 340
380 assert(cd->ir.irStruct); 341 assert(cd->ir.irStruct);
381 IrStruct* irstruct = cd->ir.irStruct; 342 IrStruct* irstruct = cd->ir.irStruct;
382 343
383 gIR->structs.push_back(irstruct); 344 gIR->structs.push_back(irstruct);
384 gIR->classes.push_back(cd);
385 345
386 bool needs_definition = false; 346 bool needs_definition = false;
387 if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)) { 347 if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)) {
388 needs_definition = true; 348 needs_definition = true;
389 } 349 }
390 350
391 llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(cd); 351 llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(cd);
392 352
393 // interfaces have no static initializer 353 // create vtbl symbol
394 // same goes for abstract classes 354 std::string varname("_D");
395 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { 355 varname.append(cd->mangle());
396 // vtable 356 varname.append("6__vtblZ");
397 std::string varname("_D"); 357 irstruct->vtbl = new llvm::GlobalVariable(irstruct->vtblInitTy.get(), true, _linkage, 0, varname, gIR->module);
398 varname.append(cd->mangle());
399 varname.append("6__vtblZ");
400 cd->ir.irStruct->vtbl = new llvm::GlobalVariable(ts->ir.vtblType->get(), true, _linkage, 0, varname, gIR->module);
401 }
402 358
403 // get interface info type 359 // get interface info type
404 const llvm::StructType* infoTy = DtoInterfaceInfoType(); 360 const llvm::StructType* infoTy = DtoInterfaceInfoType();
405 361
406 // interface info array 362 // interface info array
407 if (!cd->ir.irStruct->interfaceVec.empty()) { 363 if (!irstruct->interfaceVec.empty()) {
408 // symbol name 364 // symbol name
409 std::string nam = "_D"; 365 std::string nam = "_D";
410 nam.append(cd->mangle()); 366 nam.append(cd->mangle());
411 nam.append("16__interfaceInfosZ"); 367 nam.append("16__interfaceInfosZ");
412 // resolve array type 368 // resolve array type
413 const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->ir.irStruct->interfaceVec.size()); 369 const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, irstruct->interfaceVec.size());
414 // declare global 370 // declare global
415 irstruct->interfaceInfosTy = arrTy;
416 irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module); 371 irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module);
417 } 372 }
418 373
419 // interfaces have no static initializer 374 // DMD gives abstract classes a full ClassInfo, so we do it as well
420 // same goes for abstract classes 375
421 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { 376 // interface vtables
422 // interface vtables 377 unsigned idx = 0;
423 unsigned idx = 0; 378
424 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) 379 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
425 { 380 {
426 IrInterface* iri = *i; 381 IrInterface* iri = *i;
427 ClassDeclaration* id = iri->decl; 382 ClassDeclaration* id = iri->decl;
428 383
429 std::string nam("_D"); 384 std::string nam("_D");
430 nam.append(cd->mangle()); 385 nam.append(cd->mangle());
431 nam.append("11__interface"); 386 nam.append("11__interface");
432 nam.append(id->mangle()); 387 nam.append(id->mangle());
433 nam.append("6__vtblZ"); 388 nam.append("6__vtblZ");
434 389
435 assert(iri->vtblTy); 390 iri->vtbl = new llvm::GlobalVariable(iri->vtblInitTy.get(), true, _linkage, 0, nam, gIR->module);
436 iri->vtbl = new llvm::GlobalVariable(iri->vtblTy->get(), true, _linkage, 0, nam, gIR->module); 391
437 LLConstant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)}; 392 // always create interfaceinfos
438 iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2); 393 LLConstant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)};
439 idx++; 394 iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2);
440 } 395 idx++;
441 396 }
442 // init 397
443 std::string initname("_D"); 398 // initZ init
444 initname.append(cd->mangle()); 399 std::string initname("_D");
445 initname.append("6__initZ"); 400 initname.append(cd->mangle());
446 401 initname.append("6__initZ");
447 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->ir.type->get(), true, _linkage, NULL, initname, gIR->module); 402
448 cd->ir.irStruct->init = initvar; 403 // initZ global
449 } 404 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(irstruct->initOpaque.get(), true, _linkage, NULL, initname, gIR->module);
450 405 irstruct->init = initvar;
451 gIR->classes.pop_back(); 406
452 gIR->structs.pop_back(); 407 gIR->structs.pop_back();
453 408
409 // request const init
454 gIR->constInitList.push_back(cd); 410 gIR->constInitList.push_back(cd);
411
412 // define ? (set initializers)
455 if (needs_definition) 413 if (needs_definition)
456 gIR->defineList.push_back(cd); 414 gIR->defineList.push_back(cd);
457 415
458 // classinfo 416 // classinfo
459 DtoDeclareClassInfo(cd); 417 DtoDeclareClassInfo(cd);
460 418
461 // typeinfo 419 // do typeinfo ?
462 if (needs_definition) 420 if (needs_definition)
463 DtoTypeInfoOf(cd->type, false); 421 DtoTypeInfoOf(cd->type, false);
464 } 422 }
465 423
466 ////////////////////////////////////////////////////////////////////////////////////////// 424 //////////////////////////////////////////////////////////////////////////////////////////
467 425
468 void DtoConstInitClass(ClassDeclaration* cd) 426 void addZeros(std::vector<llvm::Constant*>& inits, size_t pos, size_t offset); // irstruct.cpp
427
428 //////////////////////////////////////////////////////////////////////////////
429
430 // assigns constant initializers to fields introduced by cd
431 static void init_field_inits(ClassDeclaration* cd)
432 {
433 size_t n = cd->fields.dim;
434 for (size_t i=0; i<n; i++)
435 {
436 VarDeclaration* v = (VarDeclaration*)cd->fields.data[i];
437 IrField* f = v->ir.irField;
438 assert(!f->constInit);
439 f->constInit = DtoConstFieldInitializer(v->loc, v->type, v->init);
440 }
441 }
442
443 //////////////////////////////////////////////////////////////////////////////
444
445 // adds data fields and interface vtables to the constant initializer of class cd
446 static size_t init_class_initializer(std::vector<LLConstant*>& inits, ClassDeclaration* target, ClassDeclaration* cd, size_t offsetbegin)
447 {
448 // first do baseclasses
449 if (cd->baseClass)
450 {
451 offsetbegin = init_class_initializer(inits, target, cd->baseClass, offsetbegin);
452 }
453
454 Logger::println("adding data of %s to %s", cd->toChars(), target->toChars());
455 LOG_SCOPE;
456
457 // add default fields
458 VarDeclaration** fields = (VarDeclaration**)cd->fields.data;
459 size_t nfields = cd->fields.dim;
460
461 std::vector<VarDeclaration*> defVars;
462 defVars.reserve(nfields);
463
464 size_t lastoffset = offsetbegin; // vtbl,monitor
465 size_t lastsize = 0;
466
467 // find fields that contribute to default
468 for (size_t i=0; i<nfields; i++)
469 {
470 VarDeclaration* var = fields[i];
471 // only add vars that don't overlap
472 size_t offset = var->offset;
473 size_t size = var->type->size();
474 if (offset >= lastoffset+lastsize)
475 {
476 Logger::println(" added");
477 lastoffset = offset;
478 lastsize = size;
479 defVars.push_back(var);
480 }
481 }
482
483 // go through the default vars and build the default constant initializer
484 // adding zeros along the way to live up to alignment expectations
485 size_t nvars = defVars.size();
486 for (size_t i=0; i<nvars; i++)
487 {
488 VarDeclaration* var = defVars[i];
489
490 Logger::println("field %s %s = %s : +%u", var->type->toChars(), var->toChars(), var->init ? var->init->toChars() : var->type->defaultInit(var->loc)->toChars(), var->offset);
491
492 // get offset and size
493 size_t offset = var->offset;
494 size_t size = var->type->size();
495
496 // is there space in between last last offset and this one?
497 // if so, fill it with zeros
498 if (offset > lastoffset+lastsize)
499 {
500 size_t pos = lastoffset + lastsize;
501 addZeros(inits, pos, offset);
502 }
503
504 // add the field
505 assert(var->ir.irField->constInit);
506 inits.push_back(var->ir.irField->constInit);
507
508 lastoffset = offset;
509 lastsize = var->type->size();
510 }
511
512 // if it's a class, and it implements interfaces, add the vtables
513 IrStruct* irstruct = cd->ir.irStruct;
514
515 size_t nvtbls = cd->vtblInterfaces->dim;
516 for(size_t i=0; i<nvtbls; i++)
517 {
518 BaseClass* bc = (BaseClass*)cd->vtblInterfaces->data[i];
519 IrStruct::InterfaceMap::iterator iter = irstruct->interfaceMap.find(bc->base);
520 assert(iter != irstruct->interfaceMap.end());
521
522 IrInterface* iri = iter->second;
523 if (iri->vtbl)
524 inits.push_back(iri->vtbl);
525 else // abstract impl
526 inits.push_back(getNullPtr(getVoidPtrType()));
527
528 lastoffset += PTRSIZE;
529 lastsize = PTRSIZE;
530 }
531
532 // return next offset
533 return lastoffset + lastsize;
534 }
535
536 //////////////////////////////////////////////////////////////////////////////
537
538 // build the vtable initializer for class cd
539 static void init_class_vtbl_initializer(ClassDeclaration* cd)
540 {
541 // generate vtable initializer
542 std::vector<LLConstant*> sinits(cd->vtbl.dim, NULL);
543
544 IrStruct* irstruct = cd->ir.irStruct;
545
546 assert(cd->vtbl.dim > 1);
547
548 // first entry always classinfo
549 assert(irstruct->classInfo);
550 sinits[0] = DtoBitCast(irstruct->classInfo, DtoType(ClassDeclaration::classinfo->type));
551
552 // add virtual functions
553 for (int k=1; k < cd->vtbl.dim; k++)
554 {
555 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k];
556 assert(dsym);
557
558 // Logger::println("vtbl[%d] = %s", k, dsym->toChars());
559
560 FuncDeclaration* fd = dsym->isFuncDeclaration();
561 assert(fd);
562
563 if (fd->isAbstract())
564 {
565 sinits[k] = getNullPtr(getVoidPtrType());
566 }
567 else
568 {
569 DtoForceDeclareDsymbol(fd);
570 assert(fd->ir.irFunc->func);
571 sinits[k] = fd->ir.irFunc->func;
572 }
573
574 // if (Logger::enabled())
575 // Logger::cout() << "vtbl[" << k << "] = " << *sinits[k] << std::endl;
576 }
577
578 irstruct->constVtbl = LLConstantStruct::get(sinits);
579
580 // refine type
581 llvm::cast<llvm::OpaqueType>(irstruct->vtblInitTy.get())->refineAbstractTypeTo(irstruct->constVtbl->getType());
582
583 if (Logger::enabled())
584 Logger::cout() << "vtbl initializer: " << *irstruct->constVtbl << std::endl;
585 }
586
587 //////////////////////////////////////////////////////////////////////////////
588
589 static void init_class_interface_vtbl_initializers(ClassDeclaration* cd)
590 {
591 IrStruct* irstruct = cd->ir.irStruct;
592
593 // don't do anything if list is empty
594 if (irstruct->interfaceVec.empty())
595 return;
596
597 std::vector<LLConstant*> inits;
598 std::vector<LLConstant*> infoInits(3);
599
600 // go through each interface
601 size_t ninter = irstruct->interfaceVec.size();
602 for (size_t i=0; i<ninter; i++)
603 {
604 IrInterface* iri = irstruct->interfaceVec[i];
605 Logger::println("interface %s", iri->decl->toChars());
606
607 // build vtable intializer for this interface implementation
608 Array& arr = iri->base->vtbl;
609 size_t narr = arr.dim;
610
611 if (narr > 0)
612 {
613 inits.resize(narr, NULL);
614
615 // first is always the interface info
616 assert(iri->info);
617 inits[0] = iri->info;
618
619 // build vtable
620 for (size_t j=1; j < narr; j++)
621 {
622 Dsymbol* dsym = (Dsymbol*)arr.data[j];
623 if (!dsym)
624 {
625 inits[j] = getNullPtr(getVoidPtrType());
626 continue;
627 }
628
629 //Logger::println("ivtbl[%d] = %s", j, dsym->toChars());
630
631 // must all be functions
632 FuncDeclaration* fd = dsym->isFuncDeclaration();
633 assert(fd);
634
635 if (fd->isAbstract())
636 inits[j] = getNullPtr(getVoidPtrType());
637 else
638 {
639 DtoForceDeclareDsymbol(fd);
640
641 assert(fd->ir.irFunc->func);
642 inits[j] = fd->ir.irFunc->func;
643 }
644
645 //if (Logger::enabled())
646 // Logger::cout() << "ivtbl[" << j << "] = " << *inits[j] << std::endl;
647 }
648
649 // build the constant
650 iri->vtblInit = LLConstantStruct::get(inits);
651 }
652
653 // build the interface info for ClassInfo
654 // generate interface info initializer
655
656 DtoForceDeclareDsymbol(iri->decl);
657
658 // classinfo
659 IrStruct* iris = iri->decl->ir.irStruct;
660 assert(iris);
661 assert(iris->classInfo);
662 infoInits[0] = DtoBitCast(iris->classInfo, DtoType(ClassDeclaration::classinfo->type));
663
664 // vtbl
665 LLConstant* c;
666 if (iri->vtbl)
667 c = llvm::ConstantExpr::getBitCast(iri->vtbl, getPtrToType(getVoidPtrType()));
668 else
669 c = getNullPtr(getPtrToType(getVoidPtrType()));
670 infoInits[1] = DtoConstSlice(DtoConstSize_t(narr), c);
671
672 // offset
673 size_t ioff;
674 if (iri->index == 0)
675 ioff = 0;
676 else
677 ioff = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(iri->index);
678
679 Logger::println("DMD interface offset: %d, LLVM interface offset: %lu", iri->base->offset, ioff);
680 assert(iri->base->offset == ioff);
681 infoInits[2] = DtoConstUint(ioff);
682
683 // create interface info initializer constant
684 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(infoInits));
685 }
686 }
687
688 //////////////////////////////////////////////////////////////////////////////
689
690 static void DtoConstInitInterface(InterfaceDeclaration* cd)
469 { 691 {
470 if (cd->ir.initialized) return; 692 if (cd->ir.initialized) return;
471 cd->ir.initialized = true; 693 cd->ir.initialized = true;
472 694
473 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 695 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
474 LOG_SCOPE; 696 LOG_SCOPE;
475 697
698 init_class_interface_vtbl_initializers(cd);
699 }
700
701 //////////////////////////////////////////////////////////////////////////////
702
703 void DtoConstInitClass(ClassDeclaration* cd)
704 {
705 if (InterfaceDeclaration* it = cd->isInterfaceDeclaration())
706 {
707 DtoConstInitInterface(it);
708 return;
709 }
710
711 if (cd->ir.initialized) return;
712 cd->ir.initialized = true;
713
714 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
715 LOG_SCOPE;
716
717 assert(!cd->isInterfaceDeclaration());
718
719 // make sure the baseclass is const initialized
720 if (cd->baseClass)
721 DtoForceConstInitDsymbol(cd->baseClass);
722
723 // get IrStruct
476 IrStruct* irstruct = cd->ir.irStruct; 724 IrStruct* irstruct = cd->ir.irStruct;
477 gIR->structs.push_back(irstruct); 725 gIR->structs.push_back(irstruct);
478 gIR->classes.push_back(cd); 726
727 // get types
728 TypeClass* tc = (TypeClass*)cd->type;
729 const llvm::StructType* structtype = isaStruct(tc->ir.type->get());
730 assert(structtype);
731 const llvm::ArrayType* vtbltype = isaArray(irstruct->vtblTy.get());
732 assert(vtbltype);
733
734 // make sure each field knows its default initializer
735 init_field_inits(cd);
736
737 // build initializer list
738 std::vector<LLConstant*> inits;
739 inits.reserve(irstruct->varDecls.size());
740
741 // vtable is always first
742 assert(irstruct->vtbl != 0);
743 inits.push_back(irstruct->vtbl);
744
745 // then comes monitor
746 inits.push_back(LLConstant::getNullValue(getVoidPtrType()));
747
748 // recursively do data and interface vtables
749 init_class_initializer(inits, cd, cd, 2 * PTRSIZE);
750
751 // build vtable initializer
752 init_class_vtbl_initializer(cd);
753
754 // build interface vtables
755 init_class_interface_vtbl_initializers(cd);
756
757 // build constant from inits
758 irstruct->constInit = LLConstantStruct::get(inits); // classes are never packed
759
760 // refine __initZ global type to the one of the initializer
761 llvm::cast<llvm::OpaqueType>(irstruct->initOpaque.get())->refineAbstractTypeTo(irstruct->constInit->getType());
762
763 if (Logger::enabled())
764 {
765 Logger::cout() << "class " << cd->toChars() << std::endl;
766 Logger::cout() << "type " << *cd->type->ir.type->get() << std::endl;
767 Logger::cout() << "initializer " << *irstruct->constInit << std::endl;
768 }
769
770 gIR->structs.pop_back();
771 }
772
773 //////////////////////////////////////////////////////////////////////////////////////////
774
775 static void DefineInterfaceInfos(IrStruct* irstruct)
776 {
777 // always do interface info array when possible
778 std::vector<LLConstant*> infoInits;
779 infoInits.reserve(irstruct->interfaceVec.size());
780
781 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
782 {
783 IrInterface* iri = *i;
784 assert(iri->infoInit);
785 infoInits.push_back(iri->infoInit);
786 }
787
788 // set initializer
789 if (!infoInits.empty())
790 {
791 const LLArrayType* arrty = LLArrayType::get(infoInits[0]->getType(), infoInits.size());
792 LLConstant* arrInit = llvm::ConstantArray::get(arrty, infoInits);
793 irstruct->interfaceInfos->setInitializer(arrInit);
794 }
795 else
796 {
797 assert(irstruct->interfaceInfos == NULL);
798 }
799 }
800
801 //////////////////////////////////////////////////////////////////////////////////////////
802
803 static void DtoDefineInterface(InterfaceDeclaration* cd)
804 {
805 if (cd->ir.defined) return;
806 cd->ir.defined = true;
807
808 Logger::println("DtoDefineClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
809 LOG_SCOPE;
810
811 // defined interface infos
812 DefineInterfaceInfos(cd->ir.irStruct);
813
814 // define the classinfo
815 if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd))
816 {
817 DtoDefineClassInfo(cd);
818 }
819 }
820
821 //////////////////////////////////////////////////////////////////////////////////////////
822
823 // FIXME: clean this up
824
825 void DtoDefineClass(ClassDeclaration* cd)
826 {
827 if (InterfaceDeclaration* id = cd->isInterfaceDeclaration())
828 {
829 DtoDefineInterface(id);
830 return;
831 }
832
833 if (cd->ir.defined) return;
834 cd->ir.defined = true;
835
836 Logger::println("DtoDefineClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
837 LOG_SCOPE;
479 838
480 // get the struct (class) type 839 // get the struct (class) type
481 assert(cd->type->ty == Tclass); 840 assert(cd->type->ty == Tclass);
482 TypeClass* ts = (TypeClass*)cd->type; 841 TypeClass* ts = (TypeClass*)cd->type;
483 const llvm::StructType* structtype = isaStruct(ts->ir.type->get()); 842
484 #if OPAQUE_VTBLS 843 IrStruct* irstruct = cd->ir.irStruct;
485 const llvm::ArrayType* vtbltype = isaArray(ts->ir.vtblType->get()); 844
486 #else 845 assert(cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd));
487 const llvm::StructType* vtbltype = isaStruct(ts->ir.vtblType->get()); 846
488 #endif 847 // sanity check
489 848 assert(irstruct->init);
490 // make sure each offset knows its default initializer 849 assert(irstruct->constInit);
491 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) 850 assert(irstruct->vtbl);
492 { 851 assert(irstruct->constVtbl);
493 IrStruct::Offset* so = &i->second; 852
494 LLConstant* finit = DtoConstFieldInitializer(so->var->loc, so->var->type, so->var->init); 853 if (Logger::enabled())
495 so->init = finit; 854 {
496 so->var->ir.irField->constInit = finit; 855 Logger::cout() << "initZ: " << *irstruct->init << std::endl;
497 } 856 Logger::cout() << "cinitZ: " << *irstruct->constInit << std::endl;
498 857 Logger::cout() << "vtblZ: " << *irstruct->vtbl << std::endl;
499 // fill out fieldtypes/inits 858 Logger::cout() << "cvtblZ: " << *irstruct->constVtbl << std::endl;
500 std::vector<LLConstant*> fieldinits; 859 }
501 860
502 // first field is always the vtable 861 // set initializers
503 if (cd->isAbstract() || cd->isInterfaceDeclaration()) 862 irstruct->init->setInitializer(irstruct->constInit);
504 { 863 irstruct->vtbl->setInitializer(irstruct->constVtbl);
505 const LLType* ptrTy = getPtrToType(ts->ir.vtblType->get()); 864
506 fieldinits.push_back(llvm::Constant::getNullValue(ptrTy)); 865 // initialize interface vtables
507 } 866 size_t n = irstruct->interfaceVec.size();
508 else 867 for (size_t i=0; i<n; i++)
509 { 868 {
510 assert(cd->ir.irStruct->vtbl != 0); 869 IrInterface* iri = irstruct->interfaceVec[i];
511 fieldinits.push_back(cd->ir.irStruct->vtbl); 870 Logger::println("interface %s", iri->base->base->toChars());
512 } 871 assert(iri->vtblInit);
513 872
514 // then comes monitor 873 // refine the init type
515 fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); 874 llvm::cast<llvm::OpaqueType>(iri->vtblInitTy.get())->refineAbstractTypeTo(iri->vtblInit->getType());
516 875
517 // go through the field inits and build the default initializer 876 // apply initializer
518 size_t nfi = irstruct->defaultFields.size(); 877 assert(iri->vtbl);
519 for (size_t i=0; i<nfi; ++i) { 878 iri->vtbl->setInitializer(iri->vtblInit);
520 LLConstant* c; 879 }
521 if (irstruct->defaultFields[i]) { 880
522 c = irstruct->defaultFields[i]->ir.irField->constInit; 881 DefineInterfaceInfos(irstruct);
523 assert(c); 882
524 } 883 // generate classinfo
525 else { 884 DtoDefineClassInfo(cd);
526 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+2));
527 assert(arrty);
528 std::vector<LLConstant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(LLType::Int8Ty, 0, false));
529 c = llvm::ConstantArray::get(arrty, vals);
530 }
531 fieldinits.push_back(c);
532 }
533
534 // last comes interface vtables
535 const llvm::StructType* infoTy = DtoInterfaceInfoType();
536 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
537 {
538 IrInterface* iri = *i;
539 iri->infoTy = infoTy;
540
541 if (cd->isAbstract() || cd->isInterfaceDeclaration())
542 {
543 fieldinits.push_back(llvm::Constant::getNullValue(structtype->getElementType(iri->index)));
544 }
545 else
546 {
547 assert(iri->vtbl);
548 fieldinits.push_back(iri->vtbl);
549 }
550 }
551
552 // generate initializer
553 #if 0
554 //Logger::cout() << cd->toPrettyChars() << " | " << *structtype << '\n';
555 assert(fieldinits.size() == structtype->getNumElements());
556 for(size_t i=0; i<structtype->getNumElements(); ++i) {
557 Logger::cout() << "s#" << i << " = " << *structtype->getElementType(i) << '\n';
558 Logger::cout() << "i#" << i << " = " << *fieldinits[i] << '\n';
559 assert(fieldinits[i]->getType() == structtype->getElementType(i));
560 }
561 #endif
562
563 #if 0
564 for(size_t i=0; i<fieldinits.size(); ++i) {
565 Logger::cout() << "i#" << i << " = " << *fieldinits[i]->getType() << '\n';
566 }
567 #endif
568
569 LLConstant* _init = llvm::ConstantStruct::get(structtype, fieldinits);
570 assert(_init);
571 cd->ir.irStruct->constInit = _init;
572
573 // abstract classes have no static vtable
574 // neither do interfaces (on their own, the implementing class supplies the vtable)
575 if (!cd->isInterfaceDeclaration() && !cd->isAbstract())
576 {
577 // generate vtable initializer
578 std::vector<LLConstant*> sinits;
579
580 for (int k=0; k < cd->vtbl.dim; k++)
581 {
582 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k];
583 assert(dsym);
584 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n';
585
586 #if OPAQUE_VTBLS
587 const LLType* targetTy = getVoidPtrType();
588 #else
589 const LLType* targetTy = vtbltype->getElementType(k);
590 #endif
591
592 LLConstant* c = NULL;
593 // virtual method
594 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
595 DtoForceDeclareDsymbol(fd);
596 assert(fd->ir.irFunc->func);
597 c = llvm::cast<llvm::Constant>(fd->ir.irFunc->func);
598 }
599 // classinfo
600 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) {
601 assert(cd->ir.irStruct->classInfo);
602 c = cd->ir.irStruct->classInfo;
603 }
604 assert(c != NULL);
605
606 // cast if necessary (overridden method)
607 if (c->getType() != targetTy)
608 c = llvm::ConstantExpr::getBitCast(c, targetTy);
609 sinits.push_back(c);
610 }
611 #if OPAQUE_VTBLS
612 const llvm::ArrayType* svtbl_ty = isaArray(ts->ir.vtblType->get());
613 cd->ir.irStruct->constVtbl = llvm::ConstantArray::get(svtbl_ty, sinits);
614 #else
615 const llvm::StructType* svtbl_ty = isaStruct(ts->ir.vtblType->get());
616 LLConstant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits);
617 cd->ir.irStruct->constVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit);
618 #endif
619
620 // create interface vtable const initalizers
621 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
622 {
623 IrInterface* iri = *i;
624 BaseClass* b = iri->base;
625
626 ClassDeclaration* id = iri->decl;
627 assert(id->type->ty == Tclass);
628 TypeClass* its = (TypeClass*)id->type;
629
630 #if OPAQUE_VTBLS
631 const llvm::ArrayType* ivtbl_ty = isaArray(its->ir.vtblType->get());
632 #else
633 const llvm::StructType* ivtbl_ty = isaStruct(its->ir.vtblType->get());
634 #endif
635
636 // generate interface info initializer
637 std::vector<LLConstant*> infoInits;
638
639 // classinfo
640 assert(id->ir.irStruct->classInfo);
641 LLConstant* c = id->ir.irStruct->classInfo;
642 infoInits.push_back(c);
643
644 // vtbl
645 const LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::Int8Ty));
646 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty);
647 c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c);
648 infoInits.push_back(c);
649
650 // offset
651 assert(iri->index >= 0);
652 size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(iri->index);
653 infoInits.push_back(DtoConstUint(ioff));
654
655 // create interface info initializer constant
656 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
657
658 // generate vtable initializer
659 std::vector<LLConstant*> iinits;
660
661 // add interface info
662 #if OPAQUE_VTBLS
663 const LLType* targetTy = getVoidPtrType();
664 iinits.push_back(llvm::ConstantExpr::getBitCast(iri->info, targetTy));
665 #else
666 iinits.push_back(iri->info);
667 #endif
668
669 for (int k=1; k < b->vtbl.dim; k++)
670 {
671 // Logger::println("interface vtbl const init nr. %d", k);
672 Dsymbol* dsym = (Dsymbol*)b->vtbl.data[k];
673
674 // error on unimplemented functions, error was already generated earlier
675 if(!dsym)
676 fatal();
677
678 FuncDeclaration* fd = dsym->isFuncDeclaration();
679 assert(fd);
680 DtoForceDeclareDsymbol(fd);
681 assert(fd->ir.irFunc->func);
682 LLConstant* c = llvm::cast<llvm::Constant>(fd->ir.irFunc->func);
683
684 #if !OPAQUE_VTBLS
685 const LLType* targetTy = iri->vtblTy->getContainedType(k);
686 #endif
687
688 // we have to bitcast, as the type created in ResolveClass expects a different this type
689 c = llvm::ConstantExpr::getBitCast(c, targetTy);
690 iinits.push_back(c);
691 // if (Logger::enabled())
692 // Logger::cout() << "c: " << *c << '\n';
693 }
694
695 #if OPAQUE_VTBLS
696 // if (Logger::enabled())
697 // Logger::cout() << "n: " << iinits.size() << " ivtbl_ty: " << *ivtbl_ty << '\n';
698 LLConstant* civtblInit = llvm::ConstantArray::get(ivtbl_ty, iinits);
699 iri->vtblInit = llvm::cast<llvm::ConstantArray>(civtblInit);
700 #else
701 LLConstant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits);
702 iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit);
703 #endif
704 }
705 }
706 // we always generate interfaceinfos as best we can
707 else
708 {
709 // TODO: this is duplicated code from right above... I'm just too lazy to generalise it right now :/
710 // create interface vtable const initalizers
711 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
712 {
713 IrInterface* iri = *i;
714 BaseClass* b = iri->base;
715
716 ClassDeclaration* id = iri->decl;
717 assert(id->type->ty == Tclass);
718 TypeClass* its = (TypeClass*)id->type;
719
720 // generate interface info initializer
721 std::vector<LLConstant*> infoInits;
722
723 // classinfo
724 assert(id->ir.irStruct->classInfo);
725 LLConstant* c = id->ir.irStruct->classInfo;
726 infoInits.push_back(c);
727
728 // vtbl
729 const LLType* byteptrptrty = getPtrToType(getPtrToType(LLType::Int8Ty));
730 c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty));
731 infoInits.push_back(c);
732
733 // offset
734 assert(iri->index >= 0);
735 size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(iri->index);
736 infoInits.push_back(DtoConstUint(ioff));
737
738 // create interface info initializer constant
739 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
740 }
741 }
742
743 gIR->classes.pop_back();
744 gIR->structs.pop_back();
745 }
746
747 //////////////////////////////////////////////////////////////////////////////////////////
748
749 void DtoDefineClass(ClassDeclaration* cd)
750 {
751 if (cd->ir.defined) return;
752 cd->ir.defined = true;
753
754 Logger::println("DtoDefineClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
755 LOG_SCOPE;
756
757 // get the struct (class) type
758 assert(cd->type->ty == Tclass);
759 TypeClass* ts = (TypeClass*)cd->type;
760
761 if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)) {
762
763 // interfaces don't have static initializer/vtable
764 // neither do abstract classes
765 if (!cd->isInterfaceDeclaration() && !cd->isAbstract())
766 {
767 cd->ir.irStruct->init->setInitializer(cd->ir.irStruct->constInit);
768 cd->ir.irStruct->vtbl->setInitializer(cd->ir.irStruct->constVtbl);
769
770 // initialize interface vtables
771 IrStruct* irstruct = cd->ir.irStruct;
772 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
773 {
774 IrInterface* iri = *i;
775 iri->vtbl->setInitializer(iri->vtblInit);
776 }
777 }
778
779 // always do interface info array when possible
780 IrStruct* irstruct = cd->ir.irStruct;
781 std::vector<LLConstant*> infoInits;
782 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
783 {
784 IrInterface* iri = *i;
785 infoInits.push_back(iri->infoInit);
786 }
787 // set initializer
788 if (!infoInits.empty())
789 {
790 LLConstant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits);
791 irstruct->interfaceInfos->setInitializer(arrInit);
792 }
793 else
794 {
795 assert(irstruct->interfaceInfos == NULL);
796 }
797
798 // generate classinfo
799 DtoDefineClassInfo(cd);
800 }
801 } 885 }
802 886
803 ////////////////////////////////////////////////////////////////////////////////////////// 887 //////////////////////////////////////////////////////////////////////////////////////////
804 888
805 DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp) 889 DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp)
823 } 907 }
824 // default allocator 908 // default allocator
825 else 909 else
826 { 910 {
827 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocclass"); 911 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocclass");
828 mem = gIR->CreateCallOrInvoke(fn, tc->sym->ir.irStruct->classInfo, ".newclass_gc_alloc")->get(); 912 LLConstant* ci = DtoBitCast(tc->sym->ir.irStruct->classInfo, DtoType(ClassDeclaration::classinfo->type));
913 mem = gIR->CreateCallOrInvoke(fn, ci, ".newclass_gc_alloc")->get();
829 mem = DtoBitCast(mem, DtoType(tc), ".newclass_gc"); 914 mem = DtoBitCast(mem, DtoType(tc), ".newclass_gc");
830 } 915 }
831 916
832 // init 917 // init
833 DtoInitClass(tc, mem); 918 DtoInitClass(tc, mem);
836 if (newexp->thisexp) 921 if (newexp->thisexp)
837 { 922 {
838 Logger::println("Resolving outer class"); 923 Logger::println("Resolving outer class");
839 LOG_SCOPE; 924 LOG_SCOPE;
840 DValue* thisval = newexp->thisexp->toElem(gIR); 925 DValue* thisval = newexp->thisexp->toElem(gIR);
841 size_t idx = 2 + tc->sym->vthis->ir.irField->index; 926 size_t idx = tc->sym->vthis->ir.irField->index;
842 LLValue* src = thisval->getRVal(); 927 LLValue* src = thisval->getRVal();
843 LLValue* dst = DtoGEPi(mem,0,idx,"tmp"); 928 LLValue* dst = DtoGEPi(mem,0,idx,"tmp");
844 if (Logger::enabled()) 929 if (Logger::enabled())
845 Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n'; 930 Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
846 DtoStore(src, dst); 931 DtoStore(src, dst);
853 938
854 // get context 939 // get context
855 LLValue* nest = DtoNestedContext(loc, tc->sym); 940 LLValue* nest = DtoNestedContext(loc, tc->sym);
856 941
857 // store into right location 942 // store into right location
858 size_t idx = 2 + tc->sym->vthis->ir.irField->index; 943 size_t idx = tc->sym->vthis->ir.irField->index;
859 LLValue* gep = DtoGEPi(mem,0,idx,"tmp"); 944 LLValue* gep = DtoGEPi(mem,0,idx,"tmp");
860 DtoStore(DtoBitCast(nest, gep->getType()->getContainedType(0)), gep); 945 DtoStore(DtoBitCast(nest, gep->getType()->getContainedType(0)), gep);
861 } 946 }
862 947
863 // call constructor 948 // call constructor
875 960
876 ////////////////////////////////////////////////////////////////////////////////////////// 961 //////////////////////////////////////////////////////////////////////////////////////////
877 962
878 void DtoInitClass(TypeClass* tc, LLValue* dst) 963 void DtoInitClass(TypeClass* tc, LLValue* dst)
879 { 964 {
965 DtoForceConstInitDsymbol(tc->sym);
966
880 size_t presz = 2*getABITypeSize(DtoSize_t()); 967 size_t presz = 2*getABITypeSize(DtoSize_t());
881 uint64_t n = getABITypeSize(tc->ir.type->get()) - presz; 968 uint64_t n = getABITypeSize(tc->ir.type->get()) - presz;
882 969
883 // set vtable field seperately, this might give better optimization 970 // set vtable field seperately, this might give better optimization
884 assert(tc->sym->ir.irStruct->vtbl); 971 assert(tc->sym->ir.irStruct->vtbl);
885 DtoStore(tc->sym->ir.irStruct->vtbl, DtoGEPi(dst,0,0,"vtbl")); 972 LLValue* tmp = DtoGEPi(dst,0,0,"vtbl");
973 LLValue* val = DtoBitCast(tc->sym->ir.irStruct->vtbl, tmp->getType()->getContainedType(0));
974 DtoStore(val, tmp);
886 975
887 // monitor always defaults to zero 976 // monitor always defaults to zero
888 LLValue* tmp = DtoGEPi(dst,0,1,"monitor"); 977 tmp = DtoGEPi(dst,0,1,"monitor");
889 DtoStore(llvm::Constant::getNullValue(tmp->getType()->getContainedType(0)), tmp); 978 val = llvm::Constant::getNullValue(tmp->getType()->getContainedType(0));
979 DtoStore(val, tmp);
890 980
891 // done? 981 // done?
892 if (n == 0) 982 if (n == 0)
893 return; 983 return;
894 984
895 // copy the rest from the static initializer 985 // copy the rest from the static initializer
896 assert(tc->sym->ir.irStruct->init); 986 assert(tc->sym->ir.irStruct->init);
897 assert(dst->getType() == tc->sym->ir.irStruct->init->getType());
898 987
899 LLValue* dstarr = DtoGEPi(dst,0,2,"tmp"); 988 LLValue* dstarr = DtoGEPi(dst,0,2,"tmp");
900 LLValue* srcarr = DtoGEPi(tc->sym->ir.irStruct->init,0,2,"tmp"); 989 LLValue* srcarr = DtoGEPi(tc->sym->ir.irStruct->init,0,2,"tmp");
901 990
902 DtoMemCpy(dstarr, srcarr, DtoConstSize_t(n)); 991 DtoMemCpy(dstarr, srcarr, DtoConstSize_t(n));
921 { 1010 {
922 Logger::println("DtoCastClass(%s, %s)", val->getType()->toChars(), _to->toChars()); 1011 Logger::println("DtoCastClass(%s, %s)", val->getType()->toChars(), _to->toChars());
923 LOG_SCOPE; 1012 LOG_SCOPE;
924 1013
925 Type* to = _to->toBasetype(); 1014 Type* to = _to->toBasetype();
1015
1016 // class -> pointer
926 if (to->ty == Tpointer) { 1017 if (to->ty == Tpointer) {
927 Logger::println("to pointer"); 1018 Logger::println("to pointer");
928 const LLType* tolltype = DtoType(_to); 1019 const LLType* tolltype = DtoType(_to);
929 LLValue* rval = DtoBitCast(val->getRVal(), tolltype); 1020 LLValue* rval = DtoBitCast(val->getRVal(), tolltype);
930 return new DImValue(_to, rval); 1021 return new DImValue(_to, rval);
931 } 1022 }
1023 // class -> bool
932 else if (to->ty == Tbool) { 1024 else if (to->ty == Tbool) {
933 Logger::println("to bool"); 1025 Logger::println("to bool");
934 LLValue* llval = val->getRVal(); 1026 LLValue* llval = val->getRVal();
935 LLValue* zero = LLConstant::getNullValue(llval->getType()); 1027 LLValue* zero = LLConstant::getNullValue(llval->getType());
936 return new DImValue(_to, gIR->ir->CreateICmpNE(llval, zero, "tmp")); 1028 return new DImValue(_to, gIR->ir->CreateICmpNE(llval, zero, "tmp"));
937 } 1029 }
938 1030
1031 // must be class/interface
939 assert(to->ty == Tclass); 1032 assert(to->ty == Tclass);
940 TypeClass* tc = (TypeClass*)to; 1033 TypeClass* tc = (TypeClass*)to;
941 1034
1035 // from type
942 Type* from = val->getType()->toBasetype(); 1036 Type* from = val->getType()->toBasetype();
943 TypeClass* fc = (TypeClass*)from; 1037 TypeClass* fc = (TypeClass*)from;
944 1038
945 if (tc->sym->isInterfaceDeclaration()) { 1039 // x -> interface
1040 if (InterfaceDeclaration* it = tc->sym->isInterfaceDeclaration()) {
946 Logger::println("to interface"); 1041 Logger::println("to interface");
1042 // interface -> interface
947 if (fc->sym->isInterfaceDeclaration()) { 1043 if (fc->sym->isInterfaceDeclaration()) {
948 Logger::println("from interface"); 1044 Logger::println("from interface");
949 return DtoDynamicCastInterface(val, _to); 1045 return DtoDynamicCastInterface(val, _to);
950 } 1046 }
1047 // class -> interface - static cast
1048 else if (it->isBaseOf(fc->sym,NULL)) {
1049 Logger::println("static down cast)");
1050 // get the from class
1051 ClassDeclaration* cd = fc->sym->isClassDeclaration();
1052 IrStruct* irstruct = cd->ir.irStruct;
1053 // find interface impl
1054 IrStruct::InterfaceMapIter iriter = irstruct->interfaceMap.find(it);
1055 assert(iriter != irstruct->interfaceMap.end());
1056 IrInterface* iri = iriter->second;
1057 // offset pointer
1058 LLValue* v = val->getRVal();
1059 v = DtoGEPi(v, 0, iri->index);
1060 if (Logger::enabled())
1061 {
1062 Logger::cout() << "V = " << *v << std::endl;
1063 Logger::cout() << "T = " << *DtoType(_to) << std::endl;
1064 }
1065 v = DtoBitCast(v, DtoType(_to));
1066 // return r-value
1067 return new DImValue(_to, v);
1068 }
1069 // class -> interface
951 else { 1070 else {
952 Logger::println("from object"); 1071 Logger::println("from object");
953 return DtoDynamicCastObject(val, _to); 1072 return DtoDynamicCastObject(val, _to);
954 } 1073 }
955 } 1074 }
1075 // x -> class
956 else { 1076 else {
957 Logger::println("to class"); 1077 Logger::println("to class");
958 int poffset; 1078 int poffset;
1079 // interface -> class
959 if (fc->sym->isInterfaceDeclaration()) { 1080 if (fc->sym->isInterfaceDeclaration()) {
960 Logger::println("interface cast"); 1081 Logger::println("interface cast");
961 return DtoCastInterfaceToObject(val, _to); 1082 return DtoCastInterfaceToObject(val, _to);
962 } 1083 }
963 else if (!tc->sym->isInterfaceDeclaration() && tc->sym->isBaseOf(fc->sym,NULL)) { 1084 // class -> class - static down cast
1085 else if (tc->sym->isBaseOf(fc->sym,NULL)) {
964 Logger::println("static down cast)"); 1086 Logger::println("static down cast)");
965 const LLType* tolltype = DtoType(_to); 1087 const LLType* tolltype = DtoType(_to);
966 LLValue* rval = DtoBitCast(val->getRVal(), tolltype); 1088 LLValue* rval = DtoBitCast(val->getRVal(), tolltype);
967 return new DImValue(_to, rval); 1089 return new DImValue(_to, rval);
968 } 1090 }
1091 // class -> class - dynamic up cast
969 else { 1092 else {
970 Logger::println("dynamic up cast"); 1093 Logger::println("dynamic up cast");
971 return DtoDynamicCastObject(val, _to); 1094 return DtoDynamicCastObject(val, _to);
972 } 1095 }
973 } 1096 }
1098 return (unsigned)-1; 1221 return (unsigned)-1;
1099 } 1222 }
1100 1223
1101 ////////////////////////////////////////////////////////////////////////////////////////// 1224 //////////////////////////////////////////////////////////////////////////////////////////
1102 1225
1103 void ClassDeclaration::offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result)
1104 {
1105 unsigned idx = 0;
1106 unsigned r = LLVM_ClassOffsetToIndex(this, os, idx);
1107 assert(r != (unsigned)-1 && "Offset not found in any aggregate field");
1108 // vtable is 0, monitor is 1
1109 r += 2;
1110 // the final index was not pushed
1111 result.push_back(r);
1112 }
1113
1114 //////////////////////////////////////////////////////////////////////////////////////////
1115
1116 LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd) 1226 LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd)
1117 { 1227 {
1118 Logger::println("indexing class field %s:", vd->toPrettyChars()); 1228 Logger::println("indexing class field %s:", vd->toPrettyChars());
1119 LOG_SCOPE; 1229 LOG_SCOPE;
1120 1230
1123 1233
1124 // vd must be a field 1234 // vd must be a field
1125 IrField* field = vd->ir.irField; 1235 IrField* field = vd->ir.irField;
1126 assert(field); 1236 assert(field);
1127 1237
1128 unsigned idx = field->index + 2; // vtbl & monitor 1238 // get the start pointer
1129 unsigned off = field->indexOffset;
1130
1131 const LLType* st = DtoType(cd->type); 1239 const LLType* st = DtoType(cd->type);
1240 // cast to the struct type
1132 src = DtoBitCast(src, st); 1241 src = DtoBitCast(src, st);
1133 1242
1134 LLValue* val = DtoGEPi(src, 0,idx); 1243 // gep to the index
1244 if (Logger::enabled())
1245 {
1246 Logger::cout() << "src2: " << *src << '\n';
1247 Logger::cout() << "index: " << field->index << '\n';
1248 Logger::cout() << "srctype: " << *src->getType() << '\n';
1249 }
1250 LLValue* val = DtoGEPi(src, 0, field->index);
1251
1252 // do we need to offset further? (union area)
1253 if (field->unionOffset)
1254 {
1255 // cast to void*
1256 val = DtoBitCast(val, getVoidPtrType());
1257 // offset
1258 val = DtoGEPi1(val, field->unionOffset);
1259 }
1260
1261 // cast it to the right type
1135 val = DtoBitCast(val, getPtrToType(DtoType(vd->type))); 1262 val = DtoBitCast(val, getPtrToType(DtoType(vd->type)));
1136
1137 if (off)
1138 val = DtoGEPi1(val, off);
1139 1263
1140 if (Logger::enabled()) 1264 if (Logger::enabled())
1141 Logger::cout() << "value: " << *val << '\n'; 1265 Logger::cout() << "value: " << *val << '\n';
1142 1266
1143 return val; 1267 return val;
1153 1277
1154 LLValue* vthis = inst->getRVal(); 1278 LLValue* vthis = inst->getRVal();
1155 if (Logger::enabled()) 1279 if (Logger::enabled())
1156 Logger::cout() << "vthis: " << *vthis << '\n'; 1280 Logger::cout() << "vthis: " << *vthis << '\n';
1157 1281
1158 LLValue* funcval; 1282 LLValue* funcval = vthis;
1159 funcval = DtoGEPi(vthis, 0, 0, "tmp"); 1283 if (!fdecl->isMember2()->isInterfaceDeclaration())
1284 funcval = DtoGEPi(funcval, 0, 0, "tmp");
1160 funcval = DtoLoad(funcval); 1285 funcval = DtoLoad(funcval);
1161 funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, fdecl->toPrettyChars()); 1286 funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, fdecl->toPrettyChars());
1162 funcval = DtoLoad(funcval); 1287 funcval = DtoLoad(funcval);
1163 1288
1164 if (Logger::enabled()) 1289 if (Logger::enabled())
1165 Logger::cout() << "funcval: " << *funcval << '\n'; 1290 Logger::cout() << "funcval: " << *funcval << '\n';
1166 1291
1167 #if OPAQUE_VTBLS
1168 funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type))); 1292 funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
1169 if (Logger::enabled()) 1293 if (Logger::enabled())
1170 Logger::cout() << "funcval casted: " << *funcval << '\n'; 1294 Logger::cout() << "funcval casted: " << *funcval << '\n';
1171 #endif
1172 1295
1173 return funcval; 1296 return funcval;
1174 } 1297 }
1175 1298
1176 ////////////////////////////////////////////////////////////////////////////////////////// 1299 //////////////////////////////////////////////////////////////////////////////////////////
1177 1300
1178 void DtoDeclareClassInfo(ClassDeclaration* cd) 1301 void DtoDeclareClassInfo(ClassDeclaration* cd)
1179 { 1302 {
1180 if (cd->ir.irStruct->classDeclared) return; 1303 IrStruct* irstruct = cd->ir.irStruct;
1181 cd->ir.irStruct->classDeclared = true; 1304
1305 if (irstruct->classInfoDeclared) return;
1306 irstruct->classInfoDeclared = true;
1182 1307
1183 Logger::println("DtoDeclareClassInfo(%s)", cd->toChars()); 1308 Logger::println("DtoDeclareClassInfo(%s)", cd->toChars());
1184 LOG_SCOPE; 1309 LOG_SCOPE;
1185 1310
1186 ClassDeclaration* cinfo = ClassDeclaration::classinfo; 1311 ClassDeclaration* cinfo = ClassDeclaration::classinfo;
1191 if (!cd->isInterfaceDeclaration()) 1316 if (!cd->isInterfaceDeclaration())
1192 gname.append("7__ClassZ"); 1317 gname.append("7__ClassZ");
1193 else 1318 else
1194 gname.append("11__InterfaceZ"); 1319 gname.append("11__InterfaceZ");
1195 1320
1196 const LLType* st = cinfo->type->ir.type->get(); 1321 irstruct->classInfo = new llvm::GlobalVariable(irstruct->classInfoOpaque.get(), false, DtoLinkage(cd), NULL, gname, gIR->module);
1197
1198 cd->ir.irStruct->classInfo = new llvm::GlobalVariable(st, false, DtoLinkage(cd), NULL, gname, gIR->module);
1199 } 1322 }
1200 1323
1201 static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd) 1324 static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd)
1202 { 1325 {
1203 std::vector<const LLType*> types; 1326 std::vector<const LLType*> types;
1204 std::vector<LLConstant*> inits; 1327 std::vector<LLConstant*> inits;
1205 1328
1206 types.push_back(DtoSize_t()); 1329 types.push_back(DtoSize_t());
1207 1330
1208 assert(vd->ir.irField); 1331 assert(vd->ir.irField);
1209 assert(vd->ir.irField->index >= 0); 1332 size_t offset = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(vd->ir.irField->index);
1210 size_t offset = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(vd->ir.irField->index+2); 1333 offset += vd->ir.irField->unionOffset;
1211 inits.push_back(DtoConstSize_t(offset)); 1334 inits.push_back(DtoConstSize_t(offset));
1212 1335
1213 LLConstant* c = DtoTypeInfoOf(vd->type, true); 1336 LLConstant* c = DtoTypeInfoOf(vd->type, true);
1214 const LLType* tiTy = c->getType(); 1337 const LLType* tiTy = c->getType();
1215 //Logger::cout() << "tiTy = " << *tiTy << '\n'; 1338 //Logger::cout() << "tiTy = " << *tiTy << '\n';
1225 { 1348 {
1226 const llvm::StructType* initTy = isaStruct(init->getType()); 1349 const llvm::StructType* initTy = isaStruct(init->getType());
1227 assert(initTy); 1350 assert(initTy);
1228 1351
1229 std::vector<LLConstant*> arrayInits; 1352 std::vector<LLConstant*> arrayInits;
1230 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass) 1353
1231 { 1354 VarDeclaration** fields = &cd->ir.irStruct->varDecls[0];
1232 if (cd2->members) 1355 size_t nvars = cd->ir.irStruct->varDecls.size();
1233 { 1356
1234 for (size_t i = 0; i < cd2->members->dim; i++) 1357 for (size_t i=0; i<nvars; i++)
1235 { 1358 {
1236 Dsymbol *sm = (Dsymbol *)cd2->members->data[i]; 1359 LLConstant* c = build_offti_entry(cd, fields[i]);
1237 if (VarDeclaration* vd = sm->isVarDeclaration()) // is this enough? 1360 assert(c);
1238 { 1361 arrayInits.push_back(c);
1239 if (!vd->isDataseg()) // static members dont have an offset!
1240 {
1241 LLConstant* c = build_offti_entry(cd, vd);
1242 assert(c);
1243 arrayInits.push_back(c);
1244 }
1245 }
1246 }
1247 }
1248 } 1362 }
1249 1363
1250 size_t ninits = arrayInits.size(); 1364 size_t ninits = arrayInits.size();
1251 LLConstant* size = DtoConstSize_t(ninits); 1365 LLConstant* size = DtoConstSize_t(ninits);
1252 LLConstant* ptr; 1366 LLConstant* ptr;
1334 // void *deallocator; 1448 // void *deallocator;
1335 // OffsetTypeInfo[] offTi; 1449 // OffsetTypeInfo[] offTi;
1336 // void *defaultConstructor; 1450 // void *defaultConstructor;
1337 // } 1451 // }
1338 1452
1339 if (cd->ir.irStruct->classDefined) return; 1453 IrStruct* ir = cd->ir.irStruct;
1340 cd->ir.irStruct->classDefined = true; 1454
1455 if (ir->classInfoDefined) return;
1456 ir->classInfoDefined = true;
1341 1457
1342 Logger::println("DtoDefineClassInfo(%s)", cd->toChars()); 1458 Logger::println("DtoDefineClassInfo(%s)", cd->toChars());
1343 LOG_SCOPE; 1459 LOG_SCOPE;
1344 1460
1345 assert(cd->type->ty == Tclass); 1461 assert(cd->type->ty == Tclass);
1346 assert(cd->ir.irStruct->classInfo); 1462 assert(ir->classInfo);
1347 1463
1348 TypeClass* cdty = (TypeClass*)cd->type; 1464 TypeClass* cdty = (TypeClass*)cd->type;
1349 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { 1465 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) {
1350 assert(cd->ir.irStruct->init); 1466 assert(ir->init);
1351 assert(cd->ir.irStruct->constInit); 1467 assert(ir->constInit);
1352 assert(cd->ir.irStruct->vtbl); 1468 assert(ir->vtbl);
1353 assert(cd->ir.irStruct->constVtbl); 1469 assert(ir->constVtbl);
1354 } 1470 }
1355 1471
1356 // holds the list of initializers for llvm 1472 // holds the list of initializers for llvm
1357 std::vector<LLConstant*> inits; 1473 std::vector<LLConstant*> inits;
1358 1474
1379 const LLType* byteptrty = getPtrToType(LLType::Int8Ty); 1495 const LLType* byteptrty = getPtrToType(LLType::Int8Ty);
1380 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1496 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1381 c = defc->getOperand(2); 1497 c = defc->getOperand(2);
1382 } 1498 }
1383 else { 1499 else {
1384 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->init, byteptrty); 1500 c = llvm::ConstantExpr::getBitCast(ir->init, byteptrty);
1385 size_t initsz = getABITypeSize(cd->ir.irStruct->constInit->getType()); 1501 //Logger::cout() << *ir->constInit->getType() << std::endl;
1502 size_t initsz = getABITypeSize(ir->constInit->getType());
1386 c = DtoConstSlice(DtoConstSize_t(initsz), c); 1503 c = DtoConstSlice(DtoConstSize_t(initsz), c);
1387 } 1504 }
1388 inits.push_back(c); 1505 inits.push_back(c);
1389 1506
1390 // class name 1507 // class name
1403 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1520 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1404 c = defc->getOperand(4); 1521 c = defc->getOperand(4);
1405 } 1522 }
1406 else { 1523 else {
1407 const LLType* byteptrptrty = getPtrToType(byteptrty); 1524 const LLType* byteptrptrty = getPtrToType(byteptrty);
1408 assert(!cd->ir.irStruct->vtbl->getType()->isAbstract());
1409 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->vtbl, byteptrptrty); 1525 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->vtbl, byteptrptrty);
1410 assert(!cd->ir.irStruct->constVtbl->getType()->isAbstract()); 1526
1411 size_t vtblsz = 0; 1527 assert(ir->constVtbl);
1412 llvm::ConstantArray* constVtblArray = llvm::dyn_cast<llvm::ConstantArray>(cd->ir.irStruct->constVtbl); 1528 size_t vtblsz = ir->constVtbl->getNumOperands();
1413 if(constVtblArray) {
1414 vtblsz = constVtblArray->getType()->getNumElements();
1415 }
1416 c = DtoConstSlice(DtoConstSize_t(vtblsz), c); 1529 c = DtoConstSlice(DtoConstSize_t(vtblsz), c);
1417 } 1530 }
1418 inits.push_back(c); 1531 inits.push_back(c);
1419 1532
1420 // interfaces array 1533 // interfaces array
1421 IrStruct* irstruct = cd->ir.irStruct; 1534 IrStruct* irstruct = cd->ir.irStruct;
1422 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) { 1535 if (!irstruct->interfaceInfos) {
1423 c = defc->getOperand(5); 1536 c = defc->getOperand(5);
1424 } 1537 }
1425 else { 1538 else {
1426 const LLType* t = defc->getOperand(5)->getType()->getContainedType(1); 1539 const LLType* t = defc->getOperand(5)->getType()->getContainedType(1);
1427 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); 1540 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t);
1428 size_t iisz = irstruct->interfaceInfosTy->getNumElements(); 1541 size_t iisz = irstruct->interfaceVec.size();
1429 c = DtoConstSlice(DtoConstSize_t(iisz), c); 1542 c = DtoConstSlice(DtoConstSize_t(iisz), c);
1430 } 1543 }
1431 inits.push_back(c); 1544 inits.push_back(c);
1432 1545
1433 // base classinfo 1546 // base classinfo
1519 { 1632 {
1520 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; 1633 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n';
1521 }*/ 1634 }*/
1522 1635
1523 // build the initializer 1636 // build the initializer
1524 const llvm::StructType* st = isaStruct(defc->getType()); 1637 LLConstant* finalinit = llvm::ConstantStruct::get(inits);
1525 LLConstant* finalinit = llvm::ConstantStruct::get(st, inits);
1526 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; 1638 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n';
1527 1639 ir->constClassInfo = finalinit;
1528 cd->ir.irStruct->constClassInfo = finalinit; 1640
1529 cd->ir.irStruct->classInfo->setInitializer(finalinit); 1641 // refine the type
1530 } 1642 llvm::cast<llvm::OpaqueType>(ir->classInfoOpaque.get())->refineAbstractTypeTo(finalinit->getType());
1643
1644 // apply initializer
1645 ir->classInfo->setInitializer(finalinit);
1646 }