diff --git a/dmd2/expression.h b/dmd2/expression.h index 1d28a95d825..2be403943af 100644 --- a/dmd2/expression.h +++ b/dmd2/expression.h @@ -72,7 +72,7 @@ struct elem; #if IN_LLVM struct IRState; -struct DValue; +class DValue; namespace llvm { class Constant; class ConstantInt; diff --git a/dmd2/irstate.h b/dmd2/irstate.h index 7ddbbc1f7e3..4ee24906b41 100644 --- a/dmd2/irstate.h +++ b/dmd2/irstate.h @@ -21,7 +21,7 @@ struct Symbol; struct FuncDeclaration; struct Blockx; #if IN_LLVM -struct DValue; +class DValue; typedef DValue elem; #else struct elem; diff --git a/dmd2/module.h b/dmd2/module.h index b80a756f19f..fe213fc3514 100644 --- a/dmd2/module.h +++ b/dmd2/module.h @@ -29,7 +29,7 @@ class Library; // Back end #if IN_LLVM class Ir; -struct DValue; +class DValue; typedef DValue elem; namespace llvm { class LLVMContext; diff --git a/dmd2/statement.h b/dmd2/statement.h index 7c9766d131c..ede1ee65e88 100644 --- a/dmd2/statement.h +++ b/dmd2/statement.h @@ -75,7 +75,7 @@ namespace llvm struct IRState; struct Blockx; #if IN_LLVM -struct DValue; +class DValue; typedef DValue elem; #endif diff --git a/gen/aa.cpp b/gen/aa.cpp index 67e6a4d4be1..9ab363a2591 100644 --- a/gen/aa.cpp +++ b/gen/aa.cpp @@ -74,7 +74,7 @@ DValue* DtoAAIndex(Loc& loc, Type* type, DValue* aa, DValue* key, bool lvalue) } // cast return value - LLType* targettype = getPtrToType(DtoType(type)); + LLType* targettype = getPtrToType(i1ToI8(DtoType(type))); if (ret->getType() != targettype) ret = DtoBitCast(ret, targettype); diff --git a/gen/aa.h b/gen/aa.h index c0d5929c7a8..ac941451e37 100644 --- a/gen/aa.h +++ b/gen/aa.h @@ -17,7 +17,7 @@ #include "lexer.h" enum TOK; -struct DValue; +class DValue; struct Loc; struct Type; namespace llvm { class Value; } diff --git a/gen/abi.h b/gen/abi.h index ea9798acd6f..abfc014b55d 100644 --- a/gen/abi.h +++ b/gen/abi.h @@ -28,7 +28,7 @@ struct Type; struct TypeFunction; struct IrFuncTyArg; -struct DValue; +class DValue; namespace llvm { diff --git a/gen/arrays.cpp b/gen/arrays.cpp index be54bf68c16..780d9f5501a 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -64,9 +64,7 @@ static LLValue *DtoSlicePtr(DValue *dval) LLStructType* DtoArrayType(Type* arrayTy) { assert(arrayTy->nextOf()); - LLType* elemty = DtoType(arrayTy->nextOf()); - if (elemty == LLType::getVoidTy(gIR->context())) - elemty = LLType::getInt8Ty(gIR->context()); + LLType* elemty = i1ToI8(voidToI8(DtoType(arrayTy->nextOf()))); llvm::Type *elems[] = { DtoSize_t(), getPtrToType(elemty) }; return llvm::StructType::get(gIR->context(), elems, false); @@ -87,10 +85,7 @@ LLArrayType* DtoStaticArrayType(Type* t) TypeSArray* tsa = static_cast(t); Type* tnext = tsa->nextOf(); - LLType* elemty = DtoType(tnext); - if (elemty == LLType::getVoidTy(gIR->context())) - elemty = LLType::getInt8Ty(gIR->context()); - + LLType* elemty = i1ToI8(voidToI8(DtoType(tnext))); return LLArrayType::get(elemty, tsa->dim->toUInteger()); } @@ -291,7 +286,7 @@ LLConstant* DtoConstArrayInitializer(ArrayInitializer* arrinit) // get elem type Type* elemty = arrty->nextOf(); - LLType* llelemty = DtoTypeNotVoid(elemty); + LLType* llelemty = i1ToI8(voidToI8(DtoType(elemty))); // true if array elements differ in type, can happen with array of unions bool mismatch = false; @@ -424,7 +419,7 @@ void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src) LLValue* dstarr = get_slice_ptr(dst,sz1); LLValue* srcarr = DtoBitCast(DtoArrayPtr(src), getVoidPtrType()); - LLType* arrayelemty = DtoTypeNotVoid(src->getType()->nextOf()->toBasetype()); + LLType* arrayelemty = voidToI8(DtoType(src->getType()->nextOf()->toBasetype())); LLValue* sz2 = gIR->ir->CreateMul(DtoConstSize_t(getTypePaddedSize(arrayelemty)), DtoArrayLen(src), "tmp"); copySlice(dstarr, sz1, srcarr, sz2); @@ -939,7 +934,7 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to) Logger::cout() << "to array" << '\n'; LLType* ptrty = DtoArrayType(totype)->getContainedType(1); - LLType* ety = DtoTypeNotVoid(fromtype->nextOf()); + LLType* ety = voidToI8(DtoType(fromtype->nextOf())); if (fromtype->ty == Tsarray) { LLValue* uval = u->getRVal(); diff --git a/gen/arrays.h b/gen/arrays.h index 391eda3236a..a78d146d590 100644 --- a/gen/arrays.h +++ b/gen/arrays.h @@ -18,8 +18,8 @@ #include "gen/llvm.h" struct ArrayInitializer; -struct DSliceValue; -struct DValue; +class DSliceValue; +class DValue; struct Expression; struct Loc; struct Type; diff --git a/gen/classes.cpp b/gen/classes.cpp index 1bd326d773f..d915c1cdbaf 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -497,7 +497,7 @@ LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd) } // cast it to the right type - val = DtoBitCast(val, getPtrToType(DtoType(vd->type))); + val = DtoBitCast(val, getPtrToType(i1ToI8(DtoType(vd->type)))); if (Logger::enabled()) Logger::cout() << "value: " << *val << '\n'; diff --git a/gen/complex.h b/gen/complex.h index 4e1eaf1e58d..17e5163f1ed 100644 --- a/gen/complex.h +++ b/gen/complex.h @@ -17,7 +17,7 @@ #include "lexer.h" #include "longdouble.h" -struct DValue; +class DValue; struct Loc; struct Type; namespace llvm diff --git a/gen/declarations.cpp b/gen/declarations.cpp index 8fc3c22e7ae..dc0f07ed192 100644 --- a/gen/declarations.cpp +++ b/gen/declarations.cpp @@ -172,7 +172,7 @@ void VarDeclaration::codegen(Ir* p) // this->ir.irGlobal->value!), and in case we also do an initializer // with a different type later, swap it out and replace any existing // uses with bitcasts to the previous type. - llvm::GlobalVariable* gvar = createGlobal(DtoType(type), isLLConst, + llvm::GlobalVariable* gvar = createGlobal(i1ToI8(DtoType(type)), isLLConst, llLinkage, llName, isThreadlocal()); this->ir.irGlobal->value = gvar; @@ -206,7 +206,7 @@ void VarDeclaration::codegen(Ir* p) ir.irGlobal->constInit = initVal; gvar->setInitializer(initVal); - // Also set up the debug info. + // Also set up the edbug info. DtoDwarfGlobalVariable(gvar, this); } diff --git a/gen/dvalue.cpp b/gen/dvalue.cpp index 160bb4ce5d7..4a98d6e3e1e 100644 --- a/gen/dvalue.cpp +++ b/gen/dvalue.cpp @@ -18,18 +18,36 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// +static bool checkVarValueType(LLType* t, bool extraDeref) +{ + if (extraDeref) + { + llvm::PointerType* pt = llvm::dyn_cast(t); + if (!pt) return false; + + t = pt->getElementType(); + } + + llvm::PointerType* pt = llvm::dyn_cast(t); + if (!pt) return false; + + // bools should not be stored as i1 any longer. + if (pt->getElementType() == llvm::Type::getInt1Ty(gIR->context())) + return false; + + return true; +} + DVarValue::DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue) : DValue(t), var(vd), val(llvmValue) { - assert(isaPointer(llvmValue)); - assert(!isSpecialRefVar(vd) || - isaPointer(isaPointer(llvmValue)->getElementType())); + assert(checkVarValueType(llvmValue->getType(), isSpecialRefVar(vd))); } DVarValue::DVarValue(Type* t, LLValue* llvmValue) : DValue(t), var(0), val(llvmValue) { - assert(isaPointer(llvmValue)); + assert(checkVarValueType(llvmValue->getType(), false)); } LLValue* DVarValue::getLVal() @@ -43,15 +61,24 @@ LLValue* DVarValue::getLVal() LLValue* DVarValue::getRVal() { assert(val); - Type* bt = type->toBasetype(); - LLValue* tmp = val; + llvm::Value* storage = val; if (var && isSpecialRefVar(var)) - tmp = DtoLoad(tmp); + storage = DtoLoad(storage); + + if (DtoIsPassedByRef(type->toBasetype())) + return storage; + + llvm::Value* rawValue = DtoLoad(storage); + + if (type->toBasetype()->ty == Tbool) + { + assert(rawValue->getType() == llvm::Type::getInt8Ty(gIR->context())); + return gIR->ir->CreateTrunc(rawValue, + llvm::Type::getInt1Ty(gIR->context())); + } - if (DtoIsPassedByRef(bt)) - return tmp; - return DtoLoad(tmp); + return rawValue; } LLValue* DVarValue::getRefStorage() diff --git a/gen/dvalue.h b/gen/dvalue.h index 03856249dc2..b9a09d4c651 100644 --- a/gen/dvalue.h +++ b/gen/dvalue.h @@ -32,19 +32,21 @@ namespace llvm class Constant; } -struct DImValue; -struct DConstValue; -struct DNullValue; -struct DVarValue; -struct DFieldValue; -struct DFuncValue; -struct DSliceValue; +class DImValue; +class DConstValue; +class DNullValue; +class DVarValue; +class DFieldValue; +class DFuncValue; +class DSliceValue; // base class for d-values -struct DValue : Object +class DValue { +public: Type* type; DValue(Type* ty) : type(ty) {} + virtual ~DValue() {} Type*& getType() { assert(type); return type; } @@ -60,6 +62,7 @@ struct DValue : Object virtual DFieldValue* isField() { return NULL; } virtual DSliceValue* isSlice() { return NULL; } virtual DFuncValue* isFunc() { return NULL; } + protected: DValue() {} DValue(const DValue&) { } @@ -67,42 +70,44 @@ struct DValue : Object }; // immediate d-value -struct DImValue : DValue +class DImValue : public DValue { - llvm::Value* val; - +public: DImValue(Type* t, llvm::Value* v) : DValue(t), val(v) { } virtual llvm::Value* getRVal() { assert(val); return val; } virtual DImValue* isIm() { return this; } + +protected: + llvm::Value* val; }; // constant d-value -struct DConstValue : DValue +class DConstValue : public DValue { - llvm::Constant* c; - +public: DConstValue(Type* t, llvm::Constant* con) : DValue(t), c(con) {} virtual llvm::Value* getRVal(); virtual DConstValue* isConst() { return this; } + + llvm::Constant* c; }; // null d-value -struct DNullValue : DConstValue +class DNullValue : public DConstValue { +public: DNullValue(Type* t, llvm::Constant* con) : DConstValue(t,con) {} virtual DNullValue* isNull() { return this; } }; // variable d-value -struct DVarValue : DValue +class DVarValue : public DValue { - VarDeclaration* var; - llvm::Value* val; - +public: DVarValue(Type* t, VarDeclaration* vd, llvm::Value* llvmValue); DVarValue(Type* t, llvm::Value* llvmValue); @@ -115,40 +120,47 @@ struct DVarValue : DValue virtual llvm::Value* getRefStorage(); virtual DVarValue* isVar() { return this; } + + VarDeclaration* var; +protected: + llvm::Value* val; }; // field d-value -struct DFieldValue : DVarValue +class DFieldValue : public DVarValue { +public: DFieldValue(Type* t, llvm::Value* llvmValue) : DVarValue(t, llvmValue) {} virtual DFieldValue* isField() { return this; } }; // slice d-value -struct DSliceValue : DValue +class DSliceValue : public DValue { - llvm::Value* len; - llvm::Value* ptr; - +public: DSliceValue(Type* t, llvm::Value* l, llvm::Value* p) : DValue(t), len(l), ptr(p) {} virtual llvm::Value* getRVal(); virtual DSliceValue* isSlice() { return this; } + + llvm::Value* len; + llvm::Value* ptr; }; // function d-value -struct DFuncValue : DValue +class DFuncValue : public DValue { - FuncDeclaration* func; - llvm::Value* val; - llvm::Value* vthis; - +public: DFuncValue(FuncDeclaration* fd, llvm::Value* v, llvm::Value* vt = 0); virtual llvm::Value* getRVal(); virtual DFuncValue* isFunc() { return this; } + + FuncDeclaration* func; + llvm::Value* val; + llvm::Value* vthis; }; #endif // LDC_GEN_DVALUE_H diff --git a/gen/functions.cpp b/gen/functions.cpp index bfca527f222..20759dd48d6 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -1059,7 +1059,7 @@ void DtoDefineFunction(FuncDeclaration* fd) if (lazy) argt = irparam->value->getType(); else - argt = DtoType(vd->type); + argt = i1ToI8(DtoType(vd->type)); LLValue* mem = DtoRawAlloca(argt, 0, vd->ident->toChars()); // let the abi transform the argument back first diff --git a/gen/functions.h b/gen/functions.h index f2a2c403dca..5fd2b65b99a 100644 --- a/gen/functions.h +++ b/gen/functions.h @@ -16,7 +16,7 @@ #include "mars.h" -struct DValue; +class DValue; struct Expression; struct FuncDeclaration; struct IRAsmBlock; diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index d952093495f..0417c2c3379 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -49,7 +49,7 @@ LLValue* DtoNew(Type* newtype) // call runtime allocator LLValue* mem = gIR->CreateCallOrInvoke(fn, ti, ".gc_mem").getInstruction(); // cast - return DtoBitCast(mem, getPtrToType(DtoType(newtype)), ".gc_mem"); + return DtoBitCast(mem, getPtrToType(i1ToI8(DtoType(newtype))), ".gc_mem"); } void DtoDeleteMemory(LLValue* ptr) @@ -113,7 +113,7 @@ void DtoDeleteArray(DValue* arr) llvm::AllocaInst* DtoAlloca(Type* type, const char* name) { - LLType* lltype = DtoType(type); + LLType* lltype = i1ToI8(DtoType(type)); llvm::AllocaInst* ai = new llvm::AllocaInst(lltype, name, gIR->topallocapoint()); ai->setAlignment(type->alignsize()); return ai; @@ -373,13 +373,12 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op, bool canSkipPostblit) Type* t = lhs->getType()->toBasetype(); Type* t2 = rhs->getType()->toBasetype(); - if (t->ty == Tvoid) { - // This is a frontend regression in DMD 2.061; should be removed once - // DMD Bugzilla issue 9268 is fixed. - error(loc, "Cannot assign values of type void."); - } + assert(t->ty != Tvoid && "Cannot assign values of type void."); - if (t->ty == Tstruct) { + if (t->ty == Tbool) { + DtoStoreZextI8(rhs->getRVal(), lhs->getLVal()); + } + else if (t->ty == Tstruct) { llvm::Value* src = rhs->getRVal(); llvm::Value* dst = lhs->getLVal(); @@ -627,7 +626,10 @@ DValue* DtoCastPtr(Loc& loc, DValue* val, Type* to) if (totype->ty == Tpointer || totype->ty == Tclass) { LLValue* src = val->getRVal(); if (Logger::enabled()) - Logger::cout() << "src: " << *src << "to type: " << *tolltype << '\n'; + { + Logger::cout() << "src: " << *src << '\n'; + Logger::cout() << "to type: " << *tolltype << '\n'; + } rval = DtoBitCast(src, tolltype); } else if (totype->ty == Tbool) { @@ -1060,9 +1062,9 @@ void DtoVarDeclaration(VarDeclaration* vd) } Type* type = isSpecialRefVar(vd) ? vd->type->pointerTo() : vd->type; - LLType* lltype = DtoType(type); llvm::Value* allocainst; + LLType* lltype = DtoType(type); if(gDataLayout->getTypeSizeInBits(lltype) == 0) allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype)); else @@ -1302,7 +1304,7 @@ LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init) else if (init->isVoidInitializer()) { Logger::println("const void initializer"); - LLType* ty = DtoTypeNotVoid(type); + LLType* ty = voidToI8(DtoType(type)); _init = LLConstant::getNullValue(ty); } else { @@ -1370,14 +1372,14 @@ LLConstant* DtoConstExpInit(Loc loc, Type* targetType, Expression* exp) Type* expBase = stripModifiers(exp->type->toBasetype())->merge(); Type* targetBase = stripModifiers(targetType->toBasetype())->merge(); - if (expBase->equals(targetBase)) + if (expBase->equals(targetBase) && targetBase->ty != Tbool) { Logger::println("Matching D types, nothing left to do."); return val; } llvm::Type* llType = val->getType(); - llvm::Type* targetLLType = DtoType(targetBase); + llvm::Type* targetLLType = i1ToI8(DtoType(targetBase)); if (llType == targetLLType) { Logger::println("Matching LLVM types, ignoring frontend glitch."); diff --git a/gen/nested.cpp b/gen/nested.cpp index eaee88d3501..45e548025f1 100644 --- a/gen/nested.cpp +++ b/gen/nested.cpp @@ -372,14 +372,14 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) { if (lazy) types.push_back(irparam->value->getType()->getContainedType(0)); else - types.push_back(DtoType(vd->type)); + types.push_back(i1ToI8(DtoType(vd->type))); } else { types.push_back(irparam->value->getType()); } } else if (isSpecialRefVar(vd)) { types.push_back(DtoType(vd->type->pointerTo())); } else { - types.push_back(DtoType(vd->type)); + types.push_back(i1ToI8(DtoType(vd->type))); } if (Logger::enabled()) { Logger::cout() << "Nested var '" << vd->toChars() << diff --git a/gen/rttibuilder.cpp b/gen/rttibuilder.cpp index cd12c7cb313..0c8ccde5cff 100644 --- a/gen/rttibuilder.cpp +++ b/gen/rttibuilder.cpp @@ -95,12 +95,12 @@ void RTTIBuilder::push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* ma void RTTIBuilder::push_array(llvm::Constant * CI, uint64_t dim, Type* valtype, Dsymbol * mangle_sym) { - std::string tmpStr(valtype->arrayOf()->toChars()); - tmpStr.erase( remove( tmpStr.begin(), tmpStr.end(), '[' ), tmpStr.end() ); - tmpStr.erase( remove( tmpStr.begin(), tmpStr.end(), ']' ), tmpStr.end() ); - tmpStr.append("arr"); + std::string tmpStr(valtype->arrayOf()->toChars()); + tmpStr.erase( remove( tmpStr.begin(), tmpStr.end(), '[' ), tmpStr.end() ); + tmpStr.erase( remove( tmpStr.begin(), tmpStr.end(), ']' ), tmpStr.end() ); + tmpStr.append("arr"); - std::string initname(mangle_sym?mangle_sym->mangle():".ldc"); + std::string initname(mangle_sym?mangle_sym->mangle():".ldc"); initname.append(".rtti."); initname.append(tmpStr); initname.append(".data"); diff --git a/gen/structs.cpp b/gen/structs.cpp index c5a57a3caa9..353010a1eca 100644 --- a/gen/structs.cpp +++ b/gen/structs.cpp @@ -138,7 +138,7 @@ LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd) } // cast it to the right type - val = DtoBitCast(val, getPtrToType(DtoType(vd->type))); + val = DtoBitCast(val, getPtrToType(i1ToI8(DtoType(vd->type)))); if (Logger::enabled()) Logger::cout() << "value: " << *val << '\n'; diff --git a/gen/structs.h b/gen/structs.h index 5af27956d20..85f51578351 100644 --- a/gen/structs.h +++ b/gen/structs.h @@ -17,7 +17,7 @@ #include "lexer.h" #include -struct DValue; +class DValue; struct StructDeclaration; struct StructInitializer; struct Type; diff --git a/gen/tocall.cpp b/gen/tocall.cpp index 35afc3536ff..fb06fc090b1 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -246,7 +246,7 @@ void DtoBuildDVarArgList(std::vector& args, { Expression* argexp = static_cast(arguments->data[i]); LLValue* argdst = DtoGEPi(mem,0,k); - argdst = DtoBitCast(argdst, getPtrToType(DtoType(argexp->type))); + argdst = DtoBitCast(argdst, getPtrToType(i1ToI8(DtoType(argexp->type)))); DtoVariadicArgument(argexp, argdst); } diff --git a/gen/toir.cpp b/gen/toir.cpp index 3a6e3302c8e..831c65a2bab 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -215,7 +215,7 @@ DValue* VarExp::toElem(IRState* p) if (isGlobal) { - llvm::Type* expectedType = DtoType(type->pointerTo()); + llvm::Type* expectedType = llvm::PointerType::getUnqual(i1ToI8(DtoType(type))); // The type of globals is determined by their initializer, so // we might need to cast. Make sure that the type sizes fit - // '==' instead of '<=' should probably work as well. @@ -438,7 +438,7 @@ DValue* StringExp::toElem(IRState* p) Type* dtype = type->toBasetype(); Type* cty = dtype->nextOf()->toBasetype(); - LLType* ct = DtoTypeNotVoid(cty); + LLType* ct = voidToI8(DtoType(cty)); //printf("ct = %s\n", type->nextOf()->toChars()); LLArrayType* at = LLArrayType::get(ct,len+1); @@ -496,7 +496,7 @@ LLConstant* StringExp::toConstElem(IRState* p) bool nullterm = (t->ty != Tsarray); size_t endlen = nullterm ? len+1 : len; - LLType* ct = DtoTypeNotVoid(cty); + LLType* ct = voidToI8(DtoType(cty)); LLArrayType* at = LLArrayType::get(ct,endlen); LLConstant* _init; @@ -2496,7 +2496,7 @@ DValue* CondExp::toElem(IRState* p) LLValue* resval = DtoAlloca(dtype,"condtmp"); dvv = new DVarValue(type, resval); } else { - dvv = new DConstValue(type, getNullValue(DtoTypeNotVoid(dtype))); + dvv = new DConstValue(type, getNullValue(voidToI8(DtoType(dtype)))); } llvm::BasicBlock* oldend = p->scopeend(); @@ -2726,7 +2726,7 @@ DValue* ArrayLiteralExp::toElem(IRState* p) Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n"; // llvm storage type - LLType* llElemType = DtoTypeNotVoid(elemType); + LLType* llElemType = voidToI8(DtoType(elemType)); LLType* llStoType = LLArrayType::get(llElemType, len); if (Logger::enabled()) Logger::cout() << "llvm storage type: '" << *llStoType << "'\n"; @@ -2785,7 +2785,7 @@ LLConstant* ArrayLiteralExp::toConstElem(IRState* p) Type* elemt = bt->nextOf(); // build llvm array type - LLArrayType* arrtype = LLArrayType::get(DtoTypeNotVoid(elemt), elements->dim); + LLArrayType* arrtype = LLArrayType::get(i1ToI8(voidToI8(DtoType(elemt))), elements->dim); // dynamic arrays can occur here as well ... bool dyn = (bt->ty != Tsarray); @@ -3190,7 +3190,7 @@ DValue* TupleExp::toElem(IRState *p) for (size_t i = 0; i < exps->dim; i++) { Expression *el = static_cast(exps->data[i]); - types.push_back(DtoTypeNotVoid(el->type)); + types.push_back(voidToI8(DtoType(el->type))); } LLValue *val = DtoRawAlloca(LLStructType::get(gIR->context(), types),0, "tuple"); for (size_t i = 0; i < exps->dim; i++) diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 3917478a94f..049cc2de298 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -246,12 +246,20 @@ LLType* DtoStructTypeFromArguments(Arguments* arguments) ////////////////////////////////////////////////////////////////////////////////////////// -LLType* DtoTypeNotVoid(Type* t) +LLType* voidToI8(LLType* t) { - LLType* lt = DtoType(t); - if (lt == LLType::getVoidTy(gIR->context())) + if (t == LLType::getVoidTy(gIR->context())) return LLType::getInt8Ty(gIR->context()); - return lt; + return t; +} + +////////////////////////////////////////////////////////////////////////////////////////// + +LLType* i1ToI8(LLType* t) +{ + if (t == LLType::getInt1Ty(gIR->context())) + return LLType::getInt8Ty(gIR->context()); + return t; } ////////////////////////////////////////////////////////////////////////////////////////// @@ -717,15 +725,27 @@ LLValue* DtoAlignedLoad(LLValue* src, const char* name) void DtoStore(LLValue* src, LLValue* dst) { -// if (Logger::enabled()) -// Logger::cout() << "storing " << *src << " into " << *dst << '\n'; + assert(src->getType() != llvm::Type::getInt1Ty(gIR->context()) && + "Should store bools as i8 instead of i1."); gIR->ir->CreateStore(src,dst); - //st->setVolatile(gIR->func()->inVolatile); +} + +void DtoStoreZextI8(LLValue* src, LLValue* dst) +{ + if (src->getType() == llvm::Type::getInt1Ty(gIR->context())) + { + llvm::Type* i8 = llvm::Type::getInt8Ty(gIR->context()); + assert(dst->getType()->getContainedType(0) == i8); + src = gIR->ir->CreateZExt(src, i8); + } + gIR->ir->CreateStore(src, dst); } // Like DtoStore, but the pointer is guaranteed to be aligned appropriately for the type. void DtoAlignedStore(LLValue* src, LLValue* dst) { + assert(src->getType() != llvm::Type::getInt1Ty(gIR->context()) && + "Should store bools as i8 instead of i1."); llvm::StoreInst* st = gIR->ir->CreateStore(src,dst); st->setAlignment(getABITypeAlign(src->getType())); } diff --git a/gen/tollvm.h b/gen/tollvm.h index 4f473e45bb6..8f9bbd927db 100644 --- a/gen/tollvm.h +++ b/gen/tollvm.h @@ -25,9 +25,8 @@ // D->LLVM type handling stuff LLType* DtoType(Type* t); - -// same as DtoType except it converts 'void' to 'i8' -LLType* DtoTypeNotVoid(Type* t); +LLType* voidToI8(LLType* t); +LLType* i1ToI8(LLType* t); // returns true is the type must be passed by pointer bool DtoIsPassedByRef(Type* type); @@ -82,6 +81,7 @@ LLConstant* DtoConstBool(bool); LLValue* DtoLoad(LLValue* src, const char* name=0); LLValue* DtoAlignedLoad(LLValue* src, const char* name=0); void DtoStore(LLValue* src, LLValue* dst); +void DtoStoreZextI8(LLValue* src, LLValue* dst); void DtoAlignedStore(LLValue* src, LLValue* dst); LLValue* DtoBitCast(LLValue* v, LLType* t, const char* name=0); LLConstant* DtoBitCast(LLConstant* v, LLType* t); diff --git a/ir/irfuncty.cpp b/ir/irfuncty.cpp index be66f086cbb..4c4ca23d93b 100644 --- a/ir/irfuncty.cpp +++ b/ir/irfuncty.cpp @@ -96,5 +96,5 @@ void IrFuncTy::getParam(Type* dty, size_t idx, DValue* val, llvm::Value* lval) return; } - DtoStore(val->getRVal(), lval); + DtoStoreZextI8(val->getRVal(), lval); } diff --git a/ir/irfuncty.h b/ir/irfuncty.h index 30c2cdf21c2..43a468fad71 100644 --- a/ir/irfuncty.h +++ b/ir/irfuncty.h @@ -26,7 +26,7 @@ #include -struct DValue; +class DValue; struct ABIRewrite; namespace llvm { class Type; diff --git a/ir/irtype.cpp b/ir/irtype.cpp index f73c71f6774..a155064d444 100644 --- a/ir/irtype.cpp +++ b/ir/irtype.cpp @@ -188,9 +188,9 @@ IrTypePointer* IrTypePointer::get(Type* dt) } } - elemType = DtoTypeNotVoid(dt->nextOf()); + elemType = i1ToI8(voidToI8(DtoType(dt->nextOf()))); - // DtoTypeNotVoid could have already created the same type, e.g. for + // DtoType could have already created the same type, e.g. for // dt == Node* in struct Node { Node* n; }. if (dt->irtype) return dt->irtype->isPointer(); @@ -226,9 +226,7 @@ llvm::Type * IrTypeSArray::sarray2llvm(Type * t) assert(t->ty == Tsarray && "not static array type"); TypeSArray* tsa = static_cast(t); uint64_t dim = static_cast(tsa->dim->toUInteger()); - LLType* elemType = DtoType(t->nextOf()); - if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext())) - elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext()); + LLType* elemType = i1ToI8(voidToI8(DtoType(t->nextOf()))); return llvm::ArrayType::get(elemType, dim); } @@ -248,7 +246,7 @@ IrTypeArray* IrTypeArray::get(Type* dt) assert(!dt->irtype); assert(dt->ty == Tarray && "not dynamic array type"); - LLType* elemType = DtoTypeNotVoid(dt->nextOf()); + LLType* elemType = i1ToI8(voidToI8(DtoType(dt->nextOf()))); // Could have already built the type as part of a struct forward reference, // just as for pointers. @@ -289,9 +287,7 @@ llvm::Type* IrTypeVector::vector2llvm(Type* dt) assert(tv->basetype->ty == Tsarray); TypeSArray* tsa = static_cast(tv->basetype); uint64_t dim = static_cast(tsa->dim->toUInteger()); - LLType* elemType = DtoType(tsa->next); - if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext())) - elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext()); + LLType* elemType = voidToI8(DtoType(tsa->next)); return llvm::VectorType::get(elemType, dim); } diff --git a/ir/irtypeclass.cpp b/ir/irtypeclass.cpp index e29aa7d428c..7de395330b4 100644 --- a/ir/irtypeclass.cpp +++ b/ir/irtypeclass.cpp @@ -169,7 +169,7 @@ void IrTypeClass::addBaseClassData( } // add default type - defaultTypes.push_back(DtoType(vd->type)); + defaultTypes.push_back(DtoType(vd->type)); // @@@ i1ToI8?! // advance offset to right past this field offset = vd->offset + vd->type->size();