# HG changeset patch # User Christian Kamm # Date 1222981939 -7200 # Node ID 8aebdf56c45540dba4c3b3985f3875f3bdfca9c0 # Parent 94b01f15814f8052e396aa7828c4834f8d7e550e Move check for access of context for nested class from backend into frontend. diff -r 94b01f15814f -r 8aebdf56c455 dmd/declaration.h --- a/dmd/declaration.h Thu Oct 02 03:38:29 2008 +0200 +++ b/dmd/declaration.h Thu Oct 02 23:12:19 2008 +0200 @@ -636,7 +636,12 @@ FuncDeclaration *isFuncDeclaration() { return this; } // llvmdc stuff + + // vars declared in this function that nested funcs reference + // is this is not empty, nestedFrameRef is set and these VarDecls + // probably have nestedref set too, see VarDeclaration::checkNestedReference std::set nestedVars; + std::string intrinsicName; bool isIntrinsic(); diff -r 94b01f15814f -r 8aebdf56c455 dmd/expression.c --- a/dmd/expression.c Thu Oct 02 03:38:29 2008 +0200 +++ b/dmd/expression.c Thu Oct 02 23:12:19 2008 +0200 @@ -3370,6 +3370,7 @@ */ Dsymbol *s = cd->toParent2(); ClassDeclaration *cdn = s->isClassDeclaration(); + FuncDeclaration *fdn = s->isFuncDeclaration(); //printf("cd isNested, cdn = %s\n", cdn ? cdn->toChars() : "null"); if (cdn) @@ -3421,6 +3422,22 @@ } else if (thisexp) error("e.new is only for allocating nested classes"); + else if (fdn) + { + // make sure the parent context fdn of cd is reachable from sc + for (Dsymbol *sp = sc->parent; 1; sp = sp->parent) + { + if (fdn == sp) + break; + FuncDeclaration *fsp = sp ? sp->isFuncDeclaration() : NULL; + if (!sp || (fsp && fsp->isStatic())) + { + error("outer function context of %s is needed to 'new' nested class %s", fdn->toPrettyChars(), cd->toPrettyChars()); + break; + } + } + + } } else if (thisexp) error("e.new is only for allocating nested classes"); diff -r 94b01f15814f -r 8aebdf56c455 gen/classes.cpp --- a/gen/classes.cpp Thu Oct 02 03:38:29 2008 +0200 +++ b/gen/classes.cpp Thu Oct 02 23:12:19 2008 +0200 @@ -842,12 +842,6 @@ Logger::println("Resolving nested context"); LOG_SCOPE; - if (gIR->func()->decl->isStatic()) - { - newexp->error("function %s is static and cannot access nested class %s", gIR->func()->decl->toPrettyChars(), tc->sym->toPrettyChars()); - fatal(); - } - // get context LLValue* nest = DtoNestedContext(loc, tc->sym); diff -r 94b01f15814f -r 8aebdf56c455 gen/llvmhelpers.cpp --- a/gen/llvmhelpers.cpp Thu Oct 02 03:38:29 2008 +0200 +++ b/gen/llvmhelpers.cpp Thu Oct 02 23:12:19 2008 +0200 @@ -390,11 +390,15 @@ LOG_SCOPE; IrFunction* irfunc = gIR->func(); - + + // if this func has its own vars that are accessed by nested funcs + // use its own context if (irfunc->nestedVar) return irfunc->nestedVar; + // otherwise, it may have gotten a context from the caller else if (irfunc->nestArg) return irfunc->nestArg; + // or just have a this argument else if (irfunc->thisArg) { ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();