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)