diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index e9f7e8614..e85401a07 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -9013,8 +9013,8 @@ class AstCUse final : public AstNode { // C++ use of a class or #include; indicates need of forward declaration // Parents: NODEMODULE private: - VUseType m_useType; // What sort of use this is - string m_name; + const VUseType m_useType; // What sort of use this is + const string m_name; public: AstCUse(FileLine* fl, VUseType useType, const string& name) @@ -9022,10 +9022,9 @@ public: , m_useType{useType} , m_name{name} {} ASTNODE_NODE_FUNCS(CUse) - virtual string name() const override { return m_name; } virtual void dump(std::ostream& str = std::cout) const override; + virtual string name() const override { return m_name; } VUseType useType() const { return m_useType; } - void useType(VUseType useType) { m_useType = useType; } }; class AstMTaskBody final : public AstNode { diff --git a/src/V3CUse.cpp b/src/V3CUse.cpp index d997256f3..78a9260c3 100644 --- a/src/V3CUse.cpp +++ b/src/V3CUse.cpp @@ -13,14 +13,12 @@ // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 // //************************************************************************* -// V3Class's Transformations: +// V3CUse's Transformations: // // Each module: // Each cell: // Create CUse for cell forward declaration -// Each class: -// Create string access functions -// Search for dtypes referencing class, and create CUse for forward declaraion +// Search for dtypes referencing class, and create CUse for forward declaration // //************************************************************************* @@ -30,58 +28,39 @@ #include "V3Global.h" #include "V3CUse.h" #include "V3Ast.h" -#include "V3EmitCBase.h" -#include +#include //###################################################################### -class CUseState final { -private: - // MEMBERS - AstNodeModule* m_modInsertp; // Current module to insert AstCUse under - using UseString = std::pair; - std::map m_didUse; // What we already used - - // NODE STATE - // AstClass::user2() -> bool. True if iterated - AstUser2InUse m_inuser2; - - // METHODS - VL_DEBUG_FUNC; // Declare debug() - -public: - AstCUse* newUse(AstNode* nodep, VUseType useType, const string& name) { - UseString key{useType, name}; - if (m_didUse.find(key) == m_didUse.end()) { - AstCUse* const newp = new AstCUse{nodep->fileline(), useType, name}; - m_modInsertp->addStmtp(newp); - UINFO(8, "Insert " << newp << endl); - m_didUse[key] = newp; - } - return m_didUse[key]; - } - - // CONSTRUCTORS - explicit CUseState(AstNodeModule* nodep) - : m_modInsertp{nodep} {} - virtual ~CUseState() = default; - VL_UNCOPYABLE(CUseState); -}; - // Visit within a module all nodes and data types they reference, finding // any classes so we can make sure they are defined when Verilated code // compiles -class CUseDTypeVisitor final : public AstNVisitor { +class CUseVisitor final : public AstNVisitor { + // NODE STATE + // AstNode::user1() -> bool. True if already visited + AstUser1InUse m_inuser1; + // MEMBERS - CUseState& m_stater; // State for inserter bool m_impOnly = false; // In details needed only for implementation + AstNodeModule* const m_modp; // Current module + std::set> m_didUse; // What we already used + // METHODS + void addNewUse(AstNode* nodep, VUseType useType, const string& name) { + if (m_didUse.emplace(useType, name).second) { + AstCUse* const newp = new AstCUse{nodep->fileline(), useType, name}; + m_modp->addStmtp(newp); + UINFO(8, "Insert " << newp << endl); + } + } + + // VISITORS virtual void visit(AstClassRefDType* nodep) override { - if (nodep->user2SetOnce()) return; // Process once - if (!m_impOnly) m_stater.newUse(nodep, VUseType::INT_FWD_CLASS, nodep->classp()->name()); + if (nodep->user1SetOnce()) return; // Process once + if (!m_impOnly) addNewUse(nodep, VUseType::INT_FWD_CLASS, nodep->classp()->name()); // No class.h, it's inside the class package's h file - m_stater.newUse(nodep, VUseType::IMP_INCLUDE, nodep->classp()->classOrPackagep()->name()); + addNewUse(nodep, VUseType::IMP_INCLUDE, nodep->classp()->classOrPackagep()->name()); // Need to include extends() when we implement, but no need for pointers to know VL_RESTORER(m_impOnly); { @@ -90,54 +69,27 @@ class CUseDTypeVisitor final : public AstNVisitor { } } virtual void visit(AstNodeDType* nodep) override { - if (nodep->user2SetOnce()) return; // Process once + if (nodep->user1SetOnce()) return; // Process once if (nodep->virtRefDTypep()) iterate(nodep->virtRefDTypep()); if (nodep->virtRefDType2p()) iterate(nodep->virtRefDType2p()); } virtual void visit(AstNode* nodep) override { - if (nodep->user2SetOnce()) return; // Process once - if (nodep->dtypep() && !nodep->dtypep()->user2()) iterate(nodep->dtypep()); + if (nodep->user1SetOnce()) return; // Process once + if (nodep->dtypep() && !nodep->dtypep()->user1()) iterate(nodep->dtypep()); + iterateChildren(nodep); + } + virtual void visit(AstCell* nodep) override { + if (nodep->user1SetOnce()) return; // Process once + // Currently no IMP_INCLUDE because we include __Syms which has them all + addNewUse(nodep, VUseType::INT_FWD_CLASS, nodep->modp()->name()); iterateChildren(nodep); } public: // CONSTRUCTORS - explicit CUseDTypeVisitor(AstNodeModule* nodep, CUseState& stater) - : m_stater(stater) { // Need () or GCC 4.8 false warning - iterate(nodep); - } - virtual ~CUseDTypeVisitor() override = default; - VL_UNCOPYABLE(CUseDTypeVisitor); -}; - -class CUseVisitor final : public AstNVisitor { - // MEMBERS - CUseState m_state; // Inserter state - - // METHODS - VL_DEBUG_FUNC; // Declare debug() - - // Module use builders - void makeUseCells(AstNodeModule* nodep) { - for (AstNode* itemp = nodep->stmtsp(); itemp; itemp = itemp->nextp()) { - if (AstCell* const cellp = VN_CAST(itemp, Cell)) { - // Currently no include because we include __Syms which has them all - m_state.newUse(nodep, VUseType::INT_FWD_CLASS, cellp->modp()->name()); - } - } - } - // VISITORS - virtual void visit(AstNodeModule* nodep) override { - makeUseCells(nodep); - { CUseDTypeVisitor dtypeVisitor{nodep, m_state}; } - } - virtual void visit(AstNode*) override {} // All in AstNodeModule - -public: - // CONSTRUCTORS - explicit CUseVisitor(AstNodeModule* nodep) - : m_state{nodep} { - iterate(nodep); + explicit CUseVisitor(AstNodeModule* modp) + : m_modp(modp) { + iterate(modp); } virtual ~CUseVisitor() override = default; VL_UNCOPYABLE(CUseVisitor); @@ -153,7 +105,7 @@ void V3CUse::cUseAll() { modp = VN_CAST(modp->nextp(), NodeModule)) { // Insert under this module; someday we should e.g. make Ast // for each output file and put under that - CUseVisitor visitor{modp}; + CUseVisitor{modp}; } V3Global::dumpCheckGlobalTree("cuse", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3); }