mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 12:40:11 +03:00
Moved VarDeclaration.checkNestedReference to funcsem (#21237)
This commit is contained in:
parent
c296cb1ec2
commit
1fe1cac81b
4 changed files with 79 additions and 78 deletions
|
@ -27,7 +27,6 @@ import dmd.dtemplate;
|
|||
import dmd.errors;
|
||||
import dmd.expression;
|
||||
import dmd.func;
|
||||
import dmd.funcsem : getLevelAndCheck;
|
||||
import dmd.globals;
|
||||
import dmd.gluelayer;
|
||||
import dmd.hdrgen;
|
||||
|
@ -1084,83 +1083,6 @@ extern (C++) class VarDeclaration : Declaration
|
|||
return e;
|
||||
}
|
||||
|
||||
/************************************
|
||||
* Check to see if this variable is actually in an enclosing function
|
||||
* rather than the current one.
|
||||
* Update nestedrefs[], closureVars[] and outerVars[].
|
||||
* Returns: true if error occurs.
|
||||
*/
|
||||
extern (D) final bool checkNestedReference(Scope* sc, Loc loc)
|
||||
{
|
||||
//printf("VarDeclaration::checkNestedReference() %s\n", toChars());
|
||||
if (sc.intypeof == 1 || sc.ctfe)
|
||||
return false;
|
||||
if (!parent || parent == sc.parent)
|
||||
return false;
|
||||
if (isDataseg() || (storage_class & STC.manifest))
|
||||
return false;
|
||||
|
||||
// The current function
|
||||
FuncDeclaration fdthis = sc.parent.isFuncDeclaration();
|
||||
if (!fdthis)
|
||||
return false; // out of function scope
|
||||
|
||||
Dsymbol p = toParent2();
|
||||
|
||||
// Function literals from fdthis to p must be delegates
|
||||
ensureStaticLinkTo(fdthis, p);
|
||||
|
||||
// The function that this variable is in
|
||||
FuncDeclaration fdv = p.isFuncDeclaration();
|
||||
if (!fdv || fdv == fdthis)
|
||||
return false;
|
||||
|
||||
// Add fdthis to nestedrefs[] if not already there
|
||||
if (!nestedrefs.contains(fdthis))
|
||||
nestedrefs.push(fdthis);
|
||||
|
||||
//printf("\tfdv = %s\n", fdv.toChars());
|
||||
//printf("\tfdthis = %s\n", fdthis.toChars());
|
||||
if (loc.isValid())
|
||||
{
|
||||
if (fdthis.getLevelAndCheck(loc, sc, fdv, this) == fdthis.LevelError)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Add this VarDeclaration to fdv.closureVars[] if not already there
|
||||
if (!sc.intypeof && !sc.traitsCompiles &&
|
||||
// https://issues.dlang.org/show_bug.cgi?id=17605
|
||||
(fdv.skipCodegen || !fdthis.skipCodegen))
|
||||
{
|
||||
if (!fdv.closureVars.contains(this))
|
||||
fdv.closureVars.push(this);
|
||||
}
|
||||
|
||||
if (!fdthis.outerVars.contains(this))
|
||||
fdthis.outerVars.push(this);
|
||||
|
||||
//printf("fdthis is %s\n", fdthis.toChars());
|
||||
//printf("var %s in function %s is nested ref\n", toChars(), fdv.toChars());
|
||||
// __dollar creates problems because it isn't a real variable
|
||||
// https://issues.dlang.org/show_bug.cgi?id=3326
|
||||
if (ident == Id.dollar)
|
||||
{
|
||||
.error(loc, "cannnot use `$` inside a function literal");
|
||||
return true;
|
||||
}
|
||||
if (ident == Id.withSym) // https://issues.dlang.org/show_bug.cgi?id=1759
|
||||
{
|
||||
ExpInitializer ez = _init.isExpInitializer();
|
||||
assert(ez);
|
||||
Expression e = ez.exp;
|
||||
if (e.op == EXP.construct || e.op == EXP.blit)
|
||||
e = (cast(AssignExp)e).e2;
|
||||
return lambdaCheckForNestedRef(e, sc);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
override final Dsymbol toAlias()
|
||||
{
|
||||
//printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym);
|
||||
|
|
|
@ -21,6 +21,7 @@ import dmd.dsymbol;
|
|||
import dmd.expression;
|
||||
import dmd.expressionsem;
|
||||
import dmd.func;
|
||||
import dmd.funcsem : checkNestedReference;
|
||||
import dmd.init;
|
||||
import dmd.initsem;
|
||||
import dmd.location;
|
||||
|
|
|
@ -3702,3 +3702,80 @@ Dsymbol isUnique(OverDeclaration od)
|
|||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/************************************
|
||||
* Check to see if this variable is actually in an enclosing function
|
||||
* rather than the current one.
|
||||
* Update nestedrefs[], closureVars[] and outerVars[].
|
||||
* Returns: true if error occurs.
|
||||
*/
|
||||
extern (D) bool checkNestedReference(VarDeclaration vd, Scope* sc, Loc loc)
|
||||
{
|
||||
//printf("VarDeclaration::checkNestedReference() %s\n", toChars());
|
||||
if (sc.intypeof == 1 || sc.ctfe)
|
||||
return false;
|
||||
if (!vd.parent || vd.parent == sc.parent)
|
||||
return false;
|
||||
if (vd.isDataseg() || (vd.storage_class & STC.manifest))
|
||||
return false;
|
||||
|
||||
// The current function
|
||||
FuncDeclaration fdthis = sc.parent.isFuncDeclaration();
|
||||
if (!fdthis)
|
||||
return false; // out of function scope
|
||||
|
||||
Dsymbol p = vd.toParent2();
|
||||
|
||||
// Function literals from fdthis to p must be delegates
|
||||
ensureStaticLinkTo(fdthis, p);
|
||||
|
||||
// The function that this variable is in
|
||||
FuncDeclaration fdv = p.isFuncDeclaration();
|
||||
if (!fdv || fdv == fdthis)
|
||||
return false;
|
||||
|
||||
// Add fdthis to nestedrefs[] if not already there
|
||||
if (!vd.nestedrefs.contains(fdthis))
|
||||
vd.nestedrefs.push(fdthis);
|
||||
|
||||
//printf("\tfdv = %s\n", fdv.toChars());
|
||||
//printf("\tfdthis = %s\n", fdthis.toChars());
|
||||
if (loc.isValid())
|
||||
{
|
||||
if (fdthis.getLevelAndCheck(loc, sc, fdv, vd) == fdthis.LevelError)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Add this VarDeclaration to fdv.closureVars[] if not already there
|
||||
if (!sc.intypeof && !sc.traitsCompiles &&
|
||||
// https://issues.dlang.org/show_bug.cgi?id=17605
|
||||
(fdv.skipCodegen || !fdthis.skipCodegen))
|
||||
{
|
||||
if (!fdv.closureVars.contains(vd))
|
||||
fdv.closureVars.push(vd);
|
||||
}
|
||||
|
||||
if (!fdthis.outerVars.contains(vd))
|
||||
fdthis.outerVars.push(vd);
|
||||
|
||||
//printf("fdthis is %s\n", fdthis.toChars());
|
||||
//printf("var %s in function %s is nested ref\n", toChars(), fdv.toChars());
|
||||
// __dollar creates problems because it isn't a real variable
|
||||
// https://issues.dlang.org/show_bug.cgi?id=3326
|
||||
if (vd.ident == Id.dollar)
|
||||
{
|
||||
.error(loc, "cannnot use `$` inside a function literal");
|
||||
return true;
|
||||
}
|
||||
if (vd.ident == Id.withSym) // https://issues.dlang.org/show_bug.cgi?id=1759
|
||||
{
|
||||
ExpInitializer ez = vd._init.isExpInitializer();
|
||||
assert(ez);
|
||||
Expression e = ez.exp;
|
||||
if (e.op == EXP.construct || e.op == EXP.blit)
|
||||
e = (cast(AssignExp)e).e2;
|
||||
return lambdaCheckForNestedRef(e, sc);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import dmd.dsymbol;
|
|||
import dmd.errors;
|
||||
import dmd.expression;
|
||||
import dmd.expressionsem;
|
||||
import dmd.funcsem : checkNestedReference;
|
||||
import dmd.globals;
|
||||
import dmd.id;
|
||||
import dmd.identifier;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue