# HG changeset patch # User lindquist # Date 1213817465 -7200 # Node ID 1e6e2b5d5bfee1fb4a045c3247877c98602b18a1 # Parent d9d5d59873d8c0fcb8c83084cbe263e6803730c6 [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. diff -r d9d5d59873d8 -r 1e6e2b5d5bfe gen/classes.cpp --- a/gen/classes.cpp Mon Jun 16 16:01:19 2008 +0200 +++ b/gen/classes.cpp Wed Jun 18 21:31:05 2008 +0200 @@ -1243,19 +1243,16 @@ 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 types; std::vector 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 @@ 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); } diff -r d9d5d59873d8 -r 1e6e2b5d5bfe gen/statements.cpp --- a/gen/statements.cpp Mon Jun 16 16:01:19 2008 +0200 +++ b/gen/statements.cpp Wed Jun 18 21:31:05 2008 +0200 @@ -681,7 +681,14 @@ } 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 @@ { Logger::println("is string switch"); // build array of the stringexpS + caseArray.reserve(cases->dim); for (int i=0; idim; ++i) { CaseStatement* cs = (CaseStatement*)cases->data[i]; @@ -719,13 +727,13 @@ // first sort it caseArray.sort(); // iterate and add indices to cases - std::vector inits; + std::vector inits(caseArray.dim); for (size_t i=0; idata[i]; + Case* c = (Case*)caseArray.data[i]; + CaseStatement* cs = (CaseStatement*)cases->data[c->index]; cs->llvmIdx = DtoConstUint(i); - Case* c = (Case*)caseArray.data[i]; - inits.push_back(c->str->toConstElem(p)); + inits[i] = c->str->toConstElem(p); } // build static array for ptr or final array const LLType* elemTy = DtoType(condition->type); @@ -811,13 +819,10 @@ } 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()); diff -r d9d5d59873d8 -r 1e6e2b5d5bfe tango/lib/compiler/llvmdc/genobj.d --- a/tango/lib/compiler/llvmdc/genobj.d Mon Jun 16 16:01:19 2008 +0200 +++ b/tango/lib/compiler/llvmdc/genobj.d Wed Jun 18 21:31:05 2008 +0200 @@ -302,7 +302,7 @@ size_t tsize() { return base.tsize(); } 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(); } void[] init() { return m_init.length ? m_init : base.init(); } diff -r d9d5d59873d8 -r 1e6e2b5d5bfe tango/lib/compiler/llvmdc/switch.d --- a/tango/lib/compiler/llvmdc/switch.d Mon Jun 16 16:01:19 2008 +0200 +++ b/tango/lib/compiler/llvmdc/switch.d Wed Jun 18 21:31:05 2008 +0200 @@ -26,6 +26,7 @@ */ private import tango.stdc.string; +//private import tango.stdc.stdio; /****************************************************** * Support for switch statements switching on strings. @@ -101,11 +102,11 @@ } 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 high; size_t mid; - size_t c; + ptrdiff_t c; char[] pca; low = 0; @@ -136,7 +137,7 @@ { mid = (low + high) >> 1; pca = table[mid]; - c = ca.length - pca.length; + c = cast(ptrdiff_t)(ca.length - pca.length); if (c == 0) { c = cast(ubyte)c1 - cast(ubyte)pca[0]; @@ -244,7 +245,7 @@ size_t low; size_t high; size_t mid; - size_t c; + ptrdiff_t c; wchar[] pca; low = 0; @@ -265,7 +266,7 @@ { mid = (low + high) >> 1; pca = table[mid]; - c = ca.length - pca.length; + c = cast(ptrdiff_t)(ca.length - pca.length); if (c == 0) { c = memcmp(ca.ptr, pca.ptr, ca.length * wchar.sizeof); @@ -369,7 +370,7 @@ size_t low; size_t high; size_t mid; - size_t c; + ptrdiff_t c; dchar[] pca; low = 0; @@ -390,7 +391,7 @@ { mid = (low + high) >> 1; pca = table[mid]; - c = ca.length - pca.length; + c = cast(ptrdiff_t)(ca.length - pca.length); if (c == 0) { c = memcmp(ca.ptr, pca.ptr, ca.length * dchar.sizeof);