Mercurial > projects > ldc
changeset 486:a34078905d01
Added pragma(llvmdc, "string") for misc per-module compiler configuration, currently "string" can only be "verbose" which forces -vv for module it appears in.
Reimplemented support for nested functions/class using a new approach.
Added error on taking address of intrinsic.
Fixed problems with the ->syntaxCopy of TypeFunction delegate exp.
Removed DtoDType and replaced all uses with ->toBasetype() instead.
Removed unused inplace stuff.
Fixed a bunch of issues in the runtime unittests, not complete yet.
Added mini tests.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Sun, 10 Aug 2008 08:37:38 +0200 |
parents | 50f6e2337a6b |
children | d7b2e8777e2b |
files | dmd/attrib.c dmd/expression.c dmd/id.c dmd/id.h dmd/idgen.c dmd/mars.c dmd/module.c dmd/module.h dmd/mtype.c dmd/mtype.h gen/arrays.cpp gen/classes.cpp gen/classes.h gen/complex.cpp gen/dvalue.h gen/enums.h gen/functions.cpp gen/functions.h gen/llvmhelpers.cpp gen/llvmhelpers.h gen/statements.cpp gen/structs.cpp gen/tocall.cpp gen/todebug.cpp gen/toir.cpp gen/tollvm.cpp gen/tollvm.h gen/toobj.cpp ir/irfunction.cpp ir/irfunction.h runtime/internal/aApplyR.d runtime/internal/aaA.d runtime/internal/adi.d tests/mini/aa7.d tests/mini/nested13.d tests/mini/nested16.d tests/mini/nested17.d tests/mini/nested19.d tests/mini/nested6.d |
diffstat | 39 files changed, 696 insertions(+), 458 deletions(-) [+] |
line wrap: on
line diff
--- a/dmd/attrib.c Sat Aug 09 09:03:52 2008 +0200 +++ b/dmd/attrib.c Sun Aug 10 08:37:38 2008 +0200 @@ -831,7 +831,7 @@ // LLVMDC #if IN_LLVM - // pragma(intrinsic, string) { funcdecl(s) } + // pragma(intrinsic, "string") { funcdecl(s) } else if (ident == Id::intrinsic) { Expression* expr = (Expression *)args->data[0]; @@ -920,6 +920,27 @@ } llvm_internal = LLVMva_arg; } + + // pragma(llvmdc, "string") { templdecl(s) } + else if (ident == Id::llvmdc) + { + Expression* expr = (Expression *)args->data[0]; + expr = expr->semantic(sc); + if (!args || args->dim != 1 || !parseStringExp(expr, arg1str)) + { + error("pragma llvmdc requires exactly 1 string literal parameter"); + fatal(); + } + else if (arg1str == "verbose") + { + sc->module->llvmForceLogging = true; + } + else + { + error("pragma llvmdc command '%s' invalid"); + fatal(); + } + } #endif // LLVMDC
--- a/dmd/expression.c Sat Aug 09 09:03:52 2008 +0200 +++ b/dmd/expression.c Sun Aug 10 08:37:38 2008 +0200 @@ -260,6 +260,10 @@ { //printf("rewriting e1 to %s's this\n", f->toChars()); n++; + + // LLVMDC seems dmd misses it sometimes here :/ + f->vthis->nestedref = 1; + e1 = new VarExp(loc, f->vthis); } } @@ -5983,6 +5987,13 @@ FuncDeclaration *f = dve->var->isFuncDeclaration(); VarDeclaration *v = dve->var->isVarDeclaration(); + // LLVMDC + if (f && f->isIntrinsic()) + { + error("cannot take the address of intrinsic function %s", e1->toChars()); + return this; + } + if (f && f->isNested()) { Expression *e;
--- a/dmd/id.c Sat Aug 09 09:03:52 2008 +0200 +++ b/dmd/id.c Sun Aug 10 08:37:38 2008 +0200 @@ -176,6 +176,7 @@ Identifier *Id::vacopy; Identifier *Id::vaend; Identifier *Id::vaarg; +Identifier *Id::llvmdc; Identifier *Id::tohash; Identifier *Id::tostring; Identifier *Id::main; @@ -357,6 +358,7 @@ vacopy = Lexer::idPool("va_copy"); vaend = Lexer::idPool("va_end"); vaarg = Lexer::idPool("va_arg"); + llvmdc = Lexer::idPool("llvmdc"); tohash = Lexer::idPool("toHash"); tostring = Lexer::idPool("toString"); main = Lexer::idPool("main");
--- a/dmd/id.h Sat Aug 09 09:03:52 2008 +0200 +++ b/dmd/id.h Sun Aug 10 08:37:38 2008 +0200 @@ -178,6 +178,7 @@ static Identifier *vacopy; static Identifier *vaend; static Identifier *vaarg; + static Identifier *llvmdc; static Identifier *tohash; static Identifier *tostring; static Identifier *main;
--- a/dmd/idgen.c Sat Aug 09 09:03:52 2008 +0200 +++ b/dmd/idgen.c Sun Aug 10 08:37:38 2008 +0200 @@ -223,6 +223,7 @@ { "vacopy", "va_copy" }, { "vaend", "va_end" }, { "vaarg", "va_arg" }, + { "llvmdc" }, // For toHash/toString { "tohash", "toHash" },
--- a/dmd/mars.c Sat Aug 09 09:03:52 2008 +0200 +++ b/dmd/mars.c Sun Aug 10 08:37:38 2008 +0200 @@ -311,6 +311,7 @@ VersionCondition::addPredefinedGlobalIdent("LLVM"); VersionCondition::addPredefinedGlobalIdent("LLVMDC"); #endif + #if _WIN32 VersionCondition::addPredefinedGlobalIdent("Windows"); VersionCondition::addPredefinedGlobalIdent("Win32");
--- a/dmd/module.c Sat Aug 09 09:03:52 2008 +0200 +++ b/dmd/module.c Sun Aug 10 08:37:38 2008 +0200 @@ -162,6 +162,9 @@ bcfile = new File(bcfilename); llfile = new File(llfilename); symfile = new File(symfilename); + + // LLVMDC + llvmForceLogging = false; } void Module::setDocfile()
--- a/dmd/module.h Sat Aug 09 09:03:52 2008 +0200 +++ b/dmd/module.h Sun Aug 10 08:37:38 2008 +0200 @@ -66,8 +66,11 @@ ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration File *srcfile; // input source file File *objfile; // output .obj file + + // LLVMDC File *bcfile; // output .bc file File *llfile; // output .ll file + File *hdrfile; // 'header' file File *symfile; // output symbol file File *docfile; // output documentation file @@ -171,6 +174,8 @@ // LLVMDC Module *isModule() { return this; } + + bool llvmForceLogging; };
--- a/dmd/mtype.c Sat Aug 09 09:03:52 2008 +0200 +++ b/dmd/mtype.c Sun Aug 10 08:37:38 2008 +0200 @@ -2651,9 +2651,10 @@ this->varargs = varargs; this->linkage = linkage; this->inuse = 0; - this->llvmRetInPtr = false; - this->llvmUsesThis = false; - this->llvmRetAttrs = 0; + this->retInPtr = false; + this->usesThis = false; + this->usesNest = false; + this->retAttrs = 0; } Type *TypeFunction::syntaxCopy() @@ -2661,9 +2662,10 @@ Type *treturn = next ? next->syntaxCopy() : NULL; Arguments *params = Argument::arraySyntaxCopy(parameters); TypeFunction *t = new TypeFunction(params, treturn, varargs, linkage); - t->llvmRetInPtr = llvmRetInPtr; - t->llvmUsesThis = llvmUsesThis; - t->llvmRetAttrs = llvmRetAttrs; + t->retInPtr = retInPtr; + t->usesThis = usesThis; + t->usesNest = usesNest; + t->retAttrs = retAttrs; return t; } @@ -3813,6 +3815,11 @@ return sym->toChars(); } +Type *TypeEnum::syntaxCopy() +{ + return this; +} + Type *TypeEnum::semantic(Loc loc, Scope *sc) { sym->semantic(sc);
--- a/dmd/mtype.h Sat Aug 09 09:03:52 2008 +0200 +++ b/dmd/mtype.h Sun Aug 10 08:37:38 2008 +0200 @@ -441,9 +441,11 @@ unsigned totym(); - bool llvmRetInPtr; - bool llvmUsesThis; - unsigned llvmRetAttrs; + // LLVMDC + bool retInPtr; + bool usesThis; + bool usesNest; + unsigned retAttrs; }; struct TypeDelegate : Type @@ -556,6 +558,7 @@ d_uns64 size(Loc loc); unsigned alignsize(); char *toChars(); + Type *syntaxCopy(); Type *semantic(Loc loc, Scope *sc); Dsymbol *toDsymbol(Scope *sc); void toDecoBuffer(OutBuffer *buf);
--- a/gen/arrays.cpp Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/arrays.cpp Sun Aug 10 08:37:38 2008 +0200 @@ -89,7 +89,7 @@ const LLArrayType* arrty = isaArray(src->getType()->getContainedType(0)); if (!arrty) { - Logger::cout() << "invalid: " << *src << '\n'; + std::cout << "invalid: " << *src << '\n'; assert(0); } const LLType* dstty = getPtrToType(arrty->getElementType()); @@ -244,7 +244,7 @@ Logger::println("DtoConstArrayInitializer: %s | %s", arrinit->toChars(), arrinit->type->toChars()); LOG_SCOPE; - Type* arrinittype = DtoDType(arrinit->type); + Type* arrinittype = arrinit->type->toBasetype(); Type* t; integer_t tdim; @@ -530,8 +530,7 @@ DValue* e = exp->toElem(gIR); - if (!e->inPlace()) - DtoAssign(exp->loc, dptr, e); + DtoAssign(exp->loc, dptr, e); return slice; } @@ -573,8 +572,8 @@ Logger::println("DtoCatArrays"); LOG_SCOPE; - Type* t1 = DtoDType(exp1->type); - Type* t2 = DtoDType(exp2->type); + Type* t1 = exp1->type->toBasetype(); + Type* t2 = exp2->type->toBasetype(); assert(t1->ty == Tarray || t1->ty == Tsarray); assert(t2->ty == Tarray || t2->ty == Tsarray); @@ -614,8 +613,8 @@ Logger::println("DtoCatArrayElement"); LOG_SCOPE; - Type* t1 = DtoDType(exp1->type); - Type* t2 = DtoDType(exp2->type); + Type* t1 = exp1->type->toBasetype(); + Type* t2 = exp2->type->toBasetype(); DValue* e1 = exp1->toElem(gIR); DValue* e2 = exp2->toElem(gIR); @@ -623,7 +622,7 @@ llvm::Value *len1, *src1, *res; // handle prefix case, eg. int~int[] - if (t2->next && t1 == DtoDType(t2->next)) + if (t2->next && t1 == t2->next->toBasetype()) { len1 = DtoArrayLen(e2); res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp"); @@ -683,8 +682,8 @@ // cast static arrays to dynamic ones, this turns them into DSliceValues Logger::println("casting to dynamic arrays"); - Type* l_ty = DtoDType(l->getType()); - Type* r_ty = DtoDType(r->getType()); + Type* l_ty = l->getType()->toBasetype(); + Type* r_ty = r->getType()->toBasetype(); assert(l_ty->next == r_ty->next); if ((l_ty->ty == Tsarray) || (r_ty->ty == Tsarray)) { Type* a_ty = l_ty->next->arrayOf(); @@ -815,7 +814,7 @@ if (!skip) { - Type* t = DtoDType(DtoDType(l->getType())->next); + Type* t = l->getType()->toBasetype()->next->toBasetype(); if (t->ty == Tchar) res = DtoArrayEqCmp_impl(loc, "_adCmpChar", l, r, false); else @@ -900,7 +899,7 @@ Logger::println("DtoArrayLen"); LOG_SCOPE; - Type* t = DtoDType(v->getType()); + Type* t = v->getType()->toBasetype(); if (t->ty == Tarray) { if (DSliceValue* s = v->isSlice()) return s->len; @@ -926,7 +925,7 @@ Logger::println("DtoArrayPtr"); LOG_SCOPE; - Type* t = DtoDType(v->getType()); + Type* t = v->getType()->toBasetype(); if (t->ty == Tarray) { if (DSliceValue* s = v->isSlice()) return s->ptr; @@ -951,8 +950,8 @@ const LLType* tolltype = DtoType(to); - Type* totype = DtoDType(to); - Type* fromtype = DtoDType(u->getType()); + Type* totype = to->toBasetype(); + Type* fromtype = u->getType()->toBasetype(); assert(fromtype->ty == Tarray || fromtype->ty == Tsarray); LLValue* rval;
--- a/gen/classes.cpp Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/classes.cpp Sun Aug 10 08:37:38 2008 +0200 @@ -786,7 +786,7 @@ ////////////////////////////////////////////////////////////////////////////////////////// -DValue* DtoNewClass(TypeClass* tc, NewExp* newexp) +DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp) { // resolve type DtoForceDeclareDsymbol(tc->sym); @@ -829,25 +829,18 @@ DtoStore(src, dst); } // set the context for nested classes - else if (tc->sym->isNested()) + else if (tc->sym->isNested() && tc->sym->vthis) { Logger::println("Resolving nested context"); LOG_SCOPE; + // get context + LLValue* nest = DtoNestedContext(loc, tc->sym); + + // store into right location size_t idx = 2 + tc->sym->vthis->ir.irField->index; LLValue* gep = DtoGEPi(mem,0,idx,"tmp"); - - // this value might be zero if it was not necessary to generate it ... - LLValue* nest = gIR->func()->nestedVar; - // ... then revert to the this ptr if there is one - if (!nest) - nest = gIR->func()->thisVar; - // ... or just use zero, since it must be unused. - if (!nest) - nest = llvm::Constant::getNullValue(gep->getType()->getContainedType(0)); - else - nest = DtoBitCast(nest, gep->getType()->getContainedType(0)); - DtoStore(nest, gep); + DtoStore(DtoBitCast(nest, gep->getType()->getContainedType(0)), gep); } // call constructor @@ -860,7 +853,7 @@ } // return default constructed class - return new DImValue(tc, mem, false); + return new DImValue(tc, mem); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -912,7 +905,7 @@ Logger::println("DtoCastClass(%s, %s)", val->getType()->toChars(), _to->toChars()); LOG_SCOPE; - Type* to = DtoDType(_to); + Type* to = _to->toBasetype(); if (to->ty == Tpointer) { const LLType* tolltype = DtoType(_to); LLValue* rval = DtoBitCast(val->getRVal(), tolltype); @@ -922,7 +915,7 @@ assert(to->ty == Tclass); TypeClass* tc = (TypeClass*)to; - Type* from = DtoDType(val->getType()); + Type* from = val->getType()->toBasetype(); TypeClass* fc = (TypeClass*)from; if (tc->sym->isInterfaceDeclaration()) { @@ -977,7 +970,7 @@ assert(funcTy->getParamType(0) == obj->getType()); // ClassInfo c - TypeClass* to = (TypeClass*)DtoDType(_to); + TypeClass* to = (TypeClass*)_to->toBasetype(); DtoForceDeclareDsymbol(to->sym); assert(to->sym->ir.irStruct->classInfo); LLValue* cinfo = to->sym->ir.irStruct->classInfo; @@ -1041,7 +1034,7 @@ ptr = DtoBitCast(ptr, funcTy->getParamType(0)); // ClassInfo c - TypeClass* to = (TypeClass*)DtoDType(_to); + TypeClass* to = (TypeClass*)_to->toBasetype(); DtoForceDeclareDsymbol(to->sym); assert(to->sym->ir.irStruct->classInfo); LLValue* cinfo = to->sym->ir.irStruct->classInfo; @@ -1116,7 +1109,7 @@ for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { VarDeclaration* vd = i->second.var; assert(vd); - Type* vdtype = DtoDType(vd->type); + Type* vdtype = vd->type->toBasetype(); //Logger::println("found %u type %s", vd->offset, vdtype->toChars()); assert(vd->ir.irField->index >= 0); if (os == vd->offset && vdtype->toBasetype() == t->toBasetype()) { @@ -1173,7 +1166,7 @@ { assert(fdecl->isVirtual());//fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())); assert(fdecl->vtblIndex > 0); - assert(DtoDType(inst->getType())->ty == Tclass); + assert(inst->getType()->toBasetype()->ty == Tclass); LLValue* vthis = inst->getRVal(); Logger::cout() << "vthis: " << *vthis << '\n';
--- a/gen/classes.h Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/classes.h Sun Aug 10 08:37:38 2008 +0200 @@ -26,7 +26,7 @@ void DtoDeclareClassInfo(ClassDeclaration* cd); void DtoDefineClassInfo(ClassDeclaration* cd); -DValue* DtoNewClass(TypeClass* type, NewExp* newexp); +DValue* DtoNewClass(Loc loc, TypeClass* type, NewExp* newexp); void DtoInitClass(TypeClass* tc, LLValue* dst); DValue* DtoCallClassCtor(TypeClass* type, CtorDeclaration* ctor, Array* arguments, LLValue* mem); void DtoFinalizeClass(LLValue* inst);
--- a/gen/complex.cpp Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/complex.cpp Sun Aug 10 08:37:38 2008 +0200 @@ -13,7 +13,7 @@ const llvm::StructType* DtoComplexType(Type* type) { - Type* t = DtoDType(type); + Type* t = type->toBasetype(); const LLType* base = DtoComplexBaseType(t); @@ -26,7 +26,7 @@ const LLType* DtoComplexBaseType(Type* t) { - TY ty = DtoDType(t)->ty; + TY ty = t->toBasetype()->ty; const LLType* base; if (ty == Tcomplex32) { return LLType::FloatTy; @@ -62,7 +62,7 @@ LLConstant* DtoConstComplex(Type* _ty, long double re, long double im) { - TY ty = DtoDType(_ty)->ty; + TY ty = _ty->toBasetype()->ty; llvm::ConstantFP* fre; llvm::ConstantFP* fim; @@ -106,7 +106,7 @@ DValue* DtoComplex(Loc& loc, Type* to, DValue* val) { - Type* t = DtoDType(val->getType()); + Type* t = val->getType()->toBasetype(); if (val->isComplex() || t->iscomplex()) { return DtoCastComplex(loc, val, to); @@ -448,7 +448,7 @@ DValue* DtoCastComplex(Loc& loc, DValue* val, Type* _to) { - Type* to = DtoDType(_to); + Type* to = _to->toBasetype(); Type* vty = val->getType(); if (to->iscomplex()) { if (vty->size() == to->size())
--- a/gen/dvalue.h Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/dvalue.h Sun Aug 10 08:37:38 2008 +0200 @@ -54,8 +54,6 @@ virtual DComplexValue* isComplex() { return NULL; } virtual DLRValue* isLRValue() { return NULL; } - virtual bool inPlace() { return false; } - protected: DValue() {} DValue(const DValue&) { } @@ -67,16 +65,13 @@ { Type* type; LLValue* val; - bool inplace; - DImValue(Type* t, LLValue* v, bool in_place = false) { type = t; val = v; inplace = in_place; } + DImValue(Type* t, LLValue* v) : type(t), val(v) { } virtual LLValue* getRVal() { assert(val); return val; } virtual Type*& getType() { assert(type); return type; } virtual DImValue* isIm() { return this; } - - virtual bool inPlace() { return inplace; } }; // constant d-value
--- a/gen/enums.h Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/enums.h Sun Aug 10 08:37:38 2008 +0200 @@ -8,5 +8,6 @@ LLVMva_start, LLVMva_copy, LLVMva_end, - LLVMva_arg + LLVMva_arg, + LLVMllvmdc };
--- a/gen/functions.cpp Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/functions.cpp Sun Aug 10 08:37:38 2008 +0200 @@ -21,7 +21,7 @@ #include "gen/classes.h" #include "gen/dvalue.h" -const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bool ismain) +const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, const LLType* nesttype, bool ismain) { assert(type->ty == Tfunction); TypeFunction* f = (TypeFunction*)type; @@ -46,6 +46,7 @@ Type* rt = f->next; bool retinptr = false; bool usesthis = false; + bool usesnest = false; // parameter types std::vector<const LLType*> paramvec; @@ -66,7 +67,7 @@ if (DtoIsReturnedInArg(rt)) { rettype = getPtrToType(DtoType(rt)); actualRettype = LLType::VoidTy; - f->llvmRetInPtr = retinptr = true; + f->retInPtr = retinptr = true; } else { rettype = DtoType(rt); @@ -75,7 +76,7 @@ if (unsigned ea = DtoShouldExtend(rt)) { - f->llvmRetAttrs |= ea; + f->retAttrs |= ea; } } @@ -88,6 +89,10 @@ paramvec.push_back(thistype); usesthis = true; } + else if (nesttype) { + paramvec.push_back(nesttype); + usesnest = true; + } if (typesafeVararg) { ClassDeclaration* ti = Type::typeinfo; @@ -111,7 +116,7 @@ for (int i=0; i < n; ++i) { Argument* arg = Argument::getNth(f->parameters, i); // ensure scalar - Type* argT = DtoDType(arg->type); + Type* argT = arg->type->toBasetype(); assert(argT); bool refOrOut = ((arg->storageClass & STCref) || (arg->storageClass & STCout)); @@ -166,8 +171,9 @@ bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs; llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); - f->llvmRetInPtr = retinptr; - f->llvmUsesThis = usesthis; + f->retInPtr = retinptr; + f->usesThis = usesthis; + f->usesNest = usesnest; f->ir.type = new llvm::PATypeHolder(functype); @@ -210,7 +216,9 @@ if (fdecl->type->ir.type != 0) return llvm::cast<llvm::FunctionType>(fdecl->type->ir.type->get()); - const LLType* thisty = NULL; + const LLType* thisty = 0; + const LLType* nestty = 0; + if (fdecl->needThis()) { if (AggregateDeclaration* ad = fdecl->isMember2()) { Logger::println("isMember = this is: %s", ad->type->toChars()); @@ -225,10 +233,10 @@ } } else if (fdecl->isNested()) { - thisty = getPtrToType(LLType::Int8Ty); + nestty = getPtrToType(LLType::Int8Ty); } - const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, thisty, fdecl->isMain()); + const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, thisty, nestty, fdecl->isMain()); return functype; } @@ -237,7 +245,7 @@ static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl) { - TypeFunction* f = (TypeFunction*)DtoDType(fdecl->type); + TypeFunction* f = (TypeFunction*)fdecl->type->toBasetype(); const llvm::FunctionType* fty = DtoVaFunctionType(fdecl); llvm::Function* func = 0; @@ -306,8 +314,9 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl) { int llidx = 1; - if (f->llvmRetInPtr) ++llidx; - if (f->llvmUsesThis) ++llidx; + if (f->retInPtr) ++llidx; + if (f->usesThis) ++llidx; + else if (f->usesNest) ++llidx; if (f->linkage == LINKd && f->varargs == 1) llidx += 2; @@ -318,15 +327,15 @@ llvm::ParamAttrsWithIndex PAWI; // set return value attrs if any - if (f->llvmRetAttrs) + if (f->retAttrs) { PAWI.Index = 0; - PAWI.Attrs = f->llvmRetAttrs; + PAWI.Attrs = f->retAttrs; attrs.push_back(PAWI); } // set sret param - if (f->llvmRetInPtr) + if (f->retInPtr) { PAWI.Index = 1; PAWI.Attrs = llvm::ParamAttr::StructRet; @@ -378,7 +387,7 @@ } // get TypeFunction* - Type* t = DtoDType(fdecl->type); + Type* t = fdecl->type->toBasetype(); TypeFunction* f = (TypeFunction*)t; bool declareOnly = false; @@ -417,8 +426,6 @@ llvm::Function* func = vafunc ? vafunc : gIR->module->getFunction(mangled_name); if (!func) func = llvm::Function::Create(functype, DtoLinkage(fdecl), mangled_name, gIR->module); - else - assert(func->getFunctionType() == functype); // add func to IRFunc fdecl->ir.irFunc->func = func; @@ -457,15 +464,22 @@ // name parameters llvm::Function::arg_iterator iarg = func->arg_begin(); int k = 0; - if (f->llvmRetInPtr) { - iarg->setName("retval"); + if (f->retInPtr) { + iarg->setName(".sretarg"); fdecl->ir.irFunc->retArg = iarg; ++iarg; } - if (f->llvmUsesThis) { - iarg->setName(fdecl->isNested()?".context":"this"); - fdecl->ir.irFunc->thisVar = iarg; - assert(fdecl->ir.irFunc->thisVar); + + if (f->usesThis) { + iarg->setName("this"); + fdecl->ir.irFunc->thisArg = iarg; + assert(fdecl->ir.irFunc->thisArg); + ++iarg; + } + else if (f->usesNest) { + iarg->setName(".nest"); + fdecl->ir.irFunc->nestArg = iarg; + assert(fdecl->ir.irFunc->nestArg); ++iarg; } @@ -520,13 +534,19 @@ Logger::println("DtoDefineFunc(%s): %s", fd->toPrettyChars(), fd->loc.toChars()); LOG_SCOPE; + // warn about naked + if (fd->naked) + { + warning("%s: naked is currently ignored", fd->locToChars()); + } + // debug info if (global.params.symdebug) { Module* mo = fd->getModule(); fd->ir.irFunc->dwarfSubProg = DtoDwarfSubProgram(fd); } - Type* t = DtoDType(fd->type); + Type* t = fd->type->toBasetype(); TypeFunction* f = (TypeFunction*)t; assert(f->ir.type); @@ -568,26 +588,32 @@ // debug info - after all allocas, but before any llvm.dbg.declare etc if (global.params.symdebug) DtoDwarfFuncStart(fd); - // need result variable? (not nested) - if (fd->vresult && !fd->vresult->nestedref) { - Logger::println("non-nested vresult value"); + // need result variable? + if (fd->vresult) { + Logger::println("vresult value"); fd->vresult->ir.irLocal = new IrLocal(fd->vresult); - fd->vresult->ir.irLocal->value = DtoAlloca(DtoType(fd->vresult->type),"function_vresult"); + fd->vresult->ir.irLocal->value = DtoAlloca(DtoType(fd->vresult->type), "function_vresult"); } // give the 'this' argument storage and debug info - // only if not referenced by nested functions - if (fd->needThis() && !fd->vthis->nestedref) + if (f->usesThis) { - LLValue* thisvar = irfunction->thisVar; + LLValue* thisvar = irfunction->thisArg; assert(thisvar); - LLValue* thismem = DtoAlloca(thisvar->getType(), ".newthis"); + LLValue* thismem = DtoAlloca(thisvar->getType(), ".this"); DtoStore(thisvar, thismem); - irfunction->thisVar = thismem; + irfunction->thisArg = thismem; + + assert(!fd->vthis->ir.irLocal); + fd->vthis->ir.irLocal = new IrLocal(fd->vthis); + fd->vthis->ir.irLocal->value = thismem; if (global.params.symdebug) DtoDwarfLocalVariable(thismem, fd->vthis); + + if (fd->vthis->nestedref) + fd->nestedVars.insert(fd->vthis); } // give arguments storage @@ -600,13 +626,16 @@ Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i]; VarDeclaration* vd = argsym->isVarDeclaration(); assert(vd); + + if (vd->nestedref) + fd->nestedVars.insert(vd); IrLocal* irloc = vd->ir.irLocal; assert(irloc); bool refoutlazy = vd->storage_class & (STCref | STCout | STClazy); - if (vd->nestedref || refoutlazy) + if (refoutlazy) { continue; } @@ -625,66 +654,99 @@ } } - LLValue* parentNested = NULL; - if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) { - if (!fd->isStatic()) // huh? - parentNested = fd2->ir.irFunc->nestedVar; - } - // need result variable? (nested) if (fd->vresult && fd->vresult->nestedref) { Logger::println("nested vresult value: %s", fd->vresult->toChars()); fd->nestedVars.insert(fd->vresult); } - // construct nested variables struct - if (!fd->nestedVars.empty() || parentNested) { - std::vector<const LLType*> nestTypes; - int j = 0; - if (parentNested) { - nestTypes.push_back(parentNested->getType()); - j++; + // construct nested variables array + if (!fd->nestedVars.empty()) + { + Logger::println("has nested frame"); + // start with add all enclosing parent frames + int nparelems = 0; + Dsymbol* par = fd->toParent2(); + while (par) + { + if (FuncDeclaration* parfd = par->isFuncDeclaration()) + { + nparelems += parfd->nestedVars.size(); + } + else if (ClassDeclaration* parcd = par->isClassDeclaration()) + { + // nothing needed + } + else + { + break; + } + par = par->toParent2(); } - for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) { + int nelems = fd->nestedVars.size() + nparelems; + + // make array type for nested vars + const LLType* nestedVarsTy = LLArrayType::get(getVoidPtrType(), nelems); + + // alloca it + LLValue* nestedVars = DtoAlloca(nestedVarsTy, ".nested_vars"); + + // copy parent frame into beginning + if (nparelems) + { + LLValue* src = irfunction->nestArg; + if (!src) + { + assert(irfunction->thisArg); + assert(fd->isMember2()); + LLValue* thisval = DtoLoad(irfunction->thisArg); + ClassDeclaration* cd = fd->isMember2()->isClassDeclaration(); + assert(cd); + assert(cd->vthis); + src = DtoLoad(DtoGEPi(thisval, 0,2+cd->vthis->ir.irField->index, ".vthis")); + } + DtoMemCpy(nestedVars, src, DtoConstSize_t(nparelems*PTRSIZE)); + } + + // store in IrFunction + irfunction->nestedVar = nestedVars; + + // go through all nested vars and assign indices + int idx = nparelems; + for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) + { VarDeclaration* vd = *i; - Logger::println("referenced nested variable %s", vd->toChars()); if (!vd->ir.irLocal) vd->ir.irLocal = new IrLocal(vd); - vd->ir.irLocal->nestedIndex = j++; - if (vd->isParameter()) { - if (!vd->ir.irLocal->value) { - assert(vd == fd->vthis); - vd->ir.irLocal->value = fd->ir.irFunc->thisVar; - } - assert(vd->ir.irLocal->value); - nestTypes.push_back(vd->ir.irLocal->value->getType()); + + if (vd->isParameter()) + { + Logger::println("nested param: %s", vd->toChars()); + LLValue* gep = DtoGEPi(nestedVars, 0, idx); + LLValue* val = DtoBitCast(vd->ir.irLocal->value, getVoidPtrType()); + DtoStore(val, gep); } - else { - nestTypes.push_back(DtoType(vd->type)); + else + { + Logger::println("nested var: %s", vd->toChars()); } + + vd->ir.irLocal->nestedIndex = idx++; } - const llvm::StructType* nestSType = llvm::StructType::get(nestTypes); - Logger::cout() << "nested var struct has type:" << *nestSType << '\n'; - fd->ir.irFunc->nestedVar = DtoAlloca(nestSType,"nestedvars"); - if (parentNested) { - assert(fd->ir.irFunc->thisVar); - LLValue* ptr = gIR->ir->CreateBitCast(fd->ir.irFunc->thisVar, parentNested->getType(), "tmp"); - gIR->ir->CreateStore(ptr, DtoGEPi(fd->ir.irFunc->nestedVar, 0,0, "tmp")); - } - for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) { - VarDeclaration* vd = *i; - if (vd->isParameter()) { - assert(vd->ir.irLocal); - gIR->ir->CreateStore(vd->ir.irLocal->value, DtoGEPi(fd->ir.irFunc->nestedVar, 0, vd->ir.irLocal->nestedIndex, "tmp")); - vd->ir.irLocal->value = fd->ir.irFunc->nestedVar; - } + + // fixup nested result variable + if (fd->vresult && fd->vresult->nestedref) { + Logger::println("nested vresult value: %s", fd->vresult->toChars()); + LLValue* gep = DtoGEPi(nestedVars, 0, fd->vresult->ir.irLocal->nestedIndex); + LLValue* val = DtoBitCast(fd->vresult->ir.irLocal->value, getVoidPtrType()); + DtoStore(val, gep); } } // copy _argptr to a memory location if (f->linkage == LINKd && f->varargs == 1) { - LLValue* argptrmem = DtoAlloca(fd->ir.irFunc->_argptr->getType(), "_argptrmem"); + LLValue* argptrmem = DtoAlloca(fd->ir.irFunc->_argptr->getType(), "_argptr_mem"); new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb()); fd->ir.irFunc->_argptr = argptrmem; } @@ -784,14 +846,14 @@ if (fnarg && ((fnarg->storageClass & STCref) || (fnarg->storageClass & STCout))) { if (arg->isVar() || arg->isLRValue()) - arg = new DImValue(argexp->type, arg->getLVal(), false); + arg = new DImValue(argexp->type, arg->getLVal()); else - arg = new DImValue(argexp->type, arg->getRVal(), false); + arg = new DImValue(argexp->type, arg->getRVal()); } // byval arg, but expr has no storage yet else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isComplex() || arg->isNull())) { - LLValue* alloc = DtoAlloca(DtoType(argexp->type), "tmpparam"); + LLValue* alloc = DtoAlloca(DtoType(argexp->type), ".tmp_arg"); DVarValue* vv = new DVarValue(argexp->type, alloc, true); DtoAssign(argexp->loc, vv, arg); arg = vv;
--- a/gen/functions.h Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/functions.h Sun Aug 10 08:37:38 2008 +0200 @@ -1,7 +1,7 @@ #ifndef LLVMDC_GEN_FUNCTIONS_H #define LLVMDC_GEN_FUNCTIONS_H -const llvm::FunctionType* DtoFunctionType(Type* t, const LLType* thistype, bool ismain = false); +const llvm::FunctionType* DtoFunctionType(Type* t, const LLType* thistype, const LLType* nesttype, bool ismain = false); const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl); const llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl);
--- a/gen/llvmhelpers.cpp Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/llvmhelpers.cpp Sun Aug 10 08:37:38 2008 +0200 @@ -349,154 +349,70 @@ // NESTED VARIABLE HELPERS ////////////////////////////////////////////////////////////////////////////////////////*/ -/* - -got: - - context pointer of 'this' function - - declaration for target context's function - -want: - - context pointer of target function in call chain - -*/ - -static LLValue* dive_into_nested(Dsymbol* from, LLValue* val) +DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd) { - from = from->toParent2(); - - // parent is a function - if (FuncDeclaration* f = from->isFuncDeclaration()) + Dsymbol* vdparent = vd->toParent2(); + assert(vdparent); + + IrFunction* irfunc = gIR->func(); + + // is the nested variable in this scope? + if (vdparent == irfunc->decl) { - IrFunction* irfunc = f->ir.irFunc; - // parent has nested var struct - if (irfunc->nestedVar) - { - return DtoBitCast(val, irfunc->nestedVar->getType()); - } - // parent has this argument - else if (irfunc->thisVar) - { - return DtoBitCast(val, irfunc->thisVar->getType()->getContainedType(0)); - } - // none of the above, means no context is required, dummy. - else - { - return getNullPtr(getVoidPtrType()); - } + LLValue* val = vd->ir.getIrValue(); + return new DVarValue(astype, vd, val, true); + } + + // get it from the nested context + LLValue* ctx = 0; + if (irfunc->decl->isMember2()) + { + ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration(); + LLValue* val = DtoLoad(irfunc->thisArg); + ctx = DtoLoad(DtoGEPi(val, 0,2+cd->vthis->ir.irField->index, ".vthis")); } - // parent is a class - else if (ClassDeclaration* c = from->isClassDeclaration()) - { - return DtoBitCast(DtoLoad(val), DtoType(c->type)); - } - // parent is not valid else - { - assert(0 && "!(class|function)"); - } + ctx = irfunc->nestArg; + assert(ctx); + + assert(vd->ir.irLocal); + LLValue* val = DtoBitCast(ctx, getPtrToType(getVoidPtrType())); + val = DtoGEPi1(val, vd->ir.irLocal->nestedIndex); + val = DtoLoad(val); + assert(vd->ir.irLocal->value); + val = DtoBitCast(val, vd->ir.irLocal->value->getType(), vd->toChars()); + return new DVarValue(astype, vd, val, true); } -LLValue* DtoNestedContext(FuncDeclaration* func) +LLValue* DtoNestedContext(Loc loc, Dsymbol* sym) { - Logger::println("listing context frame list for funcdecl '%s'", func->toPrettyChars()); + Logger::println("DtoNestedContext for %s", sym->toPrettyChars()); LOG_SCOPE; - int level = 0; - IrFunction* irfunc = gIR->func(); - Dsymbol* current = irfunc->decl; - - // this context ? - if (current == func) - { + + if (irfunc->nestedVar) return irfunc->nestedVar; - } - - // otherwise use the context argument - LLValue* val = dive_into_nested(current, irfunc->thisVar); - current = current->toParent2(); - assert(val); - - for (;;) + else if (irfunc->nestArg) + return irfunc->nestArg; + else if (irfunc->thisArg) { - Logger::cout() << "context: " << *val << '\n'; - Logger::println("(%d) looking in: %s (%s)", level, current->toPrettyChars(), current->kind()); - if (FuncDeclaration* f = current->isFuncDeclaration()) - { - if (f == func) - { - Logger::println("-> found <-"); - Logger::cout() << "-> val: " << *val << '\n'; - return val; - } - else - { - val = DtoLoad(DtoGEPi(val,0,0)); - } - } - else if (ClassDeclaration* c = current->isClassDeclaration()) - { - val = DtoLoad(DtoGEPi(val, 0, 2+c->vthis->ir.irField->index)); - val = dive_into_nested(current, val); - } - else - { - Logger::cout() << "val: " << *val << '\n'; - assert(0 && "!(class|function)"); - } - current = current->toParent2(); - ++level; + ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration(); + assert(cd); + if (!cd->vthis) + return getNullPtr(getVoidPtrType()); + LLValue* val = DtoLoad(irfunc->thisArg); + return DtoLoad(DtoGEPi(val, 0,2+cd->vthis->ir.irField->index, ".vthis")); } - - assert(0); - return val; -} - -DValue* DtoNestedVariable(Type* astype, VarDeclaration* vd) -{ - IrFunction* irfunc = gIR->func(); - - // var parent (the scope we're looking for) - Dsymbol* varParent = vd->toParent2(); - - // on level 0 - if (varParent == irfunc->decl) + else { - LLValue* nest = irfunc->nestedVar; - LLValue* v = DtoGEPi(nest, 0, vd->ir.irLocal->nestedIndex, "tmp"); - // references must be loaded to get the variable address - if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) - v = DtoLoad(v); - return new DVarValue(astype, vd, v, true); + if (irfunc->decl->isStatic()) + { + irfunc->decl->error("is static and cannot access nested %s %s", sym->kind(), sym->toChars()); + fatal(); + } + return getNullPtr(getVoidPtrType()); } - - // on level n != 0 - FuncDeclaration* varFunc = varParent->isFuncDeclaration(); - assert(varFunc); - - // get context of variable - LLValue* ctx = DtoNestedContext(varFunc); - - // if no local var, it's the context itself (class this) - if (!vd->ir.irLocal) - return new DImValue(astype, ctx); - - // extract variable - IrLocal* local = vd->ir.irLocal; - assert(local); - assert(local->nestedIndex >= 0); - LLValue* val = DtoGEPi(ctx, 0, local->nestedIndex); - - // references must be loaded to get the variable address - if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) - val = DtoLoad(val); - - Logger::cout() << "value: " << *val << '\n'; - - return new DVarValue(astype, vd, val, true); } /****************************************************************************************/ @@ -509,15 +425,15 @@ Logger::cout() << "DtoAssign(...);\n"; LOG_SCOPE; - Type* t = DtoDType(lhs->getType()); - Type* t2 = DtoDType(rhs->getType()); + Type* t = lhs->getType()->toBasetype(); + Type* t2 = rhs->getType()->toBasetype(); if (t->ty == Tstruct) { if (!t->equals(t2)) { // TODO: fix this, use 'rhs' for something DtoAggrZeroInit(lhs->getLVal()); } - else if (!rhs->inPlace()) { + else { DtoAggrCopy(lhs->getLVal(), rhs->getRVal()); } } @@ -559,7 +475,7 @@ else if (t->ty == Tdelegate) { if (rhs->isNull()) DtoAggrZeroInit(lhs->getLVal()); - else if (!rhs->inPlace()) { + else { LLValue* l = lhs->getLVal(); LLValue* r = rhs->getRVal(); Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n'; @@ -665,8 +581,8 @@ { const LLType* tolltype = DtoType(_to); - Type* to = DtoDType(_to); - Type* from = DtoDType(val->getType()); + Type* to = _to->toBasetype(); + Type* from = val->getType()->toBasetype(); assert(from->isintegral()); size_t fromsz = from->size(); @@ -720,8 +636,8 @@ { const LLType* tolltype = DtoType(to); - Type* totype = DtoDType(to); - Type* fromtype = DtoDType(val->getType()); + Type* totype = to->toBasetype(); + Type* fromtype = val->getType()->toBasetype(); assert(fromtype->ty == Tpointer || fromtype->ty == Tfunction); LLValue* rval; @@ -749,8 +665,8 @@ const LLType* tolltype = DtoType(to); - Type* totype = DtoDType(to); - Type* fromtype = DtoDType(val->getType()); + Type* totype = to->toBasetype(); + Type* fromtype = val->getType()->toBasetype(); assert(fromtype->isfloating()); size_t fromsz = fromtype->size(); @@ -814,7 +730,7 @@ DValue* DtoCast(Loc& loc, DValue* val, Type* to) { - Type* fromtype = DtoDType(val->getType()); + Type* fromtype = val->getType()->toBasetype(); Logger::println("Casting from '%s' to '%s'", fromtype->toChars(), to->toChars()); if (fromtype->isintegral()) { return DtoCastInt(loc, val, to); @@ -879,10 +795,10 @@ gIR->ir->CreateCondBr(cond, initbb, endinitbb); gIR->scope() = IRScope(initbb,endinitbb); DValue* ie = DtoInitializer(gvar, init); - if (!ie->inPlace()) { - DValue* dst = new DVarValue(t, gvar, true); - DtoAssign(init->loc, dst, ie); - } + + DVarValue dst(t, gvar, true); + DtoAssign(init->loc, &dst, ie); + gIR->ir->CreateStore(DtoConstBool(true), gflag); gIR->ir->CreateBr(endinitbb); gIR->scope() = IRScope(endinitbb,oldend); @@ -1001,7 +917,7 @@ } const LLType* _type = DtoType(vd->type); - Type* t = DtoDType(vd->type); + Type* t = vd->type->toBasetype(); //Logger::cout() << "initializer: " << *_init << '\n'; if (_type != _init->getType()) { @@ -1218,9 +1134,23 @@ if (vd->nestedref) { Logger::println("has nestedref set"); assert(vd->ir.irLocal); - vd->ir.irLocal->value = gIR->func()->decl->ir.irFunc->nestedVar; - assert(vd->ir.irLocal->value); + + // alloca as usual is no value already + if (!vd->ir.irLocal->value) + { + vd->ir.irLocal->value = DtoAlloca(DtoType(vd->type), vd->toChars()); + } + + // store the address into the nested vars array + assert(vd->ir.irLocal->nestedIndex >= 0); + LLValue* gep = DtoGEPi(gIR->func()->decl->ir.irFunc->nestedVar, 0, vd->ir.irLocal->nestedIndex); + + assert(isaPointer(vd->ir.irLocal->value)); + LLValue* val = DtoBitCast(vd->ir.irLocal->value, getVoidPtrType()); + + DtoStore(val, gep); + } // normal stack variable, allocate storage on the stack if it has not already been done else if(!vd->ir.irLocal) { @@ -1241,6 +1171,10 @@ DtoDwarfLocalVariable(allocainst, vd); } } + else + { + assert(vd->ir.irLocal->value); + } Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n'; DValue* ie = DtoInitializer(vd->ir.irLocal->value, vd->init);
--- a/gen/llvmhelpers.h Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/llvmhelpers.h Sun Aug 10 08:37:38 2008 +0200 @@ -38,9 +38,18 @@ // leaves a monitor lock void DtoLeaveMonitor(LLValue* v); -// nested variable/class helpers -LLValue* DtoNestedContext(FuncDeclaration* func); -DValue* DtoNestedVariable(Type* astype, VarDeclaration* vd); +// nested variable and context helpers + +// gets the context value for a call to a nested function or newing a class, with arbitrary nesting +LLValue* DtoNestedContext(Loc loc, Dsymbol* sym); + +// gets the dvalue of a nested variable with arbitrary nesting +DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd); + +// old nested stuff +// LLValue* DtoNestedContext(Loc loc, FuncDeclaration* func); +// LLValue* DtoNestedContext(Loc loc, ClassDeclaration* cd); +// DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd); // basic operations void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs);
--- a/gen/statements.cpp Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/statements.cpp Sun Aug 10 08:37:38 2008 +0200 @@ -57,7 +57,7 @@ { if (p->topfunc()->getReturnType() == LLType::VoidTy) { IrFunction* f = p->func(); - assert(f->type->llvmRetInPtr); + assert(f->type->retInPtr); assert(f->decl->ir.irFunc->retArg); if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum); @@ -66,8 +66,7 @@ DValue* e = exp->toElem(p); - if (!e->inPlace()) - DtoAssign(loc, rvar, e); + DtoAssign(loc, rvar, e); DtoEnclosingHandlers(enclosinghandler, NULL); @@ -647,8 +646,8 @@ static LLValue* call_string_switch_runtime(llvm::GlobalVariable* table, Expression* e) { - Type* dt = DtoDType(e->type); - Type* dtnext = DtoDType(dt->next); + Type* dt = e->type->toBasetype(); + Type* dtnext = dt->next->toBasetype(); TY ty = dtnext->ty; const char* fname; if (ty == Tchar) { @@ -934,7 +933,7 @@ // what to iterate DValue* aggrval = aggr->toElem(p); - Type* aggrtype = DtoDType(aggr->type); + Type* aggrtype = aggr->type->toBasetype(); // get length and pointer LLValue* niters = DtoArrayLen(aggrval);
--- a/gen/structs.cpp Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/structs.cpp Sun Aug 10 08:37:38 2008 +0200 @@ -67,7 +67,7 @@ for (unsigned i=0; i<sd->fields.dim; ++i) { VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i]; - Type* vdtype = DtoDType(vd->type); + Type* vdtype = vd->type->toBasetype(); //Logger::println("found %u type %s", vd->offset, vdtype->toChars()); assert(vd->ir.irField->index >= 0); if (os == vd->offset && vdtype == t) { @@ -125,7 +125,7 @@ if (sd->prot() == PROTprivate && sd->getModule() != gIR->dmodule) Logger::println("using a private struct from outside its module"); - TypeStruct* ts = (TypeStruct*)DtoDType(sd->type); + TypeStruct* ts = (TypeStruct*)sd->type->toBasetype(); bool ispacked = (ts->alignsize() == 1); @@ -279,7 +279,7 @@ Logger::println("DtoDeclareStruct(%s): %s", sd->toChars(), sd->loc.toChars()); LOG_SCOPE; - TypeStruct* ts = (TypeStruct*)DtoDType(sd->type); + TypeStruct* ts = (TypeStruct*)sd->type->toBasetype(); std::string initname("_D"); initname.append(sd->mangle());
--- a/gen/tocall.cpp Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/tocall.cpp Sun Aug 10 08:37:38 2008 +0200 @@ -71,6 +71,7 @@ else if (type->ty == Tdelegate) { LLValue* dg = fn->getRVal(); + Logger::cout() << "delegate: " << *dg << '\n'; LLValue* funcptr = DtoGEPi(dg, 0, 1); return DtoLoad(funcptr); } @@ -200,10 +201,10 @@ TypeFunction* tf = DtoTypeFunction(fnval); // misc - bool retinptr = tf->llvmRetInPtr; - bool usesthis = tf->llvmUsesThis; + bool retinptr = tf->retInPtr; + bool thiscall = tf->usesThis; bool delegatecall = (calleeType->toBasetype()->ty == Tdelegate); - bool nestedcall = (dfnval && dfnval->func && dfnval->func->isNested()); + bool nestedcall = tf->usesNest; bool dvarargs = (tf->linkage == LINKd && tf->varargs == 1); unsigned callconv = DtoCallingConv(tf->linkage); @@ -221,8 +222,8 @@ llvm::PAListPtr palist; // return attrs - if (tf->llvmRetAttrs) - palist = palist.addAttr(0, tf->llvmRetAttrs); + if (tf->retAttrs) + palist = palist.addAttr(0, tf->retAttrs); // handle implicit arguments std::vector<LLValue*> args; @@ -237,11 +238,12 @@ } // then comes a context argument... - if(usesthis || delegatecall || nestedcall) + if(thiscall || delegatecall || nestedcall) { // ... which can be a 'this' argument - if (dfnval && dfnval->vthis) + if (thiscall) { + assert(dfnval && dfnval->vthis); LLValue* thisarg = DtoBitCast(dfnval->vthis, argiter->get()); ++argiter; args.push_back(thisarg); @@ -257,11 +259,8 @@ // ... or a nested function context arg else if (nestedcall) { - LLValue* contextptr = DtoNestedContext(dfnval->func->toParent2()->isFuncDeclaration()); - if (!contextptr) - contextptr = getNullPtr(getVoidPtrType()); - else - contextptr = DtoBitCast(contextptr, getVoidPtrType()); + LLValue* contextptr = DtoNestedContext(loc, dfnval->func); + contextptr = DtoBitCast(contextptr, getVoidPtrType()); ++argiter; args.push_back(contextptr); } @@ -354,7 +353,7 @@ call->setCallingConv(callconv); call->setParamAttrs(palist); - return new DImValue(resulttype, retllval, false); + return new DImValue(resulttype, retllval); }
--- a/gen/todebug.cpp Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/todebug.cpp Sun Aug 10 08:37:38 2008 +0200 @@ -239,7 +239,7 @@ static LLGlobalVariable* dwarfDerivedType(Type* type, llvm::GlobalVariable* compileUnit) { const LLType* T = DtoType(type); - Type* t = DtoDType(type); + Type* t = type->toBasetype(); // defaults LLConstant* name = getNullPtr(getVoidPtrType()); @@ -300,7 +300,7 @@ static LLGlobalVariable* dwarfMemberType(unsigned linnum, Type* type, LLGlobalVariable* compileUnit, LLGlobalVariable* definedCU, const char* c_name, unsigned offset) { const LLType* T = DtoType(type); - Type* t = DtoDType(type); + Type* t = type->toBasetype(); // defaults LLConstant* name; @@ -356,7 +356,7 @@ static LLGlobalVariable* dwarfCompositeType(Type* type, llvm::GlobalVariable* compileUnit) { const LLType* T = DtoType(type); - Type* t = DtoDType(type); + Type* t = type->toBasetype(); // defaults LLConstant* name = getNullPtr(getVoidPtrType());
--- a/gen/toir.cpp Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/toir.cpp Sun Aug 10 08:37:38 2008 +0200 @@ -106,7 +106,7 @@ // nested variable else if (vd->nestedref) { Logger::println("nested variable"); - return DtoNestedVariable(type, vd); + return DtoNestedVariable(loc, type, vd); } // function parameter else if (vd->isParameter()) { @@ -114,7 +114,7 @@ FuncDeclaration* fd = vd->toParent2()->isFuncDeclaration(); if (fd && fd != p->func()->decl) { Logger::println("nested parameter"); - return DtoNestedVariable(type, vd); + return DtoNestedVariable(loc, type, vd); } else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->ir.getIrValue())) { return new DVarValue(type, vd, vd->ir.getIrValue(), true); @@ -151,7 +151,7 @@ else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) { // this seems to be the static initialiser for structs - Type* sdecltype = DtoDType(sdecl->type); + Type* sdecltype = sdecl->type->toBasetype(); Logger::print("Sym: type=%s\n", sdecltype->toChars()); assert(sdecltype->ty == Tstruct); TypeStruct* ts = (TypeStruct*)sdecltype; @@ -177,7 +177,7 @@ if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) { // this seems to be the static initialiser for structs - Type* sdecltype = DtoDType(sdecl->type); + Type* sdecltype = sdecl->type->toBasetype(); Logger::print("Sym: type=%s\n", sdecltype->toChars()); assert(sdecltype->ty == Tstruct); TypeStruct* ts = (TypeStruct*)sdecltype; @@ -242,7 +242,7 @@ { Logger::print("RealExp::toConstElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - Type* t = DtoDType(type); + Type* t = type->toBasetype(); return DtoConstFP(t, value); } @@ -283,7 +283,7 @@ LLConstant* c = toConstElem(p); if (c->isNullValue()) { - Type* t = DtoDType(type); + Type* t = type->toBasetype(); if (t->ty == Tcomplex32) c = DtoConstFP(Type::tfloat32, 0); else if (t->ty == Tcomplex64) @@ -314,8 +314,8 @@ Logger::print("StringExp::toElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - Type* dtype = DtoDType(type); - Type* cty = DtoDType(dtype->next); + Type* dtype = type->toBasetype(); + Type* cty = dtype->next->toBasetype(); const LLType* ct = DtoTypeNotVoid(cty); //printf("ct = %s\n", type->next->toChars()); @@ -382,8 +382,8 @@ Logger::print("StringExp::toConstElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - Type* t = DtoDType(type); - Type* cty = DtoDType(t->next); + Type* t = type->toBasetype(); + Type* cty = t->next->toBasetype(); bool nullterm = (t->ty != Tsarray); size_t endlen = nullterm ? len+1 : len; @@ -472,7 +472,19 @@ if (l->isSlice() || l->isComplex()) return l; +#if 0 + if (type->toBasetype()->ty == Tstruct && e2->type->isintegral()) + { + // handle struct = 0; + return l; + } + else + { + return r; + } +#else return r; +#endif } ////////////////////////////////////////////////////////////////////////////////////////// @@ -485,10 +497,10 @@ DValue* l = e1->toElem(p); DValue* r = e2->toElem(p); - Type* t = DtoDType(type); - Type* e1type = DtoDType(e1->type); - Type* e1next = e1type->next ? DtoDType(e1type->next) : NULL; - Type* e2type = DtoDType(e2->type); + Type* t = type->toBasetype(); + Type* e1type = e1->type->toBasetype(); + Type* e1next = e1type->next ? e1type->next->toBasetype() : NULL; + Type* e2type = e2->type->toBasetype(); if (e1type != e2type) { if (llvmFieldIndex) { @@ -537,10 +549,10 @@ DValue* l = e1->toElem(p); DValue* r = e2->toElem(p); - Type* t = DtoDType(type); + Type* t = type->toBasetype(); DValue* res; - if (DtoDType(e1->type)->ty == Tpointer) { + if (e1->type->toBasetype()->ty == Tpointer) { LLValue* gep = llvm::GetElementPtrInst::Create(l->getRVal(),r->getRVal(),"tmp",p->scopebb()); res = new DImValue(type, gep); } @@ -565,9 +577,9 @@ DValue* l = e1->toElem(p); DValue* r = e2->toElem(p); - Type* t = DtoDType(type); - Type* t1 = DtoDType(e1->type); - Type* t2 = DtoDType(e2->type); + Type* t = type->toBasetype(); + Type* t1 = e1->type->toBasetype(); + Type* t2 = e2->type->toBasetype(); if (t1->ty == Tpointer && t2->ty == Tpointer) { LLValue* lv = l->getRVal(); @@ -603,10 +615,10 @@ DValue* l = e1->toElem(p); DValue* r = e2->toElem(p); - Type* t = DtoDType(type); + Type* t = type->toBasetype(); DValue* res; - if (DtoDType(e1->type)->ty == Tpointer) { + if (e1->type->toBasetype()->ty == Tpointer) { Logger::println("ptr"); LLValue* tmp = r->getRVal(); LLValue* zero = llvm::ConstantInt::get(tmp->getType(),0,false); @@ -770,7 +782,7 @@ DValue* expv = exp->toElem(p); if (expv->getType()->toBasetype()->ty != Tint32) expv = DtoCast(loc, expv, Type::tint32); - return new DImValue(type, DtoAlloca(LLType::Int8Ty, expv->getRVal(), ".alloca")); + return new DImValue(type, p->ir->CreateAlloca(LLType::Int8Ty, expv->getRVal(), ".alloca")); } } @@ -844,6 +856,12 @@ assert(e1->op == TOKvar); VarExp* vexp = (VarExp*)e1; + if (vexp->var->needThis()) + { + error("need 'this' to access %s", vexp->var->toChars()); + fatal(); + } + // global variable if (VarDeclaration* vd = vexp->var->isVarDeclaration()) { @@ -892,8 +910,8 @@ DValue* l = e1->toElem(p); - Type* t = DtoDType(type); - Type* e1type = DtoDType(e1->type); + Type* t = type->toBasetype(); + Type* e1type = e1->type->toBasetype(); //Logger::println("e1type=%s", e1type->toChars()); //Logger::cout() << *DtoType(e1type) << '\n'; @@ -910,6 +928,16 @@ DStructIndexVector vdoffsets; arrptr = DtoIndexStruct(src, ts->sym, vd->type, vd->offset, vdoffsets); } + // happens for tuples + else if (e1type->ty == Tstruct) { + TypeStruct* ts = (TypeStruct*)e1type; + Logger::println("Struct member offset:%d", vd->offset); + + LLValue* src = l->getRVal(); + + DStructIndexVector vdoffsets; + arrptr = DtoIndexStruct(src, ts->sym, vd->type, vd->offset, vdoffsets); + } else if (e1type->ty == Tclass) { TypeClass* tc = (TypeClass*)e1type; Logger::println("Class member offset: %d", vd->offset); @@ -953,7 +981,7 @@ LLValue* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false); LLValue* vtblidx = llvm::ConstantInt::get(LLType::Int32Ty, (size_t)fdecl->vtblIndex, false); - //Logger::cout() << "vthis: " << *vthis << '\n'; + Logger::cout() << "vthis: " << *vthis << '\n'; funcval = DtoGEP(vthis, zero, zero); funcval = DtoLoad(funcval); funcval = DtoGEP(funcval, zero, vtblidx, toChars()); @@ -991,7 +1019,7 @@ // FIXME: check for TOKthis in AssertExp instead if (!var) { - LLValue* v = p->func()->thisVar; + LLValue* v = p->func()->thisArg; assert(v); return new DVarValue(type, v, true); } @@ -1000,11 +1028,11 @@ LLValue* v; if (vd->toParent2() != p->func()->decl) { Logger::println("nested this exp"); - return DtoNestedVariable(type, vd); + return DtoNestedVariable(loc, type, vd); } else { Logger::println("normal this exp"); - v = p->func()->decl->ir.irFunc->thisVar; + v = p->func()->thisArg; } return new DVarValue(type, vd, v, true); } @@ -1023,7 +1051,7 @@ DValue* l = e1->toElem(p); - Type* e1type = DtoDType(e1->type); + Type* e1type = e1->type->toBasetype(); p->arrays.push_back(l); // if $ is used it must be an array so this is fine. DValue* r = e2->toElem(p); @@ -1141,8 +1169,8 @@ DValue* l = e1->toElem(p); DValue* r = e2->toElem(p); - Type* t = DtoDType(e1->type); - Type* e2t = DtoDType(e2->type); + Type* t = e1->type->toBasetype(); + Type* e2t = e2->type->toBasetype(); assert(DtoType(t) == DtoType(e2t)); LLValue* eval = 0; @@ -1254,8 +1282,8 @@ DValue* l = e1->toElem(p); DValue* r = e2->toElem(p); - Type* t = DtoDType(e1->type); - Type* e2t = DtoDType(e2->type); + Type* t = e1->type->toBasetype(); + Type* e2t = e2->type->toBasetype(); //assert(t == e2t); LLValue* eval = 0; @@ -1341,8 +1369,8 @@ LLValue* val = l->getRVal(); LLValue* post = 0; - Type* e1type = DtoDType(e1->type); - Type* e2type = DtoDType(e2->type); + Type* e1type = e1->type->toBasetype(); + Type* e2type = e2->type->toBasetype(); if (e1type->isintegral()) { @@ -1379,7 +1407,7 @@ DtoStore(post,l->getLVal()); - return new DImValue(type,val,true); + return new DImValue(type,val); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1390,12 +1418,12 @@ LOG_SCOPE; assert(newtype); - Type* ntype = DtoDType(newtype); + Type* ntype = newtype->toBasetype(); // new class if (ntype->ty == Tclass) { Logger::println("new class"); - return DtoNewClass((TypeClass*)ntype, this); + return DtoNewClass(loc, (TypeClass*)ntype, this); } // new dynamic array else if (ntype->ty == Tarray) @@ -1439,7 +1467,7 @@ assert(ts->sym); DtoAggrCopy(mem,ts->sym->ir.irStruct->init); } - return new DImValue(type, mem, false); + return new DImValue(type, mem); } // new basic type else @@ -1454,7 +1482,7 @@ DtoAssign(loc, &tmpvar, iv); // return as pointer-to - return new DImValue(type, mem, false); + return new DImValue(type, mem); } assert(0); @@ -1468,7 +1496,7 @@ LOG_SCOPE; DValue* dval = e1->toElem(p); - Type* et = DtoDType(e1->type); + Type* et = e1->type->toBasetype(); // simple pointer if (et->ty == Tpointer) @@ -1763,12 +1791,13 @@ DValue* u = e1->toElem(p); LLValue* uval; if (DFuncValue* f = u->isFunc()) { - assert(f->func); - LLValue* contextptr = DtoNestedContext(f->func->toParent2()->isFuncDeclaration()); - if (!contextptr) - uval = LLConstant::getNullValue(getVoidPtrType()); + assert(f->func); + LLValue* contextptr; + if (p->func()->decl == f->func) + contextptr = p->func()->thisArg; else - uval = DtoBitCast(contextptr, getVoidPtrType()); + contextptr = DtoNestedContext(loc, f->func); + uval = DtoBitCast(contextptr, getVoidPtrType()); } else { DValue* src = u; @@ -1892,7 +1921,7 @@ Logger::print("CondExp::toElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - Type* dtype = DtoDType(type); + Type* dtype = type->toBasetype(); const LLType* resty = DtoType(dtype); // allocate a temporary for the final result. failed to come up with a better way :/ @@ -1953,7 +1982,7 @@ } LLValue* val = l->getRVal(); - Type* t = DtoDType(type); + Type* t = type->toBasetype(); LLValue* zero = 0; if (t->isintegral()) @@ -1975,9 +2004,9 @@ Logger::print("CatExp::toElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - Type* t = DtoDType(type); - - bool arrNarr = DtoDType(e1->type) == DtoDType(e2->type); + Type* t = type->toBasetype(); + + bool arrNarr = e1->type->toBasetype() == e2->type->toBasetype(); // array ~ array if (arrNarr) @@ -2001,9 +2030,9 @@ DValue* l = e1->toElem(p); - Type* e1type = DtoDType(e1->type); - Type* elemtype = DtoDType(e1type->next); - Type* e2type = DtoDType(e2->type); + Type* e1type = e1->type->toBasetype(); + Type* elemtype = e1type->next->toBasetype(); + Type* e2type = e2->type->toBasetype(); if (e2type == elemtype) { DSliceValue* slice = DtoCatAssignElement(l,e2); @@ -2037,17 +2066,17 @@ LLValue* lval = DtoAlloca(dgty,"dgstorage"); LLValue* context = DtoGEPi(lval,0,0); - const LLPointerType* pty = isaPointer(context->getType()->getContainedType(0)); - LLValue* llvmNested = p->func()->decl->ir.irFunc->nestedVar; - if (llvmNested == NULL) { - LLValue* nullcontext = llvm::ConstantPointerNull::get(pty); - DtoStore(nullcontext, context); - } - else { - LLValue* nestedcontext = DtoBitCast(llvmNested, pty); - DtoStore(nestedcontext, context); - } - + LLValue* cval; + IrFunction* irfn = p->func(); + if (irfn->nestedVar) + cval = irfn->nestedVar; + else if (irfn->nestArg) + cval = irfn->nestArg; + else + cval = getNullPtr(getVoidPtrType()); + cval = DtoBitCast(cval, context->getType()->getContainedType(0)); + DtoStore(cval, context); + LLValue* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb()); assert(fd->ir.irFunc->func); @@ -2072,8 +2101,6 @@ bool dyn = (arrayType->ty == Tarray); // length size_t len = elements->dim; - // store into slice? - bool sliceInPlace = false; // llvm target type const LLType* llType = DtoType(arrayType); @@ -2096,15 +2123,13 @@ // emulate assignment DVarValue* vv = new DVarValue(expr->type, elemAddr, true); DValue* e = expr->toElem(p); - DImValue* im = e->isIm(); - if (!im || !im->inPlace()) { - DtoAssign(loc, vv, e); - } + DtoAssign(loc, vv, e); } // return storage directly ? - if (!dyn || (dyn && sliceInPlace)) - return new DImValue(type, dstMem, false); + if (!dyn) + return new DImValue(type, dstMem); + // wrap in a slice return new DSliceValue(type, DtoConstSize_t(len), DtoGEPi(dstMem,0,0,"tmp")); } @@ -2188,9 +2213,7 @@ DValue* darrptr = new DVarValue(vx->type, arrptr, true); DValue* ve = vx->toElem(p); - - if (!ve->inPlace()) - DtoAssign(loc, darrptr, ve); + DtoAssign(loc, darrptr, ve); j++; } @@ -2214,7 +2237,7 @@ vals[i] = vx->toConstElem(p); } - assert(DtoDType(type)->ty == Tstruct); + assert(type->toBasetype()->ty == Tstruct); const LLType* t = DtoType(type); const LLStructType* st = isaStruct(t); return llvm::ConstantStruct::get(st,vals); @@ -2257,7 +2280,7 @@ assert(values); assert(keys->dim == values->dim); - Type* aatype = DtoDType(type); + Type* aatype = type->toBasetype(); Type* vtype = aatype->next; const LLType* aalltype = DtoType(type);
--- a/gen/tollvm.cpp Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/tollvm.cpp Sun Aug 10 08:37:38 2008 +0200 @@ -23,14 +23,14 @@ bool DtoIsPassedByRef(Type* type) { - Type* typ = DtoDType(type); + Type* typ = type->toBasetype(); TY t = typ->ty; return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray || typ->iscomplex()); } bool DtoIsReturnedInArg(Type* type) { - Type* typ = DtoDType(type); + Type* typ = type->toBasetype(); TY t = typ->ty; return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray || typ->iscomplex()); } @@ -54,16 +54,6 @@ return llvm::ParamAttr::None; } -Type* DtoDType(Type* t) -{ - if (t->ty == Ttypedef) { - Type* bt = t->toBasetype(); - assert(bt); - return DtoDType(bt); - } - return t; -} - const LLType* DtoType(Type* t) { assert(t); @@ -143,7 +133,7 @@ case Tfunction: { if (!t->ir.type || *t->ir.type == NULL) { - return DtoFunctionType(t,NULL); + return DtoFunctionType(t,NULL,NULL); } else { return t->ir.type->get(); @@ -205,7 +195,7 @@ const LLStructType* DtoDelegateType(Type* t) { const LLType* i8ptr = getVoidPtrType(); - const LLType* func = DtoFunctionType(t->next, i8ptr); + const LLType* func = DtoFunctionType(t->next, NULL, i8ptr); const LLType* funcptr = getPtrToType(func); return LLStructType::get(i8ptr, funcptr, 0); } @@ -666,8 +656,9 @@ size_t getABITypeSize(const LLType* t) { - Logger::cout() << "getting abi type of: " << *t << '\n'; - return gTargetData->getABITypeSize(t); + size_t sz = gTargetData->getABITypeSize(t); + Logger::cout() << "abi type size of: " << *t << " == " << sz << '\n'; + return sz; } unsigned char getABITypeAlign(const LLType* t)
--- a/gen/tollvm.h Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/tollvm.h Sun Aug 10 08:37:38 2008 +0200 @@ -23,10 +23,6 @@ unsigned DtoShouldExtend(Type* type); -// resolve typedefs to their real type. -// TODO should probably be removed in favor of DMD's Type::toBasetype -Type* DtoDType(Type* t); - // delegate helpers const LLStructType* DtoDelegateType(Type* t); LLValue* DtoDelegateEquals(TOK op, LLValue* lhs, LLValue* rhs); @@ -92,6 +88,7 @@ size_t getTypeBitSize(const LLType* t); size_t getTypeStoreSize(const LLType* t); size_t getABITypeSize(const LLType* t); + // type alignments unsigned char getABITypeAlign(const LLType* t); unsigned char getPrefTypeAlign(const LLType* t);
--- a/gen/toobj.cpp Sat Aug 09 09:03:52 2008 +0200 +++ b/gen/toobj.cpp Sun Aug 10 08:37:38 2008 +0200 @@ -55,9 +55,17 @@ void Module::genobjfile(int multiobj) { + bool logenabled = Logger::enabled(); + if (llvmForceLogging && !logenabled) + { + Logger::enable(); + } + Logger::cout() << "Generating module: " << (md ? md->toChars() : toChars()) << '\n'; LOG_SCOPE; + //printf("codegen: %s\n", srcfile->toChars()); + // start by deleting the old object file deleteObjFile(); @@ -161,10 +169,10 @@ if (global.params.fqnPaths) { - bcpath = LLPath(md->toChars()); + bcpath = LLPath(mname); bcpath.appendSuffix("bc"); - llpath = LLPath(md->toChars()); + llpath = LLPath(mname); llpath.appendSuffix("ll"); } else @@ -190,6 +198,11 @@ delete ir.module; gTargetData = 0; gIR = NULL; + + if (llvmForceLogging && !logenabled) + { + Logger::disable(); + } } /* ================================================================== */
--- a/ir/irfunction.cpp Sat Aug 09 09:03:52 2008 +0200 +++ b/ir/irfunction.cpp Sun Aug 10 08:37:38 2008 +0200 @@ -13,7 +13,7 @@ { decl = fd; - Type* t = DtoDType(fd->type); + Type* t = fd->type->toBasetype(); assert(t->ty == Tfunction); type = (TypeFunction*)t; func = NULL; @@ -23,10 +23,14 @@ defined = false; retArg = NULL; - thisVar = NULL; + thisArg = NULL; + nestArg = NULL; + nestedVar = NULL; + _arguments = NULL; _argptr = NULL; + dwarfSubProg = NULL; srcfileArg = NULL;
--- a/ir/irfunction.h Sat Aug 09 09:03:52 2008 +0200 +++ b/ir/irfunction.h Sun Aug 10 08:37:38 2008 +0200 @@ -18,11 +18,16 @@ bool queued; bool defined; - llvm::Value* retArg; - llvm::Value* thisVar; - llvm::Value* nestedVar; + + llvm::Value* retArg; // return in ptr arg + llvm::Value* thisArg; // class/struct 'this' arg + llvm::Value* nestArg; // nested function 'this' arg + + llvm::Value* nestedVar; // nested var alloca + llvm::Value* _arguments; llvm::Value* _argptr; + llvm::Constant* dwarfSubProg; llvm::AllocaInst* srcfileArg;
--- a/runtime/internal/aApplyR.d Sat Aug 09 09:03:52 2008 +0200 +++ b/runtime/internal/aApplyR.d Sun Aug 10 08:37:38 2008 +0200 @@ -79,7 +79,7 @@ { debug(apply) printf("_aApplyRcd1.unittest\n"); - auto s = "hello"c; + char[] s = "hello"c; int i; foreach_reverse(dchar d; s) @@ -143,7 +143,7 @@ { debug(apply) printf("_aApplyRwd1.unittest\n"); - auto s = "hello"w; + wchar[] s = "hello"w; int i; foreach_reverse(dchar d; s) @@ -229,7 +229,7 @@ { debug(apply) printf("_aApplyRcw1.unittest\n"); - auto s = "hello"c; + char[] s = "hello"c; int i; foreach_reverse(wchar d; s) @@ -310,7 +310,7 @@ { debug(apply) printf("_aApplyRwc1.unittest\n"); - auto s = "hello"w; + wchar[] s = "hello"w; int i; foreach_reverse(char d; s) @@ -389,7 +389,7 @@ { debug(apply) printf("_aApplyRdc1.unittest\n"); - auto s = "hello"d; + dchar[] s = "hello"d; int i; foreach_reverse(char d; s) @@ -461,7 +461,7 @@ { debug(apply) printf("_aApplyRdw1.unittest\n"); - auto s = "hello"d; + dchar[] s = "hello"d; int i; foreach_reverse(wchar d; s) @@ -543,7 +543,7 @@ { debug(apply) printf("_aApplyRcd2.unittest\n"); - auto s = "hello"c; + char[] s = "hello"c; int i; foreach_reverse(k, dchar d; s) @@ -608,7 +608,7 @@ { debug(apply) printf("_aApplyRwd2.unittest\n"); - auto s = "hello"w; + wchar[] s = "hello"w; int i; foreach_reverse(k, dchar d; s) @@ -696,7 +696,7 @@ { debug(apply) printf("_aApplyRcw2.unittest\n"); - auto s = "hello"c; + char[] s = "hello"c; int i; foreach_reverse(k, wchar d; s) @@ -779,7 +779,7 @@ { debug(apply) printf("_aApplyRwc2.unittest\n"); - auto s = "hello"w; + wchar[] s = "hello"w; int i; foreach_reverse(k, char d; s) @@ -859,7 +859,7 @@ { debug(apply) printf("_aApplyRdc2.unittest\n"); - auto s = "hello"d; + dchar[] s = "hello"d; int i; foreach_reverse(k, char d; s) @@ -933,7 +933,7 @@ { debug(apply) printf("_aApplyRdw2.unittest\n"); - auto s = "hello"d; + dchar[] s = "hello"d; int i; foreach_reverse(k, wchar d; s)
--- a/runtime/internal/aaA.d Sat Aug 09 09:03:52 2008 +0200 +++ b/runtime/internal/aaA.d Sun Aug 10 08:37:38 2008 +0200 @@ -101,7 +101,6 @@ size_t aligntsize(size_t tsize) { - // Is pointer alignment on the x64 4 bytes or 8? return (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1); }
--- a/runtime/internal/adi.d Sat Aug 09 09:03:52 2008 +0200 +++ b/runtime/internal/adi.d Sun Aug 10 08:37:38 2008 +0200 @@ -67,7 +67,7 @@ * reversed. */ -extern (C) Array _adReverseChar(char[] a) +extern (C) char[] _adReverseChar(char[] a) { if (a.length > 1) { @@ -127,14 +127,14 @@ hi = hi - 1 + (stridehi - stridelo); } } - return Array(a.length, a.ptr); + return a; } unittest { - auto a = "abcd"c; + char[] a = "abcd"c; - auto r = a.dup.reverse; + char[] r = a.dup.reverse; //writefln(r); assert(r == "dcba"); @@ -162,7 +162,7 @@ * reversed. */ -extern (C) Array _adReverseWchar(wchar[] a) +extern (C) wchar[] _adReverseWchar(wchar[] a) { if (a.length > 1) { @@ -220,13 +220,13 @@ hi = hi - 1 + (stridehi - stridelo); } } - return Array(a.length, a.ptr); + return a; } unittest { - wstring a = "abcd"; - wstring r; + wchar[] a = "abcd"; + wchar[] r; r = a.dup.reverse; assert(r == "dcba"); @@ -331,7 +331,7 @@ * Sort array of chars. */ -extern (C) Array _adSortChar(char[] a) +extern (C) char[] _adSortChar(char[] a) { if (a.length > 1) { @@ -346,14 +346,14 @@ } delete da; } - return Array(a.length, a.ptr); + return a; } /********************************************** * Sort array of wchars. */ -extern (C) Array _adSortWchar(wchar[] a) +extern (C) wchar[] _adSortWchar(wchar[] a) { if (a.length > 1) { @@ -368,7 +368,7 @@ } delete da; } - return Array(a.length, a.ptr); + return a; } /*************************************** @@ -392,7 +392,7 @@ { debug(adi) printf("array.Eq unittest\n"); - auto a = "hello"c; + char[] a = "hello"c; assert(a != "hel"); assert(a != "helloo"); @@ -425,7 +425,7 @@ { debug(adi) printf("array.Cmp unittest\n"); - auto a = "hello"c; + char[] a = "hello"c; assert(a > "hel"); assert(a >= "hel"); @@ -575,7 +575,7 @@ { debug(adi) printf("array.CmpChar unittest\n"); - auto a = "hello"c; + char[] a = "hello"c; assert(a > "hel"); assert(a >= "hel");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/aa7.d Sun Aug 10 08:37:38 2008 +0200 @@ -0,0 +1,57 @@ +// adapted from dstress.run.a.associative_array_19_A to catch regressions early + +module mini.aa7; + +extern (C) int printf(char*, ...); + +extern (C) void gc_collect(); + +union Key{ + char x; +} + +class Payload { + this(Key value) { + value.x += 1; + _value = value; + } + + Key value() { + return _value; + } + + Key _value; +} + +int main(){ + Payload[Key] aa; + + Key[] allKeys; + static Key a = { 'a' }; + static Key b = { 'b' }; + static Key c = { 'c' }; + allKeys ~= a; + allKeys ~= b; + allKeys ~= c; + + foreach(Key key; allKeys) { + aa[key] = new Payload(key); + } + + int i = 0; + foreach(Key key; allKeys) { + printf("1st #%d\n", i++); + assert(key in aa); + } + + gc_collect(); + + i = 0; + foreach(Key key; allKeys) { + printf("2nd #%d\n", i++); + assert(key in aa); + } + + return 0; +} +
--- a/tests/mini/nested13.d Sat Aug 09 09:03:52 2008 +0200 +++ b/tests/mini/nested13.d Sun Aug 10 08:37:38 2008 +0200 @@ -1,4 +1,4 @@ -module tangotests.nested2; +module mini.nested13; extern(C) int printf(char*, ...);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/nested16.d Sun Aug 10 08:37:38 2008 +0200 @@ -0,0 +1,31 @@ +module mini.nested16; + +void main() +{ + int idx = 123; + int func(int* idp) + { + void foo() + { + void bar(int* idp) + { + auto c = new class + { + void mem() + { + scope(exit) ++*idp; + } + }; + auto dg = () { + c.mem(); + }; + dg(); + } + bar(idp); + ++*idp; + } + foo(); + return ++*idp; + } + assert(func(&idx) == 126); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/nested17.d Sun Aug 10 08:37:38 2008 +0200 @@ -0,0 +1,45 @@ +// $HeadURL: svn://svn.berlios.de/dstress/trunk/run/n/nested_class_03_A.d $ +// $Date: 2005-06-18 09:15:32 +0200 (Sat, 18 Jun 2005) $ +// $Author: thomask $ + +// @author@ John C <johnch_atms@hotmail.com> +// @date@ 2005-06-09 +// @uri@ news:d88vta$vak$1@digitaldaemon.com + +//module dstress.run.n.nested_class_03_A; +module mini.nested17; + +interface Inner{ + int value(); +} + +class Outer{ + int x; + + Inner test(){ + printf("val = %d\n", x); + return new class Inner { + int y; + + this(){ + printf("val = %d\n", x); + y=x; + } + + int value(){ + return y; + } + }; + } +} + +int main(){ + Outer o = new Outer(); + o.x=2; + int val = o.test().value(); + printf("val = %d\n", val); + assert(val == o.x); + return 0; +} + +extern(C) int printf(char*, ...);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/nested19.d Sun Aug 10 08:37:38 2008 +0200 @@ -0,0 +1,27 @@ +module mini.nested19; + +void main() +{ + int i = 1; + + class C + { + int j = 2; + void func() + { + int k = 3; + + void foo() + { + i = i+j+k; + } + + foo(); + } + } + + auto c = new C; + c.func(); + + assert(i == 6); +}