From 4d7a6eda234bc8d12703cc577c09c2ca50ac6bda Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Thu, 7 Oct 2010 22:35:32 +0400 Subject: [PATCH] Different fixes for d2 --- CMakeLists.txt | 2 + dmd2/aggregate.h | 2 +- dmd2/cast.c | 13 +- dmd2/class.c | 2 + dmd2/declaration.c | 10 +- dmd2/declaration.h | 9 ++ dmd2/expression.c | 22 ++- dmd2/expression.h | 1 + dmd2/func.c | 10 +- dmd2/mangle.c | 2 + dmd2/module.c | 2 +- dmd2/module.h | 3 +- dmd2/mtype.c | 229 +++++++++++++++------------ dmd2/optimize.c | 13 +- dmd2/struct.c | 10 ++ gen/aa.cpp | 4 + gen/arrays.cpp | 28 +++- gen/arrays.h | 4 +- gen/classes.cpp | 16 +- gen/declarations.cpp | 2 +- gen/functions.cpp | 12 +- gen/llvmhelpers.cpp | 15 +- gen/passes/GarbageCollect2Stack.cpp | 3 +- gen/passes/SimplifyDRuntimeCalls.cpp | 4 +- gen/rttibuilder.cpp | 12 +- gen/rttibuilder.h | 5 +- gen/runtime.cpp | 4 +- gen/runtime.h | 13 ++ gen/toir.cpp | 39 ++--- gen/tollvm.cpp | 4 + gen/toobj.cpp | 25 +-- gen/typinf.cpp | 109 +++++++++---- ir/irclass.cpp | 3 +- ir/irfuncty.h | 6 +- runtime/CMakeLists.txt | 46 ++++-- 35 files changed, 443 insertions(+), 241 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index db21e7ae..f35703c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,6 +168,7 @@ set_source_files_properties( file(GLOB FE_SRC ${DMDFE_PATH}/*.c) file(GLOB FE_SRC_ROOT ${DMDFE_PATH}/root/*.c) +file(GLOB_RECURSE GEN_HDR gen/*.h) file(GLOB_RECURSE GEN_SRC gen/*.cpp) file(GLOB IR_SRC ir/*.cpp) # exclude idgen and impcnvgen and generated sources, just in case @@ -182,6 +183,7 @@ set(LDC_SOURCE_FILES ${FE_SRC} ${FE_SRC_ROOT} ${GEN_SRC} + ${GEN_HDR} ${IR_SRC} ) set_source_files_properties( diff --git a/dmd2/aggregate.h b/dmd2/aggregate.h index 97806872..463a4a37 100644 --- a/dmd2/aggregate.h +++ b/dmd2/aggregate.h @@ -41,6 +41,7 @@ struct VarDeclaration; struct dt_t; #if IN_LLVM +class ClassInfoDeclaration; namespace llvm { class Type; @@ -251,7 +252,6 @@ struct ClassDeclaration : AggregateDeclaration BaseClasses *vtblInterfaces; // array of base interfaces that have // their own vtbl[] - TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration int com; // !=0 if this is a COM class (meaning // it derives from IUnknown) diff --git a/dmd2/cast.c b/dmd2/cast.c index fb86c241..dd9c1198 100644 --- a/dmd2/cast.c +++ b/dmd2/cast.c @@ -1171,7 +1171,7 @@ Expression *AddrExp::castTo(Scope *sc, Type *t) { Dsymbol *s = (Dsymbol *)eo->vars->a.data[i]; FuncDeclaration *f2 = s->isFuncDeclaration(); assert(f2); - if (f2->overloadExactMatch(t->nextOf(), m)) + if (f2->overloadExactMatch(t->nextOf(), m)) { if (f) /* Error if match in more than one overload set, * even if one is a 'better' match than the other. @@ -1190,7 +1190,6 @@ Expression *AddrExp::castTo(Scope *sc, Type *t) } } - if (type->ty == Tpointer && type->nextOf()->ty == Tfunction && tb->ty == Tpointer && tb->nextOf()->ty == Tfunction && e1->op == TOKvar) @@ -1199,8 +1198,10 @@ Expression *AddrExp::castTo(Scope *sc, Type *t) FuncDeclaration *f = ve->var->isFuncDeclaration(); if (f) { +#if !IN_LLVM assert(0); // should be SymOffExp instead - f = f->overloadExactMatch(tb->nextOf(), m); +#endif + f = f->overloadExactMatch(tb->nextOf(), m); if (f) { e = new VarExp(loc, f); @@ -1211,6 +1212,7 @@ Expression *AddrExp::castTo(Scope *sc, Type *t) } } } + e = Expression::castTo(sc, t); } e->type = t; @@ -1474,7 +1476,10 @@ Expression *BinExp::scaleFactor(Scope *sc) stride = t1b->nextOf()->size(loc); if (!t->equals(t2b)) e2 = e2->castTo(sc, t); +// LDC: llvm uses typesafe pointer arithmetic +#if !IN_LLVM e2 = new MulExp(loc, e2, new IntegerExp(0, stride, t)); +#endif e2->type = t; type = e1->type; } @@ -1489,7 +1494,9 @@ Expression *BinExp::scaleFactor(Scope *sc) e = e1->castTo(sc, t); else e = e1; +#if !IN_LLVM e = new MulExp(loc, e, new IntegerExp(0, stride, t)); +#endif e->type = t; type = e2->type; e1 = e2; diff --git a/dmd2/class.c b/dmd2/class.c index a8d1073c..059b89ac 100644 --- a/dmd2/class.c +++ b/dmd2/class.c @@ -190,11 +190,13 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla classinfo = this; } +#if !MODULEINFO_IS_STRUCT if (id == Id::ModuleInfo) { if (Module::moduleinfo) Module::moduleinfo->error("%s", msg); Module::moduleinfo = this; } +#endif } com = 0; diff --git a/dmd2/declaration.c b/dmd2/declaration.c index 1afbc35c..5f0dd6f1 100644 --- a/dmd2/declaration.c +++ b/dmd2/declaration.c @@ -614,7 +614,7 @@ void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { if (haliassym) { - buf->writestring(haliassym->toChars()); + buf->writestring(haliassym->toChars()); buf->writeByte(' '); buf->writestring(ident->toChars()); } @@ -626,7 +626,11 @@ void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) { if (aliassym) { +#if !IN_LLVM aliassym->toCBuffer(buf, hgs); +#else + buf->writestring(aliassym->toChars()); +#endif buf->writeByte(' '); buf->writestring(ident->toChars()); } @@ -876,7 +880,7 @@ void VarDeclaration::semantic(Scope *sc) //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); v->semantic(sc); -/* +#if !IN_LLVM // removed for LDC since TupleDeclaration::toObj already creates the fields; // adding them to the scope again leads to duplicates if (sc->scopesym) @@ -884,7 +888,7 @@ void VarDeclaration::semantic(Scope *sc) if (sc->scopesym->members) sc->scopesym->members->push(v); } -*/ +#endif Expression *e = new DsymbolExp(loc, v); exps->data[i] = e; } diff --git a/dmd2/declaration.h b/dmd2/declaration.h index d52b07f1..0362d15d 100644 --- a/dmd2/declaration.h +++ b/dmd2/declaration.h @@ -450,6 +450,7 @@ struct TypeInfoClassDeclaration : TypeInfoDeclaration #endif #if IN_LLVM + void codegen(Ir*); void llvmDefine(); #endif }; @@ -618,6 +619,10 @@ struct TypeInfoSharedDeclaration : TypeInfoDeclaration #if IN_DMD void toDt(dt_t **pdt); #endif + +#if IN_LLVM + void llvmDefine(); +#endif }; struct TypeInfoWildDeclaration : TypeInfoDeclaration @@ -627,6 +632,10 @@ struct TypeInfoWildDeclaration : TypeInfoDeclaration #if IN_DMD void toDt(dt_t **pdt); #endif + +#if IN_LLVM + void llvmDefine(); +#endif }; #endif diff --git a/dmd2/expression.c b/dmd2/expression.c index 730677c1..35c24208 100644 --- a/dmd2/expression.c +++ b/dmd2/expression.c @@ -834,12 +834,14 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf, void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr) { +#if !IN_LLVM #ifdef DEBUG if (precedence[e->op] == PREC_zero) printf("precedence not defined for token '%s'\n",Token::tochars[e->op]); #endif assert(precedence[e->op] != PREC_zero); assert(pr != PREC_zero); +#endif //if (precedence[e->op] == 0) e->dump(0); if (precedence[e->op] < pr || @@ -2489,7 +2491,7 @@ Expression *ThisExp::semantic(Scope *sc) #if LOGSEMANTIC printf("ThisExp::semantic()\n"); #endif - if (type) + if (type && var) { //assert(global.errors || var); return this; } @@ -2534,7 +2536,8 @@ Expression *ThisExp::semantic(Scope *sc) assert(fd->vthis); var = fd->vthis; assert(var->parent); - type = var->type; + if (!type) + type = var->type; var->isVarDeclaration()->checkNestedReference(sc, loc); if (!sc->intypeof) sc->callSuper |= CSXthis; @@ -7402,6 +7405,14 @@ Expression *AddrExp::semantic(Scope *sc) if (f) { +#if !IN_LLVM + if (f->isIntrinsic()) + { + error("cannot take the address of intrinsic function %s", e1->toChars()); + return this; + } +#endif + if (!ve->hasOverloads || /* Because nested functions cannot be overloaded, * mark here that we took its address because castTo() @@ -7789,6 +7800,9 @@ CastExp::CastExp(Loc loc, Expression *e, Type *t) { to = t; this->mod = ~0; +#if IN_LLVM + disableOptimization = false; +#endif } #if DMDV2 @@ -7799,6 +7813,9 @@ CastExp::CastExp(Loc loc, Expression *e, unsigned mod) { to = NULL; this->mod = mod; +#if IN_LLVM + disableOptimization = false; +#endif } #endif @@ -7987,7 +8004,6 @@ void CastExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) expToCBuffer(buf, hgs, e1, precedence[op]); } - /************************************************************/ SliceExp::SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr) diff --git a/dmd2/expression.h b/dmd2/expression.h index 0c9d22ba..7c9e369e 100644 --- a/dmd2/expression.h +++ b/dmd2/expression.h @@ -1301,6 +1301,7 @@ struct CastExp : UnaExp #if IN_LLVM DValue* toElem(IRState* irs); llvm::Constant *toConstElem(IRState *irs); + bool disableOptimization; #endif }; diff --git a/dmd2/func.c b/dmd2/func.c index e681f1b0..35c1ff27 100644 --- a/dmd2/func.c +++ b/dmd2/func.c @@ -775,7 +775,9 @@ void FuncDeclaration::semantic(Scope *sc) Ldone: Module::dprogress++; - semanticRun = PASSsemanticdone; + //LDC relies on semanticRun variable not being reset here + if(semanticRun < PASSsemanticdone) + semanticRun = PASSsemanticdone; /* Save scope for possible later use (if we need the * function internals) @@ -1235,7 +1237,7 @@ void FuncDeclaration::semantic3(Scope *sc) else { // Call invariant virtually ThisExp *tv = new ThisExp(0); - tv->type = vthis->type; + tv->type = vthis->type; tv->var = vthis; Expression* v = tv; @@ -2771,7 +2773,7 @@ FuncDeclaration *FuncDeclaration::genCfunc(Parameters *args, Type *treturn, Iden } else { - tf = new TypeFunction(NULL, treturn, 0, LINKc); + tf = new TypeFunction(args, treturn, 0, LINKc); fd = new FuncDeclaration(0, 0, id, STCstatic, tf); fd->protection = PROTpublic; fd->linkage = LINKc; @@ -3011,7 +3013,7 @@ void CtorDeclaration::semantic(Scope *sc) // to the function body if (fbody && semanticRun < PASSsemantic) { - Expression *e = new ThisExp(loc); + ThisExp *e = new ThisExp(loc); if (parent->isClassDeclaration()) e->type = tret; Statement *s = new ReturnStatement(loc, e); diff --git a/dmd2/mangle.c b/dmd2/mangle.c index bda5d326..144f0185 100644 --- a/dmd2/mangle.c +++ b/dmd2/mangle.c @@ -202,7 +202,9 @@ char *ClassDeclaration::mangle() ident == Id::TypeInfo_Tuple || this == object || this == classinfo || +#if !MODULEINFO_IS_STRUCT this == Module::moduleinfo || +#endif memcmp(ident->toChars(), "TypeInfo_", 9) == 0 ) parent = NULL; diff --git a/dmd2/module.c b/dmd2/module.c index 02e1ead5..99c0781e 100644 --- a/dmd2/module.c +++ b/dmd2/module.c @@ -57,7 +57,7 @@ static llvm::cl::opt fqnNames("oq", llvm::cl::ZeroOrMore); #endif -ClassDeclaration *Module::moduleinfo; +AggregateDeclaration *Module::moduleinfo; Module *Module::rootModule; DsymbolTable *Module::modules; diff --git a/dmd2/module.h b/dmd2/module.h index 7937e9ac..21ebd01d 100644 --- a/dmd2/module.h +++ b/dmd2/module.h @@ -65,8 +65,7 @@ struct Module : Package static unsigned dprogress; // progress resolving the deferred list static void init(); - static ClassDeclaration *moduleinfo; - + static AggregateDeclaration *moduleinfo; const char *arg; // original argument name ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration diff --git a/dmd2/mtype.c b/dmd2/mtype.c index 078cec2d..8f4b1521 100644 --- a/dmd2/mtype.c +++ b/dmd2/mtype.c @@ -1538,7 +1538,7 @@ Type *Type::merge() //if (next) //next = next->merge(); - toDecoBuffer(&buf, false); + toDecoBuffer(&buf, false); sv = stringtable.update((char *)buf.data, buf.offset); if (sv->ptrvalue) { t = (Type *) sv->ptrvalue; @@ -1556,19 +1556,19 @@ Type *Type::merge() // we still need deco strings to be unique // or Type::equals fails, which breaks a bunch of stuff, // like covariant member function overloads. - OutBuffer mangle; - toDecoBuffer(&mangle, true); - StringValue* sv2 = deco_stringtable.update((char *)mangle.data, mangle.offset); - if (sv2->ptrvalue) - { Type* t2 = (Type *) sv2->ptrvalue; - assert(t2->deco); - deco = t2->deco; - } - else - { - sv2->ptrvalue = this; - deco = (char *)sv2->lstring.string; - } + OutBuffer mangle; + toDecoBuffer(&mangle, true); + StringValue* sv2 = deco_stringtable.update((char *)mangle.data, mangle.offset); + if (sv2->ptrvalue) + { Type* t2 = (Type *) sv2->ptrvalue; + assert(t2->deco); + deco = t2->deco; + } + else + { + sv2->ptrvalue = this; + deco = (char *)sv2->lstring.string; + } //printf("new value, deco = '%s' %p\n", t->deco, t->deco); } } @@ -1753,7 +1753,11 @@ Expression *Type::getProperty(Loc loc, Identifier *ident) { if (ty == Tvoid) error(loc, "void does not have an initializer"); +#if IN_LLVM + e = defaultInit(loc); +#else e = defaultInitLiteral(loc); +#endif } else if (ident == Id::mangleof) { const char *s; @@ -3123,26 +3127,26 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident) Expression *ec; Expressions *arguments; - //LDC: Build arguments. - static FuncDeclaration *adReverseChar_fd = NULL; - if(!adReverseChar_fd) { - Parameters* args = new Parameters; - Type* arrty = Type::tchar->arrayOf(); - args->push(new Parameter(STCin, arrty, NULL, NULL)); - adReverseChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseChar"); - } - static FuncDeclaration *adReverseWchar_fd = NULL; - if(!adReverseWchar_fd) { - Parameters* args = new Parameters; - Type* arrty = Type::twchar->arrayOf(); - args->push(new Parameter(STCin, arrty, NULL, NULL)); - adReverseWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseWchar"); - } + //LDC: Build arguments. + static FuncDeclaration *adReverseChar_fd = NULL; + if(!adReverseChar_fd) { + Parameters* args = new Parameters; + Type* arrty = Type::tchar->arrayOf(); + args->push(new Parameter(STCin, arrty, NULL, NULL)); + adReverseChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseChar"); + } + static FuncDeclaration *adReverseWchar_fd = NULL; + if(!adReverseWchar_fd) { + Parameters* args = new Parameters; + Type* arrty = Type::twchar->arrayOf(); + args->push(new Parameter(STCin, arrty, NULL, NULL)); + adReverseWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adReverseWchar"); + } - if(n->ty == Twchar) - ec = new VarExp(0, adReverseWchar_fd); - else - ec = new VarExp(0, adReverseChar_fd); + if(n->ty == Twchar) + ec = new VarExp(0, adReverseWchar_fd); + else + ec = new VarExp(0, adReverseChar_fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); arguments->push(e); @@ -3154,26 +3158,26 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident) Expression *ec; Expressions *arguments; - //LDC: Build arguments. - static FuncDeclaration *adSortChar_fd = NULL; - if(!adSortChar_fd) { - Parameters* args = new Parameters; - Type* arrty = Type::tchar->arrayOf(); - args->push(new Parameter(STCin, arrty, NULL, NULL)); - adSortChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortChar"); - } - static FuncDeclaration *adSortWchar_fd = NULL; - if(!adSortWchar_fd) { - Parameters* args = new Parameters; - Type* arrty = Type::twchar->arrayOf(); - args->push(new Parameter(STCin, arrty, NULL, NULL)); - adSortWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortWchar"); - } + //LDC: Build arguments. + static FuncDeclaration *adSortChar_fd = NULL; + if(!adSortChar_fd) { + Parameters* args = new Parameters; + Type* arrty = Type::tchar->arrayOf(); + args->push(new Parameter(STCin, arrty, NULL, NULL)); + adSortChar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortChar"); + } + static FuncDeclaration *adSortWchar_fd = NULL; + if(!adSortWchar_fd) { + Parameters* args = new Parameters; + Type* arrty = Type::twchar->arrayOf(); + args->push(new Parameter(STCin, arrty, NULL, NULL)); + adSortWchar_fd = FuncDeclaration::genCfunc(args, arrty, "_adSortWchar"); + } - if(n->ty == Twchar) - ec = new VarExp(0, adSortWchar_fd); - else - ec = new VarExp(0, adSortChar_fd); + if(n->ty == Twchar) + ec = new VarExp(0, adSortWchar_fd); + else + ec = new VarExp(0, adSortChar_fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); arguments->push(e); @@ -3189,37 +3193,39 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident) assert(size); dup = (ident == Id::dup || ident == Id::idup); - //LDC: Build arguments. - static FuncDeclaration *adDup_fd = NULL; - if(!adDup_fd) { - Parameters* args = new Parameters; - args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL)); - args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); - adDup_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adDup); - } - static FuncDeclaration *adReverse_fd = NULL; - if(!adReverse_fd) { - Parameters* args = new Parameters; - args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); - args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL)); - adReverse_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adReverse); - } + //LDC: Build arguments. + static FuncDeclaration *adDup_fd = NULL; + if(!adDup_fd) { + Parameters* args = new Parameters; + args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL)); + args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); + adDup_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adDup); + } + static FuncDeclaration *adReverse_fd = NULL; + if(!adReverse_fd) { + Parameters* args = new Parameters; + args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); + args->push(new Parameter(STCin, Type::tsize_t, NULL, NULL)); + adReverse_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), Id::adReverse); + } - if(dup) - ec = new VarExp(0, adDup_fd); - else - ec = new VarExp(0, adReverse_fd); + if(dup) + ec = new VarExp(0, adDup_fd); + else + ec = new VarExp(0, adReverse_fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); if (dup) arguments->push(getTypeInfo(sc)); - // LDC repaint array type to void[] - if (n->ty != Tvoid) { - e = new CastExp(e->loc, e, e->type); - e->type = Type::tvoid->arrayOf(); - } - arguments->push(e); + // LDC repaint array type to void[] + if (n->ty != Tvoid) { + CastExp *exp = new CastExp(e->loc, e, e->type); + exp->type = Type::tvoid->arrayOf(); + exp->disableOptimization = true; + e = exp; + } + arguments->push(e); if (!dup) arguments->push(new IntegerExp(0, size, Type::tsize_t)); @@ -3237,41 +3243,46 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident) { Expression *ec; Expressions *arguments; - bool isBit = (n->ty == Tbit); + bool isBit = (n->ty == Tbit); - //LDC: Build arguments. - static FuncDeclaration *adSort_fd = NULL; - if(!adSort_fd) { - Parameters* args = new Parameters; - args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); - args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL)); - adSort_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSort"); - } - static FuncDeclaration *adSortBit_fd = NULL; - if(!adSortBit_fd) { - Parameters* args = new Parameters; - args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); - args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL)); - adSortBit_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSortBit"); - } + //LDC: Build arguments. + static FuncDeclaration *adSort_fd = NULL; + if(!adSort_fd) { + Parameters* args = new Parameters; + args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); + args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL)); + adSort_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSort"); + } + static FuncDeclaration *adSortBit_fd = NULL; + if(!adSortBit_fd) { + Parameters* args = new Parameters; + args->push(new Parameter(STCin, Type::tvoid->arrayOf(), NULL, NULL)); + args->push(new Parameter(STCin, Type::typeinfo->type, NULL, NULL)); + adSortBit_fd = FuncDeclaration::genCfunc(args, Type::tvoid->arrayOf(), "_adSortBit"); + } - if(isBit) - ec = new VarExp(0, adSortBit_fd); - else - ec = new VarExp(0, adSort_fd); + if(isBit) + ec = new VarExp(0, adSortBit_fd); + else + ec = new VarExp(0, adSort_fd); e = e->castTo(sc, n->arrayOf()); // convert to dynamic array arguments = new Expressions(); - // LDC repaint array type to void[] - if (n->ty != Tvoid) { - e = new CastExp(e->loc, e, e->type); - e->type = Type::tvoid->arrayOf(); - } + // LDC repaint array type to void[] + if (n->ty != Tvoid) { + CastExp *exp = new CastExp(e->loc, e, e->type); + exp->type = Type::tvoid->arrayOf(); + exp->disableOptimization = true; + e = exp; + } arguments->push(e); - if (next->ty != Tbit) - arguments->push(n->getTypeInfo(sc)); // LDC, we don't support the getInternalTypeInfo - // optimization arbitrarily, not yet at least... + if (next->ty != Tbit) { + // LDC, we don't support the getInternalTypeInfo + // optimization arbitrarily, not yet at least... + arguments->push(n->getTypeInfo(sc)); + } + e = new CallExp(e->loc, ec, arguments); e->type = next->arrayOf(); } @@ -7499,9 +7510,17 @@ L1: { /* The handle to the monitor (call it a void*) * *(cast(void**)e + 1) */ +#if IN_LLVM + e = e->castTo(sc, tint8->pointerTo()->pointerTo()); + e = new AddExp(e->loc, e, new IntegerExp(1)); + e->type = tint8->pointerTo(); + e = e->castTo(sc, tvoidptr->pointerTo()); + e = new PtrExp(e->loc, e); +#else e = e->castTo(sc, tvoidptr->pointerTo()); e = new AddExp(e->loc, e, new IntegerExp(1)); e = new PtrExp(e->loc, e); +#endif e = e->semantic(sc); return e; } diff --git a/dmd2/optimize.c b/dmd2/optimize.c index c38fc705..449f8848 100644 --- a/dmd2/optimize.c +++ b/dmd2/optimize.c @@ -286,6 +286,8 @@ Expression *AddrExp::optimize(int result) { Expression *e; //printf("AddrExp::optimize(result = %d) %s\n", result, toChars()); + // LDC never try to interpret: it could change the semantics by turning + // const p = &s; into an something like const p = &(Struct()); /* Rewrite &(a,b) as (a,&b) */ @@ -295,13 +297,13 @@ Expression *AddrExp::optimize(int result) ae->type = type; e = new CommaExp(ce->loc, ce->e1, ae); e->type = type; - return e->optimize(result); + return e->optimize(result & ~WANTinterpret); } if (e1->op == TOKvar) { VarExp *ve = (VarExp *)e1; if (ve->var->storage_class & STCmanifest) - e1 = e1->optimize(result); + e1 = e1->optimize(result & ~WANTinterpret); } else e1 = e1->optimize(result); @@ -523,6 +525,10 @@ Expression *CallExp::optimize(int result) Expression *CastExp::optimize(int result) { +#if IN_LLVM + if (disableOptimization) + return this; +#endif //printf("CastExp::optimize(result = %d) %s\n", result, toChars()); //printf("from %s to %s\n", type->toChars(), to->toChars()); //printf("from %s\n", type->toChars()); @@ -551,6 +557,9 @@ Expression *CastExp::optimize(int result) e1->type->nextOf()->size() == type->nextOf()->size() ) { + // LDC make a copy before adjusting type to avoid + // messing up the type of an existing initializer + e1 = e1->syntaxCopy(); Expression *e = e1->castTo(NULL, type); if (X) printf(" returning1 %s\n", e->toChars()); return e; diff --git a/dmd2/struct.c b/dmd2/struct.c index 881d2288..0e83d221 100644 --- a/dmd2/struct.c +++ b/dmd2/struct.c @@ -32,6 +32,7 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id) protection = PROTpublic; type = NULL; handle = NULL; + scope = 0; structsize = 0; // size of struct alignsize = 0; // size of struct for alignment purposes structalign = 0; // struct member alignment in effect @@ -263,6 +264,15 @@ StructDeclaration::StructDeclaration(Loc loc, Identifier *id) // For forward references type = new TypeStruct(this); + +#if MODULEINFO_IS_STRUCT + if (id == Id::ModuleInfo) + { + if (Module::moduleinfo) + Module::moduleinfo->error("only object.d can define this reserved class name"); + Module::moduleinfo = this; + } +#endif } Dsymbol *StructDeclaration::syntaxCopy(Dsymbol *s) diff --git a/gen/aa.cpp b/gen/aa.cpp index db335c97..7093f33e 100644 --- a/gen/aa.cpp +++ b/gen/aa.cpp @@ -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(); diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 004fbbd7..65d6523a 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -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 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 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); } diff --git a/gen/arrays.h b/gen/arrays.h index a597bca8..cfc66ab0 100644 --- a/gen/arrays.h +++ b/gen/arrays.h @@ -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); diff --git a/gen/classes.cpp b/gen/classes.cpp index 9783dc16..7a0b5ab5 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -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; imodule,_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 diff --git a/gen/functions.cpp b/gen/functions.cpp index 7ba535ec..e48b7e45 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -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); diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 48bb2058..12eef5e2 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -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) { diff --git a/gen/passes/GarbageCollect2Stack.cpp b/gen/passes/GarbageCollect2Stack.cpp index b6a91fe1..9d6607e5 100644 --- a/gen/passes/GarbageCollect2Stack.cpp +++ b/gen/passes/GarbageCollect2Stack.cpp @@ -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) { diff --git a/gen/passes/SimplifyDRuntimeCalls.cpp b/gen/passes/SimplifyDRuntimeCalls.cpp index 6d690bb2..bb7ba76a 100644 --- a/gen/passes/SimplifyDRuntimeCalls.cpp +++ b/gen/passes/SimplifyDRuntimeCalls.cpp @@ -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; } diff --git a/gen/rttibuilder.cpp b/gen/rttibuilder.cpp index c83e8f6a..c1c961d1 100644 --- a/gen/rttibuilder.cpp +++ b/gen/rttibuilder.cpp @@ -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) diff --git a/gen/rttibuilder.h b/gen/rttibuilder.h index 1d975700..ef1d8c6d 100644 --- a/gen/rttibuilder.h +++ b/gen/rttibuilder.h @@ -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 inits; - RTTIBuilder(ClassDeclaration* base_class); + RTTIBuilder(AggregateDeclaration* base_class); void push(llvm::Constant* C); void push_null(Type* T); diff --git a/gen/runtime.cpp b/gen/runtime.cpp index e83fb085..b4d01581 100644 --- a/gen/runtime.cpp +++ b/gen/runtime.cpp @@ -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 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 types; types.push_back(rt_array(byteTy)); diff --git a/gen/runtime.h b/gen/runtime.h index 11f0bdc8..dd342bb9 100644 --- a/gen/runtime.h +++ b/gen/runtime.h @@ -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_ diff --git a/gen/toir.cpp b/gen/toir.cpp index 82bef8bc..5775b34b 100644 --- a/gen/toir.cpp +++ b/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); } diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index c870e844..d18bd29a 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -896,7 +896,11 @@ const LLStructType* DtoModuleReferenceType() // add members std::vector 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); diff --git a/gen/toobj.cpp b/gen/toobj.cpp index 51179dc0..79becff0 100644 --- a/gen/toobj.cpp +++ b/gen/toobj.cpp @@ -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 diff --git a/gen/typinf.cpp b/gen/typinf.cpp index 30847c6d..1ff705a6 100644 --- a/gen/typinf.cpp +++ b/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 diff --git a/ir/irclass.cpp b/ir/irclass.cpp index 3827c96b..b92854c0 100644 --- a/ir/irclass.cpp +++ b/ir/irclass.cpp @@ -55,6 +55,7 @@ LLGlobalVariable * IrStruct::getClassInfoSymbol() // create the initZ symbol std::string initname("_D"); initname.append(aggrdecl->mangle()); + if (aggrdecl->isInterfaceDeclaration()) initname.append("11__InterfaceZ"); else @@ -69,7 +70,7 @@ LLGlobalVariable * IrStruct::getClassInfoSymbol() // classinfos cannot be constants since they're used a locks for synchronized classInfo = new llvm::GlobalVariable( - *gIR->module, tc->getPA().get(), false, _linkage, NULL, initname); + *gIR->module, tc->getPA().get(), false, _linkage, NULL, initname); #if USE_METADATA // Generate some metadata on this ClassInfo if it's for a class. diff --git a/ir/irfuncty.h b/ir/irfuncty.h index 8016a322..9681b951 100644 --- a/ir/irfuncty.h +++ b/ir/irfuncty.h @@ -78,6 +78,9 @@ struct IrFuncTy : IrBase // range of normal parameters to reverse bool reverseParams; + // arg_this is reference + bool is_arg_this_ref; + IrFuncTy() : ret(NULL), arg_sret(NULL), @@ -86,7 +89,8 @@ struct IrFuncTy : IrBase arg_arguments(NULL), arg_argptr(NULL), c_vararg(false), - reverseParams(false) + reverseParams(false), + is_arg_this_ref(false) {} void reset() { diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index fcf88221..e9f86276 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -50,6 +50,7 @@ if(D_VERSION EQUAL 1) # set paths to source files, or fill lists directly set(RUNTIME_DC_DIR ${PROJECT_SOURCE_DIR}/internal) set(RUNTIME_GC_DIR ${RUNTIME_DIR}/lib/gc/basic) + set(RUNTIME_INCLUDE ${RUNTIME_DC_DIR}) file(GLOB CORE_D ${RUNTIME_DIR}/lib/common/tango/core/*.d) file(GLOB CORE_C ${RUNTIME_DIR}/lib/common/tango/stdc/*.c) elseif(D_VERSION EQUAL 2) @@ -57,9 +58,22 @@ elseif(D_VERSION EQUAL 2) set(RUNTIME_GC druntime-gc-basic) set(RUNTIME_DC druntime-rt-ldc) set(RUNTIME_AIO druntime-ldc) - set(RUNTIME_DC_DIR ${RUNTIME_DIR}/src/compiler/ldc) + set(RUNTIME_DC_DIR ${RUNTIME_DIR}/src/rt) set(RUNTIME_GC_DIR ${RUNTIME_DIR}/src/gc) + set(RUNTIME_INCLUDE ${RUNTIME_DIR}/src) file(GLOB CORE_D ${RUNTIME_DIR}/src/core/*.d ) + file(GLOB CORE_D_SYNC ${RUNTIME_DIR}/src/core/sync/*.d ) + if(UNIX) + file(GLOB CORE_D_SYS ${RUNTIME_DIR}/src/core/sys/posix/*.d) + elseif(WIN32) + file(GLOB CORE_D_SYS ${RUNTIME_DIR}/src/core/sys/windows/*.d) + elseif(APPLE) + file(GLOB CORE_D_SYS ${RUNTIME_DIR}/src/core/sys/osx/*.d) + endif(UNIX) + list(APPEND CORE_D ${CORE_D_SYNC} ${CORE_D_SYS} ${RUNTIME_DIR}/src/object_.d + ${RUNTIME_DIR}/src/std/intrinsic.d + ${RUNTIME_DIR}/src/core/stdc/stdarg.d + ) file(GLOB CORE_C ${RUNTIME_DIR}/src/core/stdc/*.c) endif(D_VERSION EQUAL 1) @@ -107,20 +121,23 @@ file(GLOB_RECURSE GC_D ${RUNTIME_GC_DIR}/*.d) file(GLOB_RECURSE DCRT_D ${RUNTIME_DC_DIR}/*.d) file(GLOB DCRT_C ${RUNTIME_DC_DIR}/*.c) -# compile d file into outdir, include incdir, and append names of generated .o and .bc to outlist_o and _bc -macro(dc INPUT_D OUTLIST_O OUTLIST_BC OUTDIR INCDIR MOREFLAGS) - get_filename_component(BASENAME ${INPUT_D} NAME_WE) - set(OUTPUT_O ${PROJECT_BINARY_DIR}/${OUTDIR}/${BASENAME}.o) - set(OUTPUT_BC ${PROJECT_BINARY_DIR}/${OUTDIR}/${BASENAME}.bc) +macro(dc INPUT_D OUTLIST_O OUTLIST_BC INCDIR MOREFLAGS PATH) + if ("${PATH}" STREQUAL "") + file(RELATIVE_PATH output ${RUNTIME_DIR} ${INPUT_D}) + else ("${PATH}" STREQUAL "") + file(RELATIVE_PATH output ${PATH} ${INPUT_D}) + endif ("${PATH}" STREQUAL "") + set(OUTPUT_O ${PROJECT_BINARY_DIR}/${output}.o) + set(OUTPUT_BC ${PROJECT_BINARY_DIR}/${output}.bc) list(APPEND ${OUTLIST_O} ${OUTPUT_O}) list(APPEND ${OUTLIST_BC} ${OUTPUT_BC}) - + # Compile add_custom_command( OUTPUT ${OUTPUT_O} - ${OUTPUT_BC} - COMMAND ${LDC_LOC} -c -I${INCDIR} -I${RUNTIME_GC_DIR} -output-bc ${INPUT_D} -of${OUTPUT_O} ${D_FLAGS} ${MOREFLAGS} + #${OUTPUT_BC} + COMMAND ${LDC_LOC} -c -I${INCDIR} -I${RUNTIME_GC_DIR} ${INPUT_D} -of${OUTPUT_O} ${D_FLAGS} ${MOREFLAGS} DEPENDS ${LDC_LOC} ${INPUT_D} ${LDC_IMPORTS} @@ -128,17 +145,20 @@ macro(dc INPUT_D OUTLIST_O OUTLIST_BC OUTDIR INCDIR MOREFLAGS) ) endmacro(dc) -# dc_dir include for core and gc only necessary with druntime foreach(f ${CORE_D}) - dc(${f} CORE_O CORE_BC core ${RUNTIME_DC_DIR} "") + dc(${f} CORE_O CORE_BC ${RUNTIME_INCLUDE} "" "") endforeach(f) foreach(f ${GC_D}) - dc(${f} GC_O GC_BC gc "${RUNTIME_GC_DIR} ${RUNTIME_DC_DIR}" "-disable-invariants") + dc(${f} GC_O GC_BC ${RUNTIME_INCLUDE} "-disable-invariants" "") endforeach(f) foreach(f ${DCRT_D}) - dc(${f} DCRT_O DCRT_BC dcrt ${RUNTIME_DC_DIR} "") + if(D_VERSION EQUAL 1) + dc(${f} DCRT_O DCRT_BC ${RUNTIME_INCLUDE} "" ${RUNTIME_DC_DIR}) + else(D_VERSION EQUAL 1) + dc(${f} DCRT_O DCRT_BC ${RUNTIME_INCLUDE} "" "") + endif(D_VERSION EQUAL 1) endforeach(f) if(BUILD_SINGLE_LIB)