diff --git a/dmd/declaration.c b/dmd/declaration.c index 5015b7f0..62b1c8b2 100644 --- a/dmd/declaration.c +++ b/dmd/declaration.c @@ -621,9 +621,6 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer onstack = 0; canassign = 0; value = NULL; - - // LLVMDC - needsStorage = false; } Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) @@ -645,8 +642,6 @@ Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) 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 --git a/dmd/declaration.h b/dmd/declaration.h index 00a70761..32103da2 100644 --- a/dmd/declaration.h +++ b/dmd/declaration.h @@ -266,9 +266,6 @@ struct VarDeclaration : Declaration // Eliminate need for dynamic_cast VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } - - // LLVMDC - bool needsStorage; }; /**************************************************************/ diff --git a/dmd/expression.c b/dmd/expression.c index bf1665b7..362a11d4 100644 --- a/dmd/expression.c +++ b/dmd/expression.c @@ -3628,7 +3628,6 @@ Expression *SymOffExp::semantic(Scope *sc) if (v) { v->checkNestedReference(sc, loc); - v->needsStorage = true; } return this; } @@ -3777,7 +3776,6 @@ Expression *VarExp::modifiableLvalue(Scope *sc, Expression *e) 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 @@ Expression *AddrExp::semantic(Scope *sc) e = e->semantic(sc); return e; } - else if (v) - { - v->needsStorage = true; - } } else if (e1->op == TOKarray) { diff --git a/dmd/func.c b/dmd/func.c index 8ffdfdd4..6ed927fa 100644 --- a/dmd/func.c +++ b/dmd/func.c @@ -796,11 +796,6 @@ void FuncDeclaration::semantic3(Scope *sc) 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 --git a/gen/aa.cpp b/gen/aa.cpp index f8eae571..9e1d214b 100644 --- a/gen/aa.cpp +++ b/gen/aa.cpp @@ -22,10 +22,6 @@ static LLValue* to_pkey(Loc& loc, DValue* key) 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 --git a/gen/d-asm-i386.h b/gen/d-asm-i386.h index 6f8b6f1a..98d83917 100644 --- a/gen/d-asm-i386.h +++ b/gen/d-asm-i386.h @@ -2037,9 +2037,6 @@ struct AsmProcessor } } 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 --git a/gen/dvalue.cpp b/gen/dvalue.cpp index 502921a9..7225ec20 100644 --- a/gen/dvalue.cpp +++ b/gen/dvalue.cpp @@ -53,7 +53,7 @@ LLValue* DVarValue::getRVal() 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 --git a/gen/dvalue.h b/gen/dvalue.h index 7964f7f8..ae42f72f 100644 --- a/gen/dvalue.h +++ b/gen/dvalue.h @@ -27,7 +27,6 @@ struct DConstValue; struct DNullValue; struct DVarValue; struct DFieldValue; -struct DThisValue; struct DFuncValue; struct DSliceValue; struct DArrayLenValue; @@ -49,7 +48,6 @@ struct DValue : Object 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 @@ struct DFieldValue : DVarValue 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 --git a/gen/functions.cpp b/gen/functions.cpp index 6cf3af17..708de3b0 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -546,7 +546,8 @@ void DtoDefineFunc(FuncDeclaration* fd) 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 @@ void DtoDefineFunc(FuncDeclaration* fd) // 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 @@ void DtoDefineFunc(FuncDeclaration* fd) 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 @@ void DtoDefineFunc(FuncDeclaration* fd) 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 --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index ac389ce9..59fe2a20 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -330,181 +330,154 @@ void DtoLeaveMonitor(LLValue* v) // 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()) - { - LLValue* v = fd->ir.irFunc->nestedVar; - assert(v); - return v->getType(); - } - else if (ClassDeclaration* cd = p->isClassDeclaration()) - { - return DtoType(cd->type); - } - else - { - Logger::println("symbol: '%s' kind: '%s'", sc->toChars(), sc->kind()); - assert(0); - } -} + from = from->toParent2(); -////////////////////////////////////////////////////////////////////////////////////////// - -static LLValue* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, LLValue* v) -{ - LOG_SCOPE; - if (sc == func) + // parent is a function + if (FuncDeclaration* f = from->isFuncDeclaration()) { - return v; - } - else if (FuncDeclaration* fd = sc->isFuncDeclaration()) - { - Logger::println("scope is function: %s", fd->toChars()); - - if (fd->toParent2() == func) + IrFunction* irfunc = f->ir.irFunc; + // parent has nested var struct + if (irfunc->nestedVar) { - if (!func->ir.irFunc->nestedVar) - return NULL; - return DtoBitCast(v, func->ir.irFunc->nestedVar->getType()); + return DtoBitCast(val, irfunc->nestedVar->getType()); } - - v = DtoBitCast(v, get_next_frame_ptr_type(fd)); - Logger::cout() << "v = " << *v << '\n'; - - if (fd->toParent2()->isFuncDeclaration()) + // parent has this argument + else if (irfunc->thisVar) { - 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); + return DtoBitCast(val, irfunc->thisVar->getType()->getContainedType(0)); } + // none of the above, means no context is required, dummy. else { - assert(0); + return getNullPtr(getVoidPtrType()); } - return get_frame_ptr_impl(func, fd->toParent2(), v); } - else if (ClassDeclaration* cd = sc->isClassDeclaration()) + // parent is a class + else if (ClassDeclaration* c = from->isClassDeclaration()) { - Logger::println("scope is class: %s", cd->toChars()); - return get_frame_ptr_impl(func, cd->toParent2(), v); + return DtoBitCast(DtoLoad(val), DtoType(c->type)); } + // parent is not valid 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; -} - -////////////////////////////////////////////////////////////////////////////////////////// - -static void print_frame_worker(VarDeclaration* vd, Dsymbol* par) -{ - if (vd->toParent2() == par) - { - Logger::println("found: '%s' kind: '%s'", par->toChars(), par->kind()); - return; - } - - Logger::println("diving into: '%s' kind: '%s'", par->toChars(), par->kind()); + Logger::println("listing context frame list for funcdecl '%s'", func->toPrettyChars()); LOG_SCOPE; - print_frame_worker(vd, par->toParent2()); -} -////////////////////////////////////////////////////////////////////////////////////////// + int level = 0; -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"); -} - -////////////////////////////////////////////////////////////////////////////////////////// - -LLValue* DtoNestedVariable(VarDeclaration* vd) -{ - // log the frame list IrFunction* irfunc = gIR->func(); - if (Logger::enabled()) - print_nested_frame_list(vd, irfunc->decl); + Dsymbol* current = irfunc->decl; - // 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) + // this context ? + if (current == func) { - return ptr; + return irfunc->nestedVar; } - // handle a "normal" nested variable + // otherwise use the context argument + LLValue* val = dive_into_nested(current, irfunc->thisVar); + current = current->toParent2(); + assert(val); - // we must cast here to be sure. nested classes just have a void* - ptr = DtoBitCast(ptr, func->ir.irFunc->nestedVar->getType()); + 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; + } - // 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!!! + 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) + { + 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); + } + + // 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))) - 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 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs) } 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 @@ LLValue* DtoBoolean(Loc& loc, DValue* dval) 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 --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 7b584863..9a3e8e2e 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -36,7 +36,7 @@ void DtoLeaveMonitor(LLValue* v); // 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 --git a/gen/toir.cpp b/gen/toir.cpp index 6909d72a..ebe62b8f 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -106,7 +106,7 @@ DValue* VarExp::toElem(IRState* p) // 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 @@ DValue* VarExp::toElem(IRState* p) 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 @@ DValue* AssignExp::toElem(IRState* p) 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 @@ DValue* ThisExp::toElem(IRState* p) { 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 @@ DValue* DeleteExp::toElem(IRState* p) 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 --git a/tests/mini/foreach9.d b/tests/mini/foreach9.d new file mode 100644 index 00000000..c9c63607 --- /dev/null +++ b/tests/mini/foreach9.d @@ -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 --git a/tests/mini/nested15.d b/tests/mini/nested15.d new file mode 100644 index 00000000..ca096b4f --- /dev/null +++ b/tests/mini/nested15.d @@ -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 --git a/tests/mini/nested5.d b/tests/mini/nested5.d index 47881999..890eda3a 100644 --- a/tests/mini/nested5.d +++ b/tests/mini/nested5.d @@ -11,12 +11,13 @@ void main() { 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 --git a/tests/mini/nested6a.d b/tests/mini/nested6a.d index 9b70419f..ba266c33 100644 --- a/tests/mini/nested6a.d +++ b/tests/mini/nested6a.d @@ -12,28 +12,31 @@ void main() 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 --git a/tests/runminitest.d b/tests/runminitest.d index bd2fbcc5..223aa40d 100644 --- a/tests/runminitest.d +++ b/tests/runminitest.d @@ -55,6 +55,8 @@ int main(string[] args) cmd ~= v; } int cl = classify(testname); + if (cl == COMPILE || cl == NOCOMPILE) + cmd ~= " -c"; writefln(cmd); if (system(cmd) != 0) { if (cl != NOCOMPILE)