Extracted Condition.include to visitor in expressionsem (#20977)

This commit is contained in:
Matthew Qiu 2025-03-11 19:33:53 -04:00 committed by GitHub
parent 6da6066bf1
commit aafe4f954b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 150 additions and 128 deletions

View file

@ -24,7 +24,6 @@ import dmd.dscope;
import dmd.dsymbol;
import dmd.errors;
import dmd.expression;
import dmd.expressionsem : evalStaticCondition;
import dmd.globals;
import dmd.identifier;
import dmd.location;
@ -71,8 +70,6 @@ extern (C++) abstract class Condition : ASTNode
abstract Condition syntaxCopy();
abstract int include(Scope* sc);
inout(DebugCondition) isDebugCondition() inout
{
return null;
@ -324,39 +321,6 @@ extern (C++) final class DebugCondition : DVCondition
super(loc, mod, ident);
}
override int include(Scope* sc)
{
//printf("DebugCondition::include() level = %d, debuglevel = %d\n", level, global.params.debuglevel);
if (inc != Include.notComputed)
{
return inc == Include.yes;
}
inc = Include.no;
bool definedInModule = false;
if (ident)
{
if (mod.debugids && findCondition(*mod.debugids, ident))
{
inc = Include.yes;
definedInModule = true;
}
else if (findCondition(global.debugids, ident))
inc = Include.yes;
else
{
if (!mod.debugidsNot)
mod.debugidsNot = new Identifiers();
mod.debugidsNot.push(ident);
}
}
else if (global.params.debugEnabled)
inc = Include.yes;
if (!definedInModule)
printDepsConditional(sc, this, "depsDebug ");
return (inc == Include.yes);
}
override inout(DebugCondition) isDebugCondition() inout
{
return this;
@ -390,7 +354,7 @@ extern (C++) final class VersionCondition : DVCondition
* Returns:
* `true` if it is reserved, `false` otherwise
*/
extern(D) private static bool isReserved(const(char)[] ident) @safe
extern(D) public static bool isReserved(const(char)[] ident) @safe
{
// This list doesn't include "D_*" versions, see the last return
switch (ident)
@ -599,41 +563,6 @@ extern (C++) final class VersionCondition : DVCondition
super(loc, mod, ident);
}
override int include(Scope* sc)
{
//printf("VersionCondition::include() level = %d, versionlevel = %d\n", level, global.params.versionlevel);
//if (ident) printf("\tident = '%s'\n", ident.toChars());
if (inc != Include.notComputed)
{
return inc == Include.yes;
}
inc = Include.no;
bool definedInModule = false;
if (ident)
{
if (mod.versionids && findCondition(*mod.versionids, ident))
{
inc = Include.yes;
definedInModule = true;
}
else if (findCondition(global.versionids, ident))
inc = Include.yes;
else
{
if (!mod.versionidsNot)
mod.versionidsNot = new Identifiers();
mod.versionidsNot.push(ident);
}
}
if (!definedInModule &&
(!ident || (!isReserved(ident.toString()) && ident != Id._unittest && ident != Id._assert)))
{
printDepsConditional(sc, this, "depsVersion ");
}
return (inc == Include.yes);
}
override inout(VersionCondition) isVersionCondition() inout
{
return this;
@ -662,47 +591,6 @@ extern (C++) final class StaticIfCondition : Condition
return new StaticIfCondition(loc, exp.syntaxCopy());
}
override int include(Scope* sc)
{
// printf("StaticIfCondition::include(sc = %p) this=%p inc = %d\n", sc, this, inc);
int errorReturn()
{
if (!global.gag)
inc = Include.no; // so we don't see the error message again
return 0;
}
if (inc != Include.notComputed)
{
return inc == Include.yes;
}
if (!sc)
{
error(loc, "`static if` conditional cannot be at global scope");
inc = Include.no;
return 0;
}
import dmd.staticcond;
bool errors;
bool result = evalStaticCondition(sc, exp, exp, errors);
// Prevent repeated condition evaluation.
// See: fail_compilation/fail7815.d
if (inc != Include.notComputed)
return (inc == Include.yes);
if (errors)
return errorReturn();
if (result)
inc = Include.yes;
else
inc = Include.no;
return (inc == Include.yes);
}
override void accept(Visitor v)
{
v.visit(this);
@ -734,7 +622,7 @@ bool findCondition(ref Identifiers ids, Identifier ident) @safe nothrow pure
}
// Helper for printing dependency information
private void printDepsConditional(Scope* sc, DVCondition condition, const(char)[] depType)
public void printDepsConditional(Scope* sc, DVCondition condition, const(char)[] depType)
{
if (!global.params.moduleDeps.buffer || global.params.moduleDeps.name)
return;

View file

@ -38,7 +38,6 @@ public:
DYNCAST dyncast() const override final { return DYNCAST_CONDITION; }
virtual Condition *syntaxCopy() = 0;
virtual int include(Scope *sc) = 0;
virtual DebugCondition *isDebugCondition() { return nullptr; }
virtual VersionCondition *isVersionCondition() { return nullptr; }
void accept(Visitor *v) override { v->visit(this); }
@ -70,7 +69,6 @@ class DebugCondition final : public DVCondition
public:
static void addGlobalIdent(const char *ident);
int include(Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
@ -80,7 +78,6 @@ public:
static void addGlobalIdent(const char *ident);
static void addPredefinedGlobalIdent(const char *ident);
int include(Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
@ -90,6 +87,5 @@ public:
Expression *exp;
StaticIfCondition *syntaxCopy() override;
int include(Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};

View file

@ -7533,12 +7533,12 @@ private extern(C++) class NewScopeVisitor : Visitor
extern(C++) Dsymbols* include(Dsymbol d, Scope* sc)
{
scope icv = new IncludeVisitor(sc);
scope icv = new ConditionIncludeVisitor(sc);
d.accept(icv);
return icv.symbols;
}
extern(C++) class IncludeVisitor : Visitor
extern(C++) class ConditionIncludeVisitor : Visitor
{
alias visit = typeof(super).visit;
Scope* sc;
@ -7570,7 +7570,7 @@ extern(C++) class IncludeVisitor : Visitor
return;
}
assert(cdc.condition);
symbols = cdc.condition.include(cdc._scope ? cdc._scope : sc) ? cdc.decl : cdc.elsedecl;
symbols = dmd.expressionsem.include(cdc.condition, cdc._scope ? cdc._scope : sc) ? cdc.decl : cdc.elsedecl;
}
override void visit(StaticIfDeclaration sif)
@ -8056,7 +8056,7 @@ private extern(C++) class OneMemberVisitor : Visitor
//printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition.inc);
if (cd.condition.inc != Include.notComputed)
{
Dsymbols* d = cd.condition.include(null) ? cd.decl : cd.elsedecl;
Dsymbols* d = dmd.expressionsem.include(cd.condition, null) ? cd.decl : cd.elsedecl;
result = Dsymbol.oneMembers(d, *ps, ident);
}
else

View file

@ -17672,3 +17672,143 @@ extern(D) void lowerArrayAggregate(StaticForeach sfe, Scope* sc)
sfe.aggrfe.aggr = sfe.aggrfe.aggr.optimize(WANTvalue);
sfe.aggrfe.aggr = sfe.aggrfe.aggr.ctfeInterpret();
}
extern(C++) int include(Condition c, Scope* sc)
{
scope v = new IncludeVisitor(sc);
c.accept(v);
return v.result;
}
private extern(C++) class IncludeVisitor : Visitor {
alias visit = Visitor.visit;
Scope *sc;
int result;
this(Scope* sc)
{
this.sc = sc;
}
override void visit(DebugCondition dc)
{
//printf("DebugCondition::include() level = %d, debuglevel = %d\n", level, global.params.debuglevel);
if (dc.inc != Include.notComputed)
{
result = dc.inc == Include.yes;
return;
}
dc.inc = Include.no;
bool definedInModule = false;
if (dc.ident)
{
if (dc.mod.debugids && findCondition(*dc.mod.debugids, dc.ident))
{
dc.inc = Include.yes;
definedInModule = true;
}
else if (findCondition(global.debugids, dc.ident))
dc.inc = Include.yes;
else
{
if (!dc.mod.debugidsNot)
dc.mod.debugidsNot = new Identifiers();
dc.mod.debugidsNot.push(dc.ident);
}
}
else if (global.params.debugEnabled)
dc.inc = Include.yes;
if (!definedInModule)
printDepsConditional(sc, dc, "depsDebug ");
result = (dc.inc == Include.yes);
}
override void visit(VersionCondition vc)
{
//printf("VersionCondition::include() level = %d, versionlevel = %d\n", level, global.params.versionlevel);
//if (ident) printf("\tident = '%s'\n", ident.toChars());
if (vc.inc != Include.notComputed)
{
result = vc.inc == Include.yes;
return;
}
vc.inc = Include.no;
bool definedInModule = false;
if (vc.ident)
{
if (vc.mod.versionids && findCondition(*vc.mod.versionids, vc.ident))
{
vc.inc = Include.yes;
definedInModule = true;
}
else if (findCondition(global.versionids, vc.ident))
vc.inc = Include.yes;
else
{
if (!vc.mod.versionidsNot)
vc.mod.versionidsNot = new Identifiers();
vc.mod.versionidsNot.push(vc.ident);
}
}
if (!definedInModule &&
(!vc.ident || (!vc.isReserved(vc.ident.toString()) && vc.ident != Id._unittest && vc.ident != Id._assert)))
{
printDepsConditional(sc, vc, "depsVersion ");
}
result = (vc.inc == Include.yes);
}
override void visit(StaticIfCondition sic)
{
// printf("StaticIfCondition::include(sc = %p) this=%p inc = %d\n", sc, this, inc);
int errorReturn()
{
if (!global.gag)
sic.inc = Include.no; // so we don't see the error message again
return 0;
}
if (sic.inc != Include.notComputed)
{
result = sic.inc == Include.yes;
return;
}
if (!sc)
{
error(sic.loc, "`static if` conditional cannot be at global scope");
sic.inc = Include.no;
result = 0;
return;
}
import dmd.staticcond;
bool errors;
bool local_result = evalStaticCondition(sc, sic.exp, sic.exp, errors);
// Prevent repeated condition evaluation.
// See: fail_compilation/fail7815.d
if (sic.inc != Include.notComputed)
{
result = (sic.inc == Include.yes);
return;
}
if (errors)
{
result = errorReturn();
return;
}
if (local_result)
sic.inc = Include.yes;
else
sic.inc = Include.no;
result = (sic.inc == Include.yes);
}
}

View file

@ -6574,7 +6574,6 @@ public:
Include inc;
DYNCAST dyncast() const final override;
virtual Condition* syntaxCopy() = 0;
virtual int32_t include(Scope* sc) = 0;
virtual DebugCondition* isDebugCondition();
virtual VersionCondition* isVersionCondition();
virtual StaticIfCondition* isStaticIfCondition();
@ -6603,7 +6602,6 @@ class DebugCondition final : public DVCondition
{
public:
static void addGlobalIdent(const char* ident);
int32_t include(Scope* sc) override;
DebugCondition* isDebugCondition() override;
void accept(Visitor* v) override;
};
@ -6613,7 +6611,6 @@ class VersionCondition final : public DVCondition
public:
static void addGlobalIdent(const char* ident);
static void addPredefinedGlobalIdent(const char* ident);
int32_t include(Scope* sc) override;
VersionCondition* isVersionCondition() override;
void accept(Visitor* v) override;
};
@ -6623,7 +6620,6 @@ class StaticIfCondition final : public Condition
public:
Expression* exp;
StaticIfCondition* syntaxCopy() override;
int32_t include(Scope* sc) override;
void accept(Visitor* v) override;
StaticIfCondition* isStaticIfCondition() override;
};
@ -7520,13 +7516,13 @@ public:
extern Array<Dsymbol* >* include(Dsymbol* d, Scope* sc);
class IncludeVisitor : public Visitor
class ConditionIncludeVisitor : public Visitor
{
public:
using Visitor::visit;
Scope* sc;
Array<Dsymbol* >* symbols;
IncludeVisitor(Scope* sc);
ConditionIncludeVisitor(Scope* sc);
void visit(AttribDeclaration* ad) override;
void visit(ConditionalDeclaration* cdc) override;
void visit(StaticIfDeclaration* sif) override;
@ -7553,6 +7549,8 @@ extern bool isFuncHidden(ClassDeclaration* cd, FuncDeclaration* fd);
extern void lowerNonArrayAggregate(StaticForeach* sfe, Scope* sc);
extern int32_t include(Condition* c, Scope* sc);
class NrvoWalker final : public StatementRewriteWalker
{
public: