mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
Extracted Condition.include to visitor in expressionsem (#20977)
This commit is contained in:
parent
6da6066bf1
commit
aafe4f954b
5 changed files with 150 additions and 128 deletions
|
@ -24,7 +24,6 @@ import dmd.dscope;
|
||||||
import dmd.dsymbol;
|
import dmd.dsymbol;
|
||||||
import dmd.errors;
|
import dmd.errors;
|
||||||
import dmd.expression;
|
import dmd.expression;
|
||||||
import dmd.expressionsem : evalStaticCondition;
|
|
||||||
import dmd.globals;
|
import dmd.globals;
|
||||||
import dmd.identifier;
|
import dmd.identifier;
|
||||||
import dmd.location;
|
import dmd.location;
|
||||||
|
@ -71,8 +70,6 @@ extern (C++) abstract class Condition : ASTNode
|
||||||
|
|
||||||
abstract Condition syntaxCopy();
|
abstract Condition syntaxCopy();
|
||||||
|
|
||||||
abstract int include(Scope* sc);
|
|
||||||
|
|
||||||
inout(DebugCondition) isDebugCondition() inout
|
inout(DebugCondition) isDebugCondition() inout
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
@ -324,39 +321,6 @@ extern (C++) final class DebugCondition : DVCondition
|
||||||
super(loc, mod, ident);
|
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
|
override inout(DebugCondition) isDebugCondition() inout
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
|
@ -390,7 +354,7 @@ extern (C++) final class VersionCondition : DVCondition
|
||||||
* Returns:
|
* Returns:
|
||||||
* `true` if it is reserved, `false` otherwise
|
* `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
|
// This list doesn't include "D_*" versions, see the last return
|
||||||
switch (ident)
|
switch (ident)
|
||||||
|
@ -599,41 +563,6 @@ extern (C++) final class VersionCondition : DVCondition
|
||||||
super(loc, mod, ident);
|
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
|
override inout(VersionCondition) isVersionCondition() inout
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
|
@ -662,47 +591,6 @@ extern (C++) final class StaticIfCondition : Condition
|
||||||
return new StaticIfCondition(loc, exp.syntaxCopy());
|
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)
|
override void accept(Visitor v)
|
||||||
{
|
{
|
||||||
v.visit(this);
|
v.visit(this);
|
||||||
|
@ -734,7 +622,7 @@ bool findCondition(ref Identifiers ids, Identifier ident) @safe nothrow pure
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper for printing dependency information
|
// 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)
|
if (!global.params.moduleDeps.buffer || global.params.moduleDeps.name)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -38,7 +38,6 @@ public:
|
||||||
DYNCAST dyncast() const override final { return DYNCAST_CONDITION; }
|
DYNCAST dyncast() const override final { return DYNCAST_CONDITION; }
|
||||||
|
|
||||||
virtual Condition *syntaxCopy() = 0;
|
virtual Condition *syntaxCopy() = 0;
|
||||||
virtual int include(Scope *sc) = 0;
|
|
||||||
virtual DebugCondition *isDebugCondition() { return nullptr; }
|
virtual DebugCondition *isDebugCondition() { return nullptr; }
|
||||||
virtual VersionCondition *isVersionCondition() { return nullptr; }
|
virtual VersionCondition *isVersionCondition() { return nullptr; }
|
||||||
void accept(Visitor *v) override { v->visit(this); }
|
void accept(Visitor *v) override { v->visit(this); }
|
||||||
|
@ -70,7 +69,6 @@ class DebugCondition final : public DVCondition
|
||||||
public:
|
public:
|
||||||
static void addGlobalIdent(const char *ident);
|
static void addGlobalIdent(const char *ident);
|
||||||
|
|
||||||
int include(Scope *sc) override;
|
|
||||||
void accept(Visitor *v) override { v->visit(this); }
|
void accept(Visitor *v) override { v->visit(this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,7 +78,6 @@ public:
|
||||||
static void addGlobalIdent(const char *ident);
|
static void addGlobalIdent(const char *ident);
|
||||||
static void addPredefinedGlobalIdent(const char *ident);
|
static void addPredefinedGlobalIdent(const char *ident);
|
||||||
|
|
||||||
int include(Scope *sc) override;
|
|
||||||
void accept(Visitor *v) override { v->visit(this); }
|
void accept(Visitor *v) override { v->visit(this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,6 +87,5 @@ public:
|
||||||
Expression *exp;
|
Expression *exp;
|
||||||
|
|
||||||
StaticIfCondition *syntaxCopy() override;
|
StaticIfCondition *syntaxCopy() override;
|
||||||
int include(Scope *sc) override;
|
|
||||||
void accept(Visitor *v) override { v->visit(this); }
|
void accept(Visitor *v) override { v->visit(this); }
|
||||||
};
|
};
|
||||||
|
|
|
@ -7533,12 +7533,12 @@ private extern(C++) class NewScopeVisitor : Visitor
|
||||||
|
|
||||||
extern(C++) Dsymbols* include(Dsymbol d, Scope* sc)
|
extern(C++) Dsymbols* include(Dsymbol d, Scope* sc)
|
||||||
{
|
{
|
||||||
scope icv = new IncludeVisitor(sc);
|
scope icv = new ConditionIncludeVisitor(sc);
|
||||||
d.accept(icv);
|
d.accept(icv);
|
||||||
return icv.symbols;
|
return icv.symbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern(C++) class IncludeVisitor : Visitor
|
extern(C++) class ConditionIncludeVisitor : Visitor
|
||||||
{
|
{
|
||||||
alias visit = typeof(super).visit;
|
alias visit = typeof(super).visit;
|
||||||
Scope* sc;
|
Scope* sc;
|
||||||
|
@ -7570,7 +7570,7 @@ extern(C++) class IncludeVisitor : Visitor
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
assert(cdc.condition);
|
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)
|
override void visit(StaticIfDeclaration sif)
|
||||||
|
@ -8056,7 +8056,7 @@ private extern(C++) class OneMemberVisitor : Visitor
|
||||||
//printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition.inc);
|
//printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition.inc);
|
||||||
if (cd.condition.inc != Include.notComputed)
|
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);
|
result = Dsymbol.oneMembers(d, *ps, ident);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -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.optimize(WANTvalue);
|
||||||
sfe.aggrfe.aggr = sfe.aggrfe.aggr.ctfeInterpret();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6574,7 +6574,6 @@ public:
|
||||||
Include inc;
|
Include inc;
|
||||||
DYNCAST dyncast() const final override;
|
DYNCAST dyncast() const final override;
|
||||||
virtual Condition* syntaxCopy() = 0;
|
virtual Condition* syntaxCopy() = 0;
|
||||||
virtual int32_t include(Scope* sc) = 0;
|
|
||||||
virtual DebugCondition* isDebugCondition();
|
virtual DebugCondition* isDebugCondition();
|
||||||
virtual VersionCondition* isVersionCondition();
|
virtual VersionCondition* isVersionCondition();
|
||||||
virtual StaticIfCondition* isStaticIfCondition();
|
virtual StaticIfCondition* isStaticIfCondition();
|
||||||
|
@ -6603,7 +6602,6 @@ class DebugCondition final : public DVCondition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void addGlobalIdent(const char* ident);
|
static void addGlobalIdent(const char* ident);
|
||||||
int32_t include(Scope* sc) override;
|
|
||||||
DebugCondition* isDebugCondition() override;
|
DebugCondition* isDebugCondition() override;
|
||||||
void accept(Visitor* v) override;
|
void accept(Visitor* v) override;
|
||||||
};
|
};
|
||||||
|
@ -6613,7 +6611,6 @@ class VersionCondition final : public DVCondition
|
||||||
public:
|
public:
|
||||||
static void addGlobalIdent(const char* ident);
|
static void addGlobalIdent(const char* ident);
|
||||||
static void addPredefinedGlobalIdent(const char* ident);
|
static void addPredefinedGlobalIdent(const char* ident);
|
||||||
int32_t include(Scope* sc) override;
|
|
||||||
VersionCondition* isVersionCondition() override;
|
VersionCondition* isVersionCondition() override;
|
||||||
void accept(Visitor* v) override;
|
void accept(Visitor* v) override;
|
||||||
};
|
};
|
||||||
|
@ -6623,7 +6620,6 @@ class StaticIfCondition final : public Condition
|
||||||
public:
|
public:
|
||||||
Expression* exp;
|
Expression* exp;
|
||||||
StaticIfCondition* syntaxCopy() override;
|
StaticIfCondition* syntaxCopy() override;
|
||||||
int32_t include(Scope* sc) override;
|
|
||||||
void accept(Visitor* v) override;
|
void accept(Visitor* v) override;
|
||||||
StaticIfCondition* isStaticIfCondition() override;
|
StaticIfCondition* isStaticIfCondition() override;
|
||||||
};
|
};
|
||||||
|
@ -7520,13 +7516,13 @@ public:
|
||||||
|
|
||||||
extern Array<Dsymbol* >* include(Dsymbol* d, Scope* sc);
|
extern Array<Dsymbol* >* include(Dsymbol* d, Scope* sc);
|
||||||
|
|
||||||
class IncludeVisitor : public Visitor
|
class ConditionIncludeVisitor : public Visitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Visitor::visit;
|
using Visitor::visit;
|
||||||
Scope* sc;
|
Scope* sc;
|
||||||
Array<Dsymbol* >* symbols;
|
Array<Dsymbol* >* symbols;
|
||||||
IncludeVisitor(Scope* sc);
|
ConditionIncludeVisitor(Scope* sc);
|
||||||
void visit(AttribDeclaration* ad) override;
|
void visit(AttribDeclaration* ad) override;
|
||||||
void visit(ConditionalDeclaration* cdc) override;
|
void visit(ConditionalDeclaration* cdc) override;
|
||||||
void visit(StaticIfDeclaration* sif) 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 void lowerNonArrayAggregate(StaticForeach* sfe, Scope* sc);
|
||||||
|
|
||||||
|
extern int32_t include(Condition* c, Scope* sc);
|
||||||
|
|
||||||
class NrvoWalker final : public StatementRewriteWalker
|
class NrvoWalker final : public StatementRewriteWalker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue