Internals: Make AstArg into an AstNode, not Expr (#7122)

This commit is contained in:
Geza Lore 2026-02-22 14:40:51 +00:00 committed by GitHub
parent 443678d8c4
commit 579acced99
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 26 additions and 25 deletions

View File

@ -502,6 +502,24 @@ public:
// === Concrete node types =====================================================
// === AstNode ===
class AstArg final : public AstNode {
// An argument to a function/task, which is either an expression, or is a placeholder for an
// omitted argument.
// @astgen op1 := exprp : Optional[AstNodeExpr] // nullptr if omitted
std::string m_name; // Argument name, or "" for number based interconnect
public:
AstArg(FileLine* fl, const std::string& name, AstNodeExpr* exprp)
: ASTGEN_SUPER_Arg(fl)
, m_name{name} {
this->exprp(exprp);
}
ASTGEN_MEMBERS_AstArg;
std::string name() const override VL_MT_STABLE { return m_name; }
void name(const std::string& name) override { m_name = name; }
bool emptyConnectNoNext() const { return !exprp() && name() == "" && !nextp(); }
};
// === AstNodeExpr ===
class AstAddrOfCFunc final : public AstNodeExpr {
// Get address of CFunc
@ -522,28 +540,6 @@ public:
bool cleanOut() const override { return true; }
AstCFunc* funcp() const { return m_funcp; }
};
class AstArg final : public AstNodeExpr {
// An argument to a function/task, which is either an expression, or is a placeholder for an
// omitted argument.
// TODO: AstArg should not be AstNodeExpr, but is currently used as such widely. Fix later.
// @astgen op1 := exprp : Optional[AstNodeExpr] // nullptr if omitted
string m_name; // Pin name, or "" for number based interconnect
public:
AstArg(FileLine* fl, const string& name, AstNodeExpr* exprp)
: ASTGEN_SUPER_Arg(fl)
, m_name{name} {
this->exprp(exprp);
}
ASTGEN_MEMBERS_AstArg;
bool hasDType() const override VL_MT_SAFE { return false; }
string name() const override VL_MT_STABLE { return m_name; } // * = Pin name, ""=go by number
void name(const string& name) override { m_name = name; }
bool emptyConnectNoNext() const { return !exprp() && name() == "" && !nextp(); }
string emitVerilog() override { V3ERROR_NA_RETURN(""); }
string emitC() override { V3ERROR_NA_RETURN(""); }
bool cleanOut() const override { V3ERROR_NA_RETURN(true); }
};
class AstAttrOf final : public AstNodeExpr {
// Return a value of a attribute, for example a LSB or array LSB of a signal
// @astgen op1 := fromp : Optional[AstNode<AstNodeExpr|AstNodeDType>]

View File

@ -204,6 +204,7 @@ class DataflowExtractVisitor final : public VNVisitor {
}
void visit(AstNodeExpr* nodep) override { iterateChildrenConst(nodep); }
void visit(AstArg* nodep) override { iterateChildrenConst(nodep); }
void visit(AstNodeVarRef* nodep) override {
if (nodep->access().isWriteOrRW()) {
@ -218,8 +219,7 @@ class DataflowExtractVisitor final : public VNVisitor {
}
void visit(AstNode* nodep) override {
// Conservatively assume unhandled nodes are impure. This covers all AstNodeFTaskRef
// as AstNodeFTaskRef are sadly not AstNodeExpr.
// Conservatively assume unhandled nodes are impure.
m_impure = true;
// Still need to gather all references/force/release, etc.
iterateChildrenConst(nodep);

View File

@ -566,7 +566,6 @@ private:
void visit(AstNode* nodep) override { iterateChildren(nodep); }
void visit(AstNew* nodep) override { iterateChildren(nodep); }
void visit(AstMethodCall* nodep) override { iterateChildren(nodep); }
void visit(AstArg* nodep) override { iterateChildren(nodep); }
public:
// CONSTRUCTORS

View File

@ -699,6 +699,12 @@ class RandomizeMarkVisitor final : public VNVisitor {
|| (nodep->op3p() && nodep->op3p()->user1())
|| (nodep->op4p() && nodep->op4p()->user1()));
}
void visit(AstArg* nodep) override {
iterateChildrenConst(nodep);
if (!m_constraintExprGenp && !m_inStdWith) return;
nodep->user1(nodep->exprp() && nodep->exprp()->user1());
}
void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
public: