Probe type of ExpName with a record prefix.

This commit is contained in:
Stephen Williams 2012-04-01 18:48:19 -07:00
parent 7eb89c5548
commit 021d944a30
4 changed files with 65 additions and 3 deletions

View File

@ -484,6 +484,10 @@ class ExpName : public Expression {
void dump(ostream&out, int indent = 0) const;
const char* name() const;
private:
const VType* probe_prefix_type_(Entity*ent, Architecture*arc) const;
const VType* probe_prefixed_type_(Entity*ent, Architecture*arc) const;
private:
std::auto_ptr<ExpName> prefix_;
perm_string name_;

View File

@ -409,14 +409,54 @@ int ExpLogical::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype)
return errors;
}
const VType* ExpName::probe_type(Entity*ent, Architecture*arc) const
const VType* ExpName::probe_prefix_type_(Entity*ent, Architecture*arc) const
{
if (prefix_.get()) {
cerr << get_fileline() << ": sorry: I don't know how to probe type "
<< "of " << name_ << " with prefix parts." << endl;
cerr << get_fileline() << ": sorry: I do not know how to support nested prefix parts." << endl;
return 0;
}
const VType*type = probe_type(ent, arc);
return type;
}
/*
* This method is the probe_type() imlementation for ExpName objects
* that have prefix parts. In this case we try to get the type of the
* prefix and interpret the name in that context.
*/
const VType* ExpName::probe_prefixed_type_(Entity*ent, Architecture*arc) const
{
// First, get the type of the prefix.
const VType*prefix_type = prefix_->probe_prefix_type_(ent, arc);
if (prefix_type == 0) {
return 0;
}
// If the prefix type is a record, then the current name is
// the name of a member.
if (const VTypeRecord*pref_record = dynamic_cast<const VTypeRecord*> (prefix_type)) {
const VTypeRecord::element_t*element = pref_record->element_by_name(name_);
ivl_assert(*this, element);
const VType*element_type = element->peek_type();
ivl_assert(*this, element_type);
return element_type;
}
cerr << get_fileline() << ": sorry: I don't know how to probe "
<< "prefix type " << typeid(*prefix_type).name()
<< " of " << name_ << "." << endl;
return 0;
}
const VType* ExpName::probe_type(Entity*ent, Architecture*arc) const
{
if (prefix_.get())
return probe_prefixed_type_(ent, arc);
if (const InterfacePort*cur = ent->find_port(name_)) {
ivl_assert(*this, cur->type);
return cur->type;

View File

@ -183,6 +183,18 @@ void VTypeRecord::show(ostream&out) const
write_to_stream(out);
}
const VTypeRecord::element_t* VTypeRecord::element_by_name(perm_string name) const
{
for (vector<element_t*>::const_iterator cur = elements_.begin()
; cur != elements_.end() ; ++cur) {
element_t*curp = *cur;
if (curp->peek_name() == name)
return curp;
}
return 0;
}
VTypeRecord::element_t::element_t(perm_string name, const VType*typ)
: name_(name), type_(typ)
{

View File

@ -209,6 +209,9 @@ class VTypeRecord : public VType {
void write_to_stream(std::ostream&) const;
inline perm_string peek_name() const { return name_; }
inline const VType* peek_type() const { return type_; }
private:
perm_string name_;
const VType*type_;
@ -226,6 +229,9 @@ class VTypeRecord : public VType {
void show(std::ostream&) const;
int emit_def(std::ostream&out, perm_string name) const;
const element_t* element_by_name(perm_string name) const;
private:
int emit_decl(std::ostream&out, perm_string name, bool reg_flag) const;