Mercurial > projects > ldc
comparison gen/structs.cpp @ 705:5a2983f97498
Fixed weird struct problem from downs, see mini/compile_structs1.d
Rewrote DtoIndexStruct/Class , the old implementation were way too complex for what we really need now - since the DotVar changes.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Tue, 14 Oct 2008 15:35:49 +0200 |
parents | a15ccbf7451d |
children | 3e143b611c1e |
comparison
equal
deleted
inserted
replaced
704:43165a082535 | 705:5a2983f97498 |
---|---|
50 return si->ad->ir.irStruct->dunion->getConst(inits); | 50 return si->ad->ir.irStruct->dunion->getConst(inits); |
51 } | 51 } |
52 | 52 |
53 ////////////////////////////////////////////////////////////////////////////////////////// | 53 ////////////////////////////////////////////////////////////////////////////////////////// |
54 | 54 |
55 LLValue* DtoIndexStruct(LLValue* ptr, StructDeclaration* sd, Type* t, unsigned os, DStructIndexVector& idxs) | 55 LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd) |
56 { | 56 { |
57 Logger::println("checking for offset %u type %s:", os, t->toChars()); | 57 Logger::println("indexing struct field %s:", vd->toPrettyChars()); |
58 LOG_SCOPE; | 58 LOG_SCOPE; |
59 | 59 |
60 if (idxs.empty()) | 60 // vd must be a field |
61 idxs.push_back(0); | 61 IrField* field = vd->ir.irField; |
62 | 62 assert(field); |
63 const LLType* llt = getPtrToType(DtoType(t)); | 63 |
64 unsigned idx = field->index; | |
65 unsigned off = field->indexOffset; | |
66 | |
64 const LLType* st = getPtrToType(DtoType(sd->type)); | 67 const LLType* st = getPtrToType(DtoType(sd->type)); |
68 src = DtoBitCast(src, st); | |
69 | |
70 LLValue* val = DtoGEPi(src, 0,idx); | |
71 val = DtoBitCast(val, getPtrToType(DtoType(vd->type))); | |
72 | |
73 if (off) | |
74 val = DtoGEPi1(val, off); | |
65 | 75 |
66 if (Logger::enabled()) | 76 if (Logger::enabled()) |
67 { | 77 Logger::cout() << "value: " << *val << '\n'; |
68 Logger::cout() << "ptr = " << *ptr << '\n'; | 78 |
69 Logger::cout() << "st = " << *st << '\n'; | 79 return val; |
70 } | |
71 | |
72 if (ptr->getType() != st) { | |
73 assert(sd->ir.irStruct->hasUnions); | |
74 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); | |
75 } | |
76 | |
77 for (unsigned i=0; i<sd->fields.dim; ++i) { | |
78 VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i]; | |
79 Type* vdtype = vd->type->toBasetype(); | |
80 //Logger::println("found %u type %s", vd->offset, vdtype->toChars()); | |
81 assert(vd->ir.irField->index >= 0); | |
82 if (os == vd->offset && vdtype == t) { | |
83 idxs.push_back(vd->ir.irField->index); | |
84 ptr = DtoGEPi(ptr, idxs, "tmp"); | |
85 if (ptr->getType() != llt) | |
86 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); | |
87 if (vd->ir.irField->indexOffset) | |
88 ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); | |
89 return ptr; | |
90 } | |
91 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { | |
92 TypeStruct* ts = (TypeStruct*)vdtype; | |
93 StructDeclaration* ssd = ts->sym; | |
94 idxs.push_back(vd->ir.irField->index); | |
95 if (vd->ir.irField->indexOffset) { | |
96 Logger::println("has union field offset"); | |
97 ptr = DtoGEPi(ptr, idxs, "tmp"); | |
98 if (ptr->getType() != llt) | |
99 ptr = DtoBitCast(ptr, llt); | |
100 ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); | |
101 DStructIndexVector tmp; | |
102 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); | |
103 } | |
104 else { | |
105 const LLType* sty = getPtrToType(DtoType(vd->type)); | |
106 if (ptr->getType() != sty) { | |
107 ptr = DtoBitCast(ptr, sty); | |
108 DStructIndexVector tmp; | |
109 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); | |
110 } | |
111 else { | |
112 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, idxs); | |
113 } | |
114 } | |
115 } | |
116 } | |
117 | |
118 size_t llt_sz = getTypeStoreSize(llt->getContainedType(0)); | |
119 assert(os % llt_sz == 0); | |
120 ptr = DtoBitCast(ptr, llt); | |
121 return llvm::GetElementPtrInst::Create(ptr, DtoConstUint(os / llt_sz), "tmp", gIR->scopebb()); | |
122 } | 80 } |
123 | 81 |
124 ////////////////////////////////////////////////////////////////////////////////////////// | 82 ////////////////////////////////////////////////////////////////////////////////////////// |
125 | 83 |
126 void DtoResolveStruct(StructDeclaration* sd) | 84 void DtoResolveStruct(StructDeclaration* sd) |