[svn r292] Fixed: string switch was broken in several ways.

Fixed: TypeInfo_Typedef.next was incorrect (return base of base instead of just base).
Fixed: ClassInfo offset type info (offTi) had invalid offsets.
This commit is contained in:
Tomas Lindquist Olsen
2008-06-18 21:31:05 +02:00
parent 964f91b5a1
commit ab92e1230b
4 changed files with 28 additions and 25 deletions

View File

@@ -1243,19 +1243,16 @@ void DtoDeclareClassInfo(ClassDeclaration* cd)
cd->ir.irStruct->classInfo = new llvm::GlobalVariable(st, true, DtoLinkage(cd), NULL, gname, gIR->module);
}
static LLConstant* build_offti_entry(VarDeclaration* vd)
static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd)
{
std::vector<const LLType*> types;
std::vector<LLConstant*> inits;
types.push_back(DtoSize_t());
size_t offset = vd->offset; // TODO might not be the true offset
// dmd only accounts for the vtable, not classinfo or monitor
if (global.params.is64bit)
offset += 8;
else
offset += 4;
assert(vd->ir.irField);
assert(vd->ir.irField->index >= 0);
size_t offset = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(vd->ir.irField->index+2);
inits.push_back(DtoConstSize_t(offset));
vd->type->getTypeInfo(NULL);
@@ -1288,7 +1285,7 @@ static LLConstant* build_offti_array(ClassDeclaration* cd, LLConstant* init)
Dsymbol *sm = (Dsymbol *)cd2->members->data[i];
if (VarDeclaration* vd = sm->isVarDeclaration()) // is this enough?
{
LLConstant* c = build_offti_entry(vd);
LLConstant* c = build_offti_entry(cd, vd);
assert(c);
arrayInits.push_back(c);
}

View File

@@ -681,7 +681,14 @@ static LLValue* call_string_switch_runtime(llvm::GlobalVariable* table, Expressi
}
assert(llval->getType() == fn->getFunctionType()->getParamType(1));
return gIR->ir->CreateCall2(fn, table, llval, "tmp");
llvm::CallInst* call = gIR->ir->CreateCall2(fn, table, llval, "tmp");
llvm::PAListPtr palist;
palist = palist.addAttr(1, llvm::ParamAttr::ByVal);
palist = palist.addAttr(2, llvm::ParamAttr::ByVal);
call->setParamAttrs(palist);
return call;
}
void SwitchStatement::toIR(IRState* p)
@@ -709,6 +716,7 @@ void SwitchStatement::toIR(IRState* p)
{
Logger::println("is string switch");
// build array of the stringexpS
caseArray.reserve(cases->dim);
for (int i=0; i<cases->dim; ++i)
{
CaseStatement* cs = (CaseStatement*)cases->data[i];
@@ -719,13 +727,13 @@ void SwitchStatement::toIR(IRState* p)
// first sort it
caseArray.sort();
// iterate and add indices to cases
std::vector<LLConstant*> inits;
std::vector<LLConstant*> inits(caseArray.dim);
for (size_t i=0; i<caseArray.dim; ++i)
{
CaseStatement* cs = (CaseStatement*)cases->data[i];
cs->llvmIdx = DtoConstUint(i);
Case* c = (Case*)caseArray.data[i];
inits.push_back(c->str->toConstElem(p));
CaseStatement* cs = (CaseStatement*)cases->data[c->index];
cs->llvmIdx = DtoConstUint(i);
inits[i] = c->str->toConstElem(p);
}
// build static array for ptr or final array
const LLType* elemTy = DtoType(condition->type);
@@ -811,13 +819,10 @@ void CaseStatement::toIR(IRState* p)
}
bodyBB = nbb;
if (exp->type->isintegral()) {
if (llvmIdx == NULL) {
LLConstant* c = exp->toConstElem(p);
llvmIdx = isaConstantInt(c);
}
else {
assert(llvmIdx);
}
if (!p->scopereturned())
llvm::BranchInst::Create(bodyBB, p->scopebb());