Mercurial > projects > ldc
annotate gen/classes.cpp @ 109:5ab8e92611f9 trunk
[svn r113] Added initial support for associative arrays (AAs).
Fixed some problems with the string runtime support functions.
Fixed initialization of array of structs.
Fixed slice assignment where LHS is slice but RHS is dynamic array.
Fixed problems with result of assignment expressions.
Fixed foreach problems with key type mismatches.
author | lindquist |
---|---|
date | Wed, 21 Nov 2007 04:13:15 +0100 |
parents | 5b5194b25f33 |
children | e8da7856a260 |
rev | line source |
---|---|
100 | 1 #include "gen/llvm.h" |
2 | |
3 #include "mtype.h" | |
4 #include "aggregate.h" | |
5 #include "init.h" | |
6 #include "declaration.h" | |
7 | |
8 #include "gen/irstate.h" | |
9 #include "gen/tollvm.h" | |
10 #include "gen/arrays.h" | |
11 #include "gen/logger.h" | |
12 #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
|
13 #include "gen/functions.h" |
100 | 14 |
15 ////////////////////////////////////////////////////////////////////////////////////////// | |
16 | |
17 static void LLVM_AddBaseClassData(BaseClasses* bcs) | |
18 { | |
19 // add base class data members first | |
20 for (int j=0; j<bcs->dim; j++) | |
21 { | |
22 BaseClass* bc = (BaseClass*)(bcs->data[j]); | |
23 assert(bc); | |
24 Logger::println("Adding base class members of %s", bc->base->toChars()); | |
25 LOG_SCOPE; | |
26 | |
27 LLVM_AddBaseClassData(&bc->base->baseclasses); | |
28 for (int k=0; k < bc->base->members->dim; k++) { | |
29 Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]); | |
30 if (dsym->isVarDeclaration()) | |
31 { | |
32 dsym->toObjFile(); | |
33 } | |
34 } | |
35 } | |
36 } | |
37 | |
38 ////////////////////////////////////////////////////////////////////////////////////////// | |
39 | |
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
|
40 void DtoResolveClass(ClassDeclaration* cd) |
100 | 41 { |
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
|
42 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
|
43 cd->llvmResolved = true; |
100 | 44 |
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
|
45 // 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
|
46 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
|
47 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
|
48 } |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
49 // resolve typeinfo |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
50 //DtoResolveClass(ClassDeclaration::typeinfo); |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
51 // resolve classinfo |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
52 //DtoResolveClass(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
|
53 |
027b8d8b71ec
[svn 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 Logger::println("DtoResolveClass(%s)", cd->toPrettyChars()); |
100 | 55 LOG_SCOPE; |
56 | |
57 assert(cd->type->ty == Tclass); | |
58 TypeClass* ts = (TypeClass*)cd->type; | |
59 | |
60 assert(!cd->llvmIRStruct); | |
61 IRStruct* irstruct = new IRStruct(ts); | |
62 cd->llvmIRStruct = irstruct; | |
63 | |
64 gIR->structs.push_back(irstruct); | |
65 gIR->classes.push_back(cd); | |
66 | |
67 // 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
|
68 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
|
69 const llvm::Type* vtabty = llvm::PointerType::get(ts->llvmVtblType->get()); |
100 | 70 |
71 std::vector<const llvm::Type*> fieldtypes; | |
72 fieldtypes.push_back(vtabty); | |
73 | |
74 // base classes first | |
75 LLVM_AddBaseClassData(&cd->baseclasses); | |
76 | |
77 // then add own members | |
78 for (int k=0; k < cd->members->dim; k++) { | |
79 Dsymbol* dsym = (Dsymbol*)(cd->members->data[k]); | |
80 dsym->toObjFile(); | |
81 } | |
82 | |
83 // add field types | |
84 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { | |
85 fieldtypes.push_back(i->second.type); | |
86 } | |
87 | |
88 const llvm::StructType* structtype = llvm::StructType::get(fieldtypes); | |
89 // refine abstract types for stuff like: class C {C next;} | |
90 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
|
91 |
100 | 92 llvm::PATypeHolder& spa = irstruct->recty; |
93 llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype); | |
94 structtype = isaStruct(spa.get()); | |
95 | |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
96 if (!ts->llvmType) |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
97 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
|
98 else |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
99 *ts->llvmType = structtype; |
100 | 100 |
101 bool needs_definition = false; | |
102 if (cd->parent->isModule()) { | |
103 gIR->module->addTypeName(cd->mangle(), ts->llvmType->get()); | |
104 needs_definition = (cd->getModule() == gIR->dmodule); | |
105 } | |
106 else { | |
107 assert(0 && "class parent is not a module"); | |
108 } | |
109 | |
110 // generate vtable | |
111 llvm::GlobalVariable* svtblVar = 0; | |
112 std::vector<const llvm::Type*> sinits_ty; | |
113 | |
114 for (int k=0; k < cd->vtbl.dim; k++) | |
115 { | |
116 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k]; | |
117 assert(dsym); | |
118 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n'; | |
119 | |
120 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
|
121 DtoResolveFunction(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
|
122 assert(fd->type->ty == Tfunction); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
123 TypeFunction* tf = (TypeFunction*)fd->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
|
124 const llvm::Type* fpty = llvm::PointerType::get(tf->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
|
125 sinits_ty.push_back(fpty); |
100 | 126 } |
127 else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { | |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
128 //Logger::println("*** ClassDeclaration in vtable: %s", cd->toChars()); |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
129 const llvm::Type* cinfoty; |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
130 if (cd != ClassDeclaration::classinfo) { |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
131 cd = ClassDeclaration::classinfo; |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
132 DtoResolveClass(cd); |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
133 cinfoty = cd->type->llvmType->get(); |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
134 } |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
135 else { |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
136 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
|
137 } |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
138 const llvm::Type* cty = llvm::PointerType::get(cd->type->llvmType->get()); |
100 | 139 sinits_ty.push_back(cty); |
140 } | |
141 else | |
142 assert(0); | |
143 } | |
144 | |
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
|
145 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
|
146 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
|
147 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
148 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
|
149 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
|
150 gIR->module->addTypeName(styname, svtbl_ty); |
100 | 151 |
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
|
152 // 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
|
153 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
|
154 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
155 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
|
156 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
|
157 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
158 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
|
159 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
160 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
161 ////////////////////////////////////////////////////////////////////////////////////////// |
100 | 162 |
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
|
163 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
|
164 { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
165 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
|
166 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
|
167 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
168 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
|
169 LOG_SCOPE; |
100 | 170 |
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
|
171 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
|
172 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
|
173 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
174 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
|
175 IRStruct* irstruct = cd->llvmIRStruct; |
100 | 176 |
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
|
177 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
|
178 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
|
179 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
180 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
|
181 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
|
182 needs_definition = (cd->getModule() == gIR->dmodule); |
100 | 183 } |
184 | |
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
|
185 // vtable |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
186 std::string varname("_D"); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
187 varname.append(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
|
188 varname.append("6__vtblZ"); |
100 | 189 |
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
|
190 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
|
191 styname.append("__vtblTy"); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
192 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
193 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
194 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
195 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
|
196 cd->llvmVtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
197 |
027b8d8b71ec
[svn 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 // init |
100 | 199 std::string initname("_D"); |
200 initname.append(cd->mangle()); | |
201 initname.append("6__initZ"); | |
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
|
202 |
100 | 203 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module); |
204 ts->llvmInit = initvar; | |
205 | |
206 gIR->classes.pop_back(); | |
207 gIR->structs.pop_back(); | |
208 | |
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
|
209 gIR->constInitList.push_back(cd); |
100 | 210 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
|
211 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
|
212 |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
213 // classinfo |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
214 DtoDeclareClassInfo(cd); |
106 | 215 |
216 // typeinfo | |
217 if (cd->parent->isModule() && cd->getModule() == gIR->dmodule) | |
218 cd->type->getTypeInfo(NULL); | |
100 | 219 } |
220 | |
221 ////////////////////////////////////////////////////////////////////////////////////////// | |
222 | |
223 void DtoConstInitClass(ClassDeclaration* cd) | |
224 { | |
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
|
225 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
|
226 cd->llvmInitialized = true; |
100 | 227 |
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
|
228 Logger::println("DtoConstInitClass(%s)", cd->toPrettyChars()); |
100 | 229 LOG_SCOPE; |
230 | |
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
|
231 IRStruct* irstruct = cd->llvmIRStruct; |
100 | 232 gIR->structs.push_back(irstruct); |
233 gIR->classes.push_back(cd); | |
234 | |
235 // make sure each offset knows its default initializer | |
236 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) | |
237 { | |
238 IRStruct::Offset* so = &i->second; | |
239 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); | |
240 so->init = finit; | |
241 so->var->llvmConstInit = finit; | |
242 } | |
243 | |
244 // fill out fieldtypes/inits | |
245 std::vector<llvm::Constant*> fieldinits; | |
246 | |
247 // first field is always the vtable | |
248 assert(cd->llvmVtbl != 0); | |
249 fieldinits.push_back(cd->llvmVtbl); | |
250 | |
251 // rest | |
252 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
|
253 Logger::println("adding fieldinit for: %s", i->second.var->toChars()); |
100 | 254 fieldinits.push_back(i->second.init); |
255 } | |
256 | |
257 // get the struct (class) type | |
258 assert(cd->type->ty == Tclass); | |
259 TypeClass* ts = (TypeClass*)cd->type; | |
260 const llvm::StructType* structtype = isaStruct(ts->llvmType->get()); | |
261 | |
262 // generate initializer | |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
263 /*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
|
264 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
265 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
|
266 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
|
267 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
268 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
269 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
|
270 Logger::cout() << "i#" << i << " = " << *fieldinits[i]->getType() << '\n'; |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
271 }*/ |
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
|
272 |
100 | 273 llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits); |
274 assert(_init); | |
275 cd->llvmInitZ = _init; | |
276 | |
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
|
277 // 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
|
278 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
|
279 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
280 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
|
281 { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
282 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
|
283 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
|
284 //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
|
285 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
286 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
|
287 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
|
288 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
|
289 llvm::Constant* c = llvm::cast<llvm::Constant>(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
|
290 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
|
291 } |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
292 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
|
293 assert(cd->llvmClass); |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
294 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
|
295 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
|
296 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
297 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
|
298 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
|
299 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
300 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
301 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
|
302 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
303 /*for (size_t i=0; i< sinits.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
|
304 { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
305 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
|
306 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
|
307 assert(svtbl_ty->getElementType(i) == sinits[i]->getType()); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
308 }*/ |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
309 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
310 llvm::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
|
311 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
|
312 |
100 | 313 gIR->classes.pop_back(); |
314 gIR->structs.pop_back(); | |
315 } | |
316 | |
317 ////////////////////////////////////////////////////////////////////////////////////////// | |
318 | |
319 void DtoDefineClass(ClassDeclaration* cd) | |
320 { | |
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
|
321 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
|
322 cd->llvmDefined = true; |
100 | 323 |
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
|
324 Logger::println("DtoDefineClass(%s)", cd->toPrettyChars()); |
100 | 325 LOG_SCOPE; |
326 | |
327 // get the struct (class) type | |
328 assert(cd->type->ty == Tclass); | |
329 TypeClass* ts = (TypeClass*)cd->type; | |
330 | |
331 bool def = false; | |
332 if (cd->parent->isModule() && cd->getModule() == gIR->dmodule) { | |
333 ts->llvmInit->setInitializer(cd->llvmInitZ); | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
334 cd->llvmVtbl->setInitializer(cd->llvmConstVtbl); |
100 | 335 def = true; |
336 } | |
337 | |
338 // generate classinfo | |
339 if (def) DtoDefineClassInfo(cd); | |
340 } | |
341 | |
342 ////////////////////////////////////////////////////////////////////////////////////////// | |
343 | |
344 void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance) | |
345 { | |
346 Array* arr = &tc->sym->dtors; | |
347 for (size_t i=0; i<arr->dim; i++) | |
348 { | |
349 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i]; | |
350 assert(fd->llvmValue); | |
351 new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb()); | |
352 } | |
353 } | |
354 | |
355 ////////////////////////////////////////////////////////////////////////////////////////// | |
356 | |
357 void DtoInitClass(TypeClass* tc, llvm::Value* dst) | |
358 { | |
359 assert(gIR); | |
360 | |
361 assert(tc->llvmType); | |
362 uint64_t size_t_size = gTargetData->getTypeSize(DtoSize_t()); | |
363 uint64_t n = gTargetData->getTypeSize(tc->llvmType->get()) - size_t_size; | |
364 | |
365 // set vtable field | |
366 llvm::Value* vtblvar = DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); | |
367 assert(tc->sym->llvmVtbl); | |
368 new llvm::StoreInst(tc->sym->llvmVtbl, vtblvar, gIR->scopebb()); | |
369 | |
370 // copy the static initializer | |
371 if (n > 0) { | |
372 assert(tc->llvmInit); | |
373 assert(dst->getType() == tc->llvmInit->getType()); | |
374 | |
375 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
376 | |
377 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); | |
378 dstarr = DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb()); | |
379 | |
380 llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb()); | |
381 srcarr = DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb()); | |
382 | |
383 llvm::Function* fn = LLVM_DeclareMemCpy32(); | |
384 std::vector<llvm::Value*> llargs; | |
385 llargs.resize(4); | |
386 llargs[0] = dstarr; | |
387 llargs[1] = srcarr; | |
388 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | |
389 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
390 | |
391 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
392 } | |
393 } | |
394 | |
395 ////////////////////////////////////////////////////////////////////////////////////////// | |
396 | |
397 void DtoDeclareClassInfo(ClassDeclaration* cd) | |
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 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
|
400 cd->llvmClassDeclared = true; |
100 | 401 |
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
|
402 Logger::println("DtoDeclareClassInfo(%s)", cd->toChars()); |
100 | 403 LOG_SCOPE; |
404 | |
405 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
|
406 DtoResolveClass(cinfo); |
100 | 407 |
408 std::string gname("_D"); | |
409 gname.append(cd->mangle()); | |
410 gname.append("7__ClassZ"); | |
411 | |
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
|
412 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
|
413 |
100 | 414 cd->llvmClass = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module); |
415 } | |
416 | |
417 void DtoDefineClassInfo(ClassDeclaration* cd) | |
418 { | |
419 // The layout is: | |
420 // { | |
421 // void **vptr; | |
422 // monitor_t monitor; | |
423 // byte[] initializer; // static initialization data | |
424 // char[] name; // class name | |
425 // void *[] vtbl; | |
426 // Interface[] interfaces; | |
427 // ClassInfo *base; // base class | |
428 // void *destructor; | |
429 // void *invariant; // class invariant | |
430 // uint flags; | |
431 // void *deallocator; | |
432 // OffsetTypeInfo[] offTi; | |
433 // void *defaultConstructor; | |
434 // } | |
435 | |
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 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
|
437 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
|
438 |
027b8d8b71ec
[svn 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 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
|
440 LOG_SCOPE; |
100 | 441 |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
442 assert(cd->type->ty == Tclass); |
100 | 443 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
|
444 assert(cd->llvmInitZ); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
445 assert(cd->llvmVtbl); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
446 assert(cd->llvmConstVtbl); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
447 |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
448 TypeClass* cdty = (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
|
449 assert(cdty->llvmInit); |
100 | 450 |
451 // holds the list of initializers for llvm | |
452 std::vector<llvm::Constant*> inits; | |
453 | |
454 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
|
455 DtoForceConstInitDsymbol(cinfo); |
100 | 456 assert(cinfo->llvmInitZ); |
457 | |
458 llvm::Constant* c; | |
459 | |
460 // own vtable | |
461 c = cinfo->llvmInitZ->getOperand(0); | |
462 assert(c); | |
463 inits.push_back(c); | |
464 | |
465 // monitor | |
466 // TODO no monitors yet | |
467 | |
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
|
468 // 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
|
469 const llvm::Type* byteptrty = llvm::PointerType::get(llvm::Type::Int8Ty); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
470 c = llvm::ConstantExpr::getBitCast(cdty->llvmInit, byteptrty); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
471 assert(!cd->llvmInitZ->getType()->isAbstract()); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
472 size_t initsz = gTargetData->getTypeSize(cd->llvmInitZ->getType()); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
473 c = DtoConstSlice(DtoConstSize_t(initsz), c); |
100 | 474 inits.push_back(c); |
475 | |
476 // class name | |
477 // from dmd | |
478 char *name = cd->ident->toChars(); | |
479 size_t namelen = strlen(name); | |
480 if (!(namelen > 9 && memcmp(name, "TypeInfo_", 9) == 0)) | |
481 { | |
482 name = cd->toPrettyChars(); | |
483 namelen = strlen(name); | |
484 } | |
485 c = DtoConstString(name); | |
486 inits.push_back(c); | |
487 | |
488 // vtbl array | |
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
|
489 const llvm::Type* byteptrptrty = llvm::PointerType::get(byteptrty); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
490 assert(!cd->llvmVtbl->getType()->isAbstract()); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
491 c = llvm::ConstantExpr::getBitCast(cd->llvmVtbl, byteptrptrty); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
492 assert(!cd->llvmConstVtbl->getType()->isAbstract()); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
493 size_t vtblsz = gTargetData->getTypeSize(cd->llvmConstVtbl->getType()); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
494 c = DtoConstSlice(DtoConstSize_t(vtblsz), c); |
100 | 495 inits.push_back(c); |
496 | |
497 // interfaces array | |
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
|
498 // TODO |
100 | 499 c = cinfo->llvmInitZ->getOperand(4); |
500 inits.push_back(c); | |
501 | |
502 // base 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
|
503 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
|
504 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
|
505 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
|
506 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
|
507 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
|
508 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
509 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
|
510 // null |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
511 c = cinfo->llvmInitZ->getOperand(5); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
512 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
|
513 } |
100 | 514 |
515 // destructor | |
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 // TODO |
100 | 517 c = cinfo->llvmInitZ->getOperand(6); |
518 inits.push_back(c); | |
519 | |
520 // 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
|
521 // TODO |
100 | 522 c = cinfo->llvmInitZ->getOperand(7); |
523 inits.push_back(c); | |
524 | |
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
|
525 // uint flags, adapted from original dmd code |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
526 uint flags = 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
|
527 //flags |= 4; // has offTi |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
528 //flags |= isCOMclass(); // IUnknown |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
529 if (cd->ctor) flags |= 8; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
530 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->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
|
531 { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
532 if (cd2->members) |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
533 { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
534 for (size_t i = 0; i < cd2->members->dim; 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
|
535 { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
536 Dsymbol *sm = (Dsymbol *)cd2->members->data[i]; |
106 | 537 //printf("sm = %s %s\n", sm->kind(), sm->toChars()); |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
538 if (sm->hasPointers()) |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
539 goto L2; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
540 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
541 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
542 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
543 flags |= 2; // no pointers |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
544 L2: |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
545 c = DtoConstUint(flags); |
100 | 546 inits.push_back(c); |
547 | |
548 // 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
|
549 // TODO |
100 | 550 c = cinfo->llvmInitZ->getOperand(9); |
551 inits.push_back(c); | |
552 | |
553 // offset typeinfo | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
554 // TODO |
100 | 555 c = cinfo->llvmInitZ->getOperand(10); |
556 inits.push_back(c); | |
557 | |
558 // default constructor | |
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
|
559 // TODO |
100 | 560 c = cinfo->llvmInitZ->getOperand(11); |
561 inits.push_back(c); | |
562 | |
563 /*size_t n = inits.size(); | |
564 for (size_t i=0; i<n; ++i) | |
565 { | |
566 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; | |
567 }*/ | |
568 | |
569 // build the initializer | |
570 const llvm::StructType* st = isaStruct(cinfo->llvmInitZ->getType()); | |
571 llvm::Constant* finalinit = llvm::ConstantStruct::get(st, inits); | |
572 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; | |
573 | |
574 cd->llvmClassZ = finalinit; | |
575 cd->llvmClass->setInitializer(finalinit); | |
576 } |