Mercurial > projects > ldc
annotate gen/classes.cpp @ 137:ce7b81fb957f trunk
[svn r141] fixed more problems with classinfo
moved more IR state out of the AST classes
author | lindquist |
---|---|
date | Fri, 18 Jan 2008 16:42:16 +0100 |
parents | 0e28624814e8 |
children | aeddd4d533b3 |
rev | line source |
---|---|
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1 #include <sstream> |
100 | 2 #include "gen/llvm.h" |
3 | |
4 #include "mtype.h" | |
5 #include "aggregate.h" | |
6 #include "init.h" | |
7 #include "declaration.h" | |
8 | |
9 #include "gen/irstate.h" | |
10 #include "gen/tollvm.h" | |
11 #include "gen/arrays.h" | |
12 #include "gen/logger.h" | |
13 #include "gen/classes.h" | |
132 | 14 #include "gen/structs.h" |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
15 #include "gen/functions.h" |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
16 #include "gen/runtime.h" |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
17 #include "gen/dvalue.h" |
100 | 18 |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
19 #include "ir/irstruct.h" |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
20 |
100 | 21 ////////////////////////////////////////////////////////////////////////////////////////// |
22 | |
137 | 23 static void LLVM_AddBaseClassInterfaces(ClassDeclaration* target, BaseClasses* bcs) |
24 { | |
25 // add base class data members first | |
26 for (int j=0; j<bcs->dim; j++) | |
27 { | |
28 BaseClass* bc = (BaseClass*)(bcs->data[j]); | |
29 | |
30 // resolve interfaces while we're at it | |
31 if (bc->base->isInterfaceDeclaration()) | |
32 { | |
33 Logger::println("adding interface '%s'", bc->base->toPrettyChars()); | |
34 IrInterface* iri = new IrInterface(bc, NULL); | |
35 target->irStruct->interfaces.insert(std::make_pair(bc->base, iri)); | |
36 if (!target->isAbstract()) { | |
37 // Fill in vtbl[] | |
38 bc->fillVtbl(target, &bc->vtbl, 0); | |
39 } | |
40 DtoResolveClass(bc->base); | |
41 } | |
42 | |
43 // base *classes* might add more interfaces? | |
44 LLVM_AddBaseClassInterfaces(target, &bc->base->baseclasses); | |
45 } | |
46 } | |
47 | |
48 ////////////////////////////////////////////////////////////////////////////////////////// | |
49 | |
100 | 50 static void LLVM_AddBaseClassData(BaseClasses* bcs) |
51 { | |
52 // add base class data members first | |
53 for (int j=0; j<bcs->dim; j++) | |
54 { | |
55 BaseClass* bc = (BaseClass*)(bcs->data[j]); | |
137 | 56 |
57 // interfaces never add data fields | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
58 if (bc->base->isInterfaceDeclaration()) |
137 | 59 continue; |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
60 |
137 | 61 // recursively add baseclass data |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
62 LLVM_AddBaseClassData(&bc->base->baseclasses); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
63 |
137 | 64 Array* arr = &bc->base->fields; |
65 if (arr->dim == 0) | |
66 continue; | |
67 | |
100 | 68 Logger::println("Adding base class members of %s", bc->base->toChars()); |
69 LOG_SCOPE; | |
70 | |
132 | 71 for (int k=0; k < arr->dim; k++) { |
72 VarDeclaration* v = (VarDeclaration*)(arr->data[k]); | |
73 v->toObjFile(); | |
74 } | |
100 | 75 } |
76 } | |
77 | |
78 ////////////////////////////////////////////////////////////////////////////////////////// | |
79 | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
80 void DtoResolveClass(ClassDeclaration* cd) |
100 | 81 { |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
82 if (cd->llvmResolved) return; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
83 cd->llvmResolved = true; |
100 | 84 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
85 Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
86 LOG_SCOPE; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
87 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
88 // get the TypeClass |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
89 assert(cd->type->ty == Tclass); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
90 TypeClass* ts = (TypeClass*)cd->type; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
91 |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
92 // make sure the IrStruct is created |
137 | 93 IrStruct* irstruct = cd->irStruct; |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
94 if (!irstruct) { |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
95 irstruct = new IrStruct(ts); |
137 | 96 cd->irStruct = irstruct; |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
97 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
98 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
99 // resolve the base class |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
100 if (cd->baseClass) { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
101 DtoResolveClass(cd->baseClass); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
102 } |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
103 |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
104 // resolve interface vtables |
137 | 105 /*if (cd->vtblInterfaces) { |
106 Logger::println("Vtbl interfaces for '%s'", cd->toPrettyChars()); | |
107 LOG_SCOPE; | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
108 for (int i=0; i < cd->vtblInterfaces->dim; i++) { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
109 BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i]; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
110 ClassDeclaration *id = b->base; |
137 | 111 Logger::println("Vtbl interface: '%s'", id->toPrettyChars()); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
112 DtoResolveClass(id); |
114 | 113 // Fill in vtbl[] |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
114 b->fillVtbl(cd, &b->vtbl, 1); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
115 } |
137 | 116 }*/ |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
117 |
100 | 118 gIR->structs.push_back(irstruct); |
119 gIR->classes.push_back(cd); | |
120 | |
121 // add vtable | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
122 ts->llvmVtblType = new llvm::PATypeHolder(llvm::OpaqueType::get()); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
123 const llvm::Type* vtabty = getPtrToType(ts->llvmVtblType->get()); |
100 | 124 |
125 std::vector<const llvm::Type*> fieldtypes; | |
126 fieldtypes.push_back(vtabty); | |
127 | |
115
5ba6d286c941
[svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents:
114
diff
changeset
|
128 // add monitor |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
129 fieldtypes.push_back(getPtrToType(llvm::Type::Int8Ty)); |
115
5ba6d286c941
[svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents:
114
diff
changeset
|
130 |
137 | 131 // add base class data fields first |
100 | 132 LLVM_AddBaseClassData(&cd->baseclasses); |
133 | |
134 // then add own members | |
135 for (int k=0; k < cd->members->dim; k++) { | |
136 Dsymbol* dsym = (Dsymbol*)(cd->members->data[k]); | |
137 dsym->toObjFile(); | |
138 } | |
139 | |
132 | 140 // resolve class data fields (possibly unions) |
141 Logger::println("doing class fields"); | |
142 | |
143 if (irstruct->offsets.empty()) | |
144 { | |
145 Logger::println("has no fields"); | |
146 } | |
147 else | |
148 { | |
149 Logger::println("has fields"); | |
150 unsigned prevsize = (unsigned)-1; | |
151 unsigned lastoffset = (unsigned)-1; | |
152 const llvm::Type* fieldtype = NULL; | |
153 VarDeclaration* fieldinit = NULL; | |
154 size_t fieldpad = 0; | |
155 int idx = 0; | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
156 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { |
132 | 157 // first iteration |
158 if (lastoffset == (unsigned)-1) { | |
159 lastoffset = i->first; | |
160 fieldtype = i->second.type; | |
161 fieldinit = i->second.var; | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
162 prevsize = getABITypeSize(fieldtype); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
163 i->second.var->irField->index = idx; |
132 | 164 } |
165 // colliding offset? | |
166 else if (lastoffset == i->first) { | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
167 size_t s = getABITypeSize(i->second.type); |
132 | 168 if (s > prevsize) { |
169 fieldpad += s - prevsize; | |
170 prevsize = s; | |
171 } | |
137 | 172 cd->irStruct->hasUnions = true; |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
173 i->second.var->irField->index = idx; |
132 | 174 } |
175 // intersecting offset? | |
176 else if (i->first < (lastoffset + prevsize)) { | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
177 size_t s = getABITypeSize(i->second.type); |
132 | 178 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size |
137 | 179 cd->irStruct->hasUnions = true; |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
180 i->second.var->irField->index = idx; |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
181 i->second.var->irField->indexOffset = (i->first - lastoffset) / s; |
132 | 182 } |
183 // fresh offset | |
184 else { | |
185 // commit the field | |
186 fieldtypes.push_back(fieldtype); | |
187 irstruct->defaultFields.push_back(fieldinit); | |
188 if (fieldpad) { | |
189 fieldtypes.push_back(llvm::ArrayType::get(llvm::Type::Int8Ty, fieldpad)); | |
190 irstruct->defaultFields.push_back(NULL); | |
191 idx++; | |
192 } | |
193 | |
194 idx++; | |
195 | |
196 // start new | |
197 lastoffset = i->first; | |
198 fieldtype = i->second.type; | |
199 fieldinit = i->second.var; | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
200 prevsize = getABITypeSize(fieldtype); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
201 i->second.var->irField->index = idx; |
132 | 202 fieldpad = 0; |
203 } | |
204 } | |
205 fieldtypes.push_back(fieldtype); | |
206 irstruct->defaultFields.push_back(fieldinit); | |
207 if (fieldpad) { | |
208 fieldtypes.push_back(llvm::ArrayType::get(llvm::Type::Int8Ty, fieldpad)); | |
209 irstruct->defaultFields.push_back(NULL); | |
210 } | |
211 } | |
212 | |
137 | 213 // populate interface map |
214 { | |
215 Logger::println("Adding interfaces to '%s'", cd->toPrettyChars()); | |
216 LOG_SCOPE; | |
217 LLVM_AddBaseClassInterfaces(cd, &cd->baseclasses); | |
218 Logger::println("%d interfaces added", cd->irStruct->interfaces.size()); | |
100 | 219 } |
137 | 220 |
221 // add interface vtables at the end | |
222 int interIdx = (int)fieldtypes.size(); | |
223 for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) | |
224 { | |
225 ClassDeclaration* id = i->first; | |
226 IrInterface* iri = i->second; | |
100 | 227 |
137 | 228 // set vtbl type |
229 TypeClass* itc = (TypeClass*)id->type; | |
230 const llvm::Type* ivtblTy = getPtrToType(itc->llvmVtblType->get()); | |
231 fieldtypes.push_back(ivtblTy); | |
232 | |
233 // fix the interface vtable type | |
234 iri->vtblTy = isaStruct(itc->llvmVtblType->get()); | |
235 | |
236 // set index | |
237 iri->index = interIdx++; | |
238 } | |
239 Logger::println("%d interface vtables added", cd->irStruct->interfaces.size()); | |
240 | |
241 // create type | |
100 | 242 const llvm::StructType* structtype = llvm::StructType::get(fieldtypes); |
137 | 243 |
100 | 244 // refine abstract types for stuff like: class C {C next;} |
245 assert(irstruct->recty != 0); | |
246 llvm::PATypeHolder& spa = irstruct->recty; | |
247 llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype); | |
248 structtype = isaStruct(spa.get()); | |
249 | |
137 | 250 // make it official |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
251 if (!ts->llvmType) |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
252 ts->llvmType = new llvm::PATypeHolder(structtype); |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
253 else |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
254 *ts->llvmType = structtype; |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
255 spa = *ts->llvmType; |
100 | 256 |
123
7f9a0a58394b
[svn r127] Updated the lphobos build scripts a little. Created a new rebuild profile.
lindquist
parents:
121
diff
changeset
|
257 // name the type |
7f9a0a58394b
[svn r127] Updated the lphobos build scripts a little. Created a new rebuild profile.
lindquist
parents:
121
diff
changeset
|
258 gIR->module->addTypeName(cd->mangle(), ts->llvmType->get()); |
100 | 259 |
137 | 260 // get interface info type |
261 const llvm::StructType* infoTy = DtoInterfaceInfoType(); | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
262 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
263 // create vtable type |
100 | 264 llvm::GlobalVariable* svtblVar = 0; |
265 std::vector<const llvm::Type*> sinits_ty; | |
266 | |
267 for (int k=0; k < cd->vtbl.dim; k++) | |
268 { | |
269 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k]; | |
270 assert(dsym); | |
271 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n'; | |
272 | |
273 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
274 DtoResolveFunction(fd); |
117 | 275 //assert(fd->type->ty == Tfunction); |
276 //TypeFunction* tf = (TypeFunction*)fd->type; | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
277 //const llvm::Type* fpty = getPtrToType(tf->llvmType->get()); |
117 | 278 const llvm::FunctionType* vfty = DtoBaseFunctionType(fd); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
279 const llvm::Type* vfpty = getPtrToType(vfty); |
117 | 280 sinits_ty.push_back(vfpty); |
100 | 281 } |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
282 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
283 Logger::println("*** ClassDeclaration in vtable: %s", cd2->toChars()); |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
284 const llvm::Type* cinfoty; |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
285 if (cd->isInterfaceDeclaration()) { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
286 cinfoty = infoTy; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
287 } |
137 | 288 else if (cd != ClassDeclaration::classinfo) { |
289 cinfoty = ClassDeclaration::classinfo->type->llvmType->get(); | |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
290 } |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
291 else { |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
292 // this is the ClassInfo class, the type is this type |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
293 cinfoty = ts->llvmType->get(); |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
294 } |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
295 const llvm::Type* cty = getPtrToType(cinfoty); |
100 | 296 sinits_ty.push_back(cty); |
297 } | |
298 else | |
299 assert(0); | |
300 } | |
301 | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
302 assert(!sinits_ty.empty()); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
303 const llvm::StructType* svtbl_ty = llvm::StructType::get(sinits_ty); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
304 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
305 std::string styname(cd->mangle()); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
306 styname.append("__vtblType"); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
307 gIR->module->addTypeName(styname, svtbl_ty); |
100 | 308 |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
309 // refine for final vtable type |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
310 llvm::cast<llvm::OpaqueType>(ts->llvmVtblType->get())->refineAbstractTypeTo(svtbl_ty); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
311 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
312 gIR->classes.pop_back(); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
313 gIR->structs.pop_back(); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
314 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
315 gIR->declareList.push_back(cd); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
316 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
317 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
318 ////////////////////////////////////////////////////////////////////////////////////////// |
100 | 319 |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
320 void DtoDeclareClass(ClassDeclaration* cd) |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
321 { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
322 if (cd->llvmDeclared) return; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
323 cd->llvmDeclared = true; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
324 |
132 | 325 Logger::println("DtoDeclareClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
326 LOG_SCOPE; |
100 | 327 |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
328 assert(cd->type->ty == Tclass); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
329 TypeClass* ts = (TypeClass*)cd->type; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
330 |
137 | 331 assert(cd->irStruct); |
332 IrStruct* irstruct = cd->irStruct; | |
100 | 333 |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
334 gIR->structs.push_back(irstruct); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
335 gIR->classes.push_back(cd); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
336 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
337 bool needs_definition = false; |
123
7f9a0a58394b
[svn r127] Updated the lphobos build scripts a little. Created a new rebuild profile.
lindquist
parents:
121
diff
changeset
|
338 if (cd->getModule() == gIR->dmodule) { |
7f9a0a58394b
[svn r127] Updated the lphobos build scripts a little. Created a new rebuild profile.
lindquist
parents:
121
diff
changeset
|
339 needs_definition = true; |
100 | 340 } |
341 | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
342 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage; |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
343 |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
344 // interfaces have no static initializer |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
345 // same goes for abstract classes |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
346 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
347 // vtable |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
348 std::string varname("_D"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
349 varname.append(cd->mangle()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
350 varname.append("6__vtblZ"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
351 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
352 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get()); |
137 | 353 cd->irStruct->vtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
354 } |
100 | 355 |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
356 // get interface info type |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
357 const llvm::StructType* infoTy = DtoInterfaceInfoType(); |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
358 |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
359 // interface info array |
137 | 360 if (!cd->irStruct->interfaces.empty()) { |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
361 // symbol name |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
362 std::string nam = "_D"; |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
363 nam.append(cd->mangle()); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
364 nam.append("16__interfaceInfosZ"); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
365 // resolve array type |
137 | 366 const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->irStruct->interfaces.size()); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
367 // declare global |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
368 irstruct->interfaceInfosTy = arrTy; |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
369 irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
370 } |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
371 |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
372 // interfaces have no static initializer |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
373 // same goes for abstract classes |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
374 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
375 // interface vtables |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
376 unsigned idx = 0; |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
377 for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
378 { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
379 ClassDeclaration* id = i->first; |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
380 IrInterface* iri = i->second; |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
381 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
382 std::string nam("_D"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
383 nam.append(cd->mangle()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
384 nam.append("11__interface"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
385 nam.append(id->mangle()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
386 nam.append("6__vtblZ"); |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
387 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
388 assert(iri->vtblTy); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
389 iri->vtbl = new llvm::GlobalVariable(iri->vtblTy, true, _linkage, 0, nam, gIR->module); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
390 llvm::Constant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)}; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
391 iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
392 idx++; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
393 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
394 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
395 // init |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
396 std::string initname("_D"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
397 initname.append(cd->mangle()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
398 initname.append("6__initZ"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
399 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
400 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module); |
137 | 401 cd->irStruct->init = initvar; |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
402 } |
100 | 403 |
404 gIR->classes.pop_back(); | |
405 gIR->structs.pop_back(); | |
406 | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
407 gIR->constInitList.push_back(cd); |
100 | 408 if (needs_definition) |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
409 gIR->defineList.push_back(cd); |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
410 |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
411 // classinfo |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
412 DtoDeclareClassInfo(cd); |
106 | 413 |
414 // typeinfo | |
123
7f9a0a58394b
[svn r127] Updated the lphobos build scripts a little. Created a new rebuild profile.
lindquist
parents:
121
diff
changeset
|
415 if (needs_definition) |
106 | 416 cd->type->getTypeInfo(NULL); |
100 | 417 } |
418 | |
419 ////////////////////////////////////////////////////////////////////////////////////////// | |
420 | |
421 void DtoConstInitClass(ClassDeclaration* cd) | |
422 { | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
423 if (cd->llvmInitialized) return; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
424 cd->llvmInitialized = true; |
100 | 425 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
426 if (cd->isInterfaceDeclaration()) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
427 return; // nothing to do |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
428 |
132 | 429 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); |
100 | 430 LOG_SCOPE; |
431 | |
137 | 432 IrStruct* irstruct = cd->irStruct; |
100 | 433 gIR->structs.push_back(irstruct); |
434 gIR->classes.push_back(cd); | |
435 | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
436 // get the struct (class) type |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
437 assert(cd->type->ty == Tclass); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
438 TypeClass* ts = (TypeClass*)cd->type; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
439 const llvm::StructType* structtype = isaStruct(ts->llvmType->get()); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
440 const llvm::StructType* vtbltype = isaStruct(ts->llvmVtblType->get()); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
441 |
100 | 442 // make sure each offset knows its default initializer |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
443 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) |
100 | 444 { |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
445 IrStruct::Offset* so = &i->second; |
100 | 446 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); |
447 so->init = finit; | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
448 so->var->irField->constInit = finit; |
100 | 449 } |
450 | |
451 // fill out fieldtypes/inits | |
452 std::vector<llvm::Constant*> fieldinits; | |
453 | |
454 // first field is always the vtable | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
455 if (cd->isAbstract()) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
456 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
457 fieldinits.push_back( |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
458 llvm::ConstantPointerNull::get( |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
459 getPtrToType( |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
460 ts->llvmVtblType->get() |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
461 ) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
462 ) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
463 ); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
464 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
465 else |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
466 { |
137 | 467 assert(cd->irStruct->vtbl != 0); |
468 fieldinits.push_back(cd->irStruct->vtbl); | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
469 } |
100 | 470 |
115
5ba6d286c941
[svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents:
114
diff
changeset
|
471 // then comes monitor |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
472 fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); |
115
5ba6d286c941
[svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents:
114
diff
changeset
|
473 |
137 | 474 // go through the field inits and build the default initializer |
475 size_t nfi = irstruct->defaultFields.size(); | |
476 for (size_t i=0; i<nfi; ++i) { | |
477 llvm::Constant* c; | |
478 if (irstruct->defaultFields[i]) { | |
479 c = irstruct->defaultFields[i]->irField->constInit; | |
480 assert(c); | |
481 } | |
482 else { | |
483 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+2)); | |
484 assert(arrty); | |
485 std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); | |
486 c = llvm::ConstantArray::get(arrty, vals); | |
487 } | |
488 fieldinits.push_back(c); | |
489 } | |
132 | 490 |
137 | 491 // last comes interface vtables |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
492 const llvm::StructType* infoTy = DtoInterfaceInfoType(); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
493 for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
494 { |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
495 IrInterface* iri = i->second; |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
496 iri->infoTy = infoTy; |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
497 if (cd->isAbstract()) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
498 { |
137 | 499 fieldinits.push_back(llvm::Constant::getNullValue(structtype->getElementType(iri->index))); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
500 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
501 else |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
502 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
503 assert(iri->vtbl); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
504 fieldinits.push_back(iri->vtbl); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
505 } |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
506 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
507 |
100 | 508 // generate initializer |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
509 #if 0 |
137 | 510 //Logger::cout() << cd->toPrettyChars() << " | " << *structtype << '\n'; |
511 assert(fieldinits.size() == structtype->getNumElements()); | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
512 for(size_t i=0; i<structtype->getNumElements(); ++i) { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
513 Logger::cout() << "s#" << i << " = " << *structtype->getElementType(i) << '\n'; |
137 | 514 Logger::cout() << "i#" << i << " = " << *fieldinits[i] << '\n'; |
515 assert(fieldinits[i]->getType() == structtype->getElementType(i)); | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
516 } |
137 | 517 #endif |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
518 |
137 | 519 #if 0 |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
520 for(size_t i=0; i<fieldinits.size(); ++i) { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
521 Logger::cout() << "i#" << i << " = " << *fieldinits[i]->getType() << '\n'; |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
522 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
523 #endif |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
524 |
100 | 525 llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits); |
526 assert(_init); | |
137 | 527 cd->irStruct->constInit = _init; |
100 | 528 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
529 // abstract classes have no static vtable |
137 | 530 // neither do interfaces (on their own, the implementing class supplies the vtable) |
531 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
532 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
533 // generate vtable initializer |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
534 std::vector<llvm::Constant*> sinits; |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
535 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
536 for (int k=0; k < cd->vtbl.dim; k++) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
537 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
538 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k]; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
539 assert(dsym); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
540 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n'; |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
541 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
542 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
543 DtoForceDeclareDsymbol(fd); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
544 assert(fd->irFunc->func); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
545 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->irFunc->func); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
546 // cast if necessary (overridden method) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
547 if (c->getType() != vtbltype->getElementType(k)) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
548 c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k)); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
549 sinits.push_back(c); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
550 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
551 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { |
137 | 552 assert(cd->irStruct->classInfo); |
553 llvm::Constant* c = cd->irStruct->classInfo; | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
554 sinits.push_back(c); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
555 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
556 else |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
557 assert(0); |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
558 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
559 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
560 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get()); |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
561 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
562 #if 0 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
563 for (size_t i=0; i< sinits.size(); ++i) |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
564 { |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
565 Logger::cout() << "field[" << i << "] = " << *svtbl_ty->getElementType(i) << '\n'; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
566 Logger::cout() << "init [" << i << "] = " << *sinits[i]->getType() << '\n'; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
567 assert(svtbl_ty->getElementType(i) == sinits[i]->getType()); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
568 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
569 #endif |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
570 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
571 llvm::Constant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits); |
137 | 572 cd->irStruct->constVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
573 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
574 // create interface vtable const initalizers |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
575 for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
576 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
577 ClassDeclaration* id = i->first; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
578 assert(id->type->ty == Tclass); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
579 TypeClass* its = (TypeClass*)id->type; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
580 |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
581 IrInterface* iri = i->second; |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
582 BaseClass* b = iri->base; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
583 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
584 const llvm::StructType* ivtbl_ty = isaStruct(its->llvmVtblType->get()); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
585 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
586 // generate interface info initializer |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
587 std::vector<llvm::Constant*> infoInits; |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
588 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
589 // classinfo |
137 | 590 assert(id->irStruct->classInfo); |
591 llvm::Constant* c = id->irStruct->classInfo; | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
592 infoInits.push_back(c); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
593 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
594 // vtbl |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
595 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
596 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
597 c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
598 infoInits.push_back(c); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
599 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
600 // offset |
137 | 601 // generate target independent offset with constGEP |
602 /*llvm::Value* cidx = DtoConstInt(iri->index); | |
603 Logger::cout() << "offset to interface in class type: " << *cd->type->llvmType->get() << '\n'; | |
604 size_t ioff = gTargetData->getIndexedOffset(cd->type->llvmType->get(), &cidx, 1); | |
605 infoInits.push_back(DtoConstUint(ioff));*/ | |
606 assert(iri->index >= 0); | |
607 size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->llvmType->get()))->getElementOffset(iri->index); | |
608 infoInits.push_back(DtoConstUint(ioff)); | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
609 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
610 // create interface info initializer constant |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
611 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits)); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
612 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
613 // generate vtable initializer |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
614 std::vector<llvm::Constant*> iinits; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
615 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
616 // add interface info |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
617 iinits.push_back(iri->info); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
618 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
619 for (int k=1; k < b->vtbl.dim; k++) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
620 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
621 Logger::println("interface vtbl const init nr. %d", k); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
622 Dsymbol* dsym = (Dsymbol*)b->vtbl.data[k]; |
137 | 623 assert(dsym); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
624 FuncDeclaration* fd = dsym->isFuncDeclaration(); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
625 assert(fd); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
626 DtoForceDeclareDsymbol(fd); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
627 assert(fd->irFunc->func); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
628 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->irFunc->func); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
629 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
630 // we have to bitcast, as the type created in ResolveClass expects a different this type |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
631 c = llvm::ConstantExpr::getBitCast(c, iri->vtblTy->getContainedType(k)); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
632 iinits.push_back(c); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
633 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
634 |
137 | 635 #if 0 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
636 for (size_t x=0; x< iinits.size(); ++x) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
637 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
638 Logger::cout() << "field[" << x << "] = " << *ivtbl_ty->getElementType(x) << "\n\n"; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
639 Logger::cout() << "init [" << x << "] = " << *iinits[x] << "\n\n"; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
640 assert(ivtbl_ty->getElementType(x) == iinits[x]->getType()); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
641 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
642 #endif |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
643 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
644 llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
645 iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
646 } |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
647 } |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
648 // we always generate interfaceinfos as best we can |
137 | 649 /*else |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
650 { |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
651 for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
652 { |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
653 ClassDeclaration* id = i->first; |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
654 assert(id->type->ty == Tclass); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
655 TypeClass* its = (TypeClass*)id->type; |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
656 |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
657 IrInterface* iri = i->second; |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
658 BaseClass* b = iri->base; |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
659 |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
660 // generate interface info initializer |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
661 std::vector<llvm::Constant*> infoInits; |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
662 |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
663 // classinfo |
137 | 664 assert(id->irStruct->classInfo); |
665 llvm::Constant* c = id->irStruct->classInfo; | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
666 infoInits.push_back(c); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
667 |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
668 // vtbl |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
669 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
670 c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty)); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
671 infoInits.push_back(c); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
672 |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
673 // offset |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
674 infoInits.push_back(DtoConstInt(0)); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
675 |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
676 // create interface info initializer constant |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
677 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits)); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
678 } |
137 | 679 }*/ |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
680 |
100 | 681 gIR->classes.pop_back(); |
682 gIR->structs.pop_back(); | |
683 } | |
684 | |
685 ////////////////////////////////////////////////////////////////////////////////////////// | |
686 | |
687 void DtoDefineClass(ClassDeclaration* cd) | |
688 { | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
689 if (cd->llvmDefined) return; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
690 cd->llvmDefined = true; |
100 | 691 |
132 | 692 Logger::println("DtoDefineClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); |
100 | 693 LOG_SCOPE; |
694 | |
695 // get the struct (class) type | |
696 assert(cd->type->ty == Tclass); | |
697 TypeClass* ts = (TypeClass*)cd->type; | |
698 | |
123
7f9a0a58394b
[svn r127] Updated the lphobos build scripts a little. Created a new rebuild profile.
lindquist
parents:
121
diff
changeset
|
699 if (cd->getModule() == gIR->dmodule) { |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
700 // interfaces don't have initializers |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
701 // neither do abstract classes |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
702 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
703 { |
137 | 704 cd->irStruct->init->setInitializer(cd->irStruct->constInit); |
705 cd->irStruct->vtbl->setInitializer(cd->irStruct->constVtbl); | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
706 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
707 // initialize interface vtables |
137 | 708 IrStruct* irstruct = cd->irStruct; |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
709 std::vector<llvm::Constant*> infoInits; |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
710 for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
711 { |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
712 IrInterface* iri = i->second; |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
713 iri->vtbl->setInitializer(iri->vtblInit); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
714 infoInits.push_back(iri->infoInit); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
715 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
716 // initialize interface info array |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
717 if (!infoInits.empty()) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
718 { |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
719 llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
720 irstruct->interfaceInfos->setInitializer(arrInit); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
721 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
722 } |
123
7f9a0a58394b
[svn r127] Updated the lphobos build scripts a little. Created a new rebuild profile.
lindquist
parents:
121
diff
changeset
|
723 |
7f9a0a58394b
[svn r127] Updated the lphobos build scripts a little. Created a new rebuild profile.
lindquist
parents:
121
diff
changeset
|
724 // generate classinfo |
7f9a0a58394b
[svn r127] Updated the lphobos build scripts a little. Created a new rebuild profile.
lindquist
parents:
121
diff
changeset
|
725 DtoDefineClassInfo(cd); |
100 | 726 } |
727 } | |
728 | |
729 ////////////////////////////////////////////////////////////////////////////////////////// | |
730 | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
731 DValue* DtoNewClass(TypeClass* tc, NewExp* newexp) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
732 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
733 // resolve type |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
734 DtoForceDeclareDsymbol(tc->sym); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
735 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
736 // allocate |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
737 llvm::Value* mem; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
738 if (newexp->onstack) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
739 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
740 mem = new llvm::AllocaInst(DtoType(tc)->getContainedType(0), "newclass_alloca", gIR->topallocapoint()); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
741 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
742 else |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
743 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
744 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass"); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
745 std::vector<llvm::Value*> args; |
137 | 746 args.push_back(tc->sym->irStruct->classInfo); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
747 mem = gIR->ir->CreateCall(fn, args.begin(), args.end(), "newclass_gc_alloc"); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
748 mem = DtoBitCast(mem, DtoType(tc), "newclass_gc"); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
749 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
750 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
751 // init |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
752 DtoInitClass(tc, mem); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
753 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
754 // init inner-class outer reference |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
755 if (newexp->thisexp) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
756 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
757 Logger::println("Resolving outer class"); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
758 LOG_SCOPE; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
759 DValue* thisval = newexp->thisexp->toElem(gIR); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
760 size_t idx = 2; |
137 | 761 idx += tc->sym->irStruct->interfaces.size(); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
762 llvm::Value* dst = thisval->getRVal(); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
763 llvm::Value* src = DtoGEPi(mem,0,idx,"tmp"); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
764 Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n'; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
765 DtoStore(dst, src); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
766 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
767 // set the context for nested classes |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
768 else if (tc->sym->isNested()) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
769 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
770 Logger::println("Resolving nested context"); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
771 LOG_SCOPE; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
772 size_t idx = 2; |
137 | 773 idx += tc->sym->irStruct->interfaces.size(); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
774 llvm::Value* nest = gIR->func()->decl->irFunc->nestedVar; |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
775 if (!nest) |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
776 nest = gIR->func()->decl->irFunc->thisVar; |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
777 assert(nest); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
778 llvm::Value* gep = DtoGEPi(mem,0,idx,"tmp"); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
779 nest = DtoBitCast(nest, gep->getType()->getContainedType(0)); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
780 DtoStore(nest, gep); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
781 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
782 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
783 // call constructor |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
784 if (newexp->arguments) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
785 return DtoCallClassCtor(tc, newexp->member, newexp->arguments, mem); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
786 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
787 // return default constructed class |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
788 return new DImValue(tc, mem, false); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
789 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
790 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
791 ////////////////////////////////////////////////////////////////////////////////////////// |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
792 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
793 void DtoInitClass(TypeClass* tc, llvm::Value* dst) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
794 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
795 size_t presz = 2*getABITypeSize(DtoSize_t()); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
796 uint64_t n = getABITypeSize(tc->llvmType->get()) - presz; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
797 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
798 // set vtable field seperately, this might give better optimization |
137 | 799 assert(tc->sym->irStruct->vtbl); |
800 DtoStore(tc->sym->irStruct->vtbl, DtoGEPi(dst,0,0,"vtbl")); | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
801 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
802 // monitor always defaults to zero |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
803 llvm::Value* tmp = DtoGEPi(dst,0,1,"monitor"); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
804 DtoStore(llvm::Constant::getNullValue(tmp->getType()->getContainedType(0)), tmp); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
805 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
806 // done? |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
807 if (n == 0) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
808 return; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
809 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
810 // copy the rest from the static initializer |
137 | 811 assert(tc->sym->irStruct->init); |
812 assert(dst->getType() == tc->sym->irStruct->init->getType()); | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
813 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
814 const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
815 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
816 llvm::Value* dstarr = DtoGEPi(dst,0,2,"tmp"); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
817 dstarr = DtoBitCast(dstarr, arrty); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
818 |
137 | 819 llvm::Value* srcarr = DtoGEPi(tc->sym->irStruct->init,0,2,"tmp"); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
820 srcarr = DtoBitCast(srcarr, arrty); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
821 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
822 llvm::Function* fn = LLVM_DeclareMemCpy32(); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
823 std::vector<llvm::Value*> llargs; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
824 llargs.resize(4); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
825 llargs[0] = dstarr; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
826 llargs[1] = srcarr; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
827 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
828 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
829 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
830 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
831 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
832 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
833 ////////////////////////////////////////////////////////////////////////////////////////// |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
834 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
835 DValue* DtoCallClassCtor(TypeClass* type, CtorDeclaration* ctor, Array* arguments, llvm::Value* mem) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
836 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
837 Logger::println("Calling constructor"); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
838 LOG_SCOPE; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
839 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
840 assert(ctor); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
841 DtoForceDeclareDsymbol(ctor); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
842 llvm::Function* fn = ctor->irFunc->func; |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
843 TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
844 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
845 std::vector<llvm::Value*> ctorargs; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
846 ctorargs.push_back(mem); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
847 for (size_t i=0; i<arguments->dim; ++i) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
848 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
849 Expression* ex = (Expression*)arguments->data[i]; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
850 Argument* fnarg = Argument::getNth(tf->parameters, i); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
851 DValue* argval = DtoArgument(fnarg, ex); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
852 llvm::Value* a = argval->getRVal(); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
853 const llvm::Type* aty = fn->getFunctionType()->getParamType(i+1); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
854 if (a->getType() != aty) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
855 a = DtoBitCast(a, aty); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
856 ctorargs.push_back(a); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
857 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
858 llvm::CallInst* call = new llvm::CallInst(fn, ctorargs.begin(), ctorargs.end(), "tmp", gIR->scopebb()); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
859 call->setCallingConv(DtoCallingConv(LINKd)); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
860 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
861 return new DImValue(type, call, false); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
862 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
863 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
864 ////////////////////////////////////////////////////////////////////////////////////////// |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
865 |
100 | 866 void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance) |
867 { | |
868 Array* arr = &tc->sym->dtors; | |
869 for (size_t i=0; i<arr->dim; i++) | |
870 { | |
871 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i]; | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
872 assert(fd->irFunc->func); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
873 new llvm::CallInst(fd->irFunc->func, instance, "", gIR->scopebb()); |
100 | 874 } |
875 } | |
876 | |
877 ////////////////////////////////////////////////////////////////////////////////////////// | |
878 | |
114 | 879 DValue* DtoCastClass(DValue* val, Type* _to) |
880 { | |
881 Type* to = DtoDType(_to); | |
882 if (to->ty == Tpointer) { | |
883 const llvm::Type* tolltype = DtoType(_to); | |
884 llvm::Value* rval = DtoBitCast(val->getRVal(), tolltype); | |
885 return new DImValue(_to, rval); | |
886 } | |
887 | |
888 assert(to->ty == Tclass); | |
889 TypeClass* tc = (TypeClass*)to; | |
890 | |
891 Type* from = DtoDType(val->getType()); | |
892 TypeClass* fc = (TypeClass*)from; | |
893 | |
894 if (tc->sym->isInterfaceDeclaration()) { | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
895 if (fc->sym->isInterfaceDeclaration()) { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
896 return DtoDynamicCastInterface(val, _to); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
897 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
898 else { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
899 return DtoDynamicCastObject(val, _to); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
900 } |
114 | 901 } |
902 else { | |
903 int poffset; | |
904 if (fc->sym->isInterfaceDeclaration()) { | |
905 return DtoCastInterfaceToObject(val, _to); | |
906 } | |
907 else if (tc->sym->isBaseOf(fc->sym,NULL)) { | |
908 const llvm::Type* tolltype = DtoType(_to); | |
909 llvm::Value* rval = DtoBitCast(val->getRVal(), tolltype); | |
910 return new DImValue(_to, rval); | |
911 } | |
912 else { | |
913 return DtoDynamicCastObject(val, _to); | |
914 } | |
915 } | |
916 } | |
917 | |
918 ////////////////////////////////////////////////////////////////////////////////////////// | |
919 | |
920 DValue* DtoDynamicCastObject(DValue* val, Type* _to) | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
921 { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
922 // call: |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
923 // Object _d_dynamic_cast(Object o, ClassInfo c) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
924 |
114 | 925 DtoForceDeclareDsymbol(ClassDeclaration::object); |
926 DtoForceDeclareDsymbol(ClassDeclaration::classinfo); | |
927 | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
928 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_dynamic_cast"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
929 const llvm::FunctionType* funcTy = func->getFunctionType(); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
930 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
931 std::vector<llvm::Value*> args; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
932 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
933 // Object o |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
934 llvm::Value* tmp = val->getRVal(); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
935 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
936 args.push_back(tmp); |
114 | 937 assert(funcTy->getParamType(0) == tmp->getType()); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
938 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
939 // ClassInfo c |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
940 TypeClass* to = (TypeClass*)DtoDType(_to); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
941 DtoForceDeclareDsymbol(to->sym); |
137 | 942 assert(to->sym->irStruct->classInfo); |
943 tmp = to->sym->irStruct->classInfo; | |
114 | 944 // unfortunately this is needed as the implementation of object differs somehow from the declaration |
945 // this could happen in user code as well :/ | |
946 tmp = DtoBitCast(tmp, funcTy->getParamType(1)); | |
947 args.push_back(tmp); | |
948 assert(funcTy->getParamType(1) == tmp->getType()); | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
949 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
950 // call it |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
951 llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp"); |
114 | 952 |
953 // cast return value | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
954 ret = DtoBitCast(ret, DtoType(_to)); |
114 | 955 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
956 return new DImValue(_to, ret); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
957 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
958 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
959 ////////////////////////////////////////////////////////////////////////////////////////// |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
960 |
114 | 961 DValue* DtoCastInterfaceToObject(DValue* val, Type* to) |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
962 { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
963 // call: |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
964 // Object _d_toObject(void* p) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
965 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
966 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_toObject"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
967 const llvm::FunctionType* funcTy = func->getFunctionType(); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
968 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
969 // void* p |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
970 llvm::Value* tmp = val->getRVal(); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
971 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
972 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
973 // call it |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
974 llvm::Value* ret = gIR->ir->CreateCall(func, tmp, "tmp"); |
114 | 975 |
976 // cast return value | |
977 if (to != NULL) | |
978 ret = DtoBitCast(ret, DtoType(to)); | |
979 else | |
980 to = ClassDeclaration::object->type; | |
981 | |
982 return new DImValue(to, ret); | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
983 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
984 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
985 ////////////////////////////////////////////////////////////////////////////////////////// |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
986 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
987 DValue* DtoDynamicCastInterface(DValue* val, Type* _to) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
988 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
989 // call: |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
990 // Object _d_interface_cast(void* p, ClassInfo c) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
991 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
992 DtoForceDeclareDsymbol(ClassDeclaration::object); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
993 DtoForceDeclareDsymbol(ClassDeclaration::classinfo); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
994 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
995 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_interface_cast"); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
996 const llvm::FunctionType* funcTy = func->getFunctionType(); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
997 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
998 std::vector<llvm::Value*> args; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
999 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1000 // void* p |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1001 llvm::Value* tmp = val->getRVal(); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1002 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1003 args.push_back(tmp); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1004 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1005 // ClassInfo c |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1006 TypeClass* to = (TypeClass*)DtoDType(_to); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1007 DtoForceDeclareDsymbol(to->sym); |
137 | 1008 assert(to->sym->irStruct->classInfo); |
1009 tmp = to->sym->irStruct->classInfo; | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1010 // unfortunately this is needed as the implementation of object differs somehow from the declaration |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1011 // this could happen in user code as well :/ |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1012 tmp = DtoBitCast(tmp, funcTy->getParamType(1)); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1013 args.push_back(tmp); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1014 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1015 // call it |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1016 llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp"); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1017 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1018 // cast return value |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1019 ret = DtoBitCast(ret, DtoType(_to)); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1020 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1021 return new DImValue(_to, ret); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1022 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1023 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1024 ////////////////////////////////////////////////////////////////////////////////////////// |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1025 |
132 | 1026 static unsigned LLVM_ClassOffsetToIndex(ClassDeclaration* cd, unsigned os, unsigned& idx) |
1027 { | |
1028 // start at the bottom of the inheritance chain | |
1029 if (cd->baseClass != 0) { | |
1030 unsigned o = LLVM_ClassOffsetToIndex(cd->baseClass, os, idx); | |
1031 if (o != (unsigned)-1) | |
1032 return o; | |
1033 } | |
1034 | |
1035 // check this class | |
1036 unsigned i; | |
1037 for (i=0; i<cd->fields.dim; ++i) { | |
1038 VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i]; | |
1039 if (os == vd->offset) | |
1040 return i+idx; | |
1041 } | |
1042 idx += i; | |
1043 | |
1044 return (unsigned)-1; | |
1045 } | |
1046 | |
1047 ////////////////////////////////////////////////////////////////////////////////////////// | |
1048 | |
1049 void ClassDeclaration::offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result) | |
1050 { | |
1051 unsigned idx = 0; | |
1052 unsigned r = LLVM_ClassOffsetToIndex(this, os, idx); | |
1053 assert(r != (unsigned)-1 && "Offset not found in any aggregate field"); | |
1054 // vtable is 0, monitor is 1 | |
1055 r += 2; | |
1056 // interface offset further | |
1057 r += vtblInterfaces->dim; | |
1058 // the final index was not pushed | |
1059 result.push_back(r); | |
1060 } | |
1061 | |
1062 ////////////////////////////////////////////////////////////////////////////////////////// | |
1063 | |
1064 llvm::Value* DtoIndexClass(llvm::Value* ptr, ClassDeclaration* cd, Type* t, unsigned os, std::vector<unsigned>& idxs) | |
1065 { | |
1066 Logger::println("checking for offset %u type %s:", os, t->toChars()); | |
1067 LOG_SCOPE; | |
1068 | |
1069 if (idxs.empty()) | |
1070 idxs.push_back(0); | |
1071 | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1072 const llvm::Type* llt = getPtrToType(DtoType(t)); |
132 | 1073 const llvm::Type* st = DtoType(cd->type); |
1074 if (ptr->getType() != st) { | |
137 | 1075 assert(cd->irStruct->hasUnions); |
132 | 1076 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); |
1077 } | |
1078 | |
137 | 1079 unsigned dataoffset = 2; |
132 | 1080 |
137 | 1081 IrStruct* irstruct = cd->irStruct; |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1082 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { |
132 | 1083 //for (unsigned i=0; i<cd->fields.dim; ++i) { |
1084 //VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i]; | |
1085 VarDeclaration* vd = i->second.var; | |
1086 assert(vd); | |
1087 Type* vdtype = DtoDType(vd->type); | |
1088 Logger::println("found %u type %s", vd->offset, vdtype->toChars()); | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1089 assert(vd->irField->index >= 0); |
132 | 1090 if (os == vd->offset && vdtype == t) { |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1091 idxs.push_back(vd->irField->index + dataoffset); |
132 | 1092 Logger::cout() << "indexing: " << *ptr << '\n'; |
1093 ptr = DtoGEP(ptr, idxs, "tmp"); | |
1094 if (ptr->getType() != llt) | |
1095 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); | |
1096 Logger::cout() << "indexing: " << *ptr << '\n'; | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1097 if (vd->irField->indexOffset) |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1098 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb()); |
132 | 1099 Logger::cout() << "indexing: " << *ptr << '\n'; |
1100 return ptr; | |
1101 } | |
1102 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { | |
1103 TypeStruct* ts = (TypeStruct*)vdtype; | |
1104 StructDeclaration* ssd = ts->sym; | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1105 idxs.push_back(vd->irField->index + dataoffset); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1106 if (vd->irField->indexOffset) { |
132 | 1107 Logger::println("has union field offset"); |
1108 ptr = DtoGEP(ptr, idxs, "tmp"); | |
1109 if (ptr->getType() != llt) | |
1110 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); | |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1111 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb()); |
132 | 1112 std::vector<unsigned> tmp; |
1113 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); | |
1114 } | |
1115 else { | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1116 const llvm::Type* sty = getPtrToType(DtoType(vd->type)); |
132 | 1117 if (ptr->getType() != sty) { |
1118 ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp"); | |
1119 std::vector<unsigned> tmp; | |
1120 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); | |
1121 } | |
1122 else { | |
1123 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, idxs); | |
1124 } | |
1125 } | |
1126 } | |
1127 } | |
1128 | |
1129 assert(0); | |
1130 | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1131 size_t llt_sz = getABITypeSize(llt->getContainedType(0)); |
132 | 1132 assert(os % llt_sz == 0); |
1133 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); | |
1134 return new llvm::GetElementPtrInst(ptr, DtoConstUint(os / llt_sz), "tmp", gIR->scopebb()); | |
1135 } | |
1136 | |
1137 ////////////////////////////////////////////////////////////////////////////////////////// | |
1138 | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1139 llvm::Value* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl) |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1140 { |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1141 assert(fdecl->isVirtual());//fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1142 assert(fdecl->vtblIndex > 0); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1143 assert(DtoDType(inst->getType())->ty == Tclass); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1144 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1145 llvm::Value* vthis = inst->getRVal(); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1146 //Logger::cout() << "vthis: " << *vthis << '\n'; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1147 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1148 llvm::Value* funcval; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1149 funcval = DtoGEPi(vthis, 0, 0, "tmp"); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1150 funcval = DtoLoad(funcval); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1151 funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, fdecl->toPrettyChars()); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1152 funcval = DtoLoad(funcval); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1153 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1154 //assert(funcval->getType() == DtoType(fdecl->type)); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1155 //cc = DtoCallingConv(fdecl->linkage); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1156 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1157 return funcval; |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1158 } |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1159 |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1160 ////////////////////////////////////////////////////////////////////////////////////////// |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1161 |
100 | 1162 void DtoDeclareClassInfo(ClassDeclaration* cd) |
1163 { | |
137 | 1164 if (cd->irStruct->classDeclared) return; |
1165 cd->irStruct->classDeclared = true; | |
100 | 1166 |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1167 Logger::println("DtoDeclareClassInfo(%s)", cd->toChars()); |
100 | 1168 LOG_SCOPE; |
1169 | |
1170 ClassDeclaration* cinfo = ClassDeclaration::classinfo; | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1171 DtoResolveClass(cinfo); |
100 | 1172 |
1173 std::string gname("_D"); | |
1174 gname.append(cd->mangle()); | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1175 if (!cd->isInterfaceDeclaration()) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1176 gname.append("7__ClassZ"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1177 else |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1178 gname.append("11__InterfaceZ"); |
100 | 1179 |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1180 const llvm::Type* st = cinfo->type->llvmType->get(); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1181 |
137 | 1182 cd->irStruct->classInfo = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module); |
100 | 1183 } |
1184 | |
110
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1185 static llvm::Constant* build_offti_entry(VarDeclaration* vd) |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1186 { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1187 std::vector<const llvm::Type*> types; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1188 std::vector<llvm::Constant*> inits; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1189 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1190 types.push_back(DtoSize_t()); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1191 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1192 size_t offset = vd->offset; // TODO might not be the true offset |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1193 // dmd only accounts for the vtable, not classinfo or monitor |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1194 if (global.params.is64bit) |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1195 offset += 8; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1196 else |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1197 offset += 4; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1198 inits.push_back(DtoConstSize_t(offset)); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1199 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1200 vd->type->getTypeInfo(NULL); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1201 assert(vd->type->vtinfo); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1202 DtoForceDeclareDsymbol(vd->type->vtinfo); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1203 llvm::Constant* c = isaConstant(vd->type->vtinfo->getIrValue()); |
110
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1204 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1205 const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get()); |
123
7f9a0a58394b
[svn r127] Updated the lphobos build scripts a little. Created a new rebuild profile.
lindquist
parents:
121
diff
changeset
|
1206 //Logger::cout() << "tiTy = " << *tiTy << '\n'; |
110
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1207 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1208 types.push_back(tiTy); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1209 inits.push_back(llvm::ConstantExpr::getBitCast(c, tiTy)); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1210 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1211 const llvm::StructType* sTy = llvm::StructType::get(types); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1212 return llvm::ConstantStruct::get(sTy, inits); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1213 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1214 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1215 static llvm::Constant* build_offti_array(ClassDeclaration* cd, llvm::Constant* init) |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1216 { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1217 const llvm::StructType* initTy = isaStruct(init->getType()); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1218 assert(initTy); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1219 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1220 std::vector<llvm::Constant*> arrayInits; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1221 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass) |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1222 { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1223 if (cd2->members) |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1224 { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1225 for (size_t i = 0; i < cd2->members->dim; i++) |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1226 { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1227 Dsymbol *sm = (Dsymbol *)cd2->members->data[i]; |
112
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1228 if (VarDeclaration* vd = sm->isVarDeclaration()) // is this enough? |
110
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1229 { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1230 llvm::Constant* c = build_offti_entry(vd); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1231 assert(c); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1232 arrayInits.push_back(c); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1233 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1234 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1235 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1236 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1237 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1238 size_t ninits = arrayInits.size(); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1239 llvm::Constant* size = DtoConstSize_t(ninits); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1240 llvm::Constant* ptr; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1241 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1242 if (ninits > 0) { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1243 // OffsetTypeInfo type |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1244 std::vector<const llvm::Type*> elemtypes; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1245 elemtypes.push_back(DtoSize_t()); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1246 const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get()); |
110
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1247 elemtypes.push_back(tiTy); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1248 const llvm::StructType* sTy = llvm::StructType::get(elemtypes); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1249 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1250 // array type |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1251 const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1252 llvm::Constant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1253 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1254 std::string name(cd->type->vtinfo->toChars()); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1255 name.append("__OffsetTypeInfos"); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1256 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,llvm::GlobalValue::InternalLinkage,arrInit,name,gIR->module); |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1257 ptr = llvm::ConstantExpr::getBitCast(gvar, getPtrToType(sTy)); |
110
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1258 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1259 else { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1260 ptr = llvm::ConstantPointerNull::get(isaPointer(initTy->getElementType(1))); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1261 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1262 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1263 return DtoConstSlice(size, ptr); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1264 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
1265 |
112
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1266 static llvm::Constant* build_class_dtor(ClassDeclaration* cd) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1267 { |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1268 // construct the function |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1269 std::vector<const llvm::Type*> paramTypes; |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1270 paramTypes.push_back(getPtrToType(cd->type->llvmType->get())); |
112
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1271 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1272 const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy, paramTypes, false); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1273 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1274 if (cd->dtors.dim == 0) { |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1275 return llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)); |
112
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1276 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1277 else if (cd->dtors.dim == 1) { |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1278 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0]; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1279 DtoForceDeclareDsymbol(d); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1280 assert(d->irFunc->func); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1281 return llvm::ConstantExpr::getBitCast(isaConstant(d->irFunc->func), getPtrToType(llvm::Type::Int8Ty)); |
112
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1282 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1283 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1284 std::string gname("_D"); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1285 gname.append(cd->mangle()); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1286 gname.append("12__destructorMFZv"); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1287 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1288 llvm::Function* func = new llvm::Function(fnTy, llvm::GlobalValue::InternalLinkage, gname, gIR->module); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1289 llvm::Value* thisptr = func->arg_begin(); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1290 thisptr->setName("this"); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1291 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1292 llvm::BasicBlock* bb = new llvm::BasicBlock("entry", func); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1293 LLVMBuilder builder(bb); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1294 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1295 for (size_t i = 0; i < cd->dtors.dim; i++) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1296 { |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1297 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i]; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1298 DtoForceDeclareDsymbol(d); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1299 assert(d->irFunc->func); |
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1300 builder.CreateCall(d->irFunc->func, thisptr); |
112
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1301 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1302 builder.CreateRetVoid(); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1303 |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1304 return llvm::ConstantExpr::getBitCast(func, getPtrToType(llvm::Type::Int8Ty)); |
112
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1305 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1306 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1307 static uint build_classinfo_flags(ClassDeclaration* cd) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1308 { |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1309 // adapted from original dmd code |
112
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1310 uint flags = 0; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1311 //flags |= isCOMclass(); // IUnknown |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1312 bool hasOffTi = false; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1313 if (cd->ctor) flags |= 8; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1314 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1315 { |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1316 if (cd2->members) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1317 { |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1318 for (size_t i = 0; i < cd2->members->dim; i++) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1319 { |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1320 Dsymbol *sm = (Dsymbol *)cd2->members->data[i]; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1321 if (sm->isVarDeclaration()) // is this enough? |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1322 hasOffTi = true; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1323 //printf("sm = %s %s\n", sm->kind(), sm->toChars()); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1324 if (sm->hasPointers()) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1325 goto L2; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1326 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1327 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1328 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1329 flags |= 2; // no pointers |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1330 L2: |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1331 if (hasOffTi) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1332 flags |= 4; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1333 return flags; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1334 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
1335 |
100 | 1336 void DtoDefineClassInfo(ClassDeclaration* cd) |
1337 { | |
1338 // The layout is: | |
1339 // { | |
1340 // void **vptr; | |
1341 // monitor_t monitor; | |
1342 // byte[] initializer; // static initialization data | |
1343 // char[] name; // class name | |
1344 // void *[] vtbl; | |
1345 // Interface[] interfaces; | |
1346 // ClassInfo *base; // base class | |
1347 // void *destructor; | |
1348 // void *invariant; // class invariant | |
1349 // uint flags; | |
1350 // void *deallocator; | |
1351 // OffsetTypeInfo[] offTi; | |
1352 // void *defaultConstructor; | |
1353 // } | |
1354 | |
137 | 1355 if (cd->irStruct->classDefined) return; |
1356 cd->irStruct->classDefined = true; | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1357 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1358 Logger::println("DtoDefineClassInfo(%s)", cd->toChars()); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1359 LOG_SCOPE; |
100 | 1360 |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1361 assert(cd->type->ty == Tclass); |
137 | 1362 assert(cd->irStruct->classInfo); |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1363 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1364 TypeClass* cdty = (TypeClass*)cd->type; |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1365 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { |
137 | 1366 assert(cd->irStruct->init); |
1367 assert(cd->irStruct->constInit); | |
1368 assert(cd->irStruct->vtbl); | |
1369 assert(cd->irStruct->constVtbl); | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1370 } |
100 | 1371 |
1372 // holds the list of initializers for llvm | |
1373 std::vector<llvm::Constant*> inits; | |
1374 | |
1375 ClassDeclaration* cinfo = ClassDeclaration::classinfo; | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1376 DtoForceConstInitDsymbol(cinfo); |
137 | 1377 assert(cinfo->irStruct->constInit); |
100 | 1378 |
1379 llvm::Constant* c; | |
1380 | |
1381 // own vtable | |
137 | 1382 c = cinfo->irStruct->constInit->getOperand(0); |
100 | 1383 assert(c); |
1384 inits.push_back(c); | |
1385 | |
1386 // monitor | |
137 | 1387 c = cinfo->irStruct->constInit->getOperand(1); |
115
5ba6d286c941
[svn r119] Added the monitor data field that comes after the vtable pointer to all classes. Represented as a void* initialized to zero.
lindquist
parents:
114
diff
changeset
|
1388 inits.push_back(c); |
100 | 1389 |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1390 // byte[] init |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1391 const llvm::Type* byteptrty = getPtrToType(llvm::Type::Int8Ty); |
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1392 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { |
137 | 1393 c = cinfo->irStruct->constInit->getOperand(2); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1394 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1395 else { |
137 | 1396 c = llvm::ConstantExpr::getBitCast(cd->irStruct->init, byteptrty); |
1397 assert(!cd->irStruct->constInit->getType()->isAbstract()); | |
1398 size_t initsz = getABITypeSize(cd->irStruct->constInit->getType()); | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1399 c = DtoConstSlice(DtoConstSize_t(initsz), c); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1400 } |
100 | 1401 inits.push_back(c); |
1402 | |
1403 // class name | |
1404 // from dmd | |
1405 char *name = cd->ident->toChars(); | |
1406 size_t namelen = strlen(name); | |
1407 if (!(namelen > 9 && memcmp(name, "TypeInfo_", 9) == 0)) | |
1408 { | |
1409 name = cd->toPrettyChars(); | |
1410 namelen = strlen(name); | |
1411 } | |
1412 c = DtoConstString(name); | |
1413 inits.push_back(c); | |
1414 | |
1415 // vtbl array | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1416 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { |
137 | 1417 c = cinfo->irStruct->constInit->getOperand(4); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1418 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1419 else { |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1420 const llvm::Type* byteptrptrty = getPtrToType(byteptrty); |
137 | 1421 assert(!cd->irStruct->vtbl->getType()->isAbstract()); |
1422 c = llvm::ConstantExpr::getBitCast(cd->irStruct->vtbl, byteptrptrty); | |
1423 assert(!cd->irStruct->constVtbl->getType()->isAbstract()); | |
1424 size_t vtblsz = cd->irStruct->constVtbl->getType()->getNumElements(); | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1425 c = DtoConstSlice(DtoConstSize_t(vtblsz), c); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1426 } |
100 | 1427 inits.push_back(c); |
1428 | |
1429 // interfaces array | |
137 | 1430 IrStruct* irstruct = cd->irStruct; |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1431 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) { |
137 | 1432 c = cinfo->irStruct->constInit->getOperand(5); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1433 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1434 else { |
137 | 1435 const llvm::Type* t = cinfo->irStruct->constInit->getOperand(5)->getType()->getContainedType(1); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1436 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1437 size_t iisz = irstruct->interfaceInfosTy->getNumElements(); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1438 c = DtoConstSlice(DtoConstSize_t(iisz), c); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1439 } |
100 | 1440 inits.push_back(c); |
1441 | |
1442 // base classinfo | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1443 if (cd->baseClass && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1444 DtoDeclareClassInfo(cd->baseClass); |
137 | 1445 c = cd->baseClass->irStruct->classInfo; |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1446 assert(c); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1447 inits.push_back(c); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1448 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1449 else { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1450 // null |
137 | 1451 c = cinfo->irStruct->constInit->getOperand(6); |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1452 inits.push_back(c); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1453 } |
100 | 1454 |
1455 // destructor | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1456 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { |
137 | 1457 c = cinfo->irStruct->constInit->getOperand(7); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1458 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1459 else { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1460 c = build_class_dtor(cd); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1461 } |
100 | 1462 inits.push_back(c); |
1463 | |
1464 // invariant | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1465 // TODO |
137 | 1466 c = cinfo->irStruct->constInit->getOperand(8); |
100 | 1467 inits.push_back(c); |
1468 | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1469 // uint flags |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1470 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { |
137 | 1471 c = cinfo->irStruct->constInit->getOperand(9); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1472 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1473 else { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1474 uint flags = build_classinfo_flags(cd); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1475 c = DtoConstUint(flags); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1476 } |
100 | 1477 inits.push_back(c); |
1478 | |
1479 // allocator | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
1480 // TODO |
137 | 1481 c = cinfo->irStruct->constInit->getOperand(10); |
100 | 1482 inits.push_back(c); |
1483 | |
1484 // offset typeinfo | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1485 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { |
137 | 1486 c = cinfo->irStruct->constInit->getOperand(11); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1487 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1488 else { |
137 | 1489 c = build_offti_array(cd, cinfo->irStruct->constInit->getOperand(11)); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1490 } |
100 | 1491 inits.push_back(c); |
1492 | |
1493 // default constructor | |
133
44a95ac7368a
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
lindquist
parents:
132
diff
changeset
|
1494 if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { |
111
a7ae554ce4f4
[svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents:
110
diff
changeset
|
1495 DtoForceDeclareDsymbol(cd->defaultCtor); |
136
0e28624814e8
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
lindquist
parents:
133
diff
changeset
|
1496 c = isaConstant(cd->defaultCtor->irFunc->func); |
137 | 1497 const llvm::Type* toTy = cinfo->irStruct->constInit->getOperand(12)->getType(); |
117 | 1498 c = llvm::ConstantExpr::getBitCast(c, toTy); |
111
a7ae554ce4f4
[svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents:
110
diff
changeset
|
1499 } |
a7ae554ce4f4
[svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents:
110
diff
changeset
|
1500 else { |
137 | 1501 c = cinfo->irStruct->constInit->getOperand(12); |
111
a7ae554ce4f4
[svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents:
110
diff
changeset
|
1502 } |
100 | 1503 inits.push_back(c); |
1504 | |
1505 /*size_t n = inits.size(); | |
1506 for (size_t i=0; i<n; ++i) | |
1507 { | |
1508 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; | |
1509 }*/ | |
1510 | |
1511 // build the initializer | |
137 | 1512 const llvm::StructType* st = isaStruct(cinfo->irStruct->constInit->getType()); |
100 | 1513 llvm::Constant* finalinit = llvm::ConstantStruct::get(st, inits); |
1514 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; | |
1515 | |
137 | 1516 cd->irStruct->constClassInfo = finalinit; |
1517 cd->irStruct->classInfo->setInitializer(finalinit); | |
100 | 1518 } |