mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-08 20:06:03 +03:00
Move check for access of context for nested class from backend into frontend.
This commit is contained in:
parent
e2a1394ae8
commit
b3d4bc83f8
4 changed files with 27 additions and 7 deletions
|
@ -636,7 +636,12 @@ struct FuncDeclaration : Declaration
|
||||||
FuncDeclaration *isFuncDeclaration() { return this; }
|
FuncDeclaration *isFuncDeclaration() { return this; }
|
||||||
|
|
||||||
// llvmdc stuff
|
// 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<VarDeclaration*> nestedVars;
|
std::set<VarDeclaration*> nestedVars;
|
||||||
|
|
||||||
std::string intrinsicName;
|
std::string intrinsicName;
|
||||||
|
|
||||||
bool isIntrinsic();
|
bool isIntrinsic();
|
||||||
|
|
|
@ -3370,6 +3370,7 @@ Lagain:
|
||||||
*/
|
*/
|
||||||
Dsymbol *s = cd->toParent2();
|
Dsymbol *s = cd->toParent2();
|
||||||
ClassDeclaration *cdn = s->isClassDeclaration();
|
ClassDeclaration *cdn = s->isClassDeclaration();
|
||||||
|
FuncDeclaration *fdn = s->isFuncDeclaration();
|
||||||
|
|
||||||
//printf("cd isNested, cdn = %s\n", cdn ? cdn->toChars() : "null");
|
//printf("cd isNested, cdn = %s\n", cdn ? cdn->toChars() : "null");
|
||||||
if (cdn)
|
if (cdn)
|
||||||
|
@ -3421,6 +3422,22 @@ Lagain:
|
||||||
}
|
}
|
||||||
else if (thisexp)
|
else if (thisexp)
|
||||||
error("e.new is only for allocating nested classes");
|
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)
|
else if (thisexp)
|
||||||
error("e.new is only for allocating nested classes");
|
error("e.new is only for allocating nested classes");
|
||||||
|
|
|
@ -842,12 +842,6 @@ DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp)
|
||||||
Logger::println("Resolving nested context");
|
Logger::println("Resolving nested context");
|
||||||
LOG_SCOPE;
|
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
|
// get context
|
||||||
LLValue* nest = DtoNestedContext(loc, tc->sym);
|
LLValue* nest = DtoNestedContext(loc, tc->sym);
|
||||||
|
|
||||||
|
|
|
@ -391,10 +391,14 @@ LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
|
||||||
|
|
||||||
IrFunction* irfunc = gIR->func();
|
IrFunction* irfunc = gIR->func();
|
||||||
|
|
||||||
|
// if this func has its own vars that are accessed by nested funcs
|
||||||
|
// use its own context
|
||||||
if (irfunc->nestedVar)
|
if (irfunc->nestedVar)
|
||||||
return irfunc->nestedVar;
|
return irfunc->nestedVar;
|
||||||
|
// otherwise, it may have gotten a context from the caller
|
||||||
else if (irfunc->nestArg)
|
else if (irfunc->nestArg)
|
||||||
return irfunc->nestArg;
|
return irfunc->nestArg;
|
||||||
|
// or just have a this argument
|
||||||
else if (irfunc->thisArg)
|
else if (irfunc->thisArg)
|
||||||
{
|
{
|
||||||
ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
|
ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue