diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 800c0bbd3..3b9356e60 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -168,6 +168,7 @@ class VTypePrimitive : public VType { VType*clone() const { return new VTypePrimitive(*this); } + bool type_match(const VType*that) const; void write_to_stream(std::ostream&fd) const; void show(std::ostream&) const; int get_width(ScopeBase*scope) const; @@ -221,6 +222,7 @@ class VTypeArray : public VType { VType*clone() const; int elaborate(Entity*ent, ScopeBase*scope) const; + bool type_match(const VType*that) const; void write_to_stream(std::ostream&fd) const; void write_type_to_stream(std::ostream&fd) const; void show(std::ostream&) const; diff --git a/vhdlpp/vtype_match.cc b/vhdlpp/vtype_match.cc index 86c8f90ff..459217879 100644 --- a/vhdlpp/vtype_match.cc +++ b/vhdlpp/vtype_match.cc @@ -38,5 +38,43 @@ bool VTypeDef::type_match(const VType*that) const if(VType::type_match(that)) return true; - return VType::type_match(type_); + return type_->type_match(that); +} + +bool VTypePrimitive::type_match(const VType*that) const +{ + if(VType::type_match(that)) + return true; + + if(const VTypePrimitive*prim = dynamic_cast(that)) { + // TODO it is not always true, but works for many cases + type_t that_type = prim->type(); + return ((type_ == NATURAL || type_ == INTEGER) && + (that_type == NATURAL || that_type == INTEGER)); + } + + return false; +} + +bool VTypeArray::type_match(const VType*that) const +{ + if(VType::type_match(that)) + return true; + + // Check if both arrays are of the same size + if(const VTypeArray*arr = dynamic_cast(that)) { + if(!element_type()->type_match(arr->element_type())) + return false; + + int this_width = get_width(NULL); + int that_width = arr->get_width(NULL); + + // Either one of the sizes is undefined, or both are the same size + if(this_width > 0 && that_width > 0 && this_width != that_width) + return false; + + return true; + } + + return false; }