~ubuntu-branches/ubuntu/trusty/verilator/trusty-proposed

« back to all changes in this revision

Viewing changes to .pc/Fix-PowerPC-runtime-error.patch/src/V3ParseImp.h

  • Committer: Bazaar Package Importer
  • Author(s): أحمد المحمودي (Ahmed El-Mahmoudy)
  • Date: 2011-08-23 13:15:42 UTC
  • Revision ID: james.westby@ubuntu.com-20110823131542-zcle7eobz4bbdxmm
Tags: 3.820-2
Cherry-picked Fix-PowerPC-runtime-error.patch from upstream VCS
(Closes: #598256)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- C++ -*-
 
2
//*************************************************************************
 
3
// DESCRIPTION: Verilator: Common header between parser and lex
 
4
//
 
5
// Code available from: http://www.veripool.org/verilator
 
6
//
 
7
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
 
8
//
 
9
//*************************************************************************
 
10
//
 
11
// Copyright 2009-2011 by Wilson Snyder.  This program is free software; you can
 
12
// redistribute it and/or modify it under the terms of either the GNU
 
13
// Lesser General Public License Version 3 or the Perl Artistic License
 
14
// Version 2.0.
 
15
//
 
16
// Verilator is distributed in the hope that it will be useful,
 
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
// GNU General Public License for more details.
 
20
//
 
21
//*************************************************************************
 
22
 
 
23
#ifndef _V3PARSEIMP_H_
 
24
#define _V3PARSEIMP_H_ 1
 
25
#include "config_build.h"
 
26
#include "verilatedos.h"
 
27
#include "V3Error.h"
 
28
#include "V3Global.h"
 
29
#include "V3Parse.h"
 
30
#include "V3SymTable.h"
 
31
#include <deque>
 
32
 
 
33
class V3Lexer;
 
34
 
 
35
// IMPORTANT: Don't include this file other than in the bison and flex,
 
36
// as it's definitions will confuse other parsers
 
37
 
 
38
//======================================================================
 
39
// Types (between parser & lexer)
 
40
 
 
41
typedef enum { uniq_NONE, uniq_UNIQUE, uniq_UNIQUE0, uniq_PRIORITY } V3UniqState;
 
42
 
 
43
typedef enum { iprop_NONE, iprop_CONTEXT, iprop_PURE } V3ImportProperty;
 
44
 
 
45
//============================================================================
 
46
// We can't use bison's %union as we want to pass the fileline with all tokens
 
47
 
 
48
struct V3ParseBisonYYSType {
 
49
    FileLine*   fl;
 
50
    AstNode*    scp;    // Symbol table scope for future lookups
 
51
    union {
 
52
        V3Number*       nump;
 
53
        string*         strp;
 
54
        int             cint;
 
55
        double          cdouble;
 
56
        V3UniqState     uniqstate;
 
57
        AstSignedState  signstate;
 
58
        V3ImportProperty iprop;
 
59
        V3ErrorCode::en errcodeen;
 
60
 
 
61
        AstNode*        nodep;
 
62
 
 
63
        AstBasicDType*  bdtypep;
 
64
        AstBegin*       beginp;
 
65
        AstCase*        casep;
 
66
        AstCaseItem*    caseitemp;
 
67
        AstConst*       constp;
 
68
        AstNodeModule*  modulep;
 
69
        AstNodeDType*   dtypep;
 
70
        AstNodeFTask*   ftaskp;
 
71
        AstNodeFTaskRef* ftaskrefp;
 
72
        AstNodeSenItem* senitemp;
 
73
        AstNodeVarRef*  varnodep;
 
74
        AstPackage*     packagep;
 
75
        AstParseRef*    parserefp;
 
76
        AstPin*         pinp;
 
77
        AstRange*       rangep;
 
78
        AstSenTree*     sentreep;
 
79
        AstVar*         varp;
 
80
        AstVarRef*      varrefp;
 
81
    };
 
82
};
 
83
 
 
84
#define YYSTYPE V3ParseBisonYYSType
 
85
 
 
86
//######################################################################
 
87
// Symbol table for parsing
 
88
 
 
89
class V3ParseSym {
 
90
    // TYPES
 
91
    typedef vector<V3SymTable*> SymStack;
 
92
 
 
93
private:
 
94
    // MEMBERS
 
95
    static int  s_anonNum;              // Number of next anonymous object
 
96
    V3SymTable* m_symTableNextId;       // Symbol table for next lexer lookup
 
97
    V3SymTable* m_symCurrentp;          // Active symbol table for additions/lookups
 
98
    V3SymTable* m_symRootp;             // Root symbol table
 
99
    SymStack    m_sympStack;            // Stack of nodes with symbol tables
 
100
    SymStack    m_symsp;                // All symbol tables, to cleanup
 
101
 
 
102
private:
 
103
    // METHODS
 
104
    static V3SymTable* getTable(AstNode* nodep) {
 
105
        if (!nodep->user4p()) nodep->v3fatalSrc("Current symtable not found");
 
106
        return nodep->user4p()->castSymTable();
 
107
    }
 
108
 
 
109
public:
 
110
    V3SymTable* nextId() const { return m_symTableNextId; }
 
111
    V3SymTable* symCurrentp() const { return m_symCurrentp; }
 
112
    V3SymTable* symRootp() const { return m_symRootp; }
 
113
 
 
114
    V3SymTable* findNewTable(AstNode* nodep, V3SymTable* parentp) {
 
115
        if (!nodep->user4p()) {
 
116
            V3SymTable* symsp = new V3SymTable(nodep, parentp);
 
117
            nodep->user4p(symsp);
 
118
            m_symsp.push_back(symsp);
 
119
        }
 
120
        return getTable(nodep);
 
121
    }
 
122
    void nextId(AstNode* entp) {
 
123
        if (entp) {
 
124
            UINFO(9,"symTableNextId under "<<entp<<"-"<<entp->type().ascii()<<endl);
 
125
            m_symTableNextId = getTable(entp);
 
126
        }
 
127
        else {
 
128
            UINFO(9,"symTableNextId under NULL"<<endl);
 
129
            m_symTableNextId = NULL;
 
130
        }
 
131
    }
 
132
    void reinsert(AstNode* nodep, V3SymTable* parentp=NULL) {
 
133
        reinsert(nodep, parentp, nodep->name());
 
134
    }
 
135
    void reinsert(AstNode* nodep, V3SymTable* parentp, string name) {
 
136
        if (!parentp) parentp = symCurrentp();
 
137
        if (name == "") {  // New name with space in name so can't collide with users
 
138
            name = string(" anon") + nodep->type().ascii() + cvtToStr(++s_anonNum);
 
139
        }
 
140
        parentp->reinsert(name,nodep);
 
141
    }
 
142
    void pushNew(AstNode* nodep) { pushNewUnder(nodep, NULL); }
 
143
    void pushNewUnder(AstNode* nodep, V3SymTable* parentp) {
 
144
        if (!parentp) parentp = symCurrentp();
 
145
        V3SymTable* symp = findNewTable(nodep, parentp);  // Will set user4p, which is how we connect table to node
 
146
        reinsert(nodep, parentp);
 
147
        pushScope(symp);
 
148
    }
 
149
    void pushScope(V3SymTable* symp) {
 
150
        m_sympStack.push_back(symp);
 
151
        m_symCurrentp = symp;
 
152
    }
 
153
    void popScope(AstNode* nodep) {
 
154
        if (symCurrentp()->ownerp() != nodep) {
 
155
            if (debug()) { showUpward(); dump(cout,"-mism: "); }
 
156
            nodep->v3fatalSrc("Symbols suggest ending "<<symCurrentp()->ownerp()->prettyTypeName()
 
157
                              <<" but parser thinks ending "<<nodep->prettyTypeName());
 
158
            return;
 
159
        }
 
160
        m_sympStack.pop_back();
 
161
        if (m_sympStack.empty()) { nodep->v3fatalSrc("symbol stack underflow"); return; }
 
162
        m_symCurrentp = m_sympStack.back();
 
163
    }
 
164
    void showUpward () {
 
165
        UINFO(1,"ParseSym Stack:\n");
 
166
        for (SymStack::reverse_iterator it=m_sympStack.rbegin(); it!=m_sympStack.rend(); ++it) {
 
167
            V3SymTable* symp = *it;
 
168
            UINFO(1,"\t"<<symp->ownerp()<<endl);
 
169
        }
 
170
        UINFO(1,"ParseSym Current: "<<symCurrentp()->ownerp()<<endl);
 
171
    }
 
172
    void dump(ostream& os, const string& indent="") {
 
173
        os<<"ParseSym Dump:\n";
 
174
        m_sympStack[0]->dump(os, indent, true);
 
175
    }
 
176
    AstNode* findEntUpward (const string& name) {
 
177
        // Lookup the given string as an identifier, return type of the id, scanning upward
 
178
        return symCurrentp()->findIdUpward(name);
 
179
    }
 
180
    void import(AstNode* packagep, const string& id_or_star) {
 
181
        // Import from package::id_or_star to this
 
182
        V3SymTable* symp = getTable(packagep);
 
183
        if (!symp) {  // Internal problem, because we earlier found pkg to label it an ID__aPACKAGE
 
184
            packagep->v3fatalSrc("Import package not found");
 
185
            return;
 
186
        }
 
187
        // Walk old sym table and reinsert into current table
 
188
        // We let V3Link report the error instead of us
 
189
        symCurrentp()->import(symp, id_or_star);
 
190
    }
 
191
public:
 
192
    // CREATORS
 
193
    V3ParseSym(AstNetlist* rootp) {
 
194
        s_anonNum = 0;          // Number of next anonymous object
 
195
        pushScope(findNewTable(rootp, NULL));
 
196
        m_symTableNextId = NULL;
 
197
        m_symCurrentp = symCurrentp();
 
198
        m_symRootp = symCurrentp();
 
199
    }
 
200
    ~V3ParseSym() {
 
201
        for (SymStack::iterator it = m_symsp.begin(); it != m_symsp.end(); ++it) {
 
202
            delete (*it);
 
203
        }
 
204
    }
 
205
};
 
206
 
 
207
//######################################################################
 
208
 
 
209
class V3ParseImp {
 
210
    // MEMBERS
 
211
    AstNetlist*         m_rootp;        // Root of the design
 
212
    V3InFilter*         m_filterp;      // Reading filter
 
213
    V3Lexer*            m_lexerp;       // Current FlexLexer
 
214
    static V3ParseImp*  s_parsep;       // Current THIS, bison() isn't class based
 
215
    FileLine*           m_fileline;     // Filename/linenumber currently active
 
216
 
 
217
    V3ParseSym  m_sym;                  // Symbol table
 
218
    bool        m_inCellDefine;         // Inside a `celldefine
 
219
    bool        m_inLibrary;            // Currently reading a library vs. regular file
 
220
    int         m_inBeginKwd;           // Inside a `begin_keywords
 
221
    int         m_lastVerilogState;     // Last LEX state in `begin_keywords
 
222
 
 
223
    bool        m_ahead;                // aheadToken is valid
 
224
    int         m_aheadToken;           // Token we read ahead
 
225
    V3ParseBisonYYSType m_aheadVal;     // aheadToken's value
 
226
 
 
227
    deque<string*> m_stringps;          // Created strings for later cleanup
 
228
    deque<V3Number*> m_numberps;        // Created numbers for later cleanup
 
229
    deque<FileLine>  m_lintState;       // Current lint state for save/restore
 
230
    deque<string> m_ppBuffers;          // Preprocessor->lex buffer of characters to process
 
231
 
 
232
public:
 
233
    // Note these are an exception to using the filename as the debug type
 
234
    static int debugBison() {
 
235
        static int level = -1;
 
236
        if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel("bison");
 
237
        return level;
 
238
    }
 
239
    static int debugFlex() {
 
240
        static int level = -1;
 
241
        if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel("flex");
 
242
        return level;
 
243
    }
 
244
    static int debug() { return debugBison() ? debugFlex() : 0; }
 
245
 
 
246
    // Functions called by lex rules:
 
247
    int yylexThis();
 
248
    static bool optPsl() { return v3Global.opt.psl(); }
 
249
    static bool optFuture(const string& flag) { return v3Global.opt.isFuture(flag); }
 
250
 
 
251
    void ppline (const char* text);
 
252
    void linenoInc() { fileline()->linenoInc(); }
 
253
    void verilatorCmtLint(const char* text, bool on);
 
254
    void verilatorCmtLintSave();
 
255
    void verilatorCmtLintRestore();
 
256
    void verilatorCmtBad(const char* text);
 
257
    double parseDouble(const char* text, size_t length);
 
258
    void pushBeginKeywords(int state) { m_inBeginKwd++; m_lastVerilogState=state; }
 
259
    bool popBeginKeywords() { if (m_inBeginKwd) { m_inBeginKwd--; return true; } else return false; }
 
260
    int lastVerilogState() { return m_lastVerilogState; }
 
261
    static const char* tokenName(int tok);
 
262
 
 
263
    void ppPushText(const string& text) { m_ppBuffers.push_back(text); }
 
264
    size_t ppInputToLex(char* buf, size_t max_size);
 
265
 
 
266
    static V3ParseImp* parsep() { return s_parsep; }
 
267
 
 
268
    // TODO: Many of these functions are the old interface; they'd be better as non-static
 
269
    // and called as READP->newString(...) etc.
 
270
    string* newString(const string& text) {
 
271
        // Allocate a string, remembering it so we can reclaim storage at lex end
 
272
        string* strp = new string (text);
 
273
        m_stringps.push_back(strp);
 
274
        return strp;
 
275
    }
 
276
    string* newString(const char* text) {
 
277
        // Allocate a string, remembering it so we can reclaim storage at lex end
 
278
        string* strp = new string (text);
 
279
        m_stringps.push_back(strp);
 
280
        return strp;
 
281
    }
 
282
    string* newString(const char* text, size_t length) {
 
283
        string* strp = new string (text, length);
 
284
        m_stringps.push_back(strp);
 
285
        return strp;
 
286
    }
 
287
    V3Number* newNumber(FileLine* fl, const char* text) {
 
288
        V3Number* nump = new V3Number (fl, text);
 
289
        m_numberps.push_back(nump);
 
290
        return nump;
 
291
    }
 
292
 
 
293
    // Return next token, for bison, since bison isn't class based, use a global THIS
 
294
    FileLine* fileline() { return m_fileline; }
 
295
    AstNetlist* rootp() { return m_rootp; }
 
296
    FileLine* copyOrSameFileLine() { return fileline()->copyOrSameFileLine(); }
 
297
    bool inCellDefine() { return m_inCellDefine; }
 
298
    void inCellDefine(bool flag) { m_inCellDefine = flag; }
 
299
    bool inLibrary() { return m_inLibrary; }
 
300
 
 
301
    // Interactions with parser
 
302
    int  bisonParse();
 
303
 
 
304
    // Interactions with lexer
 
305
    void lexNew(int debug);
 
306
    void lexDestroy();
 
307
    void stateExitPsl();        // Parser -> lexer communication
 
308
    void statePushVlg();        // Parser -> lexer communication
 
309
    void statePop();    // Parser -> lexer communication
 
310
    int stateVerilogRecent();   // Parser -> lexer communication
 
311
    size_t flexPpInputToLex(char* buf, size_t max_size) { return ppInputToLex(buf,max_size); }
 
312
 
 
313
    //==== Symbol tables
 
314
    V3ParseSym* symp() { return &m_sym; }
 
315
 
 
316
public:
 
317
    // CREATORS
 
318
    V3ParseImp(AstNetlist* rootp, V3InFilter* filterp)
 
319
        : m_sym(rootp), m_filterp(filterp) {
 
320
        m_rootp = rootp; m_lexerp = NULL;
 
321
        m_inCellDefine = false;
 
322
        m_inLibrary = false;
 
323
        m_inBeginKwd = 0;
 
324
        m_lastVerilogState = stateVerilogRecent();
 
325
        m_ahead = false;
 
326
        m_aheadToken = 0;
 
327
    }
 
328
    ~V3ParseImp();
 
329
    void parserClear();
 
330
 
 
331
    // METHODS
 
332
    // Preprocess and read the Verilog file specified into the netlist database
 
333
    int lexToBison();  // Pass token to bison
 
334
 
 
335
    void parseFile(FileLine* fileline, const string& modfilename, bool inLibrary);
 
336
 
 
337
private:
 
338
    void lexFile(const string& modname);
 
339
    int lexToken(); // Internal; called from lexToBison
 
340
};
 
341
 
 
342
#endif // Guard