diff --git a/PFunction.cc b/PFunction.cc index 9d18a3baf..42adc7189 100644 --- a/PFunction.cc +++ b/PFunction.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2008,2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -21,7 +21,7 @@ #include "PTask.h" -PFunction::PFunction(perm_string name, PScope*parent, bool is_auto__) +PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__) : PScope(name, parent), ports_(0), statement_(0) { is_auto_ = is_auto__; diff --git a/PGenerate.cc b/PGenerate.cc index 3deebe6a2..ba6bc49b9 100644 --- a/PGenerate.cc +++ b/PGenerate.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006,2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 2006,2009,2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -21,12 +21,10 @@ # include "PWire.h" # include "ivl_assert.h" -PGenerate::PGenerate(unsigned id) -: id_number(id) +PGenerate::PGenerate(LexicalScope*parent, unsigned id) +: LexicalScope(parent), id_number(id) { direct_nested_ = false; - parent = 0; - lexical_scope = 0; } PGenerate::~PGenerate() diff --git a/PGenerate.h b/PGenerate.h index 8a8dce377..29de61ea3 100644 --- a/PGenerate.h +++ b/PGenerate.h @@ -1,7 +1,7 @@ #ifndef __PGenerate_H #define __PGenerate_H /* - * Copyright (c) 2006-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 2006-2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -53,7 +53,7 @@ class PWire; class PGenerate : public LineInfo, public LexicalScope { public: - explicit PGenerate(unsigned id_number); + explicit PGenerate(LexicalScope*parent, unsigned id_number); ~PGenerate(); // Generate schemes have an ID number, for when the scope is @@ -63,7 +63,7 @@ class PGenerate : public LineInfo, public LexicalScope { // This is used during parsing to stack lexical scopes within // this generate scheme. - PScope*lexical_scope; +// LexicalScope*lexical_scope; enum scheme_t {GS_NONE, GS_LOOP, GS_CONDIT, GS_ELSE, GS_CASE, GS_CASE_ITEM, GS_NBLOCK}; @@ -92,7 +92,7 @@ class PGenerate : public LineInfo, public LexicalScope { // Generate schemes can contain further generate schemes. list generate_schemes; - PGenerate*parent; +// PGenerate*parent; // This method is called by the elaboration of a module to // generate scopes. the container is the scope that is to diff --git a/PScope.cc b/PScope.cc index 92022fa26..f23a506ee 100644 --- a/PScope.cc +++ b/PScope.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Stephen Williams (steve@icarus.com) + * Copyright (c) 2008,2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -19,13 +19,13 @@ # include "PScope.h" -PScope::PScope(perm_string n, PScope*parent) -: name_(n), parent_(parent) +PScope::PScope(perm_string n, LexicalScope*parent) +: LexicalScope(parent), name_(n) { } PScope::PScope(perm_string n) -: name_(n), parent_(0) +: LexicalScope(0), name_(n) { } diff --git a/PScope.h b/PScope.h index c2749ac9f..b5f94e4ed 100644 --- a/PScope.h +++ b/PScope.h @@ -1,7 +1,7 @@ #ifndef __PScope_H #define __PScope_H /* - * Copyright (c) 2008 Stephen Williams (steve@icarus.com) + * Copyright (c) 2008,2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -46,7 +46,7 @@ class NetScope; class LexicalScope { public: - explicit LexicalScope() { } + explicit LexicalScope(LexicalScope*parent) : parent_(parent) { } // A virtual destructor is so that dynamic_cast can work. virtual ~LexicalScope() { } @@ -94,6 +94,8 @@ class LexicalScope { list behaviors; list analog_behaviors; + LexicalScope* parent_scope() const { return parent_; } + protected: void dump_parameters_(ostream&out, unsigned indent) const; @@ -104,6 +106,7 @@ class LexicalScope { void dump_wires_(ostream&out, unsigned indent) const; private: + LexicalScope*parent_; }; class PScope : public LexicalScope { @@ -117,12 +120,11 @@ class PScope : public LexicalScope { // modules do not nest in Verilog, the parent must be nil for // modules. Scopes for tasks and functions point to their // containing module. - PScope(perm_string name, PScope*parent); + PScope(perm_string name, LexicalScope*parent); PScope(perm_string name); virtual ~PScope(); perm_string pscope_name() const { return name_; } - PScope* pscope_parent() { return parent_; } protected: bool elaborate_sig_wires_(Design*des, NetScope*scope) const; @@ -131,7 +133,6 @@ class PScope : public LexicalScope { private: perm_string name_; - PScope*parent_; }; #endif diff --git a/PTask.cc b/PTask.cc index 8e19e334e..14e88dee6 100644 --- a/PTask.cc +++ b/PTask.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2008,2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -21,7 +21,7 @@ # include "PTask.h" -PTask::PTask(perm_string name, PScope*parent, bool is_auto__) +PTask::PTask(perm_string name, LexicalScope*parent, bool is_auto__) : PScope(name, parent), ports_(0), statement_(0) { is_auto_ = is_auto__; diff --git a/PTask.h b/PTask.h index de05ac053..a7fe3f7b5 100644 --- a/PTask.h +++ b/PTask.h @@ -1,7 +1,7 @@ #ifndef __PTask_H #define __PTask_H /* - * Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2008,2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -51,7 +51,7 @@ struct PTaskFuncArg { class PTask : public PScope, public LineInfo { public: - explicit PTask(perm_string name, PScope*parent, bool is_auto); + explicit PTask(perm_string name, LexicalScope*parent, bool is_auto); ~PTask(); void set_ports(svector*p); @@ -93,7 +93,7 @@ class PTask : public PScope, public LineInfo { class PFunction : public PScope, public LineInfo { public: - explicit PFunction(perm_string name, PScope*parent, bool is_auto); + explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto); ~PFunction(); void set_ports(svector*p); diff --git a/Statement.cc b/Statement.cc index 517656a83..fc6670e38 100644 --- a/Statement.cc +++ b/Statement.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2008,2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -93,7 +93,7 @@ PAssignNB::~PAssignNB() { } -PBlock::PBlock(perm_string n, PScope*parent, BL_TYPE t) +PBlock::PBlock(perm_string n, LexicalScope*parent, BL_TYPE t) : PScope(n, parent), bl_type_(t) { } diff --git a/Statement.h b/Statement.h index 30d8a60b4..f358ae7e0 100644 --- a/Statement.h +++ b/Statement.h @@ -159,7 +159,7 @@ class PBlock : public PScope, public Statement { enum BL_TYPE { BL_SEQ, BL_PAR }; // If the block has a name, it is a scope and also has a parent. - explicit PBlock(perm_string n, PScope*parent, BL_TYPE t); + explicit PBlock(perm_string n, LexicalScope*parent, BL_TYPE t); // If it doesn't have a name, it's not a scope explicit PBlock(BL_TYPE t); ~PBlock(); diff --git a/pform.cc b/pform.cc index 08701a9b7..7320e78f3 100644 --- a/pform.cc +++ b/pform.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -258,29 +258,20 @@ static inline void FILE_NAME(LineInfo*obj, const char*file, unsigned lineno) * * Items that have scoped names are put in the lexical_scope object. */ -static PScope* lexical_scope = 0; +static LexicalScope* lexical_scope = 0; void pform_pop_scope() { - if (pform_cur_generate) { - assert(pform_cur_generate->lexical_scope); - PScope*cur = pform_cur_generate->lexical_scope; - pform_cur_generate->lexical_scope = cur->pscope_parent(); - } else { - assert(lexical_scope); - lexical_scope = lexical_scope->pscope_parent(); - } + lexical_scope = lexical_scope->parent_scope(); } PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto) { perm_string task_name = lex_strings.make(name); - PTask*task; + PTask*task = new PTask(task_name, lexical_scope, is_auto); + FILE_NAME(task, loc); if (pform_cur_generate) { - task = new PTask(task_name, pform_cur_generate->lexical_scope, - is_auto); - FILE_NAME(task, loc); // Check if the task is already in the dictionary. if (pform_cur_generate->tasks.find(task->pscope_name()) != pform_cur_generate->tasks.end()) { @@ -291,11 +282,7 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto) error_count += 1; } pform_cur_generate->tasks[task->pscope_name()] = task; - pform_cur_generate->lexical_scope = task; } else { - task = new PTask(task_name, lexical_scope, - is_auto); - FILE_NAME(task, loc); // Check if the task is already in the dictionary. if (pform_cur_module->tasks.find(task->pscope_name()) != pform_cur_module->tasks.end()) { @@ -305,8 +292,8 @@ PTask* pform_push_task_scope(const struct vlltype&loc, char*name, bool is_auto) error_count += 1; } pform_cur_module->tasks[task->pscope_name()] = task; - lexical_scope = task; } + lexical_scope = task; return task; } @@ -316,11 +303,9 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, char*name, { perm_string func_name = lex_strings.make(name); - PFunction*func; + PFunction*func = new PFunction(func_name, lexical_scope, is_auto); + FILE_NAME(func, loc); if (pform_cur_generate) { - func = new PFunction(func_name, pform_cur_generate->lexical_scope, - is_auto); - FILE_NAME(func, loc); // Check if the function is already in the dictionary. if (pform_cur_generate->funcs.find(func->pscope_name()) != pform_cur_generate->funcs.end()) { @@ -331,11 +316,7 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, char*name, error_count += 1; } pform_cur_generate->funcs[func->pscope_name()] = func; - pform_cur_generate->lexical_scope = func; } else { - func = new PFunction(func_name, lexical_scope, - is_auto); - FILE_NAME(func, loc); // Check if the function is already in the dictionary. if (pform_cur_module->funcs.find(func->pscope_name()) != pform_cur_module->funcs.end()) { @@ -345,8 +326,8 @@ PFunction* pform_push_function_scope(const struct vlltype&loc, char*name, error_count += 1; } pform_cur_module->funcs[func->pscope_name()] = func; - lexical_scope = func; } + lexical_scope = func; return func; } @@ -355,14 +336,8 @@ PBlock* pform_push_block_scope(char*name, PBlock::BL_TYPE bt) { perm_string block_name = lex_strings.make(name); - PBlock*block; - if (pform_cur_generate) { - block = new PBlock(block_name, pform_cur_generate->lexical_scope, bt); - pform_cur_generate->lexical_scope = block; - } else { - block = new PBlock(block_name, lexical_scope, bt); - lexical_scope = block; - } + PBlock*block = new PBlock(block_name, lexical_scope, bt); + lexical_scope = block; return block; } @@ -380,29 +355,10 @@ void pform_bind_attributes(map&attributes, delete attr; } -static LexicalScope*pform_get_cur_scope() -{ - if (pform_cur_generate) - if (pform_cur_generate->lexical_scope) - return pform_cur_generate->lexical_scope; - else - return pform_cur_generate; - else - return lexical_scope; -} - static bool pform_at_module_level() { - if (pform_cur_generate) - if (pform_cur_generate->lexical_scope) - return false; - else - return true; - else - if (lexical_scope->pscope_parent()) - return false; - else - return true; + return (lexical_scope == pform_cur_module) + || (lexical_scope == pform_cur_generate); } PWire*pform_get_wire_in_scope(perm_string name) @@ -411,22 +367,22 @@ PWire*pform_get_wire_in_scope(perm_string name) scope depth will be empty because generate schemes cannot be within sub-scopes. Only directly in modules. */ - return pform_get_cur_scope()->wires_find(name); + return lexical_scope->wires_find(name); } static void pform_put_wire_in_scope(perm_string name, PWire*net) { - pform_get_cur_scope()->wires[name] = net; + lexical_scope->wires[name] = net; } static void pform_put_behavior_in_scope(PProcess*pp) { - pform_get_cur_scope()->behaviors.push_back(pp); + lexical_scope->behaviors.push_back(pp); } void pform_put_behavior_in_scope(AProcess*pp) { - pform_get_cur_scope()->analog_behaviors.push_back(pp); + lexical_scope->analog_behaviors.push_back(pp); } void pform_set_default_nettype(NetNet::Type type, @@ -819,7 +775,7 @@ void pform_endmodule(const char*name, bool in_celldefine, // The current lexical scope should be this module by now, and // this module should not have a parent lexical scope. ivl_assert(*pform_cur_module, lexical_scope == pform_cur_module); - lexical_scope = pform_cur_module->pscope_parent(); + pform_pop_scope(); ivl_assert(*pform_cur_module, lexical_scope == 0); pform_cur_module = 0; @@ -864,11 +820,11 @@ void pform_start_generate_for(const struct vlltype&li, PExpr*test, char*ident2, PExpr*next) { - PGenerate*gen = new PGenerate(scope_generate_counter++); + PGenerate*gen = new PGenerate(lexical_scope, scope_generate_counter++); + lexical_scope = gen; FILE_NAME(gen, li); - gen->parent = pform_cur_generate; pform_cur_generate = gen; pform_cur_generate->scheme_type = PGenerate::GS_LOOP; @@ -884,11 +840,11 @@ void pform_start_generate_for(const struct vlltype&li, void pform_start_generate_if(const struct vlltype&li, PExpr*test) { - PGenerate*gen = new PGenerate(scope_generate_counter++); + PGenerate*gen = new PGenerate(lexical_scope, scope_generate_counter++); + lexical_scope = gen; FILE_NAME(gen, li); - gen->parent = pform_cur_generate; pform_cur_generate = gen; pform_cur_generate->scheme_type = PGenerate::GS_CONDIT; @@ -906,11 +862,11 @@ void pform_start_generate_else(const struct vlltype&li) PGenerate*cur = pform_cur_generate; pform_endgenerate(); - PGenerate*gen = new PGenerate(scope_generate_counter++); + PGenerate*gen = new PGenerate(lexical_scope, scope_generate_counter++); + lexical_scope = gen; FILE_NAME(gen, li); - gen->parent = pform_cur_generate; pform_cur_generate = gen; pform_cur_generate->scheme_type = PGenerate::GS_ELSE; @@ -926,11 +882,11 @@ void pform_start_generate_else(const struct vlltype&li) */ void pform_start_generate_case(const struct vlltype&li, PExpr*expr) { - PGenerate*gen = new PGenerate(scope_generate_counter++); + PGenerate*gen = new PGenerate(lexical_scope, scope_generate_counter++); + lexical_scope = gen; FILE_NAME(gen, li); - gen->parent = pform_cur_generate; pform_cur_generate = gen; pform_cur_generate->scheme_type = PGenerate::GS_CASE; @@ -945,11 +901,11 @@ void pform_start_generate_case(const struct vlltype&li, PExpr*expr) */ void pform_start_generate_nblock(const struct vlltype&li, char*name) { - PGenerate*gen = new PGenerate(scope_generate_counter++); + PGenerate*gen = new PGenerate(lexical_scope, scope_generate_counter++); + lexical_scope = gen; FILE_NAME(gen, li); - gen->parent = pform_cur_generate; pform_cur_generate = gen; pform_cur_generate->scheme_type = PGenerate::GS_NBLOCK; @@ -973,11 +929,11 @@ void pform_generate_case_item(const struct vlltype&li, svector*expr_list assert(pform_cur_generate); assert(pform_cur_generate->scheme_type == PGenerate::GS_CASE); - PGenerate*gen = new PGenerate(pform_cur_generate->id_number); + PGenerate*gen = new PGenerate(lexical_scope, pform_cur_generate->id_number); + lexical_scope = gen; FILE_NAME(gen, li); - gen->parent = pform_cur_generate; pform_cur_generate = gen; pform_cur_generate->scheme_type = PGenerate::GS_CASE_ITEM; @@ -1017,17 +973,20 @@ void pform_endgenerate() pform_cur_generate->scope_name = lex_strings.make(tmp); } - PGenerate*cur = pform_cur_generate; - pform_cur_generate = cur->parent; + // The current lexical scope should be this generate construct by now + ivl_assert(*pform_cur_generate, lexical_scope == pform_cur_generate); + pform_pop_scope(); - if (pform_cur_generate != 0) { - assert(cur->scheme_type == PGenerate::GS_CASE_ITEM - || pform_cur_generate->scheme_type != PGenerate::GS_CASE); - pform_cur_generate->generate_schemes.push_back(cur); + PGenerate*parent_generate = dynamic_cast(lexical_scope); + if (parent_generate) { + assert(pform_cur_generate->scheme_type == PGenerate::GS_CASE_ITEM + || parent_generate->scheme_type != PGenerate::GS_CASE); + parent_generate->generate_schemes.push_back(pform_cur_generate); } else { - assert(cur->scheme_type != PGenerate::GS_CASE_ITEM); - pform_cur_module->generate_schemes.push_back(cur); + assert(pform_cur_generate->scheme_type != PGenerate::GS_CASE_ITEM); + pform_cur_module->generate_schemes.push_back(pform_cur_generate); } + pform_cur_generate = parent_generate; } MIN_TYP_MAX min_typ_max_flag = TYP; @@ -1478,10 +1437,8 @@ void pform_set_net_range(list*names, */ static void pform_make_event(perm_string name, const char*fn, unsigned ln) { - LexicalScope*scope = pform_get_cur_scope(); - // Check if the named event is already in the dictionary. - if (scope->events.find(name) != scope->events.end()) { + if (lexical_scope->events.find(name) != lexical_scope->events.end()) { LineInfo tloc; FILE_NAME(&tloc, fn, ln); cerr << tloc.get_fileline() << ": error: duplicate definition " @@ -1492,7 +1449,7 @@ static void pform_make_event(perm_string name, const char*fn, unsigned ln) PEvent*event = new PEvent(name); FILE_NAME(event, fn, ln); - scope->events[name] = event; + lexical_scope->events[name] = event; } void pform_make_events(list*names, const char*fn, unsigned ln) @@ -2149,12 +2106,7 @@ void pform_set_type_attrib(perm_string name, const string&key, */ void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r) { - PWire*cur = 0; - if (pform_cur_generate) { - cur = pform_cur_generate->wires_find(name); - } else { - cur = lexical_scope->wires_find(name); - } + PWire*cur = lexical_scope->wires_find(name); if (cur == 0) { VLerror("internal error: name is not a valid memory for index."); return; @@ -2187,7 +2139,7 @@ void pform_set_parameter(const struct vlltype&loc, bool signed_flag, svector*range, PExpr*expr, LexicalScope::range_t*value_range) { - LexicalScope*scope = pform_get_cur_scope(); + LexicalScope*scope = lexical_scope; if (scope == pform_cur_generate) { VLerror("parameter declarations are not permitted in generate blocks"); return; @@ -2239,7 +2191,7 @@ void pform_set_localparam(const struct vlltype&loc, perm_string name, ivl_variable_type_t type, bool signed_flag, svector*range, PExpr*expr) { - LexicalScope*scope = pform_get_cur_scope(); + LexicalScope*scope = lexical_scope; // Check if the localparam name is already in the dictionary. if (scope->localparams.find(name) != scope->localparams.end()) { @@ -2260,7 +2212,7 @@ void pform_set_localparam(const struct vlltype&loc, } assert(expr); - Module::param_expr_t&parm = pform_get_cur_scope()->localparams[name]; + Module::param_expr_t&parm = scope->localparams[name]; FILE_NAME(&parm, loc); parm.expr = expr; diff --git a/pform_dump.cc b/pform_dump.cc index 06a827be5..1b1b122cb 100644 --- a/pform_dump.cc +++ b/pform_dump.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2009 Stephen Williams (steve@icarus.com) + * Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -978,6 +978,7 @@ void PGenerate::dump(ostream&out, unsigned indent) const { out << setw(indent) << "" << "generate(" << id_number << ")"; + PGenerate*parent = dynamic_cast(parent_scope()); switch (scheme_type) { case GS_NONE: break; @@ -999,6 +1000,7 @@ void PGenerate::dump(ostream&out, unsigned indent) const out << " case (" << *loop_test << ")"; break; case GS_CASE_ITEM: + assert(parent); if (loop_test) out << " (" << *loop_test << ") == (" << *parent->loop_test << ")"; else