vhdlpp: Fixes for subtypes handling.

This commit is contained in:
Maciej Suminski 2016-01-08 14:30:58 +01:00
parent 79f38b8c56
commit b6f1cb221e
5 changed files with 62 additions and 41 deletions

View File

@ -23,6 +23,7 @@
# include "sequential.h"
# include "subprogram.h"
# include "vsignal.h"
# include "std_types.h"
# include <iostream>
# include <typeinfo>
# include <ivl_assert.h>
@ -70,15 +71,16 @@ int Architecture::emit(ostream&out, Entity*entity)
// of the full definition.
typedef_context_t typedef_ctx;
//for (map<perm_string,const VType*>::iterator cur = use_types_.begin()
//; cur != use_types_.end() ; ++cur) {
for (map<perm_string,const VType*>::iterator cur = use_types_.begin()
; cur != use_types_.end() ; ++cur) {
if(is_global_type(cur->first))
continue;
//if(const VTypeDef*def = dynamic_cast<const VTypeDef*>(cur->second))
//errors += def->emit_typedef(out, typedef_ctx);
//}
if(const VTypeDef*def = dynamic_cast<const VTypeDef*>(cur->second))
errors += def->emit_typedef(out, typedef_ctx);
}
for (map<perm_string,const VType*>::iterator cur = cur_types_.begin()
; cur != cur_types_.end() ; ++cur) {
if(const VTypeDef*def = dynamic_cast<const VTypeDef*>(cur->second))
errors += def->emit_typedef(out, typedef_ctx);
}

View File

@ -67,9 +67,6 @@ void Package::write_to_stream(ostream&fd) const
// and identifiers.
for (map<perm_string,const VType*>::const_iterator cur = use_types_.begin()
; cur != use_types_.end() ; ++cur) {
const VTypeDef*def = dynamic_cast<const VTypeDef*> (cur->second);
if (def == 0)
continue;
// Do not include global types in types dump
if (is_global_type(cur->first))
@ -79,9 +76,6 @@ void Package::write_to_stream(ostream&fd) const
}
for (map<perm_string,const VType*>::const_iterator cur = cur_types_.begin()
; cur != cur_types_.end() ; ++cur) {
const VTypeDef*def = dynamic_cast<const VTypeDef*> (cur->second);
if (def == 0)
continue;
// Do not include global types in types dump
if (is_global_type(cur->first))
@ -92,31 +86,11 @@ void Package::write_to_stream(ostream&fd) const
for (map<perm_string,const VType*>::const_iterator cur = use_types_.begin()
; cur != use_types_.end() ; ++cur) {
// Do not include global types in types dump
if (is_global_type(cur->first))
continue;
if(!dynamic_cast<const VTypeDef*>(cur->second))
fd << "sub";
fd << "type " << cur->first << " is ";
cur->second->write_type_to_stream(fd);
fd << "; -- imported" << endl;
cur->second->write_typedef_to_stream(fd, cur->first);
}
for (map<perm_string,const VType*>::const_iterator cur = cur_types_.begin()
; cur != cur_types_.end() ; ++cur) {
// Do not include global types in types dump
if (is_global_type(cur->first))
continue;
if(!dynamic_cast<const VTypeDef*>(cur->second))
fd << "sub";
fd << "type " << cur->first << " is ";
cur->second->write_type_to_stream(fd);
fd << ";" << endl;
cur->second->write_typedef_to_stream(fd, cur->first);
}
for (map<perm_string,struct const_t*>::const_iterator cur = cur_constants_.begin()

View File

@ -547,6 +547,8 @@ block_declarative_item
| subprogram_body
| subtype_declaration
| type_declaration
| use_clause_lib
@ -2606,12 +2608,24 @@ subprogram_statement_part
subtype_declaration
: K_subtype IDENTIFIER K_is subtype_indication ';'
{ perm_string name = lex_strings.make($2);
delete[] $2;
if ($4 == 0) {
errormsg(@1, "Failed to declare type name %s.\n", name.str());
} else {
active_scope->bind_name(name, $4);
VTypeDef*tmp;
map<perm_string,VTypeDef*>::iterator cur = active_scope->incomplete_types.find(name);
if (cur == active_scope->incomplete_types.end()) {
tmp = new VSubTypeDef(name, $4);
active_scope->bind_name(name, tmp);
} else {
tmp = cur->second;
tmp->set_definition($4);
active_scope->incomplete_types.erase(cur);
}
if(const VTypeEnum*enum_type = dynamic_cast<const VTypeEnum*>($4)) {
active_scope->use_enum(enum_type);
}
}
delete[]$2;
}
;

View File

@ -72,6 +72,10 @@ class VType {
// definitions. Most types accept the default definition of this.
virtual void write_type_to_stream(std::ostream&fd) const;
// Emits a type definition. This is used to distinguish types and
// subtypes.
virtual void write_typedef_to_stream(std::ostream&fd, perm_string name) const;
// This virtual method writes a human-readable version of the
// type to a given file for debug purposes. (Question: is this
// really necessary given the write_to_stream method?)
@ -383,7 +387,7 @@ class VTypeDef : public VType {
public:
explicit VTypeDef(perm_string name);
explicit VTypeDef(perm_string name, const VType*is);
~VTypeDef();
virtual ~VTypeDef();
VType*clone() const { return new VTypeDef(*this); }
@ -399,7 +403,7 @@ class VTypeDef : public VType {
// type, and this method gets it for us.
inline const VType* peek_definition(void) const { return type_; }
void write_to_stream(std::ostream&fd) const;
virtual void write_to_stream(std::ostream&fd) const;
void write_type_to_stream(std::ostream&fd) const;
int get_width(ScopeBase*scope) const { return type_->get_width(scope); }
int emit_typedef(std::ostream&out, typedef_context_t&ctx) const;
@ -409,12 +413,20 @@ class VTypeDef : public VType {
bool can_be_packed() const { return type_->can_be_packed(); }
bool is_unbounded() const { return type_->is_unbounded(); }
private:
int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const;
private:
protected:
perm_string name_;
const VType*type_;
private:
int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const;
};
class VSubTypeDef : public VTypeDef {
public:
explicit VSubTypeDef(perm_string name) : VTypeDef(name) {}
explicit VSubTypeDef(perm_string name, const VType*is) : VTypeDef(name, is) {}
void write_typedef_to_stream(std::ostream&fd, perm_string name) const;
};
#endif /* IVL_vtype_H */

View File

@ -36,6 +36,16 @@ void VType::write_type_to_stream(ostream&fd) const
write_to_stream(fd);
}
void VType::write_typedef_to_stream(ostream&fd, perm_string name) const
{
if(is_global_type(name))
return;
fd << "type " << name << " is ";
write_type_to_stream(fd);
fd << ";" << endl;
}
void VTypeArray::write_to_stream(ostream&fd) const
{
if(write_special_case(fd))
@ -238,3 +248,12 @@ void VTypeEnum::write_to_stream(std::ostream&fd) const
fd << ")";
}
void VSubTypeDef::write_typedef_to_stream(ostream&fd, perm_string name) const
{
if(is_global_type(name))
return;
fd << "subtype " << name << " is ";
write_type_to_stream(fd);
fd << ";" << endl;
}