Mercurial > projects > ldc
comparison gen/toobj.c @ 77:714057ff2dbb trunk
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
author | lindquist |
---|---|
date | Wed, 31 Oct 2007 09:34:18 +0100 |
parents | eb379601d445 |
children | 3587401b6eeb |
comparison
equal
deleted
inserted
replaced
76:9e1bd80a7e98 | 77:714057ff2dbb |
---|---|
142 /* ================================================================== */ | 142 /* ================================================================== */ |
143 | 143 |
144 void Declaration::toObjFile() | 144 void Declaration::toObjFile() |
145 { | 145 { |
146 Logger::println("Ignoring Declaration::toObjFile for %s", toChars()); | 146 Logger::println("Ignoring Declaration::toObjFile for %s", toChars()); |
147 } | |
148 | |
149 /* ================================================================== */ | |
150 | |
151 /// Returns the LLVM style index from a DMD style offset | |
152 size_t AggregateDeclaration::offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result) | |
153 { | |
154 Logger::println("checking for offset %u type %s:", os, t->toChars()); | |
155 LOG_SCOPE; | |
156 for (unsigned i=0; i<fields.dim; ++i) { | |
157 VarDeclaration* vd = (VarDeclaration*)fields.data[i]; | |
158 Type* vdtype = LLVM_DtoDType(vd->type); | |
159 Logger::println("found %u type %s", vd->offset, vdtype->toChars()); | |
160 if (os == vd->offset && vdtype == t) { | |
161 assert(vd->llvmFieldIndex >= 0); | |
162 result.push_back(vd->llvmFieldIndex); | |
163 return vd->llvmFieldIndexOffset; | |
164 } | |
165 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { | |
166 TypeStruct* ts = (TypeStruct*)vdtype; | |
167 StructDeclaration* sd = ts->sym; | |
168 result.push_back(i); | |
169 return sd->offsetToIndex(t, os - vd->offset, result); | |
170 } | |
171 } | |
172 //assert(0 && "Offset not found in any aggregate field"); | |
173 return (size_t)-1; | |
174 } | |
175 | |
176 /* ================================================================== */ | |
177 | |
178 static unsigned LLVM_ClassOffsetToIndex(ClassDeclaration* cd, unsigned os, unsigned& idx) | |
179 { | |
180 // start at the bottom of the inheritance chain | |
181 if (cd->baseClass != 0) { | |
182 unsigned o = LLVM_ClassOffsetToIndex(cd->baseClass, os, idx); | |
183 if (o != (unsigned)-1) | |
184 return o; | |
185 } | |
186 | |
187 // check this class | |
188 unsigned i; | |
189 for (i=0; i<cd->fields.dim; ++i) { | |
190 VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i]; | |
191 if (os == vd->offset) | |
192 return i+idx; | |
193 } | |
194 idx += i; | |
195 | |
196 return (unsigned)-1; | |
197 } | |
198 | |
199 /// Returns the LLVM style index from a DMD style offset | |
200 /// Handles class inheritance | |
201 size_t ClassDeclaration::offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result) | |
202 { | |
203 unsigned idx = 0; | |
204 unsigned r = LLVM_ClassOffsetToIndex(this, os, idx); | |
205 assert(r != (unsigned)-1 && "Offset not found in any aggregate field"); | |
206 result.push_back(r+1); // vtable is 0 | |
207 return 0; | |
208 } | 147 } |
209 | 148 |
210 /* ================================================================== */ | 149 /* ================================================================== */ |
211 | 150 |
212 void InterfaceDeclaration::toObjFile() | 151 void InterfaceDeclaration::toObjFile() |
269 // colliding offset? | 208 // colliding offset? |
270 else if (lastoffset == i->first) { | 209 else if (lastoffset == i->first) { |
271 const llvm::Type* t = LLVM_DtoType(i->second.var->type); | 210 const llvm::Type* t = LLVM_DtoType(i->second.var->type); |
272 size_t s = gTargetData->getTypeSize(t); | 211 size_t s = gTargetData->getTypeSize(t); |
273 if (s > prevsize) { | 212 if (s > prevsize) { |
274 fieldpad = s - prevsize; | 213 fieldpad += s - prevsize; |
275 prevsize = s; | 214 prevsize = s; |
276 } | 215 } |
277 llvmHasUnions = true; | 216 llvmHasUnions = true; |
278 i->second.var->llvmFieldIndex = idx; | 217 i->second.var->llvmFieldIndex = idx; |
279 } | 218 } |
390 gIR->structs.pop_back(); | 329 gIR->structs.pop_back(); |
391 | 330 |
392 // generate typeinfo | 331 // generate typeinfo |
393 if (getModule() == gIR->dmodule && llvmInternal != LLVMnotypeinfo) | 332 if (getModule() == gIR->dmodule && llvmInternal != LLVMnotypeinfo) |
394 type->getTypeInfo(NULL); | 333 type->getTypeInfo(NULL); |
334 } | |
335 | |
336 /* ================================================================== */ | |
337 | |
338 static unsigned LLVM_ClassOffsetToIndex(ClassDeclaration* cd, unsigned os, unsigned& idx) | |
339 { | |
340 // start at the bottom of the inheritance chain | |
341 if (cd->baseClass != 0) { | |
342 unsigned o = LLVM_ClassOffsetToIndex(cd->baseClass, os, idx); | |
343 if (o != (unsigned)-1) | |
344 return o; | |
345 } | |
346 | |
347 // check this class | |
348 unsigned i; | |
349 for (i=0; i<cd->fields.dim; ++i) { | |
350 VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i]; | |
351 if (os == vd->offset) | |
352 return i+idx; | |
353 } | |
354 idx += i; | |
355 | |
356 return (unsigned)-1; | |
357 } | |
358 | |
359 void ClassDeclaration::offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result) | |
360 { | |
361 unsigned idx = 0; | |
362 unsigned r = LLVM_ClassOffsetToIndex(this, os, idx); | |
363 assert(r != (unsigned)-1 && "Offset not found in any aggregate field"); | |
364 result.push_back(r+1); // vtable is 0 | |
395 } | 365 } |
396 | 366 |
397 /* ================================================================== */ | 367 /* ================================================================== */ |
398 | 368 |
399 static void LLVM_AddBaseClassData(BaseClasses* bcs) | 369 static void LLVM_AddBaseClassData(BaseClasses* bcs) |