Skip to content

Commit b0d6181

Browse files
committed
Get the scope of class methods right
Class methods belong in a class scope, not the containing module. So create a lexical scope that carries tasks and functions and create a PClass to represent classes.
1 parent b80afdf commit b0d6181

File tree

11 files changed

+197
-23
lines changed

11 files changed

+197
-23
lines changed

Makefile.in

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,10 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
110110
netenum.o netstruct.o net_event.o net_expr.o net_func.o net_link.o net_modulo.o \
111111
net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \
112112
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
113-
pform_disciplines.o pform_dump.o pform_struct_type.o pform_types.o \
113+
pform_disciplines.o pform_dump.o pform_pclass.o pform_struct_type.o \
114+
pform_types.o \
114115
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
115-
Attrib.o HName.o Module.o PDelays.o PEvent.o PExpr.o PGate.o \
116+
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PGate.o \
116117
PGenerate.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \
117118
Statement.o AStatement.o $M $(FF) $(TT)
118119

Module.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ list<Module::named_expr_t> Module::user_defparms;
2828

2929
/* n is a permallocated string. */
3030
Module::Module(perm_string n)
31-
: PScope(n)
31+
: PScopeExtra(n)
3232
{
3333
library_flag = false;
3434
is_cell = false;

Module.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class NetScope;
4949
* therefore the handle for grasping the described circuit.
5050
*/
5151

52-
class Module : public PScope, public LineInfo {
52+
class Module : public PScopeExtra, public LineInfo {
5353

5454
/* The module ports are in general a vector of port_t
5555
objects. Each port has a name and an ordered list of
@@ -112,10 +112,6 @@ class Module : public PScope, public LineInfo {
112112
bool time_from_timescale;
113113
bool timescale_warn_done;
114114

115-
/* Task definitions within this module */
116-
map<perm_string,PTask*> tasks;
117-
map<perm_string,PFunction*> funcs;
118-
119115
/* The module has a list of generate schemes that appear in
120116
the module definition. These are used at elaboration time. */
121117
list<PGenerate*> generate_schemes;

PClass.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2012 Stephen Williams ([email protected])
3+
*
4+
* This source code is free software; you can redistribute it
5+
* and/or modify it in source code form under the terms of the GNU
6+
* General Public License as published by the Free Software
7+
* Foundation; either version 2 of the License, or (at your option)
8+
* any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program; if not, write to the Free Software
17+
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18+
*/
19+
20+
# include "PClass.h"
21+
22+
PClass::PClass(perm_string name, LexicalScope*parent)
23+
: PScopeExtra(name, parent)
24+
{
25+
}
26+
27+
28+
PClass::~PClass()
29+
{
30+
}

PClass.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#ifndef __PClass_H
2+
#define __PClass_H
3+
/*
4+
* Copyright (c) 2012 Stephen Williams ([email protected])
5+
*
6+
* This source code is free software; you can redistribute it
7+
* and/or modify it in source code form under the terms of the GNU
8+
* General Public License as published by the Free Software
9+
* Foundation; either version 2 of the License, or (at your option)
10+
* any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20+
*/
21+
22+
# include "PScope.h"
23+
# include "LineInfo.h"
24+
# include "StringHeap.h"
25+
26+
/*
27+
* SystemVerilog supports class declarations with their own lexical
28+
* scope, etc. The parser arranges for these to be created and
29+
* collected.
30+
*/
31+
32+
class PClass : public PScopeExtra, public LineInfo {
33+
34+
public:
35+
explicit PClass (perm_string name, LexicalScope*parent);
36+
~PClass();
37+
38+
};
39+
40+
#endif

PScope.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,18 @@ PWire* LexicalScope::wires_find(perm_string name)
4141
else
4242
return (*cur).second;
4343
}
44+
45+
PScopeExtra::PScopeExtra(perm_string n, LexicalScope*parent)
46+
: PScope(n, parent)
47+
{
48+
}
49+
50+
PScopeExtra::PScopeExtra(perm_string n)
51+
: PScope(n)
52+
{
53+
}
54+
55+
PScopeExtra::~PScopeExtra()
56+
{
57+
}
58+

PScope.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727

2828
class PEvent;
2929
class PExpr;
30+
class PFunction;
3031
class AProcess;
3132
class PProcess;
33+
class PTask;
3234
class PWire;
3335

3436
class Design;
@@ -150,4 +152,21 @@ class PScope : public LexicalScope {
150152
perm_string name_;
151153
};
152154

155+
/*
156+
* Some scopes can carry definitions. These include Modules and PClass
157+
* scopes. These derive from PScopeExtra so that they hold the maps of
158+
* extra definitions.
159+
*/
160+
class PScopeExtra : public PScope {
161+
162+
public:
163+
PScopeExtra(perm_string, LexicalScope*parent);
164+
PScopeExtra(perm_string);
165+
~PScopeExtra();
166+
167+
/* Task definitions within this module */
168+
map<perm_string,PTask*> tasks;
169+
map<perm_string,PFunction*> funcs;
170+
};
171+
153172
#endif

parse.y

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -628,18 +628,21 @@ assignment_pattern /* IEEE1800-2005: A.6.7.1 */
628628

629629
class_declaration /* IEEE1800-2005: A.1.2 */
630630
: K_virtual_opt K_class class_identifier class_declaration_extends_opt ';'
631-
class_items_opt K_endclass
632-
{ // Process a class.
631+
{ pform_start_class_declaration(@2, $3);
633632
if ($4) {
634633
yyerror(@4, "sorry: Class extends not supported yet.");
635634
}
635+
}
636+
class_items_opt K_endclass
637+
{ // Process a class.
638+
pform_end_class_declaration();
636639
yyerror(@2, "sorry: Class declarations not supported yet.");
637640
}
638641
class_declaration_endname_opt
639642
{ // Wrap up the class.
640-
if ($9 && $3 && $3->name != $9) {
641-
yyerror(@9, "error: Class end name doesn't match class name.");
642-
delete[]$9;
643+
if ($10 && $3 && $3->name != $10) {
644+
yyerror(@10, "error: Class end name doesn't match class name.");
645+
delete[]$10;
643646
}
644647
}
645648
;
@@ -1348,7 +1351,7 @@ task_declaration /* IEEE1800-2005: A.2.7 */
13481351
current_task_set_statement(@3, $7);
13491352
pform_pop_scope();
13501353
current_task = 0;
1351-
if ($7->size() > 1 && !gn_system_verilog()) {
1354+
if ($7 && $7->size() > 1 && !gn_system_verilog()) {
13521355
yyerror(@7, "error: Task body with multiple statements requres SystemVerilog.");
13531356
}
13541357
delete $7;

pform.cc

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
# include "pform.h"
2424
# include "parse_misc.h"
2525
# include "parse_api.h"
26+
# include "PClass.h"
2627
# include "PEvent.h"
2728
# include "PUdp.h"
2829
# include "PGenerate.h"
@@ -267,12 +268,30 @@ void pform_pop_scope()
267268
lexical_scope = lexical_scope->parent_scope();
268269
}
269270

271+
PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name)
272+
{
273+
PClass*class_scope = new PClass(name, lexical_scope);
274+
FILE_NAME(class_scope, loc);
275+
276+
lexical_scope = class_scope;
277+
return class_scope;
278+
}
279+
270280
PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto)
271281
{
272282
perm_string task_name = lex_strings.make(name);
273283

274284
PTask*task = new PTask(task_name, lexical_scope, is_auto);
275285
FILE_NAME(task, loc);
286+
287+
LexicalScope*scope = lexical_scope;
288+
PScopeExtra*scopex = dynamic_cast<PScopeExtra*> (scope);
289+
while (scope && !scopex) {
290+
scope = scope->parent_scope();
291+
scopex = dynamic_cast<PScopeExtra*> (scope);
292+
}
293+
assert(scopex);
294+
276295
if (pform_cur_generate) {
277296
// Check if the task is already in the dictionary.
278297
if (pform_cur_generate->tasks.find(task->pscope_name()) !=
@@ -286,15 +305,15 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto)
286305
pform_cur_generate->tasks[task->pscope_name()] = task;
287306
} else {
288307
// Check if the task is already in the dictionary.
289-
if (pform_cur_module->tasks.find(task->pscope_name()) !=
290-
pform_cur_module->tasks.end()) {
308+
if (scopex->tasks.find(task->pscope_name()) != scopex->tasks.end()) {
291309
cerr << task->get_fileline() << ": error: duplicate "
292310
"definition for task '" << name << "' in '"
293-
<< pform_cur_module->mod_name() << "'." << endl;
311+
<< scopex->pscope_name() << "'." << endl;
294312
error_count += 1;
295313
}
296-
pform_cur_module->tasks[task->pscope_name()] = task;
314+
scopex->tasks[task->pscope_name()] = task;
297315
}
316+
298317
lexical_scope = task;
299318

300319
return task;
@@ -307,6 +326,15 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, char*name,
307326

308327
PFunction*func = new PFunction(func_name, lexical_scope, is_auto);
309328
FILE_NAME(func, loc);
329+
330+
LexicalScope*scope = lexical_scope;
331+
PScopeExtra*scopex = dynamic_cast<PScopeExtra*> (scope);
332+
while (scope && !scopex) {
333+
scope = scope->parent_scope();
334+
scopex = dynamic_cast<PScopeExtra*> (scope);
335+
}
336+
assert(scopex);
337+
310338
if (pform_cur_generate) {
311339
// Check if the function is already in the dictionary.
312340
if (pform_cur_generate->funcs.find(func->pscope_name()) !=
@@ -320,14 +348,13 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, char*name,
320348
pform_cur_generate->funcs[func->pscope_name()] = func;
321349
} else {
322350
// Check if the function is already in the dictionary.
323-
if (pform_cur_module->funcs.find(func->pscope_name()) !=
324-
pform_cur_module->funcs.end()) {
351+
if (scopex->funcs.find(func->pscope_name()) != scopex->funcs.end()) {
325352
cerr << func->get_fileline() << ": error: duplicate "
326353
"definition for function '" << name << "' in '"
327-
<< pform_cur_module->mod_name() << "'." << endl;
354+
<< scopex->pscope_name() << "'." << endl;
328355
error_count += 1;
329356
}
330-
pform_cur_module->funcs[func->pscope_name()] = func;
357+
scopex->funcs[func->pscope_name()] = func;
331358
}
332359
lexical_scope = func;
333360

@@ -2640,7 +2667,7 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list<pe
26402667
return;
26412668
}
26422669

2643-
if (class_type_t*class_type = dynamic_cast<class_type_t*> (data_type)) {
2670+
if (/*class_type_t*class_type =*/ dynamic_cast<class_type_t*> (data_type)) {
26442671
VLerror(li, "sorry: Class types not supported.");
26452672
return;
26462673
}

pform.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
class PGate;
5959
class PExpr;
6060
class PSpecPath;
61+
class PClass;
6162
struct vlltype;
6263

6364
/*
@@ -168,6 +169,10 @@ extern Module::port_t* pform_module_port_reference(perm_string name,
168169
extern void pform_endmodule(const char*, bool inside_celldefine,
169170
Module::UCDriveType uc_drive_def);
170171

172+
extern void pform_start_class_declaration(const struct vlltype&loc,
173+
class_type_t*type);
174+
extern void pform_end_class_declaration(void);
175+
171176
extern void pform_make_udp(perm_string name, list<perm_string>*parms,
172177
svector<PWire*>*decl, list<string>*table,
173178
Statement*init,
@@ -187,6 +192,7 @@ extern void pform_make_udp(perm_string name,
187192
*/
188193
extern void pform_pop_scope();
189194

195+
extern PClass* pform_push_class_scope(const struct vlltype&loc, perm_string name);
190196
extern PTask*pform_push_task_scope(const struct vlltype&loc, char*name,
191197
bool is_auto);
192198
extern PFunction*pform_push_function_scope(const struct vlltype&loc, char*name,

0 commit comments

Comments
 (0)