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