Changed some hardcoded offset/alignment for classes in DMD, broke offsets for 64bits.

Changed ClassInfo generation to no longer access the default initializer of ClassInfo, fixes problems with index mismatch.
This commit is contained in:
Tomas Lindquist Olsen 2008-11-30 20:22:09 +01:00
parent 81eded2ece
commit 577237e073
5 changed files with 136 additions and 149 deletions

View file

@ -551,8 +551,8 @@ void ClassDeclaration::semantic(Scope *sc)
// sc->offset += PTRSIZE; // room for uplevel context pointer // sc->offset += PTRSIZE; // room for uplevel context pointer
} }
else else
{ sc->offset = 8; // allow room for vptr[] and monitor { sc->offset = 2*PTRSIZE; // allow room for vptr[] and monitor
alignsize = 4; alignsize = PTRSIZE;
} }
structsize = sc->offset; structsize = sc->offset;
Scope scsave = *sc; Scope scsave = *sc;
@ -1139,7 +1139,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
sc->linkage = LINKwindows; sc->linkage = LINKwindows;
sc->structalign = 8; sc->structalign = 8;
structalign = sc->structalign; structalign = sc->structalign;
sc->offset = 8; sc->offset = 2*PTRSIZE;
inuse++; inuse++;
for (i = 0; i < members->dim; i++) for (i = 0; i < members->dim; i++)
{ {

View file

@ -559,7 +559,7 @@ void ClassDeclaration::semantic(Scope *sc)
} }
else else
{ sc->offset = PTRSIZE * 2; // allow room for __vptr and __monitor { sc->offset = PTRSIZE * 2; // allow room for __vptr and __monitor
alignsize = 4; alignsize = PTRSIZE;
} }
structsize = sc->offset; structsize = sc->offset;
Scope scsave = *sc; Scope scsave = *sc;

View file

@ -75,6 +75,8 @@ static void add_interface(ClassDeclaration* target, BaseClass* b, int newinstanc
iri->index = irstruct->index++; iri->index = irstruct->index++;
} }
//////////////////////////////////////////////////////////////////////////////////////////
static void add_class_data(ClassDeclaration* target, ClassDeclaration* cd) static void add_class_data(ClassDeclaration* target, ClassDeclaration* cd)
{ {
Logger::println("Adding data from class: %s", cd->toChars()); Logger::println("Adding data from class: %s", cd->toChars());
@ -443,7 +445,7 @@ static size_t init_class_initializer(std::vector<LLConstant*>& inits, ClassDecla
std::vector<VarDeclaration*> defVars; std::vector<VarDeclaration*> defVars;
defVars.reserve(nfields); defVars.reserve(nfields);
size_t lastoffset = offsetbegin; // vtbl,monitor size_t lastoffset = offsetbegin;
size_t lastsize = 0; size_t lastsize = 0;
// find fields that contribute to default // find fields that contribute to default
@ -455,13 +457,21 @@ static size_t init_class_initializer(std::vector<LLConstant*>& inits, ClassDecla
size_t size = var->type->size(); size_t size = var->type->size();
if (offset >= lastoffset+lastsize) if (offset >= lastoffset+lastsize)
{ {
Logger::println(" added"); Logger::println(" added %s", var->toChars());
lastoffset = offset; lastoffset = offset;
lastsize = size; lastsize = size;
defVars.push_back(var); defVars.push_back(var);
} }
else
{
Logger::println(" skipped %s", var->toChars());
}
} }
// reset offsets, we're going from beginning again
lastoffset = offsetbegin;
lastsize = 0;
// go through the default vars and build the default constant initializer // go through the default vars and build the default constant initializer
// adding zeros along the way to live up to alignment expectations // adding zeros along the way to live up to alignment expectations
size_t nvars = defVars.size(); size_t nvars = defVars.size();
@ -760,11 +770,13 @@ static void DefineInterfaceInfos(IrStruct* irstruct)
{ {
// always do interface info array when possible // always do interface info array when possible
std::vector<LLConstant*> infoInits; std::vector<LLConstant*> infoInits;
infoInits.reserve(irstruct->interfaceVec.size());
for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) size_t n = irstruct->interfaceVec.size();
infoInits.reserve(n);
for (size_t i=0; i < n; i++)
{ {
IrInterface* iri = *i; IrInterface* iri = irstruct->interfaceVec[i];
assert(iri->infoInit); assert(iri->infoInit);
infoInits.push_back(iri->infoInit); infoInits.push_back(iri->infoInit);
} }
@ -834,13 +846,13 @@ void DtoDefineClass(ClassDeclaration* cd)
assert(irstruct->vtbl); assert(irstruct->vtbl);
assert(irstruct->constVtbl); assert(irstruct->constVtbl);
if (Logger::enabled()) // if (Logger::enabled())
{ // {
Logger::cout() << "initZ: " << *irstruct->init << std::endl; // Logger::cout() << "initZ: " << *irstruct->init << std::endl;
Logger::cout() << "cinitZ: " << *irstruct->constInit << std::endl; // Logger::cout() << "cinitZ: " << *irstruct->constInit << std::endl;
Logger::cout() << "vtblZ: " << *irstruct->vtbl << std::endl; // Logger::cout() << "vtblZ: " << *irstruct->vtbl << std::endl;
Logger::cout() << "cvtblZ: " << *irstruct->constVtbl << std::endl; // Logger::cout() << "cvtblZ: " << *irstruct->constVtbl << std::endl;
} // }
// set initializers // set initializers
irstruct->init->setInitializer(irstruct->constInit); irstruct->init->setInitializer(irstruct->constInit);
@ -1184,29 +1196,6 @@ DValue* DtoDynamicCastInterface(DValue* val, Type* _to)
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
static unsigned LLVM_ClassOffsetToIndex(ClassDeclaration* cd, unsigned os, unsigned& idx)
{
// start at the bottom of the inheritance chain
if (cd->baseClass != 0) {
unsigned o = LLVM_ClassOffsetToIndex(cd->baseClass, os, idx);
if (o != (unsigned)-1)
return o;
}
// check this class
unsigned i;
for (i=0; i<cd->fields.dim; ++i) {
VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i];
if (os == vd->offset)
return i+idx;
}
idx += i;
return (unsigned)-1;
}
//////////////////////////////////////////////////////////////////////////////////////////
LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd) LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd)
{ {
Logger::println("indexing class field %s:", vd->toPrettyChars()); Logger::println("indexing class field %s:", vd->toPrettyChars());
@ -1255,24 +1244,31 @@ LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd)
LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl) LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl)
{ {
assert(fdecl->isVirtual());//fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())); // sanity checks
assert(fdecl->vtblIndex > 0); assert(fdecl->isVirtual());
assert(fdecl->vtblIndex > 0); // 0 is always ClassInfo/Interface*
assert(inst->getType()->toBasetype()->ty == Tclass); assert(inst->getType()->toBasetype()->ty == Tclass);
// get instance
LLValue* vthis = inst->getRVal(); LLValue* vthis = inst->getRVal();
if (Logger::enabled()) if (Logger::enabled())
Logger::cout() << "vthis: " << *vthis << '\n'; Logger::cout() << "vthis: " << *vthis << '\n';
LLValue* funcval = vthis; LLValue* funcval = vthis;
if (!fdecl->isMember2()->isInterfaceDeclaration()) // get the vtbl for objects
if (!fdecl->isMember()->isInterfaceDeclaration())
funcval = DtoGEPi(funcval, 0, 0, "tmp"); funcval = DtoGEPi(funcval, 0, 0, "tmp");
// load vtbl ptr
funcval = DtoLoad(funcval); funcval = DtoLoad(funcval);
// index vtbl
funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, fdecl->toChars()); funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, fdecl->toChars());
// load funcptr
funcval = DtoLoad(funcval); funcval = DtoLoad(funcval);
if (Logger::enabled()) if (Logger::enabled())
Logger::cout() << "funcval: " << *funcval << '\n'; Logger::cout() << "funcval: " << *funcval << '\n';
// cast to final funcptr type
funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type))); funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
if (Logger::enabled()) if (Logger::enabled())
Logger::cout() << "funcval casted: " << *funcval << '\n'; Logger::cout() << "funcval casted: " << *funcval << '\n';
@ -1292,9 +1288,11 @@ void DtoDeclareClassInfo(ClassDeclaration* cd)
Logger::println("DtoDeclareClassInfo(%s)", cd->toChars()); Logger::println("DtoDeclareClassInfo(%s)", cd->toChars());
LOG_SCOPE; LOG_SCOPE;
// resovle ClassInfo
ClassDeclaration* cinfo = ClassDeclaration::classinfo; ClassDeclaration* cinfo = ClassDeclaration::classinfo;
DtoResolveClass(cinfo); DtoResolveClass(cinfo);
// do the mangle
std::string gname("_D"); std::string gname("_D");
gname.append(cd->mangle()); gname.append(cd->mangle());
if (!cd->isInterfaceDeclaration()) if (!cd->isInterfaceDeclaration())
@ -1302,74 +1300,67 @@ void DtoDeclareClassInfo(ClassDeclaration* cd)
else else
gname.append("11__InterfaceZ"); gname.append("11__InterfaceZ");
// create global
irstruct->classInfo = new llvm::GlobalVariable(irstruct->classInfoOpaque.get(), false, DtoLinkage(cd), NULL, gname, gIR->module); irstruct->classInfo = new llvm::GlobalVariable(irstruct->classInfoOpaque.get(), false, DtoLinkage(cd), NULL, gname, gIR->module);
} }
//////////////////////////////////////////////////////////////////////////////////////////
// build a single element for the OffsetInfo[] of ClassInfo
static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd) static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd)
{ {
std::vector<const LLType*> types; std::vector<LLConstant*> inits(2);
std::vector<LLConstant*> inits;
types.push_back(DtoSize_t());
// size_t offset;
//
assert(vd->ir.irField); assert(vd->ir.irField);
// grab the offset from llvm and the formal class type
size_t offset = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(vd->ir.irField->index); size_t offset = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(vd->ir.irField->index);
// offset nested struct/union fields
offset += vd->ir.irField->unionOffset; offset += vd->ir.irField->unionOffset;
inits.push_back(DtoConstSize_t(offset));
LLConstant* c = DtoTypeInfoOf(vd->type, true); // assert that it matches DMD
const LLType* tiTy = c->getType(); Logger::println("offsets: %lu vs %u", offset, vd->offset);
//Logger::cout() << "tiTy = " << *tiTy << '\n'; assert(offset == vd->offset);
types.push_back(tiTy); inits[0] = DtoConstSize_t(offset);
inits.push_back(c);
const llvm::StructType* sTy = llvm::StructType::get(types); // TypeInfo ti;
return llvm::ConstantStruct::get(sTy, inits); inits[1] = DtoTypeInfoOf(vd->type, true);
// done
return llvm::ConstantStruct::get(inits);
} }
static LLConstant* build_offti_array(ClassDeclaration* cd, LLConstant* init) static LLConstant* build_offti_array(ClassDeclaration* cd, const LLType* arrayT)
{ {
const llvm::StructType* initTy = isaStruct(init->getType()); IrStruct* irstruct = cd->ir.irStruct;
assert(initTy);
std::vector<LLConstant*> arrayInits; size_t nvars = irstruct->varDecls.size();
std::vector<LLConstant*> arrayInits(nvars);
VarDeclaration** fields = &cd->ir.irStruct->varDecls[0];
size_t nvars = cd->ir.irStruct->varDecls.size();
for (size_t i=0; i<nvars; i++) for (size_t i=0; i<nvars; i++)
{ {
LLConstant* c = build_offti_entry(cd, fields[i]); arrayInits[i] = build_offti_entry(cd, irstruct->varDecls[i]);
assert(c);
arrayInits.push_back(c);
} }
size_t ninits = arrayInits.size(); LLConstant* size = DtoConstSize_t(nvars);
LLConstant* size = DtoConstSize_t(ninits);
LLConstant* ptr; LLConstant* ptr;
if (ninits > 0) { if (nvars == 0)
// OffsetTypeInfo type return LLConstant::getNullValue( arrayT );
std::vector<const LLType*> elemtypes;
elemtypes.push_back(DtoSize_t());
const LLType* tiTy = getPtrToType(Type::typeinfo->type->ir.type->get());
elemtypes.push_back(tiTy);
const llvm::StructType* sTy = llvm::StructType::get(elemtypes);
// array type // array type
const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits); const llvm::ArrayType* arrTy = llvm::ArrayType::get(arrayInits[0]->getType(), nvars);
LLConstant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits); LLConstant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits);
std::string name(cd->type->vtinfo->toChars()); // mangle
name.append("__OffsetTypeInfos"); std::string name(cd->type->vtinfo->toChars());
name.append("__OffsetTypeInfos");
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,DtoInternalLinkage(cd),arrInit,name,gIR->module); // create symbol
ptr = llvm::ConstantExpr::getBitCast(gvar, getPtrToType(sTy)); llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,DtoInternalLinkage(cd),arrInit,name,gIR->module);
} ptr = DtoBitCast(gvar, getPtrToType(arrTy->getElementType()));
else {
ptr = llvm::ConstantPointerNull::get(isaPointer(initTy->getElementType(1)));
}
return DtoConstSlice(size, ptr); return DtoConstSlice(size, ptr);
} }
@ -1446,7 +1437,8 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
assert(ir->classInfo); assert(ir->classInfo);
TypeClass* cdty = (TypeClass*)cd->type; TypeClass* cdty = (TypeClass*)cd->type;
if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { if (!cd->isInterfaceDeclaration() && !cd->isAbstract())
{
assert(ir->init); assert(ir->init);
assert(ir->constInit); assert(ir->constInit);
assert(ir->vtbl); assert(ir->vtbl);
@ -1460,28 +1452,26 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
DtoForceConstInitDsymbol(cinfo); DtoForceConstInitDsymbol(cinfo);
assert(cinfo->ir.irStruct->constInit); assert(cinfo->ir.irStruct->constInit);
// def init constant
LLConstant* defc = cinfo->ir.irStruct->constInit;
assert(defc);
LLConstant* c; LLConstant* c;
const LLType* voidPtr = getVoidPtrType();
const LLType* voidPtrPtr = getPtrToType(voidPtr);
// own vtable // own vtable
c = defc->getOperand(0); c = cinfo->ir.irStruct->vtbl;
assert(c); assert(c);
inits.push_back(c); inits.push_back(c);
// monitor // monitor
c = defc->getOperand(1); c = LLConstant::getNullValue(voidPtr);
inits.push_back(c); inits.push_back(c);
// byte[] init // byte[] init
const LLType* byteptrty = getPtrToType(LLType::Int8Ty); if (cd->isInterfaceDeclaration())
if (cd->isInterfaceDeclaration() || cd->isAbstract()) { c = DtoConstSlice(DtoConstSize_t(0), LLConstant::getNullValue(voidPtr));
c = defc->getOperand(2); else
} {
else { c = DtoBitCast(ir->init, voidPtr);
c = llvm::ConstantExpr::getBitCast(ir->init, byteptrty);
//Logger::cout() << *ir->constInit->getType() << std::endl; //Logger::cout() << *ir->constInit->getType() << std::endl;
size_t initsz = getABITypeSize(ir->constInit->getType()); size_t initsz = getABITypeSize(ir->constInit->getType());
c = DtoConstSlice(DtoConstSize_t(initsz), c); c = DtoConstSlice(DtoConstSize_t(initsz), c);
@ -1501,34 +1491,30 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
inits.push_back(c); inits.push_back(c);
// vtbl array // vtbl array
if (cd->isInterfaceDeclaration() || cd->isAbstract()) { if (cd->isInterfaceDeclaration())
c = defc->getOperand(4); c = DtoConstSlice(DtoConstSize_t(0), LLConstant::getNullValue(getPtrToType(voidPtr)));
}
else { else {
const LLType* byteptrptrty = getPtrToType(byteptrty); c = DtoBitCast(ir->vtbl, voidPtrPtr);
c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->vtbl, byteptrptrty); c = DtoConstSlice(DtoConstSize_t(cd->vtbl.dim), c);
assert(ir->constVtbl);
size_t vtblsz = ir->constVtbl->getNumOperands();
c = DtoConstSlice(DtoConstSize_t(vtblsz), c);
} }
inits.push_back(c); inits.push_back(c);
// interfaces array // interfaces array
IrStruct* irstruct = cd->ir.irStruct; VarDeclaration* intersVar = (VarDeclaration*)cinfo->fields.data[3];
if (!irstruct->interfaceInfos) { const LLType* intersTy = DtoType(intersVar->type);
c = defc->getOperand(5); if (!ir->interfaceInfos)
} c = LLConstant::getNullValue(intersTy);
else { else {
const LLType* t = defc->getOperand(5)->getType()->getContainedType(1); const LLType* t = intersTy->getContainedType(1); // .ptr
c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); c = DtoBitCast(ir->interfaceInfos, t);
size_t iisz = irstruct->interfaceVec.size(); size_t iisz = ir->interfaceVec.size();
c = DtoConstSlice(DtoConstSize_t(iisz), c); c = DtoConstSlice(DtoConstSize_t(iisz), c);
} }
inits.push_back(c); inits.push_back(c);
// base classinfo // base classinfo
if (cd->baseClass && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { // interfaces never get a base , just the interfaces[]
if (cd->baseClass && !cd->isInterfaceDeclaration()) {
DtoDeclareClassInfo(cd->baseClass); DtoDeclareClassInfo(cd->baseClass);
c = cd->baseClass->ir.irStruct->classInfo; c = cd->baseClass->ir.irStruct->classInfo;
assert(c); assert(c);
@ -1536,34 +1522,33 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
} }
else { else {
// null // null
c = defc->getOperand(6); c = LLConstant::getNullValue(DtoType(cinfo->type));
inits.push_back(c); inits.push_back(c);
} }
// destructor // destructor
if (cd->isInterfaceDeclaration() || cd->isAbstract()) { if (cd->isInterfaceDeclaration())
c = defc->getOperand(7); c = LLConstant::getNullValue(voidPtr);
} else
else {
c = build_class_dtor(cd); c = build_class_dtor(cd);
}
inits.push_back(c); inits.push_back(c);
// invariant // invariant
if (cd->inv) { VarDeclaration* invVar = (VarDeclaration*)cinfo->fields.data[6];
const LLType* invTy = DtoType(invVar->type);
if (cd->inv)
{
DtoForceDeclareDsymbol(cd->inv); DtoForceDeclareDsymbol(cd->inv);
c = cd->inv->ir.irFunc->func; c = cd->inv->ir.irFunc->func;
c = llvm::ConstantExpr::getBitCast(c, defc->getOperand(8)->getType()); c = DtoBitCast(c, invTy);
}
else {
c = defc->getOperand(8);
} }
else
c = LLConstant::getNullValue(invTy);
inits.push_back(c); inits.push_back(c);
// uint flags // uint flags
if (cd->isInterfaceDeclaration() || cd->isAbstract()) { if (cd->isInterfaceDeclaration())
c = defc->getOperand(9); c = DtoConstUint(0);
}
else { else {
unsigned flags = build_classinfo_flags(cd); unsigned flags = build_classinfo_flags(cd);
c = DtoConstUint(flags); c = DtoConstUint(flags);
@ -1571,42 +1556,44 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
inits.push_back(c); inits.push_back(c);
// deallocator // deallocator
if (cd->aggDelete) { if (cd->aggDelete)
{
DtoForceDeclareDsymbol(cd->aggDelete); DtoForceDeclareDsymbol(cd->aggDelete);
c = cd->aggDelete->ir.irFunc->func; c = cd->aggDelete->ir.irFunc->func;
c = llvm::ConstantExpr::getBitCast(c, defc->getOperand(10)->getType()); c = DtoBitCast(c, voidPtr);
}
else {
c = defc->getOperand(10);
} }
else
c = LLConstant::getNullValue(voidPtr);
inits.push_back(c); inits.push_back(c);
// offset typeinfo // offset typeinfo
if (cd->isInterfaceDeclaration() || cd->isAbstract()) { VarDeclaration* offTiVar = (VarDeclaration*)cinfo->fields.data[9];
c = defc->getOperand(11); const LLType* offTiTy = DtoType(offTiVar->type);
} if (cd->isInterfaceDeclaration())
else { c = LLConstant::getNullValue(offTiTy);
c = build_offti_array(cd, defc->getOperand(11)); else
} c = build_offti_array(cd, offTiTy);
inits.push_back(c); inits.push_back(c);
// default constructor // default constructor
if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { if (cd->defaultCtor)
{
DtoForceDeclareDsymbol(cd->defaultCtor); DtoForceDeclareDsymbol(cd->defaultCtor);
c = isaConstant(cd->defaultCtor->ir.irFunc->func); c = isaConstant(cd->defaultCtor->ir.irFunc->func);
const LLType* toTy = defc->getOperand(12)->getType(); c = DtoBitCast(c, voidPtr);
c = llvm::ConstantExpr::getBitCast(c, toTy);
}
else {
c = defc->getOperand(12);
} }
else
c = LLConstant::getNullValue(voidPtr);
inits.push_back(c); inits.push_back(c);
#if DMDV2 #if DMDV2
// xgetMembers // xgetMembers
c = defc->getOperand(13); VarDeclaration* xgetVar = (VarDeclaration*)cinfo->fields.data[11];
inits.push_back(c); const LLType* xgetTy = DtoType(xgetVar->type);
// FIXME: fill it out!
inits.push_back( LLConstant::getNullValue(xgetTy) );
#else #else
#endif #endif

View file

@ -138,7 +138,7 @@ LLConstant* DtoConstStructInitializer(StructInitializer* si)
qsort(&vars[0], nvars, sizeof(VarInitPair), &varinit_offset_cmp_func); qsort(&vars[0], nvars, sizeof(VarInitPair), &varinit_offset_cmp_func);
// check integrity // check integrity
// and do error checking, since the frontend does verify static struct initializers // and do error checking, since the frontend does not verify static struct initializers
size_t lastoffset = 0; size_t lastoffset = 0;
size_t lastsize = 0; size_t lastsize = 0;
bool overlap = false; bool overlap = false;

View file

@ -2035,7 +2035,7 @@ DValue* ComExp::toElem(IRState* p)
DValue* u = e1->toElem(p); DValue* u = e1->toElem(p);
LLValue* value = u->getRVal(); LLValue* value = u->getRVal();
LLValue* minusone = llvm::ConstantInt::get(value->getType(), -1, true); LLValue* minusone = llvm::ConstantInt::get(value->getType(), (uint64_t)-1, true);
value = llvm::BinaryOperator::Create(llvm::Instruction::Xor, value, minusone, "tmp", p->scopebb()); value = llvm::BinaryOperator::Create(llvm::Instruction::Xor, value, minusone, "tmp", p->scopebb());
return new DImValue(type, value); return new DImValue(type, value);