Skip to content

Commit b449c17

Browse files
Move checkNestedFuncReference to expressionsem.d (dlang#21592)
1 parent 0cb6dfe commit b449c17

2 files changed

Lines changed: 84 additions & 84 deletions

File tree

compiler/src/dmd/expressionsem.d

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3927,6 +3927,90 @@ private extern(C++) final class IsMemcmpableVisitor : Visitor
39273927
}
39283928
}
39293929

3930+
/*********************************************
3931+
* In the current function 'sc.func', we are calling 'fd'.
3932+
* 1. Check to see if the current function can call 'fd' , issue error if not.
3933+
* 2. If the current function is not the parent of 'fd' , then add
3934+
* the current function to the list of siblings of 'fd' .
3935+
* 3. If the current function is a literal, and it's accessing an uplevel scope,
3936+
* then mark it as a delegate.
3937+
* Returns true if error occurs.
3938+
*/
3939+
private bool checkNestedFuncReference(FuncDeclaration fd, Scope* sc, Loc loc)
3940+
{
3941+
//printf("FuncDeclaration::checkNestedFuncReference() %s\n", toPrettyChars());
3942+
if (auto fld = fd.isFuncLiteralDeclaration())
3943+
{
3944+
if (fld.tok == TOK.reserved)
3945+
{
3946+
fld.tok = TOK.function_;
3947+
fld.vthis = null;
3948+
}
3949+
}
3950+
if (!fd.parent || fd.parent == sc.parent)
3951+
return false;
3952+
if (fd.ident == Id.require || fd.ident == Id.ensure)
3953+
return false;
3954+
if (!fd.isThis() && !fd.isNested())
3955+
return false;
3956+
// The current function
3957+
FuncDeclaration fdthis = sc.parent.isFuncDeclaration();
3958+
if (!fdthis)
3959+
return false; // out of function scope
3960+
Dsymbol p = fd.toParentLocal();
3961+
Dsymbol p2 = fd.toParent2();
3962+
// Function literals from fdthis to p must be delegates
3963+
ensureStaticLinkTo(fdthis, p);
3964+
if (p != p2)
3965+
ensureStaticLinkTo(fdthis, p2);
3966+
if (!fd.isNested())
3967+
return false;
3968+
3969+
// The function that this function is in
3970+
bool checkEnclosing(FuncDeclaration fdv)
3971+
{
3972+
if (!fdv)
3973+
return false;
3974+
if (fdv == fdthis)
3975+
return false;
3976+
//printf("this = %s in [%s]\n", this.toChars(), this.loc.toChars());
3977+
//printf("fdv = %s in [%s]\n", fdv .toChars(), fdv .loc.toChars());
3978+
//printf("fdthis = %s in [%s]\n", fdthis.toChars(), fdthis.loc.toChars());
3979+
// Add this function to the list of those which called us
3980+
if (fdthis != fd)
3981+
{
3982+
bool found = false;
3983+
for (size_t i = 0; i < fd.siblingCallers.length; ++i)
3984+
{
3985+
if (fd.siblingCallers[i] == fdthis)
3986+
found = true;
3987+
}
3988+
if (!found)
3989+
{
3990+
//printf("\tadding sibling %s to %s\n", fdthis.toPrettyChars(), toPrettyChars());
3991+
if (!sc.intypeof && !sc.traitsCompiles)
3992+
{
3993+
fd.siblingCallers.push(fdthis);
3994+
fd.computedEscapingSiblings = false;
3995+
}
3996+
}
3997+
}
3998+
const lv = fdthis.getLevelAndCheck(loc, sc, fdv, fd);
3999+
if (lv == fd.LevelError)
4000+
return true; // error
4001+
if (lv == -1)
4002+
return false; // downlevel call
4003+
if (lv == 0)
4004+
return false; // same level call
4005+
return false; // Uplevel call
4006+
}
4007+
if (checkEnclosing(p.isFuncDeclaration()))
4008+
return true;
4009+
if (checkEnclosing(p == p2 ? null : p2.isFuncDeclaration()))
4010+
return true;
4011+
return false;
4012+
}
4013+
39304014
private extern (C++) final class ExpressionSemanticVisitor : Visitor
39314015
{
39324016
alias visit = Visitor.visit;

compiler/src/dmd/funcsem.d

Lines changed: 0 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,90 +2485,6 @@ private bool canInferAttributes(FuncDeclaration fd, Scope* sc)
24852485
return false;
24862486
}
24872487

2488-
/*********************************************
2489-
* In the current function 'sc.func', we are calling 'fd'.
2490-
* 1. Check to see if the current function can call 'fd' , issue error if not.
2491-
* 2. If the current function is not the parent of 'fd' , then add
2492-
* the current function to the list of siblings of 'fd' .
2493-
* 3. If the current function is a literal, and it's accessing an uplevel scope,
2494-
* then mark it as a delegate.
2495-
* Returns true if error occurs.
2496-
*/
2497-
bool checkNestedFuncReference(FuncDeclaration fd, Scope* sc, Loc loc)
2498-
{
2499-
//printf("FuncDeclaration::checkNestedFuncReference() %s\n", toPrettyChars());
2500-
if (auto fld = fd.isFuncLiteralDeclaration())
2501-
{
2502-
if (fld.tok == TOK.reserved)
2503-
{
2504-
fld.tok = TOK.function_;
2505-
fld.vthis = null;
2506-
}
2507-
}
2508-
if (!fd.parent || fd.parent == sc.parent)
2509-
return false;
2510-
if (fd.ident == Id.require || fd.ident == Id.ensure)
2511-
return false;
2512-
if (!fd.isThis() && !fd.isNested())
2513-
return false;
2514-
// The current function
2515-
FuncDeclaration fdthis = sc.parent.isFuncDeclaration();
2516-
if (!fdthis)
2517-
return false; // out of function scope
2518-
Dsymbol p = fd.toParentLocal();
2519-
Dsymbol p2 = fd.toParent2();
2520-
// Function literals from fdthis to p must be delegates
2521-
ensureStaticLinkTo(fdthis, p);
2522-
if (p != p2)
2523-
ensureStaticLinkTo(fdthis, p2);
2524-
if (!fd.isNested())
2525-
return false;
2526-
2527-
// The function that this function is in
2528-
bool checkEnclosing(FuncDeclaration fdv)
2529-
{
2530-
if (!fdv)
2531-
return false;
2532-
if (fdv == fdthis)
2533-
return false;
2534-
//printf("this = %s in [%s]\n", this.toChars(), this.loc.toChars());
2535-
//printf("fdv = %s in [%s]\n", fdv .toChars(), fdv .loc.toChars());
2536-
//printf("fdthis = %s in [%s]\n", fdthis.toChars(), fdthis.loc.toChars());
2537-
// Add this function to the list of those which called us
2538-
if (fdthis != fd)
2539-
{
2540-
bool found = false;
2541-
for (size_t i = 0; i < fd.siblingCallers.length; ++i)
2542-
{
2543-
if (fd.siblingCallers[i] == fdthis)
2544-
found = true;
2545-
}
2546-
if (!found)
2547-
{
2548-
//printf("\tadding sibling %s to %s\n", fdthis.toPrettyChars(), toPrettyChars());
2549-
if (!sc.intypeof && !sc.traitsCompiles)
2550-
{
2551-
fd.siblingCallers.push(fdthis);
2552-
fd.computedEscapingSiblings = false;
2553-
}
2554-
}
2555-
}
2556-
const lv = fdthis.getLevelAndCheck(loc, sc, fdv, fd);
2557-
if (lv == fd.LevelError)
2558-
return true; // error
2559-
if (lv == -1)
2560-
return false; // downlevel call
2561-
if (lv == 0)
2562-
return false; // same level call
2563-
return false; // Uplevel call
2564-
}
2565-
if (checkEnclosing(p.isFuncDeclaration()))
2566-
return true;
2567-
if (checkEnclosing(p == p2 ? null : p2.isFuncDeclaration()))
2568-
return true;
2569-
return false;
2570-
}
2571-
25722488
/****************************************************
25732489
* Check whether result variable can be built.
25742490
* Returns:

0 commit comments

Comments
 (0)