# HG changeset patch # User Tomas Lindquist Olsen # Date 1217811574 -7200 # Node ID 45a67b6f1310eab6af367194d44f43e07f9c01ab # Parent 261b05cf4d1c8f3500c780045faae7293afaa8a3 Removed the 'needsstorage' thing from Dsymbol. Arguments are not always given storage when applicable. This is not longer treat specially in this regard. Code for accessing nested variables and contexts rewritten. Probably more. Fairly well tested. diff -r 261b05cf4d1c -r 45a67b6f1310 dmd/declaration.c --- a/dmd/declaration.c Sun Aug 03 16:59:28 2008 +0200 +++ b/dmd/declaration.c Mon Aug 04 02:59:34 2008 +0200 @@ -621,9 +621,6 @@ onstack = 0; canassign = 0; value = NULL; - - // LLVMDC - needsStorage = false; } Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) @@ -645,8 +642,6 @@ sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init); sv->storage_class = storage_class; - // LLVMDC - sv->needsStorage = needsStorage; } #ifdef _DH // Syntax copy for header file diff -r 261b05cf4d1c -r 45a67b6f1310 dmd/declaration.h --- a/dmd/declaration.h Sun Aug 03 16:59:28 2008 +0200 +++ b/dmd/declaration.h Mon Aug 04 02:59:34 2008 +0200 @@ -266,9 +266,6 @@ // Eliminate need for dynamic_cast VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } - - // LLVMDC - bool needsStorage; }; /**************************************************************/ diff -r 261b05cf4d1c -r 45a67b6f1310 dmd/expression.c --- a/dmd/expression.c Sun Aug 03 16:59:28 2008 +0200 +++ b/dmd/expression.c Mon Aug 04 02:59:34 2008 +0200 @@ -3628,7 +3628,6 @@ if (v) { v->checkNestedReference(sc, loc); - v->needsStorage = true; } return this; } @@ -3777,7 +3776,6 @@ if (v && v->canassign == 0 && (var->isConst() || (global.params.Dversion > 1 && var->isFinal()))) error("cannot modify final variable '%s'", var->toChars()); - v->needsStorage = true; if (var->isCtorinit()) { // It's only modifiable if inside the right constructor @@ -5991,10 +5989,6 @@ e = e->semantic(sc); return e; } - else if (v) - { - v->needsStorage = true; - } } else if (e1->op == TOKarray) { diff -r 261b05cf4d1c -r 45a67b6f1310 dmd/func.c --- a/dmd/func.c Sun Aug 03 16:59:28 2008 +0200 +++ b/dmd/func.c Mon Aug 04 02:59:34 2008 +0200 @@ -796,11 +796,6 @@ if (v->storage_class & STClazy) v->storage_class |= STCin; v->semantic(sc2); - #if IN_LLVM - // LLVMDC: the argument needs an addres if we want to attach debug info to it. - if (global.params.symdebug) - v->needsStorage = true; - #endif if (!sc2->insert(v)) error("parameter %s.%s is already defined", toChars(), v->toChars()); else diff -r 261b05cf4d1c -r 45a67b6f1310 gen/aa.cpp --- a/gen/aa.cpp Sun Aug 03 16:59:28 2008 +0200 +++ b/gen/aa.cpp Mon Aug 04 02:59:34 2008 +0200 @@ -22,10 +22,6 @@ if (key->isIm()) { pkey = key->getRVal(); } - else if (key->isThis()) { - pkey = key->getRVal(); - needmem = true; - } else if (DVarValue* var = key->isVar()) { if (var->lval) { pkey = key->getLVal(); diff -r 261b05cf4d1c -r 45a67b6f1310 gen/d-asm-i386.h --- a/gen/d-asm-i386.h Sun Aug 03 16:59:28 2008 +0200 +++ b/gen/d-asm-i386.h Mon Aug 04 02:59:34 2008 +0200 @@ -2037,9 +2037,6 @@ } } else if (exp->op == TOKvar) { VarDeclaration * v = ((VarExp *) exp)->var->isVarDeclaration(); - if (v) { - v->needsStorage = true; - } if (v && v->storage_class & STCfield) { operand->constDisplacement += v->offset; diff -r 261b05cf4d1c -r 45a67b6f1310 gen/dvalue.cpp --- a/gen/dvalue.cpp Sun Aug 03 16:59:28 2008 +0200 +++ b/gen/dvalue.cpp Mon Aug 04 02:59:34 2008 +0200 @@ -53,7 +53,7 @@ else { if (rval) return rval; //Logger::cout() << "val: " << *val << '\n'; - if (!isThis() && !isField() && DtoCanLoad(val)) { + if (!isField() && DtoCanLoad(val)) { return DtoLoad(val); } return val; diff -r 261b05cf4d1c -r 45a67b6f1310 gen/dvalue.h --- a/gen/dvalue.h Sun Aug 03 16:59:28 2008 +0200 +++ b/gen/dvalue.h Mon Aug 04 02:59:34 2008 +0200 @@ -27,7 +27,6 @@ struct DNullValue; struct DVarValue; struct DFieldValue; -struct DThisValue; struct DFuncValue; struct DSliceValue; struct DArrayLenValue; @@ -49,7 +48,6 @@ virtual DNullValue* isNull() { return NULL; } virtual DVarValue* isVar() { return NULL; } virtual DFieldValue* isField() { return NULL; } - virtual DThisValue* isThis() { return NULL; } virtual DSliceValue* isSlice() { return NULL; } virtual DFuncValue* isFunc() { return NULL; } virtual DArrayLenValue* isArrayLen() { return NULL; } @@ -130,13 +128,6 @@ virtual DFieldValue* isField() { return this; } }; -// this d-value -struct DThisValue : DVarValue -{ - DThisValue(Type* t, VarDeclaration* vd, LLValue* llvmValue) : DVarValue(t, vd, llvmValue, true) {} - virtual DThisValue* isThis() { return this; } -}; - // slice d-value struct DSliceValue : DValue { diff -r 261b05cf4d1c -r 45a67b6f1310 gen/functions.cpp --- a/gen/functions.cpp Sun Aug 03 16:59:28 2008 +0200 +++ b/gen/functions.cpp Mon Aug 04 02:59:34 2008 +0200 @@ -546,7 +546,8 @@ Logger::println("Doing function body for: %s", fd->toChars()); assert(fd->ir.irFunc); - gIR->functions.push_back(fd->ir.irFunc); + IrFunction* irfunction = fd->ir.irFunc; + gIR->functions.push_back(irfunction); if (fd->isMain()) gIR->emitMain = true; @@ -562,7 +563,7 @@ // create alloca point llvm::Instruction* allocaPoint = new llvm::AllocaInst(LLType::Int32Ty, "alloca point", beginbb); - gIR->func()->allocapoint = allocaPoint; + irfunction->allocapoint = allocaPoint; // debug info - after all allocas, but before any llvm.dbg.declare etc if (global.params.symdebug) DtoDwarfFuncStart(fd); @@ -574,18 +575,23 @@ fd->vresult->ir.irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint); } - // give 'this' argument debug info (and storage) - if (fd->needThis() && global.params.symdebug) + // give the 'this' argument storage and debug info + // only if not referenced by nested functions + if (fd->needThis() && !fd->vthis->nestedref) { - LLValue** thisvar = &fd->ir.irFunc->thisVar; - assert(*thisvar); - LLValue* thismem = new llvm::AllocaInst((*thisvar)->getType(), "newthis", allocaPoint); - DtoDwarfLocalVariable(thismem, fd->vthis); - gIR->ir->CreateStore(*thisvar, thismem); - *thisvar = thismem; + LLValue* thisvar = irfunction->thisVar; + assert(thisvar); + + LLValue* thismem = new llvm::AllocaInst(thisvar->getType(), ".newthis", allocaPoint); + DtoStore(thisvar, thismem); + irfunction->thisVar = thismem; + + if (global.params.symdebug) + DtoDwarfLocalVariable(thismem, fd->vthis); } // give arguments storage + // and debug info if (fd->parameters) { size_t n = fd->parameters->dim; @@ -595,44 +601,27 @@ VarDeclaration* vd = argsym->isVarDeclaration(); assert(vd); + IrLocal* irloc = vd->ir.irLocal; + assert(irloc); + bool refoutlazy = vd->storage_class & (STCref | STCout | STClazy); - // FIXME: llvm seems to want an alloca/byval for debug info - if (!vd->needsStorage || vd->nestedref || refoutlazy) + if (vd->nestedref || refoutlazy) { - Logger::println("skipping arg storage for (%s) %s ", vd->loc.toChars(), vd->toChars()); continue; } - // static array params don't support debug info it seems - // probably because they're not passed byval - else if (vd->type->toBasetype()->ty == Tsarray) - { - Logger::println("skipping arg storage for static array (%s) %s ", vd->loc.toChars(), vd->toChars()); - continue; - } - // debug info for normal aggr params seem to work fine else if (DtoIsPassedByRef(vd->type)) { - Logger::println("skipping arg storage for aggregate (%s) %s ", vd->loc.toChars(), vd->toChars()); - LLValue* vdirval = vd->ir.getIrValue(); + LLValue* vdirval = irloc->value; if (global.params.symdebug && !(isaArgument(vdirval) && !isaArgument(vdirval)->hasByValAttr())) DtoDwarfLocalVariable(vdirval, vd); continue; } - LLValue* a = vd->ir.irLocal->value; - assert(a); - std::string s(a->getName()); - Logger::println("giving argument '%s' storage", s.c_str()); - s.append("_storage"); - - LLValue* v = new llvm::AllocaInst(a->getType(),s,allocaPoint); - - if (global.params.symdebug) - DtoDwarfLocalVariable(v, vd); - - gIR->ir->CreateStore(a,v); - vd->ir.irLocal->value = v; + LLValue* a = irloc->value; + LLValue* v = new llvm::AllocaInst(a->getType(), "."+a->getName(), allocaPoint); + DtoStore(a,v); + irloc->value = v; } } diff -r 261b05cf4d1c -r 45a67b6f1310 gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Sun Aug 03 16:59:28 2008 +0200 +++ b/gen/llvmhelpers.cpp Mon Aug 04 02:59:34 2008 +0200 @@ -330,181 +330,154 @@ // NESTED VARIABLE HELPERS ////////////////////////////////////////////////////////////////////////////////////////*/ -static const LLType* get_next_frame_ptr_type(Dsymbol* sc) +/* + +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) { - assert(sc->isFuncDeclaration() || sc->isClassDeclaration()); - Dsymbol* p = sc->toParent2(); - if (!p->isFuncDeclaration() && !p->isClassDeclaration()) - Logger::println("unexpected parent symbol found while resolving frame pointer - '%s' kind: '%s'", p->toChars(), p->kind()); - assert(p->isFuncDeclaration() || p->isClassDeclaration()); - if (FuncDeclaration* fd = p->isFuncDeclaration()) + from = from->toParent2(); + + // parent is a function + if (FuncDeclaration* f = from->isFuncDeclaration()) { - LLValue* v = fd->ir.irFunc->nestedVar; - assert(v); - return v->getType(); + 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()); + } } - else if (ClassDeclaration* cd = p->isClassDeclaration()) + // parent is a class + else if (ClassDeclaration* c = from->isClassDeclaration()) { - return DtoType(cd->type); + return DtoBitCast(DtoLoad(val), DtoType(c->type)); } + // parent is not valid else { - Logger::println("symbol: '%s' kind: '%s'", sc->toChars(), sc->kind()); - assert(0); - } -} - -////////////////////////////////////////////////////////////////////////////////////////// - -static LLValue* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, LLValue* v) -{ - LOG_SCOPE; - if (sc == func) - { - return v; - } - else if (FuncDeclaration* fd = sc->isFuncDeclaration()) - { - Logger::println("scope is function: %s", fd->toChars()); - - if (fd->toParent2() == func) - { - if (!func->ir.irFunc->nestedVar) - return NULL; - return DtoBitCast(v, func->ir.irFunc->nestedVar->getType()); - } - - v = DtoBitCast(v, get_next_frame_ptr_type(fd)); - Logger::cout() << "v = " << *v << '\n'; - - if (fd->toParent2()->isFuncDeclaration()) - { - v = DtoGEPi(v, 0,0, "tmp"); - v = DtoLoad(v); - } - else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration()) - { - v = DtoGEPi(v,0,2+cd->vthis->ir.irField->index,"tmp"); - v = DtoLoad(v); - } - else - { - assert(0); - } - return get_frame_ptr_impl(func, fd->toParent2(), v); - } - else if (ClassDeclaration* cd = sc->isClassDeclaration()) - { - Logger::println("scope is class: %s", cd->toChars()); - return get_frame_ptr_impl(func, cd->toParent2(), v); - } - else - { - Logger::println("symbol: '%s'", sc->toPrettyChars()); - assert(0); + assert(0 && "!(class|function)"); } } -////////////////////////////////////////////////////////////////////////////////////////// - -static LLValue* get_frame_ptr(FuncDeclaration* func) -{ - Logger::println("Resolving context pointer for nested function: '%s'", func->toPrettyChars()); - LOG_SCOPE; - IrFunction* irfunc = gIR->func(); - - // in the right scope already - if (func == irfunc->decl) - return irfunc->decl->ir.irFunc->nestedVar; - - // use the 'this' pointer - LLValue* ptr = irfunc->decl->ir.irFunc->thisVar; - assert(ptr); - - // return the fully resolved frame pointer - ptr = get_frame_ptr_impl(func, irfunc->decl, ptr); - if (ptr) Logger::cout() << "Found context!" << *ptr; - else Logger::cout() << "NULL context!\n"; - - return ptr; -} - -////////////////////////////////////////////////////////////////////////////////////////// - LLValue* DtoNestedContext(FuncDeclaration* func) { - // resolve frame ptr - LLValue* ptr = get_frame_ptr(func); - Logger::cout() << "Nested context ptr = "; - if (ptr) Logger::cout() << *ptr; - else Logger::cout() << "NULL"; - Logger::cout() << '\n'; - return ptr; -} + Logger::println("listing context frame list for funcdecl '%s'", func->toPrettyChars()); + LOG_SCOPE; + + int level = 0; -////////////////////////////////////////////////////////////////////////////////////////// + IrFunction* irfunc = gIR->func(); + Dsymbol* current = irfunc->decl; -static void print_frame_worker(VarDeclaration* vd, Dsymbol* par) -{ - if (vd->toParent2() == par) + // this context ? + if (current == func) { - Logger::println("found: '%s' kind: '%s'", par->toChars(), par->kind()); - return; + return irfunc->nestedVar; } - Logger::println("diving into: '%s' kind: '%s'", par->toChars(), par->kind()); - LOG_SCOPE; - print_frame_worker(vd, par->toParent2()); -} - -////////////////////////////////////////////////////////////////////////////////////////// + // otherwise use the context argument + LLValue* val = dive_into_nested(current, irfunc->thisVar); + current = current->toParent2(); + assert(val); -static void print_nested_frame_list(VarDeclaration* vd, Dsymbol* par) -{ - Logger::println("Frame pointer list for nested var: '%s'", vd->toPrettyChars()); - LOG_SCOPE; - if (vd->toParent2() != par) - print_frame_worker(vd, par); - else - Logger::println("Found at level 0"); - Logger::println("Done"); + for (;;) + { + 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; + } + + assert(0); + return val; } -////////////////////////////////////////////////////////////////////////////////////////// - -LLValue* DtoNestedVariable(VarDeclaration* vd) +DValue* DtoNestedVariable(Type* astype, VarDeclaration* vd) { - // log the frame list IrFunction* irfunc = gIR->func(); - if (Logger::enabled()) - print_nested_frame_list(vd, irfunc->decl); + + // var parent (the scope we're looking for) + Dsymbol* varParent = vd->toParent2(); - // resolve frame ptr - FuncDeclaration* func = vd->toParent2()->isFuncDeclaration(); - assert(func); - LLValue* ptr = DtoNestedContext(func); - assert(ptr && "nested var, but no context"); - - // if there is no nestedVar the context itself is what we're after - if (!func->ir.irFunc->nestedVar) + // on level 0 + if (varParent == irfunc->decl) { - return ptr; + 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); } - // handle a "normal" nested variable + // on level n != 0 + FuncDeclaration* varFunc = varParent->isFuncDeclaration(); + assert(varFunc); - // we must cast here to be sure. nested classes just have a void* - ptr = DtoBitCast(ptr, func->ir.irFunc->nestedVar->getType()); + // 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); - // index nested var and load (if necessary) - LLValue* v = DtoGEPi(ptr, 0, vd->ir.irLocal->nestedIndex, "tmp"); - // references must be loaded, for normal variables this IS already the variable storage!!! + // 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))) - v = DtoLoad(v); + val = DtoLoad(val); - // log and return - Logger::cout() << "Nested var ptr = " << *v << '\n'; - return v; + Logger::cout() << "value: " << *val << '\n'; + + return new DVarValue(astype, vd, val, true); } /****************************************************************************************/ @@ -576,19 +549,12 @@ } else if (t->ty == Tclass) { assert(t2->ty == Tclass); - // assignment to this in constructor special case - if (lhs->isThis()) { - LLValue* tmp = rhs->getRVal(); - FuncDeclaration* fdecl = gIR->func()->decl; - // respecify the this param - if (!llvm::isa(fdecl->ir.irFunc->thisVar)) - fdecl->ir.irFunc->thisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint()); - DtoStore(tmp, fdecl->ir.irFunc->thisVar); - } - // regular class ref -> class ref assignment - else { - DtoStore(rhs->getRVal(), lhs->getLVal()); - } + LLValue* l = lhs->getLVal(); + LLValue* r = rhs->getRVal(); + Logger::cout() << "l : " << *l << '\n'; + Logger::cout() << "r : " << *r << '\n'; + r = DtoBitCast(r, l->getType()->getContainedType(0)); + DtoStore(r, l); } else if (t->iscomplex()) { assert(!lhs->isComplex()); @@ -1540,6 +1506,8 @@ else if (ty == Tpointer || ty == Tclass) { LLValue* val = dval->getRVal(); LLValue* zero = LLConstant::getNullValue(val->getType()); + Logger::cout() << "val: " << *val << '\n'; + Logger::cout() << "zero: " << *zero << '\n'; return gIR->ir->CreateICmpNE(val, zero, "tmp"); } // dynamic array diff -r 261b05cf4d1c -r 45a67b6f1310 gen/llvmhelpers.h --- a/gen/llvmhelpers.h Sun Aug 03 16:59:28 2008 +0200 +++ b/gen/llvmhelpers.h Mon Aug 04 02:59:34 2008 +0200 @@ -36,7 +36,7 @@ // nested variable/class helpers LLValue* DtoNestedContext(FuncDeclaration* func); -LLValue* DtoNestedVariable(VarDeclaration* vd); +DValue* DtoNestedVariable(Type* astype, VarDeclaration* vd); // basic operations void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs); diff -r 261b05cf4d1c -r 45a67b6f1310 gen/toir.cpp --- a/gen/toir.cpp Sun Aug 03 16:59:28 2008 +0200 +++ b/gen/toir.cpp Mon Aug 04 02:59:34 2008 +0200 @@ -106,7 +106,7 @@ // nested variable else if (vd->nestedref) { Logger::println("nested variable"); - return new DVarValue(type, vd, DtoNestedVariable(vd), true); + return DtoNestedVariable(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 new DVarValue(type, vd, DtoNestedVariable(vd), true); + return DtoNestedVariable(type, vd); } else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa(vd->ir.getIrValue())) { return new DVarValue(type, vd, vd->ir.getIrValue(), true); @@ -472,16 +472,7 @@ if (l->isSlice() || l->isComplex()) return l; - if (type->toBasetype()->ty == Tstruct && e2->type->isintegral()) - { - // handle struct = 0; - return l; - } - else - { - assert(type->equals(e2->type)); - return r; - } + return r; } ////////////////////////////////////////////////////////////////////////////////////////// @@ -986,25 +977,20 @@ { LLValue* v = p->func()->thisVar; assert(v); - return new DImValue(type, v); + return new DVarValue(type, v, true); } // regular this expr else if (VarDeclaration* vd = var->isVarDeclaration()) { LLValue* v; if (vd->toParent2() != p->func()->decl) { Logger::println("nested this exp"); - v = DtoLoad(DtoNestedVariable(vd)); + return DtoNestedVariable(type, vd); } else { Logger::println("normal this exp"); v = p->func()->decl->ir.irFunc->thisVar; - if (llvm::isa(v)) - v = DtoLoad(v); } - const LLType* t = DtoType(type); - if (v->getType() != t) - v = DtoBitCast(v, t); - return new DThisValue(type, vd, v); + return new DVarValue(type, vd, v, true); } // anything we're not yet handling ? @@ -1497,7 +1483,7 @@ LLValue* rval = dval->getRVal(); DtoDeleteClass(rval); } - if (!dval->isThis() && dval->isVar() && dval->isVar()->lval) { + if (dval->isVar() && dval->isVar()->lval) { LLValue* lval = dval->getLVal(); DtoStore(llvm::Constant::getNullValue(lval->getType()->getContainedType(0)), lval); } diff -r 261b05cf4d1c -r 45a67b6f1310 tests/mini/foreach9.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/foreach9.d Mon Aug 04 02:59:34 2008 +0200 @@ -0,0 +1,24 @@ +module mini.foreach9; +extern(C) int printf(char* str, ...); + +struct array2d(T) { + int test() { + printf("%p\n", cast(void*) this); + foreach (x; *this) { + printf("%p\n", cast(void*) this); + } + return true; + } + int opApply(int delegate(ref int) dg) { + int x; + return dg(x), 0; + } +} + +unittest { + array2d!(int) test; + test.test(); + //int i = 0; i /= i; +} + +void main() { } diff -r 261b05cf4d1c -r 45a67b6f1310 tests/mini/nested15.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/nested15.d Mon Aug 04 02:59:34 2008 +0200 @@ -0,0 +1,35 @@ +// $HeadURL: svn://svn.berlios.de/dstress/trunk/run/t/this_13_A.d $ +// $Date: 2006-12-31 20:59:08 +0100 (Sun, 31 Dec 2006) $ +// $Author: thomask $ + +// @author@ Frank Benoit +// @date@ 2006-10-09 +// @uri@ http://d.puremagic.com/issues/show_bug.cgi?id=419 +// @desc@ [Issue 419] New: Anonymous classes are not working. + +// added to mini to catch regressions earlier + +module mini.nested15; + +class I { + abstract void get( char[] s ); +} + +class C{ + void init(){ + I i = new class() I { + void get( char[] s ){ + func(); + } + }; + } + void func( ){ } +} + +int main(){ + C c = new C(); + c.init(); + + return 0; +} + diff -r 261b05cf4d1c -r 45a67b6f1310 tests/mini/nested5.d --- a/tests/mini/nested5.d Sun Aug 03 16:59:28 2008 +0200 +++ b/tests/mini/nested5.d Mon Aug 04 02:59:34 2008 +0200 @@ -11,12 +11,13 @@ { void func() { - printf("Hello world %d\n", i++); + printf("Hello nested world %d\n", i++); //i++; } } - scope c = new C; + auto c = new C; c.func(); + printf("i = %d\n", i); assert(i == 44); } diff -r 261b05cf4d1c -r 45a67b6f1310 tests/mini/nested6a.d --- a/tests/mini/nested6a.d Sun Aug 03 16:59:28 2008 +0200 +++ b/tests/mini/nested6a.d Mon Aug 04 02:59:34 2008 +0200 @@ -12,28 +12,31 @@ int j; void func() { - int k; + int k; printf("C.func() %d\n", i++); class C2 { - int l; + int l; void func2() { + printf("in C2.func2()\n"); printf("C2.func2() %d\n", i++); } - int m; + int m; } { - scope c2 = new C2; + printf("new C2\n"); + auto c2 = new C2; + printf("C2.func2()\n"); c2.func2(); } - int n; + int n; } - int o; + int o; } - scope c = new C; + auto c = new C; c.func(); } diff -r 261b05cf4d1c -r 45a67b6f1310 tests/runminitest.d --- a/tests/runminitest.d Sun Aug 03 16:59:28 2008 +0200 +++ b/tests/runminitest.d Mon Aug 04 02:59:34 2008 +0200 @@ -55,6 +55,8 @@ cmd ~= v; } int cl = classify(testname); + if (cl == COMPILE || cl == NOCOMPILE) + cmd ~= " -c"; writefln(cmd); if (system(cmd) != 0) { if (cl != NOCOMPILE)