1 // -*- C++ -*- 2 //************************************************************************* 3 // 4 // Copyright 2009-2021 by Wilson Snyder. This program is free software; 5 // you can redistribute it and/or modify it under the terms of either the 6 // GNU Lesser General Public License Version 3 or the Perl Artistic License 7 // Version 2.0. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 //************************************************************************* 15 /// \file 16 /// \brief Verilog::Parse: Symbol table accessing 17 /// 18 /// Authors: Wilson Snyder 19 /// 20 /// Code available from: https://www.veripool.org/verilog-perl 21 /// 22 //************************************************************************* 23 24 #ifndef _VAST_H_ 25 #define _VAST_H_ 1 26 27 #include <string> 28 #include <cstdlib> 29 #include <cassert> 30 using namespace std; 31 32 // We don't include perl.h as it gets upset when merged with bison 33 // code. So just grab a minimal set. 34 struct av; 35 struct hv; 36 37 //###################################################################### 38 // Enumeration that indicates what type of symbol is in the symbol tree. 39 // We may later change to use a different object for each type 40 41 class VAstType { 42 public: 43 enum en { 44 NOT_FOUND = 0, 45 NETLIST = 1, // Top of structure, created by Parser.pm:sub new{} 46 AN_ERROR = 2, // Consistency error in internal tables (ERROR alone is a #define on some systems) 47 UNKNOWN = 3, // Things that need scope, but don't know type yet 48 // 49 BLOCK, 50 CHECKER, 51 CLASS, // For yaID__CLASS 52 CLOCKING, 53 COVERGROUP, // For yaID__COVERGROUP 54 ENUM, 55 FORK, 56 FUNCTION, 57 INTERFACE, 58 LET, 59 MODPORT, 60 MODULE, 61 PACKAGE, // For yaID__PACKAGE 62 PROGRAM, 63 PROPERTY, 64 SEQUENCE, 65 STRUCT, 66 TASK, 67 TYPE, // For yaID__TYPE 68 UNION, 69 _MAX 70 }; 71 enum en m_e; VAstType()72 inline VAstType() {}; VAstType(en _e)73 inline VAstType(en _e) : m_e(_e) {}; VAstType(int _e)74 explicit inline VAstType(int _e) : m_e(static_cast<en>(_e)) {}; en()75 operator en() const { return m_e; }; ascii()76 const char* ascii() const { 77 static const char* names[] = { 78 "NOT_FOUND", "netlist", "error", "unknown", 79 "block", "checker", "class", "clocking", "covergroup", 80 "enum", "fork", "function", "interface", "let", 81 "modport", "module", "package", "program", "property", 82 "sequence", "struct", "task", "type", "union", 83 "_MAX" 84 }; 85 return names[m_e]; 86 } 87 }; 88 inline bool operator== (VAstType lhs, VAstType rhs) { return (lhs.m_e == rhs.m_e); } 89 inline bool operator== (VAstType lhs, VAstType::en rhs) { return (lhs.m_e == rhs); } 90 inline bool operator== (VAstType::en lhs, VAstType rhs) { return (lhs == rhs.m_e); } 91 92 //###################################################################### 93 // Single symbol table 94 95 class VAstEnt { 96 private: 97 // MEMBERS 98 // NOT ALLOWED - this class really has this==AV* 99 100 // STATIC MEMBERS 101 static int s_debug; 102 public: debug(int flag)103 static void debug(int flag) { s_debug=flag; } debug()104 static int debug() { return s_debug; } 105 106 private: 107 // CREATORS VAstEnt()108 VAstEnt() { assert(0); } // Not made by users, it's an AV* ~VAstEnt()109 ~VAstEnt() { assert(0); } // Not made by users, it's an AV* 110 111 av* newAVEnt(VAstType type); 112 static void initAVEnt(struct av* avp, VAstType type, struct av* parentp); 113 114 // ACCESSORS castAVp()115 inline struct av* castAVp() { return (struct av*)(this); } avToSymEnt(struct av * avp)116 inline VAstEnt* avToSymEnt(struct av* avp) { return (VAstEnt*)(avp); } 117 118 /// $self->[2]: For current entry, the hash of symbols under it 119 struct hv* subhash(); 120 121 /// Insert into current table 122 void replaceInsert(VAstEnt* newentp, const string& name); 123 124 public: 125 // ACCESSORS 126 127 /// $self->[0]: For current entry, the node type 128 VAstType type(); 129 130 /// $self->[1]: For current entry, what node it is under or NULL if netlist 131 VAstEnt* parentp(); 132 133 /// type() indicates we shouldn't report this as a containing object typeIgnoreObjof()134 bool typeIgnoreObjof() { VAstType t=type(); return t==VAstType::BLOCK || t==VAstType::FORK; } 135 136 /// Info on current node, for debug 137 string ascii(const string& name=""); 138 139 // METHODS 140 /// Return internal pointer for given name or null 141 VAstEnt* findSym(const string& name); 142 143 /// Find or create a symbol under current entry 144 VAstEnt* findInsert(VAstType type, const string& name); 145 146 /// Replace or create a symbol entry under current entry 147 VAstEnt* replaceInsert(VAstType type, const string& name); 148 149 /// Insert into current table from another imported package's table 150 void import(VAstEnt* fromEntp, const string& id_or_star); 151 152 protected: 153 friend class VSymStack; 154 void initNetlist(VFileLine* fl); 155 }; 156 157 #endif // guard 158