diff --git a/vhdlpp/expression_elaborate.cc b/vhdlpp/expression_elaborate.cc index d16f63db4..8471407e7 100644 --- a/vhdlpp/expression_elaborate.cc +++ b/vhdlpp/expression_elaborate.cc @@ -906,6 +906,10 @@ const VType* ExpName::probe_type(Entity*ent, ScopeBase*scope) const if (arc && (gtype = arc->probe_genvar_type(name_))) { return gtype; } + + if (scope->is_enum_name(name_)) { + return &primitive_INTEGER; + } } cerr << get_fileline() << ": error: Signal/variable " << name_ diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index a509d8fa6..464624a44 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -2393,6 +2393,9 @@ type_declaration tmp->set_definition($4); active_scope->incomplete_types.erase(cur); } + if(const VTypeEnum*enum_type = dynamic_cast($4)) { + active_scope->use_enum(enum_type); + } } delete[]$2; } diff --git a/vhdlpp/scope.cc b/vhdlpp/scope.cc index eac3ece1e..2ce681697 100644 --- a/vhdlpp/scope.cc +++ b/vhdlpp/scope.cc @@ -59,6 +59,8 @@ ScopeBase::ScopeBase(const ActiveScope&ref) use_subprograms_ = ref.use_subprograms_; cur_subprograms_ = ref.cur_subprograms_; + use_enums_ = ref.use_enums_; + // This constructor is invoked when the parser is finished with // an active scope and is making the actual scope. At this point // we know that "this" is the parent scope for the subprograms, @@ -181,6 +183,17 @@ Subprogram* ScopeBase::find_subprogram(perm_string name) const return 0; } +bool ScopeBase::is_enum_name(perm_string name) const +{ + for(list::const_iterator it = use_enums_.begin(); + it != use_enums_.end(); ++it) { + if((*it)->has_name(name)) + return true; + } + + return false; +} + /* * This method is only used by the ActiveScope derived class to import * definition from another scope. @@ -219,6 +232,8 @@ void ScopeBase::do_use_from(const ScopeBase*that) ; cur != that->cur_constants_.end() ; ++ cur) { use_constants_[cur->first] = cur->second; } + + use_enums_ = that->use_enums_; } void ScopeBase::transfer_from(ScopeBase&ref) diff --git a/vhdlpp/scope.h b/vhdlpp/scope.h index 6bb7ed4e5..ea4c55d64 100644 --- a/vhdlpp/scope.h +++ b/vhdlpp/scope.h @@ -58,6 +58,7 @@ class ScopeBase { Variable* find_variable(perm_string by_name) const; virtual const InterfacePort* find_param(perm_string by_name) const; Subprogram* find_subprogram(perm_string by_name) const; + bool is_enum_name(perm_string name) const; // Moves all signals, variables and components from another scope to // this one. After the transfer new_* maps are emptied in the another scope. void transfer_from(ScopeBase&ref); @@ -114,6 +115,8 @@ class ScopeBase { std::map use_subprograms_; //imported std::map cur_subprograms_; //current + std::list use_enums_; + void do_use_from(const ScopeBase*that); }; @@ -199,6 +202,9 @@ class ActiveScope : public ScopeBase { cur_types_[name] = t; } + inline void use_enum(const VTypeEnum* t) + { use_enums_.push_back(t); } + inline void use_name(perm_string name, const VType* t) { use_types_[name] = t; } diff --git a/vhdlpp/vtype.cc b/vhdlpp/vtype.cc index 4a05d82aa..efda4d1a1 100644 --- a/vhdlpp/vtype.cc +++ b/vhdlpp/vtype.cc @@ -23,6 +23,7 @@ # include # include # include +# include using namespace std; @@ -251,6 +252,11 @@ void VTypeEnum::show(ostream&out) const out << ")"; } +bool VTypeEnum::has_name(perm_string name) const +{ + return std::find(names_.begin(), names_.end(), name) != names_.end(); +} + VTypeRecord::VTypeRecord(std::list*elements) : elements_(elements->size()) { diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 595ca381c..562ebb155 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -295,6 +295,9 @@ class VTypeEnum : public VType { void show(std::ostream&) const; int emit_def(std::ostream&out, perm_string name) const; + // Checks if the name is stored in the enum. + bool has_name(perm_string name) const; + private: std::vectornames_; };