Mercurial > projects > ldc
annotate gen/classes.cpp @ 117:56a21f3e5d3e trunk
[svn r121] Finished ModuleInfo implementation.
Static ctors/dtors now work according to spec.
Changed class vtable types slightly in some cases. Overridden functions now always take the the type of the first class declaring the method as this parameter. This helps when using headers (w. implementation somewhere else)
author | lindquist |
---|---|
date | Mon, 26 Nov 2007 04:49:23 +0100 |
parents | 5ba6d286c941 |
children | 9c79b61fb638 |
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" | |
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
|
14 #include "gen/functions.h" |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
15 #include "gen/runtime.h" |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
16 #include "gen/dvalue.h" |
100 | 17 |
18 ////////////////////////////////////////////////////////////////////////////////////////// | |
19 | |
20 static void LLVM_AddBaseClassData(BaseClasses* bcs) | |
21 { | |
22 // add base class data members first | |
23 for (int j=0; j<bcs->dim; j++) | |
24 { | |
25 BaseClass* bc = (BaseClass*)(bcs->data[j]); | |
26 assert(bc); | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
27 if (bc->base->isInterfaceDeclaration()) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
28 continue; // interfaces only has methods |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
29 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
30 LLVM_AddBaseClassData(&bc->base->baseclasses); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
31 |
100 | 32 Logger::println("Adding base class members of %s", bc->base->toChars()); |
33 LOG_SCOPE; | |
34 | |
35 for (int k=0; k < bc->base->members->dim; k++) { | |
36 Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]); | |
37 if (dsym->isVarDeclaration()) | |
38 { | |
39 dsym->toObjFile(); | |
40 } | |
41 } | |
42 } | |
43 } | |
44 | |
45 ////////////////////////////////////////////////////////////////////////////////////////// | |
46 | |
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
|
47 void DtoResolveClass(ClassDeclaration* cd) |
100 | 48 { |
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
|
49 if (cd->llvmResolved) return; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
50 cd->llvmResolved = true; |
100 | 51 |
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
|
52 // first resolve the base class |
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
|
53 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
|
54 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
|
55 } |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
56 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
57 // resolve interfaces |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
58 if (cd->vtblInterfaces) { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
59 for (int i=0; i < cd->vtblInterfaces->dim; i++) { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
60 BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i]; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
61 ClassDeclaration *id = b->base; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
62 DtoResolveClass(id); |
114 | 63 // Fill in vtbl[] |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
64 b->fillVtbl(cd, &b->vtbl, 1); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
65 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
66 } |
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
|
67 |
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
|
68 Logger::println("DtoResolveClass(%s)", cd->toPrettyChars()); |
100 | 69 LOG_SCOPE; |
70 | |
71 assert(cd->type->ty == Tclass); | |
72 TypeClass* ts = (TypeClass*)cd->type; | |
73 | |
74 assert(!cd->llvmIRStruct); | |
75 IRStruct* irstruct = new IRStruct(ts); | |
76 cd->llvmIRStruct = irstruct; | |
77 | |
78 gIR->structs.push_back(irstruct); | |
79 gIR->classes.push_back(cd); | |
80 | |
81 // add vtable | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
82 ts->llvmVtblType = new llvm::PATypeHolder(llvm::OpaqueType::get()); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
83 const llvm::Type* vtabty = llvm::PointerType::get(ts->llvmVtblType->get()); |
100 | 84 |
85 std::vector<const llvm::Type*> fieldtypes; | |
86 fieldtypes.push_back(vtabty); | |
87 | |
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
|
88 // add monitor |
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
|
89 fieldtypes.push_back(llvm::PointerType::get(llvm::Type::Int8Ty)); |
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
|
90 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
91 // add interface vtables |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
92 if (cd->vtblInterfaces) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
93 for (size_t i = 0; i < cd->vtblInterfaces->dim; i++) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
94 { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
95 BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i]; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
96 ClassDeclaration *id = b->base; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
97 assert(id->type->ty == Tclass); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
98 TypeClass* itc = (TypeClass*)id->type; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
99 const llvm::Type* ivtblTy = llvm::PointerType::get(itc->llvmVtblType->get()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
100 fieldtypes.push_back(ivtblTy); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
101 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
102 // add this interface to the map |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
103 IRInterface* iri = new IRInterface(b, isaStruct(itc->llvmVtblType->get())); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
104 irstruct->interfaces.insert(std::make_pair(id, iri)); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
105 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
106 |
100 | 107 // base classes first |
108 LLVM_AddBaseClassData(&cd->baseclasses); | |
109 | |
110 // then add own members | |
111 for (int k=0; k < cd->members->dim; k++) { | |
112 Dsymbol* dsym = (Dsymbol*)(cd->members->data[k]); | |
113 dsym->toObjFile(); | |
114 } | |
115 | |
116 // add field types | |
117 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { | |
118 fieldtypes.push_back(i->second.type); | |
119 } | |
120 | |
121 const llvm::StructType* structtype = llvm::StructType::get(fieldtypes); | |
122 // refine abstract types for stuff like: class C {C next;} | |
123 assert(irstruct->recty != 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
|
124 |
100 | 125 llvm::PATypeHolder& spa = irstruct->recty; |
126 llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype); | |
127 structtype = isaStruct(spa.get()); | |
128 | |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
129 if (!ts->llvmType) |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
130 ts->llvmType = new llvm::PATypeHolder(structtype); |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
131 else |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
132 *ts->llvmType = structtype; |
100 | 133 |
114 | 134 if (cd->isNested()) { |
135 assert(0 && "nested classes not implemented"); | |
100 | 136 } |
137 else { | |
114 | 138 gIR->module->addTypeName(cd->mangle(), ts->llvmType->get()); |
100 | 139 } |
140 | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
141 // build interface info type |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
142 std::vector<const llvm::Type*> infoTypes; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
143 // ClassInfo classinfo |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
144 ClassDeclaration* cinfod = ClassDeclaration::classinfo; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
145 DtoResolveClass(cinfod); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
146 infoTypes.push_back(llvm::PointerType::get(cinfod->type->llvmType->get())); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
147 // void*[] vtbl |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
148 std::vector<const llvm::Type*> infoVtbltypes; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
149 infoVtbltypes.push_back(DtoSize_t()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
150 const llvm::Type* byteptrptrty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty)); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
151 infoVtbltypes.push_back(byteptrptrty); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
152 infoTypes.push_back(llvm::StructType::get(infoVtbltypes)); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
153 // int offset |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
154 infoTypes.push_back(llvm::Type::Int32Ty); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
155 // create type |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
156 const llvm::StructType* infoTy = llvm::StructType::get(infoTypes); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
157 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
158 // create vtable type |
100 | 159 llvm::GlobalVariable* svtblVar = 0; |
160 std::vector<const llvm::Type*> sinits_ty; | |
161 | |
162 for (int k=0; k < cd->vtbl.dim; k++) | |
163 { | |
164 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k]; | |
165 assert(dsym); | |
166 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n'; | |
167 | |
168 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
|
169 DtoResolveFunction(fd); |
117 | 170 //assert(fd->type->ty == Tfunction); |
171 //TypeFunction* tf = (TypeFunction*)fd->type; | |
172 //const llvm::Type* fpty = llvm::PointerType::get(tf->llvmType->get()); | |
173 const llvm::FunctionType* vfty = DtoBaseFunctionType(fd); | |
174 const llvm::Type* vfpty = llvm::PointerType::get(vfty); | |
175 sinits_ty.push_back(vfpty); | |
100 | 176 } |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
177 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
178 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
|
179 const llvm::Type* cinfoty; |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
180 if (cd->isInterfaceDeclaration()) { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
181 cinfoty = infoTy; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
182 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
183 else if (cd != cinfod) { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
184 DtoResolveClass(cinfod); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
185 cinfoty = cinfod->type->llvmType->get(); |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
186 } |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
187 else { |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
188 // this is the ClassInfo class, the type is this type |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
189 cinfoty = ts->llvmType->get(); |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
190 } |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
191 const llvm::Type* cty = llvm::PointerType::get(cinfoty); |
100 | 192 sinits_ty.push_back(cty); |
193 } | |
194 else | |
195 assert(0); | |
196 } | |
197 | |
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
|
198 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
|
199 const llvm::StructType* svtbl_ty = llvm::StructType::get(sinits_ty); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
200 |
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
|
201 std::string styname(cd->mangle()); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
202 styname.append("__vtblType"); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
203 gIR->module->addTypeName(styname, svtbl_ty); |
100 | 204 |
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
|
205 // refine for final vtable type |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
206 llvm::cast<llvm::OpaqueType>(ts->llvmVtblType->get())->refineAbstractTypeTo(svtbl_ty); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
207 |
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
|
208 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
|
209 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
|
210 |
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
|
211 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
|
212 } |
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
|
213 |
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
|
214 ////////////////////////////////////////////////////////////////////////////////////////// |
100 | 215 |
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
|
216 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
|
217 { |
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
|
218 if (cd->llvmDeclared) return; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
219 cd->llvmDeclared = true; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
220 |
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
|
221 Logger::println("DtoDeclareClass(%s)", cd->toPrettyChars()); |
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
|
222 LOG_SCOPE; |
100 | 223 |
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
|
224 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
|
225 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
|
226 |
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
|
227 assert(cd->llvmIRStruct); |
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
|
228 IRStruct* irstruct = cd->llvmIRStruct; |
100 | 229 |
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
|
230 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
|
231 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
|
232 |
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
|
233 bool needs_definition = false; |
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
|
234 if (cd->parent->isModule()) { |
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
|
235 needs_definition = (cd->getModule() == gIR->dmodule); |
100 | 236 } |
237 | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
238 // interface vtables are emitted by the class implementing them |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
239 // also interfaces have no static initializer |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
240 if (!cd->isInterfaceDeclaration()) { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
241 // vtable |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
242 std::string varname("_D"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
243 varname.append(cd->mangle()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
244 varname.append("6__vtblZ"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
245 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
246 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
247 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
248 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
249 cd->llvmVtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module); |
100 | 250 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
251 // build interface info type |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
252 std::vector<const llvm::Type*> types; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
253 // ClassInfo classinfo |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
254 ClassDeclaration* cd2 = ClassDeclaration::classinfo; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
255 DtoResolveClass(cd2); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
256 types.push_back(llvm::PointerType::get(cd2->type->llvmType->get())); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
257 // void*[] vtbl |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
258 std::vector<const llvm::Type*> vtbltypes; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
259 vtbltypes.push_back(DtoSize_t()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
260 const llvm::Type* byteptrptrty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty)); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
261 vtbltypes.push_back(byteptrptrty); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
262 types.push_back(llvm::StructType::get(vtbltypes)); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
263 // int offset |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
264 types.push_back(llvm::Type::Int32Ty); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
265 // create type |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
266 const llvm::StructType* infoTy = llvm::StructType::get(types); |
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
|
267 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
268 // interface info array |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
269 if (needs_definition && cd->vtblInterfaces->dim > 0) { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
270 // symbol name |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
271 std::string nam = "_D"; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
272 nam.append(cd->mangle()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
273 nam.append("16__interfaceInfosZ"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
274 // resolve array type |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
275 const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
276 // declare global |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
277 irstruct->interfaceInfosTy = arrTy; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
278 irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, llvm::GlobalValue::InternalLinkage, 0, nam, gIR->module); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
279 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
280 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
281 // interface vtables |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
282 unsigned idx = 0; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
283 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
284 { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
285 ClassDeclaration* id = i->first; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
286 IRInterface* iri = i->second; |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
287 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
288 std::string nam("_D"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
289 nam.append(cd->mangle()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
290 nam.append("11__interface"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
291 nam.append(id->mangle()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
292 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
|
293 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
294 assert(iri->vtblTy); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
295 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
|
296 iri->infoTy = infoTy; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
297 llvm::Constant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)}; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
298 iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
299 idx++; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
300 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
301 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
302 // init |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
303 std::string initname("_D"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
304 initname.append(cd->mangle()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
305 initname.append("6__initZ"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
306 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
307 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
308 ts->llvmInit = initvar; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
309 } |
100 | 310 |
311 gIR->classes.pop_back(); | |
312 gIR->structs.pop_back(); | |
313 | |
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
|
314 gIR->constInitList.push_back(cd); |
100 | 315 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
|
316 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
|
317 |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
318 // classinfo |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
319 DtoDeclareClassInfo(cd); |
106 | 320 |
321 // typeinfo | |
322 if (cd->parent->isModule() && cd->getModule() == gIR->dmodule) | |
323 cd->type->getTypeInfo(NULL); | |
100 | 324 } |
325 | |
326 ////////////////////////////////////////////////////////////////////////////////////////// | |
327 | |
328 void DtoConstInitClass(ClassDeclaration* cd) | |
329 { | |
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
|
330 if (cd->llvmInitialized) return; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
331 cd->llvmInitialized = true; |
100 | 332 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
333 if (cd->isInterfaceDeclaration()) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
334 return; // nothing to do |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
335 |
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
|
336 Logger::println("DtoConstInitClass(%s)", cd->toPrettyChars()); |
100 | 337 LOG_SCOPE; |
338 | |
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
|
339 IRStruct* irstruct = cd->llvmIRStruct; |
100 | 340 gIR->structs.push_back(irstruct); |
341 gIR->classes.push_back(cd); | |
342 | |
343 // make sure each offset knows its default initializer | |
344 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) | |
345 { | |
346 IRStruct::Offset* so = &i->second; | |
347 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); | |
348 so->init = finit; | |
349 so->var->llvmConstInit = finit; | |
350 } | |
351 | |
352 // fill out fieldtypes/inits | |
353 std::vector<llvm::Constant*> fieldinits; | |
354 | |
355 // first field is always the vtable | |
356 assert(cd->llvmVtbl != 0); | |
357 fieldinits.push_back(cd->llvmVtbl); | |
358 | |
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
|
359 // then comes monitor |
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
|
360 fieldinits.push_back(llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty))); |
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
|
361 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
362 // next comes interface vtables |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
363 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
364 { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
365 IRInterface* iri = i->second; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
366 assert(iri->vtbl); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
367 fieldinits.push_back(iri->vtbl); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
368 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
369 |
100 | 370 // rest |
371 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++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
|
372 Logger::println("adding fieldinit for: %s", i->second.var->toChars()); |
100 | 373 fieldinits.push_back(i->second.init); |
374 } | |
375 | |
376 // get the struct (class) type | |
377 assert(cd->type->ty == Tclass); | |
378 TypeClass* ts = (TypeClass*)cd->type; | |
379 const llvm::StructType* structtype = isaStruct(ts->llvmType->get()); | |
117 | 380 const llvm::StructType* vtbltype = isaStruct(ts->llvmVtblType->get()); |
100 | 381 |
382 // generate initializer | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
383 #if 0 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
384 Logger::cout() << cd->toPrettyChars() << " | " << *structtype << '\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
|
385 |
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
|
386 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
|
387 Logger::cout() << "s#" << i << " = " << *structtype->getElementType(i) << '\n'; |
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
|
388 } |
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
|
389 |
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
|
390 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
|
391 Logger::cout() << "i#" << i << " = " << *fieldinits[i]->getType() << '\n'; |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
392 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
393 #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
|
394 |
100 | 395 llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits); |
396 assert(_init); | |
397 cd->llvmInitZ = _init; | |
398 | |
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
|
399 // generate vtable initializer |
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
|
400 std::vector<llvm::Constant*> sinits; |
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
|
401 |
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
|
402 for (int k=0; k < cd->vtbl.dim; k++) |
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
|
403 { |
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
|
404 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k]; |
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
|
405 assert(dsym); |
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
|
406 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n'; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
407 |
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
|
408 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
409 DtoForceDeclareDsymbol(fd); |
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
|
410 assert(fd->llvmValue); |
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
|
411 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue); |
117 | 412 // cast if necessary (overridden method) |
413 if (c->getType() != vtbltype->getElementType(k)) | |
414 c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k)); | |
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
|
415 sinits.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
|
416 } |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
417 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
418 assert(cd->llvmClass); |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
419 llvm::Constant* c = cd->llvmClass; |
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 sinits.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
|
421 } |
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
|
422 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
|
423 assert(0); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
424 } |
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
|
425 |
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
|
426 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get()); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
427 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
428 #if 0 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
429 for (size_t i=0; i< sinits.size(); ++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
|
430 { |
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
|
431 Logger::cout() << "field[" << i << "] = " << *svtbl_ty->getElementType(i) << '\n'; |
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
|
432 Logger::cout() << "init [" << i << "] = " << *sinits[i]->getType() << '\n'; |
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
|
433 assert(svtbl_ty->getElementType(i) == sinits[i]->getType()); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
434 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
435 #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
|
436 |
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
|
437 llvm::Constant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits); |
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
|
438 cd->llvmConstVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit); |
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
|
439 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
440 // create interface vtable const initalizers |
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
|
441 int idx = 2; |
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
|
442 int idxScale = PTRSIZE; |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
443 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
444 { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
445 ClassDeclaration* id = i->first; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
446 assert(id->type->ty == Tclass); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
447 TypeClass* its = (TypeClass*)id->type; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
448 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
449 IRInterface* iri = i->second; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
450 BaseClass* b = iri->base; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
451 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
452 const llvm::StructType* ivtbl_ty = isaStruct(its->llvmVtblType->get()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
453 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
454 // generate interface info initializer |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
455 std::vector<llvm::Constant*> infoInits; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
456 // classinfo |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
457 assert(id->llvmClass); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
458 llvm::Constant* c = id->llvmClass; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
459 infoInits.push_back(c); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
460 // vtbl |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
461 const llvm::Type* byteptrptrty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty)); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
462 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
463 c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
464 infoInits.push_back(c); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
465 // offset |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
466 infoInits.push_back(DtoConstInt(idx*idxScale)); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
467 // create interface info initializer constant |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
468 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits)); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
469 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
470 // generate vtable initializer |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
471 std::vector<llvm::Constant*> iinits; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
472 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
473 // add interface info |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
474 iinits.push_back(iri->info); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
475 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
476 for (int k=1; k < b->vtbl.dim; k++) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
477 { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
478 Logger::println("interface vtbl const init nr. %d", k); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
479 Dsymbol* dsym = (Dsymbol*)b->vtbl.data[k]; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
480 FuncDeclaration* fd = dsym->isFuncDeclaration(); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
481 assert(fd); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
482 DtoForceDeclareDsymbol(fd); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
483 assert(fd->llvmValue); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
484 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
485 // we have to bitcast, as the type created in ResolveClass expects a different this type |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
486 c = llvm::ConstantExpr::getBitCast(c, iri->vtblTy->getContainedType(k)); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
487 iinits.push_back(c); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
488 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
489 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
490 #if 1 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
491 for (size_t x=0; x< iinits.size(); ++x) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
492 { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
493 Logger::cout() << "field[" << x << "] = " << *ivtbl_ty->getElementType(x) << "\n\n"; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
494 Logger::cout() << "init [" << x << "] = " << *iinits[x] << "\n\n"; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
495 assert(ivtbl_ty->getElementType(x) == iinits[x]->getType()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
496 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
497 #endif |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
498 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
499 llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
500 iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
501 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
502 idx++; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
503 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
504 |
100 | 505 gIR->classes.pop_back(); |
506 gIR->structs.pop_back(); | |
507 } | |
508 | |
509 ////////////////////////////////////////////////////////////////////////////////////////// | |
510 | |
511 void DtoDefineClass(ClassDeclaration* cd) | |
512 { | |
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
|
513 if (cd->llvmDefined) return; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
514 cd->llvmDefined = true; |
100 | 515 |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
516 Logger::println("DtoDefineClass(%s)", cd->toPrettyChars()); |
100 | 517 LOG_SCOPE; |
518 | |
519 // get the struct (class) type | |
520 assert(cd->type->ty == Tclass); | |
521 TypeClass* ts = (TypeClass*)cd->type; | |
522 | |
523 bool def = false; | |
524 if (cd->parent->isModule() && cd->getModule() == gIR->dmodule) { | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
525 // interfaces don't have initializers |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
526 if (!cd->isInterfaceDeclaration()) { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
527 ts->llvmInit->setInitializer(cd->llvmInitZ); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
528 cd->llvmVtbl->setInitializer(cd->llvmConstVtbl); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
529 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
530 // initialize interface vtables |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
531 IRStruct* irstruct = cd->llvmIRStruct; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
532 std::vector<llvm::Constant*> infoInits; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
533 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
534 { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
535 IRInterface* iri = i->second; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
536 iri->vtbl->setInitializer(iri->vtblInit); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
537 infoInits.push_back(iri->infoInit); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
538 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
539 // initialize interface info array |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
540 if (!infoInits.empty()) { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
541 llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
542 irstruct->interfaceInfos->setInitializer(arrInit); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
543 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
544 } |
100 | 545 def = true; |
546 } | |
547 | |
548 // generate classinfo | |
549 if (def) DtoDefineClassInfo(cd); | |
550 } | |
551 | |
552 ////////////////////////////////////////////////////////////////////////////////////////// | |
553 | |
554 void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance) | |
555 { | |
556 Array* arr = &tc->sym->dtors; | |
557 for (size_t i=0; i<arr->dim; i++) | |
558 { | |
559 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i]; | |
560 assert(fd->llvmValue); | |
561 new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb()); | |
562 } | |
563 } | |
564 | |
565 ////////////////////////////////////////////////////////////////////////////////////////// | |
566 | |
567 void DtoInitClass(TypeClass* tc, llvm::Value* dst) | |
568 { | |
569 assert(gIR); | |
570 | |
571 assert(tc->llvmType); | |
572 uint64_t size_t_size = gTargetData->getTypeSize(DtoSize_t()); | |
573 uint64_t n = gTargetData->getTypeSize(tc->llvmType->get()) - size_t_size; | |
574 | |
575 // set vtable field | |
576 llvm::Value* vtblvar = DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); | |
577 assert(tc->sym->llvmVtbl); | |
578 new llvm::StoreInst(tc->sym->llvmVtbl, vtblvar, gIR->scopebb()); | |
579 | |
580 // copy the static initializer | |
581 if (n > 0) { | |
582 assert(tc->llvmInit); | |
583 assert(dst->getType() == tc->llvmInit->getType()); | |
584 | |
585 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
586 | |
587 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); | |
588 dstarr = DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb()); | |
589 | |
590 llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb()); | |
591 srcarr = DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb()); | |
592 | |
593 llvm::Function* fn = LLVM_DeclareMemCpy32(); | |
594 std::vector<llvm::Value*> llargs; | |
595 llargs.resize(4); | |
596 llargs[0] = dstarr; | |
597 llargs[1] = srcarr; | |
598 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | |
599 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
600 | |
601 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
602 } | |
603 } | |
604 | |
605 ////////////////////////////////////////////////////////////////////////////////////////// | |
606 | |
114 | 607 DValue* DtoCastClass(DValue* val, Type* _to) |
608 { | |
609 Type* to = DtoDType(_to); | |
610 if (to->ty == Tpointer) { | |
611 const llvm::Type* tolltype = DtoType(_to); | |
612 llvm::Value* rval = DtoBitCast(val->getRVal(), tolltype); | |
613 return new DImValue(_to, rval); | |
614 } | |
615 | |
616 assert(to->ty == Tclass); | |
617 TypeClass* tc = (TypeClass*)to; | |
618 | |
619 Type* from = DtoDType(val->getType()); | |
620 TypeClass* fc = (TypeClass*)from; | |
621 | |
622 if (tc->sym->isInterfaceDeclaration()) { | |
623 assert(!fc->sym->isInterfaceDeclaration()); | |
624 return DtoDynamicCastObject(val, _to); | |
625 } | |
626 else { | |
627 int poffset; | |
628 if (fc->sym->isInterfaceDeclaration()) { | |
629 return DtoCastInterfaceToObject(val, _to); | |
630 } | |
631 else if (tc->sym->isBaseOf(fc->sym,NULL)) { | |
632 const llvm::Type* tolltype = DtoType(_to); | |
633 llvm::Value* rval = DtoBitCast(val->getRVal(), tolltype); | |
634 return new DImValue(_to, rval); | |
635 } | |
636 else { | |
637 return DtoDynamicCastObject(val, _to); | |
638 } | |
639 } | |
640 } | |
641 | |
642 ////////////////////////////////////////////////////////////////////////////////////////// | |
643 | |
644 DValue* DtoDynamicCastObject(DValue* val, Type* _to) | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
645 { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
646 // call: |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
647 // Object _d_dynamic_cast(Object o, ClassInfo c) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
648 |
114 | 649 DtoForceDeclareDsymbol(ClassDeclaration::object); |
650 DtoForceDeclareDsymbol(ClassDeclaration::classinfo); | |
651 | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
652 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_dynamic_cast"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
653 const llvm::FunctionType* funcTy = func->getFunctionType(); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
654 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
655 std::vector<llvm::Value*> args; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
656 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
657 // Object o |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
658 llvm::Value* tmp = val->getRVal(); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
659 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
660 args.push_back(tmp); |
114 | 661 assert(funcTy->getParamType(0) == tmp->getType()); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
662 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
663 // ClassInfo c |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
664 TypeClass* to = (TypeClass*)DtoDType(_to); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
665 DtoForceDeclareDsymbol(to->sym); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
666 assert(to->sym->llvmClass); |
114 | 667 tmp = to->sym->llvmClass; |
668 // unfortunately this is needed as the implementation of object differs somehow from the declaration | |
669 // this could happen in user code as well :/ | |
670 tmp = DtoBitCast(tmp, funcTy->getParamType(1)); | |
671 args.push_back(tmp); | |
672 assert(funcTy->getParamType(1) == tmp->getType()); | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
673 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
674 // call it |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
675 llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp"); |
114 | 676 |
677 // cast return value | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
678 ret = DtoBitCast(ret, DtoType(_to)); |
114 | 679 |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
680 return new DImValue(_to, ret); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
681 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
682 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
683 ////////////////////////////////////////////////////////////////////////////////////////// |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
684 |
114 | 685 DValue* DtoCastInterfaceToObject(DValue* val, Type* to) |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
686 { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
687 // call: |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
688 // Object _d_toObject(void* p) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
689 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
690 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_toObject"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
691 const llvm::FunctionType* funcTy = func->getFunctionType(); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
692 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
693 // void* p |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
694 llvm::Value* tmp = val->getRVal(); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
695 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
696 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
697 // call it |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
698 llvm::Value* ret = gIR->ir->CreateCall(func, tmp, "tmp"); |
114 | 699 |
700 // cast return value | |
701 if (to != NULL) | |
702 ret = DtoBitCast(ret, DtoType(to)); | |
703 else | |
704 to = ClassDeclaration::object->type; | |
705 | |
706 return new DImValue(to, ret); | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
707 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
708 |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
709 ////////////////////////////////////////////////////////////////////////////////////////// |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
710 |
100 | 711 void DtoDeclareClassInfo(ClassDeclaration* cd) |
712 { | |
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
|
713 if (cd->llvmClassDeclared) return; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
714 cd->llvmClassDeclared = true; |
100 | 715 |
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
|
716 Logger::println("DtoDeclareClassInfo(%s)", cd->toChars()); |
100 | 717 LOG_SCOPE; |
718 | |
719 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
|
720 DtoResolveClass(cinfo); |
100 | 721 |
722 std::string gname("_D"); | |
723 gname.append(cd->mangle()); | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
724 if (!cd->isInterfaceDeclaration()) |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
725 gname.append("7__ClassZ"); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
726 else |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
727 gname.append("11__InterfaceZ"); |
100 | 728 |
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
|
729 const llvm::Type* st = cinfo->type->llvmType->get(); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
730 |
100 | 731 cd->llvmClass = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module); |
732 } | |
733 | |
110
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
734 static llvm::Constant* build_offti_entry(VarDeclaration* vd) |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
735 { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
736 std::vector<const llvm::Type*> types; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
737 std::vector<llvm::Constant*> inits; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
738 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
739 types.push_back(DtoSize_t()); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
740 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
741 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
|
742 // dmd only accounts for the vtable, not classinfo or monitor |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
743 if (global.params.is64bit) |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
744 offset += 8; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
745 else |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
746 offset += 4; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
747 inits.push_back(DtoConstSize_t(offset)); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
748 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
749 vd->type->getTypeInfo(NULL); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
750 assert(vd->type->vtinfo); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
751 DtoForceDeclareDsymbol(vd->type->vtinfo); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
752 llvm::Constant* c = isaConstant(vd->type->vtinfo->llvmValue); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
753 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
754 const llvm::Type* tiTy = llvm::PointerType::get(Type::typeinfo->type->llvmType->get()); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
755 Logger::cout() << "tiTy = " << *tiTy << '\n'; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
756 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
757 types.push_back(tiTy); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
758 inits.push_back(llvm::ConstantExpr::getBitCast(c, tiTy)); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
759 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
760 const llvm::StructType* sTy = llvm::StructType::get(types); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
761 return llvm::ConstantStruct::get(sTy, inits); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
762 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
763 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
764 static llvm::Constant* build_offti_array(ClassDeclaration* cd, llvm::Constant* init) |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
765 { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
766 const llvm::StructType* initTy = isaStruct(init->getType()); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
767 assert(initTy); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
768 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
769 std::vector<llvm::Constant*> arrayInits; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
770 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass) |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
771 { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
772 if (cd2->members) |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
773 { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
774 for (size_t i = 0; i < cd2->members->dim; i++) |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
775 { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
776 Dsymbol *sm = (Dsymbol *)cd2->members->data[i]; |
112
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
777 if (VarDeclaration* vd = sm->isVarDeclaration()) // is this enough? |
110
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
778 { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
779 llvm::Constant* c = build_offti_entry(vd); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
780 assert(c); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
781 arrayInits.push_back(c); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
782 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
783 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
784 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
785 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
786 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
787 size_t ninits = arrayInits.size(); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
788 llvm::Constant* size = DtoConstSize_t(ninits); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
789 llvm::Constant* ptr; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
790 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
791 if (ninits > 0) { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
792 // OffsetTypeInfo type |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
793 std::vector<const llvm::Type*> elemtypes; |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
794 elemtypes.push_back(DtoSize_t()); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
795 const llvm::Type* tiTy = llvm::PointerType::get(Type::typeinfo->type->llvmType->get()); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
796 elemtypes.push_back(tiTy); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
797 const llvm::StructType* sTy = llvm::StructType::get(elemtypes); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
798 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
799 // array type |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
800 const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
801 llvm::Constant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
802 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
803 std::string name(cd->type->vtinfo->toChars()); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
804 name.append("__OffsetTypeInfos"); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
805 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,llvm::GlobalValue::InternalLinkage,arrInit,name,gIR->module); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
806 ptr = llvm::ConstantExpr::getBitCast(gvar, llvm::PointerType::get(sTy)); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
807 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
808 else { |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
809 ptr = llvm::ConstantPointerNull::get(isaPointer(initTy->getElementType(1))); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
810 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
811 |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
812 return DtoConstSlice(size, ptr); |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
813 } |
e8da7856a260
[svn r114] Implemented the ClassInfo.offTi member.
lindquist
parents:
106
diff
changeset
|
814 |
112
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
815 static llvm::Constant* build_class_dtor(ClassDeclaration* cd) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
816 { |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
817 // construct the function |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
818 std::vector<const llvm::Type*> paramTypes; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
819 paramTypes.push_back(llvm::PointerType::get(cd->type->llvmType->get())); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
820 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
821 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
|
822 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
823 if (cd->dtors.dim == 0) { |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
824 return llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
825 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
826 else if (cd->dtors.dim == 1) { |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
827 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0]; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
828 DtoForceDeclareDsymbol(d); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
829 assert(d->llvmValue); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
830 return llvm::ConstantExpr::getBitCast(isaConstant(d->llvmValue), llvm::PointerType::get(llvm::Type::Int8Ty)); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
831 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
832 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
833 std::string gname("_D"); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
834 gname.append(cd->mangle()); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
835 gname.append("12__destructorMFZv"); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
836 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
837 llvm::Function* func = new llvm::Function(fnTy, llvm::GlobalValue::InternalLinkage, gname, gIR->module); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
838 llvm::Value* thisptr = func->arg_begin(); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
839 thisptr->setName("this"); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
840 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
841 llvm::BasicBlock* bb = new llvm::BasicBlock("entry", func); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
842 LLVMBuilder builder(bb); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
843 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
844 for (size_t i = 0; i < cd->dtors.dim; i++) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
845 { |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
846 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i]; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
847 DtoForceDeclareDsymbol(d); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
848 assert(d->llvmValue); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
849 builder.CreateCall(d->llvmValue, thisptr); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
850 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
851 builder.CreateRetVoid(); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
852 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
853 return llvm::ConstantExpr::getBitCast(func, llvm::PointerType::get(llvm::Type::Int8Ty)); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
854 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
855 |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
856 static uint build_classinfo_flags(ClassDeclaration* cd) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
857 { |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
858 // adapted from original dmd code |
112
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
859 uint flags = 0; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
860 //flags |= isCOMclass(); // IUnknown |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
861 bool hasOffTi = false; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
862 if (cd->ctor) flags |= 8; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
863 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
864 { |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
865 if (cd2->members) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
866 { |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
867 for (size_t i = 0; i < cd2->members->dim; i++) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
868 { |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
869 Dsymbol *sm = (Dsymbol *)cd2->members->data[i]; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
870 if (sm->isVarDeclaration()) // is this enough? |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
871 hasOffTi = true; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
872 //printf("sm = %s %s\n", sm->kind(), sm->toChars()); |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
873 if (sm->hasPointers()) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
874 goto L2; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
875 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
876 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
877 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
878 flags |= 2; // no pointers |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
879 L2: |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
880 if (hasOffTi) |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
881 flags |= 4; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
882 return flags; |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
883 } |
368547b1cbe6
[svn r116] Implemented the ClassInfo.destructor field.
lindquist
parents:
111
diff
changeset
|
884 |
100 | 885 void DtoDefineClassInfo(ClassDeclaration* cd) |
886 { | |
887 // The layout is: | |
888 // { | |
889 // void **vptr; | |
890 // monitor_t monitor; | |
891 // byte[] initializer; // static initialization data | |
892 // char[] name; // class name | |
893 // void *[] vtbl; | |
894 // Interface[] interfaces; | |
895 // ClassInfo *base; // base class | |
896 // void *destructor; | |
897 // void *invariant; // class invariant | |
898 // uint flags; | |
899 // void *deallocator; | |
900 // OffsetTypeInfo[] offTi; | |
901 // void *defaultConstructor; | |
902 // } | |
903 | |
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
|
904 if (cd->llvmClassDefined) return; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
905 cd->llvmClassDefined = true; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
906 |
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
|
907 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
|
908 LOG_SCOPE; |
100 | 909 |
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
|
910 assert(cd->type->ty == Tclass); |
100 | 911 assert(cd->llvmClass); |
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
|
912 |
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
|
913 TypeClass* cdty = (TypeClass*)cd->type; |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
914 if (!cd->isInterfaceDeclaration()) { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
915 assert(cd->llvmInitZ); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
916 assert(cd->llvmVtbl); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
917 assert(cd->llvmConstVtbl); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
918 assert(cdty->llvmInit); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
919 } |
100 | 920 |
921 // holds the list of initializers for llvm | |
922 std::vector<llvm::Constant*> inits; | |
923 | |
924 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
|
925 DtoForceConstInitDsymbol(cinfo); |
100 | 926 assert(cinfo->llvmInitZ); |
927 | |
928 llvm::Constant* c; | |
929 | |
930 // own vtable | |
931 c = cinfo->llvmInitZ->getOperand(0); | |
932 assert(c); | |
933 inits.push_back(c); | |
934 | |
935 // monitor | |
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
|
936 c = cinfo->llvmInitZ->getOperand(1); |
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
|
937 inits.push_back(c); |
100 | 938 |
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
|
939 // byte[] init |
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
|
940 const llvm::Type* byteptrty = llvm::PointerType::get(llvm::Type::Int8Ty); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
941 if (cd->isInterfaceDeclaration()) { |
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
|
942 c = cinfo->llvmInitZ->getOperand(2); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
943 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
944 else { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
945 c = llvm::ConstantExpr::getBitCast(cdty->llvmInit, byteptrty); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
946 assert(!cd->llvmInitZ->getType()->isAbstract()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
947 size_t initsz = gTargetData->getTypeSize(cd->llvmInitZ->getType()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
948 c = DtoConstSlice(DtoConstSize_t(initsz), c); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
949 } |
100 | 950 inits.push_back(c); |
951 | |
952 // class name | |
953 // from dmd | |
954 char *name = cd->ident->toChars(); | |
955 size_t namelen = strlen(name); | |
956 if (!(namelen > 9 && memcmp(name, "TypeInfo_", 9) == 0)) | |
957 { | |
958 name = cd->toPrettyChars(); | |
959 namelen = strlen(name); | |
960 } | |
961 c = DtoConstString(name); | |
962 inits.push_back(c); | |
963 | |
964 // vtbl array | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
965 if (cd->isInterfaceDeclaration()) { |
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
|
966 c = cinfo->llvmInitZ->getOperand(4); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
967 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
968 else { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
969 const llvm::Type* byteptrptrty = llvm::PointerType::get(byteptrty); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
970 assert(!cd->llvmVtbl->getType()->isAbstract()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
971 c = llvm::ConstantExpr::getBitCast(cd->llvmVtbl, byteptrptrty); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
972 assert(!cd->llvmConstVtbl->getType()->isAbstract()); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
973 size_t vtblsz = cd->llvmConstVtbl->getType()->getNumElements(); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
974 c = DtoConstSlice(DtoConstSize_t(vtblsz), c); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
975 } |
100 | 976 inits.push_back(c); |
977 | |
978 // interfaces array | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
979 IRStruct* irstruct = cd->llvmIRStruct; |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
980 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos) { |
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
|
981 c = cinfo->llvmInitZ->getOperand(5); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
982 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
983 else { |
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
|
984 const llvm::Type* t = cinfo->llvmInitZ->getOperand(5)->getType()->getContainedType(1); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
985 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
986 size_t iisz = irstruct->interfaceInfosTy->getNumElements(); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
987 c = DtoConstSlice(DtoConstSize_t(iisz), c); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
988 } |
100 | 989 inits.push_back(c); |
990 | |
991 // base classinfo | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
992 if (cd->baseClass && !cd->isInterfaceDeclaration()) { |
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
|
993 DtoDeclareClassInfo(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
|
994 c = cd->baseClass->llvmClass; |
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
|
995 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
|
996 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
|
997 } |
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
|
998 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
|
999 // null |
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
|
1000 c = cinfo->llvmInitZ->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
|
1001 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
|
1002 } |
100 | 1003 |
1004 // destructor | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1005 if (cd->isInterfaceDeclaration()) { |
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
|
1006 c = cinfo->llvmInitZ->getOperand(7); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1007 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1008 else { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1009 c = build_class_dtor(cd); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1010 } |
100 | 1011 inits.push_back(c); |
1012 | |
1013 // 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
|
1014 // TODO |
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
|
1015 c = cinfo->llvmInitZ->getOperand(8); |
100 | 1016 inits.push_back(c); |
1017 | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1018 // uint flags |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1019 if (cd->isInterfaceDeclaration()) { |
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
|
1020 c = cinfo->llvmInitZ->getOperand(9); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1021 } |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1022 else { |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1023 uint flags = build_classinfo_flags(cd); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1024 c = DtoConstUint(flags); |
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1025 } |
100 | 1026 inits.push_back(c); |
1027 | |
1028 // 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
|
1029 // TODO |
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
|
1030 c = cinfo->llvmInitZ->getOperand(10); |
100 | 1031 inits.push_back(c); |
1032 | |
1033 // offset typeinfo | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1034 if (cd->isInterfaceDeclaration()) { |
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
|
1035 c = cinfo->llvmInitZ->getOperand(11); |
113
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 else { |
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
|
1038 c = build_offti_array(cd, cinfo->llvmInitZ->getOperand(11)); |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1039 } |
100 | 1040 inits.push_back(c); |
1041 | |
1042 // default constructor | |
113
27b9f749d9fe
[svn r117] Initial working implementation of interfaces.
lindquist
parents:
112
diff
changeset
|
1043 if (cd->defaultCtor && !cd->isInterfaceDeclaration()) { |
111
a7ae554ce4f4
[svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents:
110
diff
changeset
|
1044 DtoForceDeclareDsymbol(cd->defaultCtor); |
a7ae554ce4f4
[svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents:
110
diff
changeset
|
1045 c = isaConstant(cd->defaultCtor->llvmValue); |
117 | 1046 const llvm::Type* toTy = cinfo->llvmInitZ->getOperand(12)->getType(); |
1047 c = llvm::ConstantExpr::getBitCast(c, toTy); | |
111
a7ae554ce4f4
[svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents:
110
diff
changeset
|
1048 } |
a7ae554ce4f4
[svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents:
110
diff
changeset
|
1049 else { |
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
|
1050 c = cinfo->llvmInitZ->getOperand(12); |
111
a7ae554ce4f4
[svn r115] Implemented the ClassInfo.defaultConstructor member.
lindquist
parents:
110
diff
changeset
|
1051 } |
100 | 1052 inits.push_back(c); |
1053 | |
1054 /*size_t n = inits.size(); | |
1055 for (size_t i=0; i<n; ++i) | |
1056 { | |
1057 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; | |
1058 }*/ | |
1059 | |
1060 // build the initializer | |
1061 const llvm::StructType* st = isaStruct(cinfo->llvmInitZ->getType()); | |
1062 llvm::Constant* finalinit = llvm::ConstantStruct::get(st, inits); | |
1063 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; | |
1064 | |
1065 cd->llvmClassZ = finalinit; | |
1066 cd->llvmClass->setInitializer(finalinit); | |
1067 } |