mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 09:31:03 +03:00
[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:
parent
964f91b5a1
commit
ab92e1230b
4 changed files with 28 additions and 25 deletions
|
@ -1243,19 +1243,16 @@ void DtoDeclareClassInfo(ClassDeclaration* cd)
|
||||||
cd->ir.irStruct->classInfo = new llvm::GlobalVariable(st, true, DtoLinkage(cd), NULL, gname, gIR->module);
|
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<const LLType*> types;
|
||||||
std::vector<LLConstant*> inits;
|
std::vector<LLConstant*> inits;
|
||||||
|
|
||||||
types.push_back(DtoSize_t());
|
types.push_back(DtoSize_t());
|
||||||
|
|
||||||
size_t offset = vd->offset; // TODO might not be the true offset
|
assert(vd->ir.irField);
|
||||||
// dmd only accounts for the vtable, not classinfo or monitor
|
assert(vd->ir.irField->index >= 0);
|
||||||
if (global.params.is64bit)
|
size_t offset = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(vd->ir.irField->index+2);
|
||||||
offset += 8;
|
|
||||||
else
|
|
||||||
offset += 4;
|
|
||||||
inits.push_back(DtoConstSize_t(offset));
|
inits.push_back(DtoConstSize_t(offset));
|
||||||
|
|
||||||
vd->type->getTypeInfo(NULL);
|
vd->type->getTypeInfo(NULL);
|
||||||
|
@ -1288,7 +1285,7 @@ static LLConstant* build_offti_array(ClassDeclaration* cd, LLConstant* init)
|
||||||
Dsymbol *sm = (Dsymbol *)cd2->members->data[i];
|
Dsymbol *sm = (Dsymbol *)cd2->members->data[i];
|
||||||
if (VarDeclaration* vd = sm->isVarDeclaration()) // is this enough?
|
if (VarDeclaration* vd = sm->isVarDeclaration()) // is this enough?
|
||||||
{
|
{
|
||||||
LLConstant* c = build_offti_entry(vd);
|
LLConstant* c = build_offti_entry(cd, vd);
|
||||||
assert(c);
|
assert(c);
|
||||||
arrayInits.push_back(c);
|
arrayInits.push_back(c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -681,7 +681,14 @@ static LLValue* call_string_switch_runtime(llvm::GlobalVariable* table, Expressi
|
||||||
}
|
}
|
||||||
assert(llval->getType() == fn->getFunctionType()->getParamType(1));
|
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)
|
void SwitchStatement::toIR(IRState* p)
|
||||||
|
@ -709,6 +716,7 @@ void SwitchStatement::toIR(IRState* p)
|
||||||
{
|
{
|
||||||
Logger::println("is string switch");
|
Logger::println("is string switch");
|
||||||
// build array of the stringexpS
|
// build array of the stringexpS
|
||||||
|
caseArray.reserve(cases->dim);
|
||||||
for (int i=0; i<cases->dim; ++i)
|
for (int i=0; i<cases->dim; ++i)
|
||||||
{
|
{
|
||||||
CaseStatement* cs = (CaseStatement*)cases->data[i];
|
CaseStatement* cs = (CaseStatement*)cases->data[i];
|
||||||
|
@ -719,13 +727,13 @@ void SwitchStatement::toIR(IRState* p)
|
||||||
// first sort it
|
// first sort it
|
||||||
caseArray.sort();
|
caseArray.sort();
|
||||||
// iterate and add indices to cases
|
// 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)
|
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];
|
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
|
// build static array for ptr or final array
|
||||||
const LLType* elemTy = DtoType(condition->type);
|
const LLType* elemTy = DtoType(condition->type);
|
||||||
|
@ -811,13 +819,10 @@ void CaseStatement::toIR(IRState* p)
|
||||||
}
|
}
|
||||||
bodyBB = nbb;
|
bodyBB = nbb;
|
||||||
|
|
||||||
if (exp->type->isintegral()) {
|
if (llvmIdx == NULL) {
|
||||||
LLConstant* c = exp->toConstElem(p);
|
LLConstant* c = exp->toConstElem(p);
|
||||||
llvmIdx = isaConstantInt(c);
|
llvmIdx = isaConstantInt(c);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
assert(llvmIdx);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!p->scopereturned())
|
if (!p->scopereturned())
|
||||||
llvm::BranchInst::Create(bodyBB, p->scopebb());
|
llvm::BranchInst::Create(bodyBB, p->scopebb());
|
||||||
|
|
|
@ -302,7 +302,7 @@ class TypeInfo_Typedef : TypeInfo
|
||||||
size_t tsize() { return base.tsize(); }
|
size_t tsize() { return base.tsize(); }
|
||||||
void swap(void *p1, void *p2) { return base.swap(p1, p2); }
|
void swap(void *p1, void *p2) { return base.swap(p1, p2); }
|
||||||
|
|
||||||
TypeInfo next() { return base.next(); }
|
TypeInfo next() { return base; }
|
||||||
uint flags() { return base.flags(); }
|
uint flags() { return base.flags(); }
|
||||||
void[] init() { return m_init.length ? m_init : base.init(); }
|
void[] init() { return m_init.length ? m_init : base.init(); }
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private import tango.stdc.string;
|
private import tango.stdc.string;
|
||||||
|
//private import tango.stdc.stdio;
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* Support for switch statements switching on strings.
|
* Support for switch statements switching on strings.
|
||||||
|
@ -101,11 +102,11 @@ out (result)
|
||||||
}
|
}
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
//printf("body _d_switch_string(%.*s)\n", ca);
|
//printf("body _d_switch_string(%.*s)\n", ca.length, ca.ptr);
|
||||||
size_t low;
|
size_t low;
|
||||||
size_t high;
|
size_t high;
|
||||||
size_t mid;
|
size_t mid;
|
||||||
size_t c;
|
ptrdiff_t c;
|
||||||
char[] pca;
|
char[] pca;
|
||||||
|
|
||||||
low = 0;
|
low = 0;
|
||||||
|
@ -136,7 +137,7 @@ body
|
||||||
{
|
{
|
||||||
mid = (low + high) >> 1;
|
mid = (low + high) >> 1;
|
||||||
pca = table[mid];
|
pca = table[mid];
|
||||||
c = ca.length - pca.length;
|
c = cast(ptrdiff_t)(ca.length - pca.length);
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
{
|
{
|
||||||
c = cast(ubyte)c1 - cast(ubyte)pca[0];
|
c = cast(ubyte)c1 - cast(ubyte)pca[0];
|
||||||
|
@ -244,7 +245,7 @@ body
|
||||||
size_t low;
|
size_t low;
|
||||||
size_t high;
|
size_t high;
|
||||||
size_t mid;
|
size_t mid;
|
||||||
size_t c;
|
ptrdiff_t c;
|
||||||
wchar[] pca;
|
wchar[] pca;
|
||||||
|
|
||||||
low = 0;
|
low = 0;
|
||||||
|
@ -265,7 +266,7 @@ body
|
||||||
{
|
{
|
||||||
mid = (low + high) >> 1;
|
mid = (low + high) >> 1;
|
||||||
pca = table[mid];
|
pca = table[mid];
|
||||||
c = ca.length - pca.length;
|
c = cast(ptrdiff_t)(ca.length - pca.length);
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
{
|
{
|
||||||
c = memcmp(ca.ptr, pca.ptr, ca.length * wchar.sizeof);
|
c = memcmp(ca.ptr, pca.ptr, ca.length * wchar.sizeof);
|
||||||
|
@ -369,7 +370,7 @@ body
|
||||||
size_t low;
|
size_t low;
|
||||||
size_t high;
|
size_t high;
|
||||||
size_t mid;
|
size_t mid;
|
||||||
size_t c;
|
ptrdiff_t c;
|
||||||
dchar[] pca;
|
dchar[] pca;
|
||||||
|
|
||||||
low = 0;
|
low = 0;
|
||||||
|
@ -390,7 +391,7 @@ body
|
||||||
{
|
{
|
||||||
mid = (low + high) >> 1;
|
mid = (low + high) >> 1;
|
||||||
pca = table[mid];
|
pca = table[mid];
|
||||||
c = ca.length - pca.length;
|
c = cast(ptrdiff_t)(ca.length - pca.length);
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
{
|
{
|
||||||
c = memcmp(ca.ptr, pca.ptr, ca.length * dchar.sizeof);
|
c = memcmp(ca.ptr, pca.ptr, ca.length * dchar.sizeof);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue