diff --git a/vhdlpp/architec_emit.cc b/vhdlpp/architec_emit.cc index ce60631af..1305426ab 100644 --- a/vhdlpp/architec_emit.cc +++ b/vhdlpp/architec_emit.cc @@ -30,12 +30,16 @@ int Scope::emit_signals(ostream&out, Entity*entity, Architecture*arc) { int errors = 0; - for (map::iterator cur = signals_.begin() - ; cur != signals_.end() ; ++cur) { + for (map::iterator cur = old_signals_.begin() + ; cur != old_signals_.end() ; ++cur) { errors += cur->second->emit(out, entity, arc); } + for (map::iterator cur = new_signals_.begin() + ; cur != new_signals_.end() ; ++cur) { + errors += cur->second->emit(out, entity, arc); + } return errors; } @@ -43,12 +47,19 @@ int Architecture::emit(ostream&out, Entity*entity) { int errors = 0; - for (map::iterator cur = constants_.begin() - ; cur != constants_.end() ; ++cur) { + for (map::iterator cur = old_constants_.begin() + ; cur != old_constants_.end() ; ++cur) { - out << "localparam " << cur->first << " = "; - errors += cur->second.val->emit(out, entity, this); - out << ";" << endl; + out << "localparam " << cur->first << " = "; + errors += cur->second->val->emit(out, entity, this); + out << ";" << endl; + } + for (map::iterator cur = new_constants_.begin() + ; cur != new_constants_.end() ; ++cur) { + + out << "localparam " << cur->first << " = "; + errors += cur->second->val->emit(out, entity, this); + out << ";" << endl; } errors += emit_signals(out, entity, this); diff --git a/vhdlpp/debug.cc b/vhdlpp/debug.cc index 0847f11a3..54fac14d8 100644 --- a/vhdlpp/debug.cc +++ b/vhdlpp/debug.cc @@ -79,36 +79,58 @@ void ComponentBase::dump_ports(ostream&out, int indent) const void Scope::dump_scope(ostream&out) const { // Dump types - for (map::const_iterator cur = types_.begin() - ; cur != types_.end() ; ++cur) { + for (map::const_iterator cur = old_types_.begin() + ; cur != old_types_.end() ; ++cur) { out << " " << cur->first << ": "; cur->second->show(out); out << endl; } + for (map::const_iterator cur = new_types_.begin() + ; cur != new_types_.end() ; ++cur) { + out << " " << cur->first << ": "; + cur->second->show(out); + out << endl; + } // Dump constants - for (map::const_iterator cur = constants_.begin() - ; cur != constants_.end() ; ++cur) { + for (map::const_iterator cur = old_constants_.begin() + ; cur != old_constants_.end() ; ++cur) { out << " constant " << cur->first << " = "; out << endl; } - - // Dump signal declarations - for (map::const_iterator cur = signals_.begin() - ; cur != signals_.end() ; ++cur) { - if (cur->second) - cur->second->dump(out, 3); - else - out << " signal " << cur->first.str() << ": ???" << endl; + for (map::const_iterator cur = new_constants_.begin() + ; cur != new_constants_.end() ; ++cur) { + out << " constant " << cur->first << " = "; + out << endl; + } + // Dump signal declarations + for (map::const_iterator cur = old_signals_.begin() + ; cur != old_signals_.end() ; ++cur) { + if (cur->second) + cur->second->dump(out, 3); + else + out << " signal " << cur->first.str() << ": ???" << endl; + } + for (map::const_iterator cur = new_signals_.begin() + ; cur != new_signals_.end() ; ++cur) { + if (cur->second) + cur->second->dump(out, 3); + else + out << " signal " << cur->first.str() << ": ???" << endl; } - // Dump component declarations - for (map::const_iterator cur = components_.begin() - ; cur != components_.end() ; ++cur) { + for (map::const_iterator cur = old_components_.begin() + ; cur != old_components_.end() ; ++cur) { out << " component " << cur->first << " is" << endl; cur->second->dump_ports(out); out << " end component " << cur->first << endl; } + for (map::const_iterator cur = new_components_.begin() + ; cur != new_components_.end() ; ++cur) { + out << " component " << cur->first << " is" << endl; + cur->second->dump_ports(out); + out << " end component " << cur->first << endl; + } } void Entity::dump(ostream&out, int indent) const diff --git a/vhdlpp/scope.cc b/vhdlpp/scope.cc index 6f2da84b9..a715e86f4 100644 --- a/vhdlpp/scope.cc +++ b/vhdlpp/scope.cc @@ -18,61 +18,130 @@ */ # include "scope.h" +# include # include +# include using namespace std; ScopeBase::ScopeBase(const ScopeBase&ref) { - constants_ = ref.constants_; - signals_ = ref.signals_; - components_ = ref.components_; - types_ = ref.types_; + merge(ref.old_constants_.begin(), ref.old_constants_.end(), + ref.new_constants_.begin(), ref.new_constants_.end(), + insert_iterator >( + old_constants_, old_constants_.end()) + ); + merge(ref.old_signals_.begin(), ref.old_signals_.end(), + ref.new_signals_.begin(), ref.new_signals_.end(), + insert_iterator >( + old_signals_, old_signals_.end()) + ); + merge(ref.old_components_.begin(), ref.old_components_.end(), + ref.new_components_.begin(), ref.new_components_.end(), + insert_iterator >( + old_components_, old_components_.end()) + ); + merge(ref.old_types_.begin(), ref.old_types_.end(), + ref.new_types_.begin(), ref.new_types_.end(), + insert_iterator >( + old_types_, old_types_.end()) + ); } ScopeBase::~ScopeBase() { + //freeing of member objects is performed by child classes +} + +void ScopeBase::cleanup() +{ + /* + * A parent scope is destroyed only if all child scopes + * were previously destroyed. There for we can delete all + * objects that were defined in this scope, leaving + * objects from the other scopes untouched. + */ + for(map::iterator it = new_signals_.begin() + ; it != new_signals_.end(); ++it) + delete it->second; + for(map::iterator it = new_components_.begin() + ; it != new_components_.end(); ++it) + delete it->second; + for(map::iterator it = new_types_.begin() + ; it != new_types_.end(); ++it) + delete it->second; + for(map::iterator it = new_constants_.begin() + ; it != new_constants_.end(); ++it) + delete it->second; } const VType*ScopeBase::find_type(perm_string by_name) { - map::const_iterator cur = types_.find(by_name); - if (cur == types_.end()) - return 0; - else + map::const_iterator cur = new_types_.find(by_name); + if (cur == new_types_.end()) { + cur = old_types_.find(by_name); + if (cur == old_types_.end()) + return 0; + else + return cur->second; + } else return cur->second; } bool ScopeBase::find_constant(perm_string by_name, const VType*&typ, Expression*&exp) { - map::const_iterator cur = constants_.find(by_name); - if (cur == constants_.end()) - return false; - - typ = cur->second.typ; - exp = cur->second.val; - return true; + map::const_iterator cur = new_constants_.find(by_name); + if (cur == new_constants_.end()) { + cur = old_constants_.find(by_name); + if (cur == old_constants_.end()) + return false; + else { + typ = cur->second->typ; + exp = cur->second->val; + return true; + } + } else { + typ = cur->second->typ; + exp = cur->second->val; + return true; + } } void ScopeBase::do_use_from(const ScopeBase*that) { - for (map::const_iterator cur = that->components_.begin() - ; cur != that->components_.end() ; ++ cur) { + for (map::const_iterator cur = that->old_components_.begin() + ; cur != that->old_components_.end() ; ++ cur) { if (cur->second == 0) continue; - components_[cur->first] = cur->second; + old_components_[cur->first] = cur->second; + } + for (map::const_iterator cur = that->new_components_.begin() + ; cur != that->new_components_.end() ; ++ cur) { + if (cur->second == 0) + continue; + old_components_[cur->first] = cur->second; } - for (map::const_iterator cur = that->types_.begin() - ; cur != that->types_.end() ; ++ cur) { + for (map::const_iterator cur = that->old_types_.begin() + ; cur != that->old_types_.end() ; ++ cur) { if (cur->second == 0) continue; - types_[cur->first] = cur->second; + old_types_[cur->first] = cur->second; + } + for (map::const_iterator cur = that->new_types_.begin() + ; cur != that->new_types_.end() ; ++ cur) { + if (cur->second == 0) + continue; + old_types_[cur->first] = cur->second; } - for (map::const_iterator cur = that->constants_.begin() - ; cur != that->constants_.end() ; ++ cur) { - constants_[cur->first] = cur->second; + for (map::const_iterator cur = that->old_constants_.begin() + ; cur != that->old_constants_.end() ; ++ cur) { + old_constants_[cur->first] = cur->second; + } + for (map::const_iterator cur = that->new_constants_.begin() + ; cur != that->new_constants_.end() ; ++ cur) { + old_constants_[cur->first] = cur->second; } } @@ -87,18 +156,27 @@ Scope::~Scope() ComponentBase* Scope::find_component(perm_string by_name) { - map::const_iterator cur = components_.find(by_name); - if (cur == components_.end()) - return 0; - else + map::const_iterator cur = new_components_.find(by_name); + if (cur == new_components_.end()) { + cur = old_components_.find(by_name); + if (cur == old_components_.end()) + return 0; + else + return cur->second; + } else return cur->second; } Signal* Scope::find_signal(perm_string by_name) { - map::const_iterator cur = signals_.find(by_name); - if (cur == signals_.end()) - return 0; - else + map::const_iterator cur = new_signals_.find(by_name); + if (cur == new_signals_.end()) { + cur = old_signals_.find(by_name); + if (cur == old_signals_.end()) + return 0; + else + return cur->second; + } else { return cur->second; + } } diff --git a/vhdlpp/scope.h b/vhdlpp/scope.h index fd5e80272..c17f7932b 100644 --- a/vhdlpp/scope.h +++ b/vhdlpp/scope.h @@ -22,12 +22,12 @@ # include # include # include "StringHeap.h" +# include "entity.h" +# include "expression.h" +# include "vsignal.h" class Architecture; class ComponentBase; -class Entity; -class Expression; -class Signal; class VType; class ScopeBase { @@ -40,18 +40,27 @@ class ScopeBase { const VType* find_type(perm_string by_name); bool find_constant(perm_string by_name, const VType*&typ, Expression*&exp); protected: + void cleanup(); + // Signal declarations... - std::map signals_; + std::map old_signals_; //previous scopes + std::map new_signals_; //current scope // Component declarations... - std::map components_; + std::map old_components_; //previous scopes + std::map new_components_; //current scope // Type declarations... - std::map types_; + std::map old_types_; //previous scopes + std::map new_types_; //current scope // Constant declarations... struct const_t { + ~const_t() {delete typ; delete val;} + const_t(const VType*t, Expression* v) : typ(t), val(v) {}; + const VType*typ; Expression*val; }; - std::map constants_; + std::map old_constants_; //previous scopes + std::map new_constants_; //current scope void do_use_from(const ScopeBase*that); }; @@ -90,20 +99,44 @@ class ActiveScope : public ScopeBase { void use_from(const ScopeBase*that) { do_use_from(that); } + + /* All bind_name function check if the given name was present + * in previous scopes. If it is found, it is erased (but the pointer + * is not freed), in order to implement name shadowing. The pointer + * be freed only in the scope where the object was defined. This is + * done in ScopeBase::cleanup() function .*/ + void bind_name(perm_string name, Signal*obj) - { signals_[name] = obj; } + { map::iterator it; + if((it = old_signals_.find(name)) != old_signals_.end() ) + old_signals_.erase(it); + new_signals_[name] = obj; + } void bind_name(perm_string name, ComponentBase*obj) - { components_[name] = obj; } + { map::iterator it; + if((it = old_components_.find(name)) != old_components_.end() ) + old_components_.erase(it); + new_components_[name] = obj; + } - void bind_name(perm_string name, const VType*obj) - { types_[name] = obj; } + void bind_name(perm_string name, const VType* t) + { map::iterator it; + if((it = old_types_.find(name)) != old_types_.end() ) + old_types_.erase(it); + new_types_[name] = t; + } void bind_name(perm_string name, const VType*obj, Expression*val) + { map::iterator it; + if((it = old_constants_.find(name)) != old_constants_.end() ) + old_constants_.erase(it); + new_constants_[name] = new const_t(obj, val); + } + + void destroy_global_scope() { - const_t&tmp = constants_[name]; - tmp.typ = obj; - tmp.val = val; + cleanup(); } };