mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-07-22 07:05:22 +02:00
Different fixes for d2
This commit is contained in:
@@ -129,8 +129,12 @@ DValue* DtoAAIn(Loc& loc, Type* type, DValue* aa, DValue* key)
|
||||
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
|
||||
|
||||
// pkey param
|
||||
#if DMDV1
|
||||
LLValue* pkey = makeLValue(loc, key);
|
||||
pkey = DtoBitCast(pkey, funcTy->getParamType(2));
|
||||
#else
|
||||
LLValue* pkey = getNullValue(getVoidPtrType());
|
||||
#endif
|
||||
|
||||
// call runtime
|
||||
LLValue* ret = gIR->CreateCallOrInvoke3(func, aaval, keyti, pkey, "aa.in").getInstruction();
|
||||
|
||||
@@ -209,12 +209,20 @@ void DtoArrayInit(Loc& loc, DValue* array, DValue* value)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr)
|
||||
void DtoSetArray(DValue* array, LLValue* dim, LLValue* ptr)
|
||||
{
|
||||
Logger::println("SetArray");
|
||||
LLValue *arr = array->getLVal();
|
||||
assert(isaStruct(arr->getType()->getContainedType(0)));
|
||||
#if 1
|
||||
DtoStore(dim, DtoGEPi(arr,0,0));
|
||||
DtoStore(ptr, DtoGEPi(arr,0,1));
|
||||
#else
|
||||
DSliceValue *slice = DtoResizeDynArray(array->type, array, dim);
|
||||
DtoMemCpy(DtoArrayPtr(array), ptr, dim);
|
||||
DtoStore(dim, DtoGEPi(arr,0,0));
|
||||
DtoStore(slice->ptr, DtoGEPi(arr,0,1));
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -498,7 +506,7 @@ DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim)
|
||||
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, LLValue* newdim)
|
||||
{
|
||||
Logger::println("DtoResizeDynArray : %s", arrayType->toChars());
|
||||
LOG_SCOPE;
|
||||
@@ -516,7 +524,7 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim)
|
||||
|
||||
LLSmallVector<LLValue*,4> args;
|
||||
args.push_back(DtoTypeInfoOf(arrayType));
|
||||
args.push_back(newdim->getRVal());
|
||||
args.push_back(newdim);
|
||||
args.push_back(DtoArrayLen(array));
|
||||
|
||||
LLValue* arrPtr = DtoArrayPtr(array);
|
||||
@@ -528,7 +536,7 @@ DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim)
|
||||
if (newptr->getType() != arrPtr->getType())
|
||||
newptr = DtoBitCast(newptr, arrPtr->getType(), ".gc_mem");
|
||||
|
||||
return new DSliceValue(arrayType, newdim->getRVal(), newptr);
|
||||
return new DSliceValue(arrayType, newdim, newptr);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -544,7 +552,7 @@ void DtoCatAssignElement(Loc& loc, Type* arrayType, DValue* array, Expression* e
|
||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendcT");
|
||||
LLSmallVector<LLValue*,3> args;
|
||||
args.push_back(DtoTypeInfoOf(arrayType));
|
||||
args.push_back(DtoBitCast(array->getLVal(), getVoidPtrType()));
|
||||
args.push_back(DtoBitCast(array->getLVal(), fn->getFunctionType()->getParamType(1)));
|
||||
args.push_back(DtoBitCast(valueToAppend, getVoidPtrType()));
|
||||
|
||||
gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray");
|
||||
@@ -565,7 +573,7 @@ DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp)
|
||||
res = gIR->ir->CreateAdd(len1,len2,"tmp");
|
||||
|
||||
DValue* newdim = new DImValue(Type::tsize_t, res);
|
||||
DSliceValue* slice = DtoResizeDynArray(arr->getType(), arr, newdim);
|
||||
DSliceValue* slice = DtoResizeDynArray(arr->getType(), arr, newdim->getRVal());
|
||||
|
||||
src1 = slice->ptr;
|
||||
src2 = DtoArrayPtr(e);
|
||||
@@ -734,7 +742,7 @@ static LLValue* DtoArrayEqCmp_impl(Loc& loc, const char* func, DValue* l, DValue
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
LLValue* DtoArrayEquals(Loc& loc, TOK op, DValue* l, DValue* r)
|
||||
{
|
||||
LLValue* res = DtoArrayEqCmp_impl(loc, "_adEq", l, r, true);
|
||||
LLValue* res = DtoArrayEqCmp_impl(loc, _adEq, l, r, true);
|
||||
res = gIR->ir->CreateICmpNE(res, DtoConstInt(0), "tmp");
|
||||
if (op == TOKnotequal)
|
||||
res = gIR->ir->CreateNot(res, "tmp");
|
||||
@@ -1007,6 +1015,12 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to)
|
||||
LLConstant* nul = getNullPtr(ptr->getType());
|
||||
rval = gIR->ir->CreateICmpNE(ptr, nul, "tmp");
|
||||
}
|
||||
else if (fromtype->nextOf()->ty == Tvoid) {
|
||||
// TODO:
|
||||
rval = DtoArrayPtr(u);
|
||||
rval = DtoBitCast(rval, getPtrToType(tolltype));
|
||||
rval = DtoLoad(rval);
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
@@ -17,12 +17,12 @@ void DtoArrayCopyToSlice(DSliceValue* dst, DValue* src);
|
||||
|
||||
void DtoArrayInit(Loc& loc, DValue* array, DValue* value);
|
||||
void DtoArrayAssign(LLValue* l, LLValue* r);
|
||||
void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr);
|
||||
void DtoSetArray(DValue* array, LLValue* dim, LLValue* ptr);
|
||||
void DtoSetArrayToNull(LLValue* v);
|
||||
|
||||
DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool defaultInit=true);
|
||||
DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size_t ndims, bool defaultInit=true);
|
||||
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim);
|
||||
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, llvm::Value* newdim);
|
||||
|
||||
void DtoCatAssignElement(Loc& loc, Type* type, DValue* arr, Expression* exp);
|
||||
DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp);
|
||||
|
||||
@@ -145,7 +145,7 @@ DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp)
|
||||
// default allocator
|
||||
else
|
||||
{
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocclass");
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, _d_allocclass);
|
||||
LLConstant* ci = DtoBitCast(tc->sym->ir.irStruct->getClassInfoSymbol(), DtoType(ClassDeclaration::classinfo->type));
|
||||
mem = gIR->CreateCallOrInvoke(fn, ci, ".newclass_gc_alloc").getInstruction();
|
||||
mem = DtoBitCast(mem, DtoType(tc), ".newclass_gc");
|
||||
@@ -686,7 +686,8 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
||||
// void *defaultConstructor;
|
||||
// version(D_Version2)
|
||||
// const(MemberInfo[]) function(string) xgetMembers;
|
||||
// TypeInfo typeinfo; // since dmd 1.045
|
||||
// else
|
||||
// TypeInfo typeinfo; // since dmd 1.045
|
||||
// }
|
||||
|
||||
Logger::println("DtoDefineClassInfo(%s)", cd->toChars());
|
||||
@@ -700,11 +701,7 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
||||
|
||||
ClassDeclaration* cinfo = ClassDeclaration::classinfo;
|
||||
|
||||
#if DMDV2
|
||||
if (cinfo->fields.dim != 13)
|
||||
#else
|
||||
if (cinfo->fields.dim != 12)
|
||||
#endif
|
||||
{
|
||||
error("object.d ClassInfo class is incorrect");
|
||||
fatal();
|
||||
@@ -798,7 +795,8 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
||||
#endif // GENERATE_OFFTI
|
||||
|
||||
// default constructor
|
||||
b.push_funcptr(cd->defaultCtor, Type::tvoid->pointerTo());
|
||||
VarDeclaration* defConstructorVar = (VarDeclaration*)cinfo->fields.data[10];
|
||||
b.push_funcptr(cd->defaultCtor, defConstructorVar->type);
|
||||
|
||||
#if DMDV2
|
||||
|
||||
@@ -808,11 +806,13 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
||||
// FIXME: fill it out!
|
||||
b.push_null(xgetVar->type);
|
||||
|
||||
#endif
|
||||
#else
|
||||
|
||||
// typeinfo - since 1.045
|
||||
b.push_typeinfo(cd->type);
|
||||
|
||||
#endif
|
||||
|
||||
/*size_t n = inits.size();
|
||||
for (size_t i=0; i<n; ++i)
|
||||
{
|
||||
|
||||
@@ -133,7 +133,7 @@ void VarDeclaration::codegen(Ir* p)
|
||||
llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this);
|
||||
std::string _name(mangle());
|
||||
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(*gIR->module,_type,_isconst,_linkage,NULL,_name);
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(*gIR->module,_type,_isconst,_linkage,NULL,_name,0,isThreadlocal());
|
||||
this->ir.irGlobal->value = gvar;
|
||||
|
||||
// set the alignment
|
||||
|
||||
@@ -76,6 +76,9 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest
|
||||
if (thistype)
|
||||
{
|
||||
bool toref = (thistype->toBasetype()->ty == Tstruct);
|
||||
#if STRUCTTHISREF
|
||||
fty.is_arg_this_ref = toref;
|
||||
#endif
|
||||
fty.arg_this = new IrFuncTyArg(thistype, toref);
|
||||
lidx++;
|
||||
}
|
||||
@@ -475,8 +478,6 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
else // fall back to C, it should be the right thing to do
|
||||
func->setCallingConv(llvm::CallingConv::C);
|
||||
|
||||
fdecl->ir.irFunc->func = func;
|
||||
|
||||
// parameter attributes
|
||||
if (!fdecl->isIntrinsic()) {
|
||||
set_param_attrs(f, func, fdecl);
|
||||
@@ -607,7 +608,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
||||
|
||||
Type* t = fd->type->toBasetype();
|
||||
TypeFunction* f = (TypeFunction*)t;
|
||||
assert(f->irtype);
|
||||
// assert(f->irtype);
|
||||
|
||||
llvm::Function* func = fd->ir.irFunc->func;
|
||||
const llvm::FunctionType* functype = func->getFunctionType();
|
||||
@@ -665,7 +666,10 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
||||
|
||||
LLValue* thismem = DtoRawAlloca(thisvar->getType(), 0, "this"); // FIXME: align?
|
||||
DtoStore(thisvar, thismem);
|
||||
irfunction->thisArg = thismem;
|
||||
if (f->fty.is_arg_this_ref)
|
||||
irfunction->thisArg = DtoLoad(thismem, "thisRef");
|
||||
else
|
||||
irfunction->thisArg = thismem;
|
||||
|
||||
assert(!fd->vthis->ir.irLocal);
|
||||
fd->vthis->ir.irLocal = new IrLocal(fd->vthis);
|
||||
|
||||
@@ -378,8 +378,8 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs)
|
||||
}
|
||||
// rhs is slice
|
||||
else if (DSliceValue* s = rhs->isSlice()) {
|
||||
assert(s->getType()->toBasetype() == lhs->getType()->toBasetype());
|
||||
DtoSetArray(lhs->getLVal(),DtoArrayLen(s),DtoArrayPtr(s));
|
||||
//assert(s->getType()->toBasetype() == lhs->getType()->toBasetype());
|
||||
DtoSetArray(lhs,DtoArrayLen(s),DtoArrayPtr(s));
|
||||
}
|
||||
// null
|
||||
else if (rhs->isNull()) {
|
||||
@@ -391,7 +391,7 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs)
|
||||
}
|
||||
// some implicitly converting ref assignment
|
||||
else {
|
||||
DtoSetArray(lhs->getLVal(), DtoArrayLen(rhs), DtoArrayPtr(rhs));
|
||||
DtoSetArray(lhs, DtoArrayLen(rhs), DtoArrayPtr(rhs));
|
||||
}
|
||||
}
|
||||
else if (t->ty == Tsarray) {
|
||||
@@ -1271,12 +1271,7 @@ void DtoAnnotation(const char* str)
|
||||
|
||||
LLConstant* DtoTypeInfoOf(Type* type, bool base)
|
||||
{
|
||||
#if DMDV2
|
||||
// FIXME: this is probably wrong, but it makes druntime's genobj.d compile!
|
||||
type = type->mutableOf()->merge(); // needed.. getTypeInfo does the same
|
||||
#else
|
||||
type = type->merge(); // needed.. getTypeInfo does the same
|
||||
#endif
|
||||
type = type->merge2(); // needed.. getTypeInfo does the same
|
||||
type->getTypeInfo(NULL);
|
||||
TypeInfoDeclaration* tidecl = type->vtinfo;
|
||||
assert(tidecl);
|
||||
@@ -1351,7 +1346,7 @@ bool mustDefineSymbol(Dsymbol* s)
|
||||
if (fd->semanticRun < 4)
|
||||
return false;
|
||||
|
||||
if (fd->isArrayOp)
|
||||
if (fd->isArrayOp)
|
||||
return true;
|
||||
|
||||
if (global.params.useAvailableExternally && fd->availableExternally) {
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
STATISTIC(NumGcToStack, "Number of calls promoted to constant-size allocas");
|
||||
@@ -296,7 +297,7 @@ GarbageCollect2Stack::GarbageCollect2Stack()
|
||||
KnownFunctions["_d_allocmemoryT"] = &AllocMemoryT;
|
||||
KnownFunctions["_d_newarrayvT"] = &NewArrayVT;
|
||||
KnownFunctions["_d_newarrayT"] = &NewArrayT;
|
||||
KnownFunctions["_d_allocclass"] = &AllocClass;
|
||||
KnownFunctions[_d_allocclass] = &AllocClass;
|
||||
}
|
||||
|
||||
static void RemoveCall(CallSite CS, const Analysis& A) {
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "gen/runtime.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
STATISTIC(NumSimplified, "Number of runtime calls simplified");
|
||||
@@ -332,7 +334,7 @@ void SimplifyDRuntimeCalls::InitOptimizations() {
|
||||
Optimizations["_d_newarraymT"] = &Allocation;
|
||||
Optimizations["_d_newarraymiT"] = &Allocation;
|
||||
Optimizations["_d_newarraymvT"] = &Allocation;
|
||||
Optimizations["_d_allocclass"] = &Allocation;
|
||||
Optimizations[_d_allocclass] = &Allocation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include "ir/irstruct.h"
|
||||
|
||||
RTTIBuilder::RTTIBuilder(ClassDeclaration* base_class)
|
||||
RTTIBuilder::RTTIBuilder(AggregateDeclaration* base_class)
|
||||
{
|
||||
// make sure the base typeinfo class has been processed
|
||||
base_class->codegen(Type::sir);
|
||||
@@ -23,10 +23,12 @@ RTTIBuilder::RTTIBuilder(ClassDeclaration* base_class)
|
||||
baseir = base->ir.irStruct;
|
||||
assert(baseir && "no IrStruct for TypeInfo base class");
|
||||
|
||||
// just start with adding the vtbl
|
||||
inits.push_back(baseir->getVtblSymbol());
|
||||
// and monitor
|
||||
push_null_vp();
|
||||
if (base->isClassDeclaration()) {
|
||||
// just start with adding the vtbl
|
||||
inits.push_back(baseir->getVtblSymbol());
|
||||
// and monitor
|
||||
push_null_vp();
|
||||
}
|
||||
}
|
||||
|
||||
void RTTIBuilder::push(llvm::Constant* C)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
struct ClassDeclaration;
|
||||
struct AggregateDeclaration;
|
||||
struct TypeClass;
|
||||
struct Type;
|
||||
|
||||
@@ -12,7 +13,7 @@ struct IrStruct;
|
||||
|
||||
struct RTTIBuilder
|
||||
{
|
||||
ClassDeclaration* base;
|
||||
AggregateDeclaration* base;
|
||||
TypeClass* basetype;
|
||||
IrStruct* baseir;
|
||||
|
||||
@@ -20,7 +21,7 @@ struct RTTIBuilder
|
||||
// 14 is enough for any D1 ClassInfo
|
||||
llvm::SmallVector<llvm::Constant*, 14> inits;
|
||||
|
||||
RTTIBuilder(ClassDeclaration* base_class);
|
||||
RTTIBuilder(AggregateDeclaration* base_class);
|
||||
|
||||
void push(llvm::Constant* C);
|
||||
void push_null(Type* T);
|
||||
|
||||
@@ -339,7 +339,7 @@ static void LLVM_D_BuildRuntimeModule()
|
||||
|
||||
// Object _d_allocclass(ClassInfo ci)
|
||||
{
|
||||
llvm::StringRef fname("_d_allocclass");
|
||||
llvm::StringRef fname(_d_allocclass);
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(classInfoTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
||||
@@ -608,7 +608,7 @@ static void LLVM_D_BuildRuntimeModule()
|
||||
// int _adEq(void[] a1, void[] a2, TypeInfo ti)
|
||||
// int _adCmp(void[] a1, void[] a2, TypeInfo ti)
|
||||
{
|
||||
llvm::StringRef fname("_adEq");
|
||||
llvm::StringRef fname(_adEq);
|
||||
llvm::StringRef fname2("_adCmp");
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(rt_array(byteTy));
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#ifndef LDC_GEN_RUNTIME_H_
|
||||
#define LDC_GEN_RUNTIME_H_
|
||||
|
||||
// D runtime support helpers
|
||||
|
||||
bool LLVM_D_InitRuntime();
|
||||
@@ -6,3 +9,13 @@ void LLVM_D_FreeRuntime();
|
||||
llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name);
|
||||
|
||||
llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(llvm::Module* target, const char* name);
|
||||
|
||||
#if DMDV1
|
||||
#define _d_allocclass "_d_allocclass"
|
||||
#define _adEq "_adEq"
|
||||
#else
|
||||
#define _d_allocclass "_d_newclass"
|
||||
#define _adEq "_adEq2"
|
||||
#endif
|
||||
|
||||
#endif // LDC_GEN_RUNTIME_H_
|
||||
|
||||
39
gen/toir.cpp
39
gen/toir.cpp
@@ -121,6 +121,13 @@ DValue* VarExp::toElem(IRState* p)
|
||||
LLValue* tmp = DtoArrayLen(p->arrays.back());
|
||||
return new DImValue(type, tmp);
|
||||
}
|
||||
// classinfo
|
||||
else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration())
|
||||
{
|
||||
Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
|
||||
cid->cd->codegen(Type::sir);;
|
||||
return new DVarValue(type, vd, cid->cd->ir.irStruct->getClassInfoSymbol());
|
||||
}
|
||||
// typeinfo
|
||||
else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
|
||||
{
|
||||
@@ -133,13 +140,6 @@ DValue* VarExp::toElem(IRState* p)
|
||||
m = p->ir->CreateBitCast(m, vartype, "tmp");
|
||||
return new DImValue(type, m);
|
||||
}
|
||||
// classinfo
|
||||
else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration())
|
||||
{
|
||||
Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
|
||||
cid->cd->codegen(Type::sir);;
|
||||
return new DVarValue(type, vd, cid->cd->ir.irStruct->getClassInfoSymbol());
|
||||
}
|
||||
// nested variable
|
||||
#if DMDV2
|
||||
else if (vd->nestedrefs.dim) {
|
||||
@@ -552,7 +552,7 @@ DValue* AssignExp::toElem(IRState* p)
|
||||
DValue* arr = ale->e1->toElem(p);
|
||||
DVarValue arrval(ale->e1->type, arr->getLVal());
|
||||
DValue* newlen = e2->toElem(p);
|
||||
DSliceValue* slice = DtoResizeDynArray(arrval.getType(), &arrval, newlen);
|
||||
DSliceValue* slice = DtoResizeDynArray(arrval.getType(), &arrval, newlen->getRVal());
|
||||
DtoAssign(loc, &arrval, slice);
|
||||
return newlen;
|
||||
}
|
||||
@@ -648,22 +648,16 @@ DValue* AddExp::toElem(IRState* p)
|
||||
|
||||
errorOnIllegalArrayOp(this, e1, e2);
|
||||
|
||||
if (e1type != e2type) {
|
||||
if (e1type->ty == Tpointer) {
|
||||
Logger::println("add to pointer");
|
||||
if (DConstValue* cv = r->isConst()) {
|
||||
if (cv->c->isNullValue()) {
|
||||
Logger::println("is zero");
|
||||
return new DImValue(type, l->getRVal());
|
||||
}
|
||||
if (e1type != e2type && e1type->ty == Tpointer) {
|
||||
Logger::println("add to pointer");
|
||||
if (DConstValue* cv = r->isConst()) {
|
||||
if (cv->c->isNullValue()) {
|
||||
Logger::println("is zero");
|
||||
return new DImValue(type, l->getRVal());
|
||||
}
|
||||
LLValue* v = llvm::GetElementPtrInst::Create(l->getRVal(), r->getRVal(), "tmp", p->scopebb());
|
||||
return new DImValue(type, v);
|
||||
}
|
||||
else if (t->iscomplex()) {
|
||||
return DtoComplexAdd(loc, type, l, r);
|
||||
}
|
||||
assert(0);
|
||||
LLValue* v = llvm::GetElementPtrInst::Create(l->getRVal(), r->getRVal(), "tmp", p->scopebb());
|
||||
return new DImValue(type, v);
|
||||
}
|
||||
else if (t->iscomplex()) {
|
||||
return DtoComplexAdd(loc, type, l, r);
|
||||
@@ -1785,6 +1779,7 @@ DValue* AssertExp::toElem(IRState* p)
|
||||
(invdecl = ((TypeStruct*)condty->nextOf())->sym->inv) != NULL)
|
||||
{
|
||||
Logger::print("calling struct invariant");
|
||||
((TypeStruct*)condty->nextOf())->sym->codegen(Type::sir);
|
||||
DFuncValue invfunc(invdecl, invdecl->ir.irFunc->func, cond->getRVal());
|
||||
DtoCallFunction(loc, NULL, &invfunc, NULL);
|
||||
}
|
||||
|
||||
@@ -896,7 +896,11 @@ const LLStructType* DtoModuleReferenceType()
|
||||
// add members
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(getPtrToType(opaque));
|
||||
#if DMDV1
|
||||
types.push_back(DtoType(Module::moduleinfo->type));
|
||||
#else
|
||||
types.push_back(DtoType(Module::moduleinfo->type->pointerTo()));
|
||||
#endif
|
||||
|
||||
// resolve type
|
||||
const LLStructType* st = LLStructType::get(gIR->context(), types);
|
||||
|
||||
@@ -635,8 +635,11 @@ void Module::genmoduleinfo()
|
||||
// void* xgetMembers;
|
||||
// void function() ictor;
|
||||
//
|
||||
// version(D_Version2)
|
||||
// void*[4] reserved; // useless to us
|
||||
// version(D_Version2) {
|
||||
// void *sharedctor;
|
||||
// void *shareddtor;
|
||||
// uint index;
|
||||
// void*[1] reserved;
|
||||
// }
|
||||
|
||||
// resolve ModuleInfo
|
||||
@@ -646,14 +649,18 @@ void Module::genmoduleinfo()
|
||||
fatal();
|
||||
}
|
||||
// check for patch
|
||||
#if DMDV2
|
||||
else if (moduleinfo->fields.dim != 10)
|
||||
#else
|
||||
else if (moduleinfo->fields.dim != 9)
|
||||
#endif
|
||||
else
|
||||
{
|
||||
error("object.d ModuleInfo class is incorrect");
|
||||
fatal();
|
||||
#if DMDV2
|
||||
unsigned sizeof_ModuleInfo = 16 * PTRSIZE;
|
||||
#else
|
||||
unsigned sizeof_ModuleInfo = 14 * PTRSIZE;
|
||||
#endif
|
||||
if (sizeof_ModuleInfo != moduleinfo->structsize)
|
||||
{
|
||||
error("object.d ModuleInfo class is incorrect");
|
||||
fatal();
|
||||
}
|
||||
}
|
||||
|
||||
// use the RTTIBuilder
|
||||
|
||||
109
gen/typinf.cpp
109
gen/typinf.cpp
@@ -112,43 +112,52 @@ Expression *Type::getInternalTypeInfo(Scope *sc)
|
||||
|
||||
Expression *Type::getTypeInfo(Scope *sc)
|
||||
{
|
||||
Expression *e;
|
||||
Type *t;
|
||||
|
||||
//printf("Type::getTypeInfo() %p, %s\n", this, toChars());
|
||||
t = merge(); // do this since not all Type's are merge'd
|
||||
if (!Type::typeinfo)
|
||||
{
|
||||
error(0, "TypeInfo not found. object.d may be incorrectly installed or corrupt, compile with -v switch");
|
||||
fatal();
|
||||
}
|
||||
|
||||
Expression *e = 0;
|
||||
Type *t = merge2(); // do this since not all Type's are merge'd
|
||||
|
||||
if (!t->vtinfo)
|
||||
{
|
||||
#if DMDV2
|
||||
if (t->isConst())
|
||||
t->vtinfo = new TypeInfoConstDeclaration(t);
|
||||
else if (t->isImmutable())
|
||||
t->vtinfo = new TypeInfoInvariantDeclaration(t);
|
||||
else
|
||||
if (t->isShared())
|
||||
t->vtinfo = new TypeInfoSharedDeclaration(t);
|
||||
else if (t->isConst())
|
||||
t->vtinfo = new TypeInfoConstDeclaration(t);
|
||||
else if (t->isImmutable())
|
||||
t->vtinfo = new TypeInfoInvariantDeclaration(t);
|
||||
else if (t->isWild())
|
||||
t->vtinfo = new TypeInfoWildDeclaration(t);
|
||||
else
|
||||
#endif
|
||||
t->vtinfo = t->getTypeInfoDeclaration();
|
||||
assert(t->vtinfo);
|
||||
t->vtinfo = t->getTypeInfoDeclaration();
|
||||
assert(t->vtinfo);
|
||||
|
||||
/* If this has a custom implementation in std/typeinfo, then
|
||||
* do not generate a COMDAT for it.
|
||||
*/
|
||||
if (!t->builtinTypeInfo())
|
||||
{ // Generate COMDAT
|
||||
if (sc) // if in semantic() pass
|
||||
{ // Find module that will go all the way to an object file
|
||||
Module *m = sc->module->importedFrom;
|
||||
m->members->push(t->vtinfo);
|
||||
}
|
||||
else // if in obj generation pass
|
||||
{
|
||||
/* If this has a custom implementation in std/typeinfo, then
|
||||
* do not generate a COMDAT for it.
|
||||
*/
|
||||
if (!t->builtinTypeInfo())
|
||||
{ // Generate COMDAT
|
||||
if (sc) // if in semantic() pass
|
||||
{ // Find module that will go all the way to an object file
|
||||
Module *m = sc->module->importedFrom;
|
||||
m->members->push(t->vtinfo);
|
||||
}
|
||||
else // if in obj generation pass
|
||||
{
|
||||
#if IN_DMD
|
||||
t->vtinfo->toObjFile(0); // TODO: multiobj
|
||||
t->vtinfo->toObjFile(0); // TODO: multiobj
|
||||
#else
|
||||
t->vtinfo->codegen(sir);
|
||||
t->vtinfo->codegen(sir);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
e = new VarExp(0, t->vtinfo);
|
||||
e = e->addressOf(sc);
|
||||
e->type = t->vtinfo->type; // do this so we don't get redundant dereference
|
||||
@@ -239,7 +248,7 @@ int Type::builtinTypeInfo()
|
||||
int TypeBasic::builtinTypeInfo()
|
||||
{
|
||||
#if DMDV2
|
||||
return !mod;
|
||||
return mod ? 0 : 1;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
@@ -260,7 +269,7 @@ int TypeClass::builtinTypeInfo()
|
||||
* claim it is built in so it isn't regenerated by each module.
|
||||
*/
|
||||
#if IN_DMD
|
||||
return 1;
|
||||
return mod ? 0 : 1;
|
||||
#elif IN_LLVM
|
||||
// FIXME if I enable this, the way LDC does typeinfo will cause a bunch
|
||||
// of linker errors to missing class typeinfo definitions.
|
||||
@@ -673,8 +682,24 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
#if DMDV2
|
||||
void TypeInfoClassDeclaration::codegen(Ir*i)
|
||||
{
|
||||
|
||||
IrGlobal* irg = new IrGlobal(this);
|
||||
ir.irGlobal = irg;
|
||||
assert(tinfo->ty == Tclass);
|
||||
TypeClass *tc = (TypeClass *)tinfo;
|
||||
tc->sym->codegen(Type::sir); // make sure class is resolved
|
||||
irg->value = tc->sym->ir.irStruct->getClassInfoSymbol();
|
||||
}
|
||||
#endif
|
||||
|
||||
void TypeInfoClassDeclaration::llvmDefine()
|
||||
{
|
||||
#if DMDV2
|
||||
assert(0);
|
||||
#endif
|
||||
Logger::println("TypeInfoClassDeclaration::llvmDefine() %s", toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
@@ -779,4 +804,32 @@ void TypeInfoInvariantDeclaration::llvmDefine()
|
||||
b.finalize(ir.irGlobal);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
void TypeInfoSharedDeclaration::llvmDefine()
|
||||
{
|
||||
Logger::println("TypeInfoSharedDeclaration::llvmDefine() %s", toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
RTTIBuilder b(Type::typeinfoshared);
|
||||
// TypeInfo base
|
||||
b.push_typeinfo(tinfo->unSharedOf()->merge());
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
void TypeInfoWildDeclaration::llvmDefine()
|
||||
{
|
||||
Logger::println("TypeInfoWildDeclaration::llvmDefine() %s", toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
RTTIBuilder b(Type::typeinfowild);
|
||||
// TypeInfo base
|
||||
b.push_typeinfo(tinfo->mutableOf()->merge());
|
||||
// finish
|
||||
b.finalize(ir.irGlobal);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user