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