From aafe4f954bcb71307584d238831261f75d57a0b0 Mon Sep 17 00:00:00 2001 From: Matthew Qiu <93230055+MatthewQiu-5@users.noreply.github.com> Date: Tue, 11 Mar 2025 19:33:53 -0400 Subject: [PATCH] Extracted Condition.include to visitor in expressionsem (#20977) --- compiler/src/dmd/cond.d | 116 +------------------------ compiler/src/dmd/cond.h | 4 - compiler/src/dmd/dsymbolsem.d | 8 +- compiler/src/dmd/expressionsem.d | 140 +++++++++++++++++++++++++++++++ compiler/src/dmd/frontend.h | 10 +-- 5 files changed, 150 insertions(+), 128 deletions(-) diff --git a/compiler/src/dmd/cond.d b/compiler/src/dmd/cond.d index 19c6fe3d5c..9e562b6b9c 100644 --- a/compiler/src/dmd/cond.d +++ b/compiler/src/dmd/cond.d @@ -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; diff --git a/compiler/src/dmd/cond.h b/compiler/src/dmd/cond.h index 174a8fb9aa..0afa042f9d 100644 --- a/compiler/src/dmd/cond.h +++ b/compiler/src/dmd/cond.h @@ -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); } }; diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d index de5e4bda26..54165857fd 100644 --- a/compiler/src/dmd/dsymbolsem.d +++ b/compiler/src/dmd/dsymbolsem.d @@ -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 diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 83f28be96a..45675efd7c 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -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); + } +} diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index 557d9bb7f3..9e07b7236f 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -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* include(Dsymbol* d, Scope* sc); -class IncludeVisitor : public Visitor +class ConditionIncludeVisitor : public Visitor { public: using Visitor::visit; Scope* sc; Array* 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: