Add find_vars method to VHDL syntax objects

Finds set of read and written variables. For use in
post-processing the syntax tree for cleanup.
This commit is contained in:
Nick Gasson 2010-08-15 21:52:58 +01:00 committed by Stephen Williams
parent d1314d53bd
commit 72f1e5a692
2 changed files with 140 additions and 1 deletions

View File

@ -255,6 +255,17 @@ void stmt_container::move_stmts_from(stmt_container *other)
other->stmts_.clear();
}
void stmt_container::find_vars(vhdl_var_set_t& read,
vhdl_var_set_t& write)
{
// Iterate over each sub-statement and find all its
// read/written variables
for (stmt_list_t::const_iterator it = stmts_.begin();
it != stmts_.end(); ++it)
(*it)->find_vars(read, write);
}
void stmt_container::emit(std::ostream &of, int level, bool newline) const
{
emit_children<vhdl_seq_stmt>(of, stmts_, level, "", newline);
@ -347,6 +358,13 @@ vhdl_wait_stmt::~vhdl_wait_stmt()
}
void vhdl_wait_stmt::find_vars(vhdl_var_set_t& read,
vhdl_var_set_t& write)
{
if (expr_)
expr_->find_vars(read);
}
void vhdl_wait_stmt::emit(std::ostream &of, int level) const
{
of << "wait";
@ -497,6 +515,13 @@ vhdl_expr_list::~vhdl_expr_list()
}
void vhdl_expr_list::find_vars(vhdl_var_set_t& read)
{
for (list<vhdl_expr*>::const_iterator it = exprs_.begin();
it != exprs_.end(); ++it)
(*it)->find_vars(read);
}
void vhdl_expr_list::emit(std::ostream &of, int level) const
{
of << "(";
@ -520,6 +545,12 @@ void vhdl_pcall_stmt::emit(std::ostream &of, int level) const
of << ";";
}
void vhdl_pcall_stmt::find_vars(vhdl_var_set_t& read,
vhdl_var_set_t& write)
{
exprs_.find_vars(read);
}
vhdl_var_ref::~vhdl_var_ref()
{
@ -546,6 +577,11 @@ void vhdl_var_ref::set_slice(vhdl_expr *s, int w)
}
}
void vhdl_var_ref::find_vars(vhdl_var_set_t& read)
{
read.insert(this);
}
void vhdl_var_ref::emit(std::ostream &of, int level) const
{
of << name_;
@ -575,6 +611,11 @@ void vhdl_null_stmt::emit(std::ostream &of, int level) const
emit_comment(of, level, true);
}
void vhdl_fcall::find_vars(vhdl_var_set_t& read)
{
exprs_.find_vars(read);
}
void vhdl_fcall::emit(std::ostream &of, int level) const
{
of << name_;
@ -586,6 +627,13 @@ vhdl_abstract_assign_stmt::~vhdl_abstract_assign_stmt()
}
void vhdl_abstract_assign_stmt::find_vars(vhdl_var_set_t& read,
vhdl_var_set_t& write)
{
write.insert(lhs_);
rhs_->find_vars(read);
}
void vhdl_nbassign_stmt::emit(std::ostream &of, int level) const
{
lhs_->emit(of, level);
@ -767,6 +815,21 @@ void vhdl_if_stmt::emit(std::ostream &of, int level) const
of << "end if;";
}
void vhdl_if_stmt::find_vars(vhdl_var_set_t& read,
vhdl_var_set_t& write)
{
test_->find_vars(read);
then_part_.find_vars(read, write);
else_part_.find_vars(read, write);
for (list<elsif>::const_iterator it = elsif_parts_.begin();
it != elsif_parts_.end(); ++it) {
(*it).test->find_vars(read);
(*it).container->find_vars(read, write);
}
}
int vhdl_expr::paren_levels(0);
void vhdl_expr::open_parens(std::ostream& of)
@ -788,6 +851,11 @@ vhdl_unaryop_expr::~vhdl_unaryop_expr()
}
void vhdl_unaryop_expr::find_vars(vhdl_var_set_t& read)
{
operand_->find_vars(read);
}
void vhdl_unaryop_expr::emit(std::ostream &of, int level) const
{
open_parens(of);
@ -823,6 +891,13 @@ void vhdl_binop_expr::add_expr(vhdl_expr *e)
operands_.push_back(e);
}
void vhdl_binop_expr::find_vars(vhdl_var_set_t& read)
{
for (list<vhdl_expr*>::const_iterator it = operands_.begin();
it != operands_.end(); ++it)
(*it)->find_vars(read);
}
void vhdl_binop_expr::emit(std::ostream &of, int level) const
{
open_parens(of);
@ -896,6 +971,18 @@ vhdl_case_stmt::~vhdl_case_stmt()
}
void vhdl_case_stmt::find_vars(vhdl_var_set_t& read,
vhdl_var_set_t& write)
{
test_->find_vars(read);
for (case_branch_list_t::const_iterator it = branches_.begin();
it != branches_.end(); ++it) {
(*it)->when_->find_vars(read);
(*it)->stmts_.find_vars(read, write);
}
}
void vhdl_case_stmt::emit(std::ostream &of, int level) const
{
of << "case ";
@ -921,6 +1008,14 @@ vhdl_while_stmt::~vhdl_while_stmt()
}
void vhdl_while_stmt::find_vars(vhdl_var_set_t& read,
vhdl_var_set_t& write)
{
test_->find_vars(read);
vhdl_loop_stmt::find_vars(read, write);
}
void vhdl_while_stmt::emit(std::ostream &of, int level) const
{
of << "while ";
@ -929,6 +1024,12 @@ void vhdl_while_stmt::emit(std::ostream &of, int level) const
vhdl_loop_stmt::emit(of, level);
}
void vhdl_loop_stmt::find_vars(vhdl_var_set_t& read,
vhdl_var_set_t& write)
{
stmts_.find_vars(read, write);
}
void vhdl_loop_stmt::emit(std::ostream &of, int level) const
{
of << "loop";
@ -941,6 +1042,16 @@ vhdl_for_stmt::~vhdl_for_stmt()
}
void vhdl_for_stmt::find_vars(vhdl_var_set_t& read,
vhdl_var_set_t& write)
{
from_->find_vars(read);
to_->find_vars(write);
vhdl_loop_stmt::find_vars(read, write);
}
void vhdl_for_stmt::emit(std::ostream &of, int level) const
{
of << "for " << lname_ << " in ";

View File

@ -22,6 +22,7 @@
#define INC_VHDL_SYNTAX_HH
#include <inttypes.h>
#include <set>
#include <cassert>
#include "vhdl_element.hh"
#include "vhdl_type.hh"
@ -31,6 +32,9 @@ using namespace std;
class vhdl_scope;
class vhdl_entity;
class vhdl_arch;
class vhdl_var_ref;
typedef set<vhdl_var_ref*> vhdl_var_set_t;
class vhdl_expr : public vhdl_element {
public:
@ -48,6 +52,7 @@ public:
virtual vhdl_expr *to_std_logic();
virtual vhdl_expr *to_std_ulogic();
virtual vhdl_expr *to_vector(vhdl_type_name_t name, int w);
virtual void find_vars(vhdl_var_set_t& read) const {}
protected:
static void open_parens(ostream& of);
@ -73,13 +78,13 @@ public:
const std::string &get_name() const { return name_; }
void set_name(const std::string &name) { name_ = name; }
void set_slice(vhdl_expr *s, int w=0);
void find_vars(vhdl_var_set_t& read);
private:
std::string name_;
vhdl_expr *slice_;
unsigned slice_width_;
};
enum vhdl_binop_t {
VHDL_BINOP_AND = 0,
VHDL_BINOP_OR,
@ -121,6 +126,7 @@ public:
void add_expr(vhdl_expr *e);
void emit(std::ostream &of, int level) const;
void find_vars(vhdl_var_set_t& read);
private:
std::list<vhdl_expr*> operands_;
vhdl_binop_t op_;
@ -140,6 +146,7 @@ public:
~vhdl_unaryop_expr();
void emit(std::ostream &of, int level) const;
void find_vars(vhdl_var_set_t& read);
private:
vhdl_unaryop_t op_;
vhdl_expr *operand_;
@ -252,6 +259,7 @@ public:
void emit(std::ostream &of, int level) const;
bool empty() const { return exprs_.empty(); }
void add_expr(vhdl_expr *e);
void find_vars(vhdl_var_set_t& read);
private:
std::list<vhdl_expr*> exprs_;
};
@ -268,6 +276,7 @@ public:
void add_expr(vhdl_expr *e) { exprs_.add_expr(e); }
void emit(std::ostream &of, int level) const;
void find_vars(vhdl_var_set_t& read);
private:
std::string name_;
vhdl_expr_list exprs_;
@ -338,6 +347,12 @@ private:
class vhdl_seq_stmt : public vhdl_element {
public:
virtual ~vhdl_seq_stmt() {}
// Find all the variables that are read or written in the
// expressions within this statement
// This is used to clean up the VHDL output
virtual void find_vars(vhdl_var_set_t& read,
vhdl_var_set_t& write) = 0;
};
@ -353,6 +368,7 @@ public:
void move_stmts_from(stmt_container *other);
void emit(std::ostream &of, int level, bool newline=true) const;
bool empty() const { return stmts_.empty(); }
void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write);
typedef std::list<vhdl_seq_stmt*> stmt_list_t;
stmt_list_t &get_stmts() { return stmts_; }
@ -371,6 +387,7 @@ public:
virtual ~vhdl_abstract_assign_stmt();
void set_after(vhdl_expr *after) { after_ = after; }
void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write);
protected:
vhdl_var_ref *lhs_;
vhdl_expr *rhs_, *after_;
@ -421,6 +438,7 @@ public:
void emit(std::ostream &of, int level) const;
void add_sensitivity(const std::string &s) { sensitivity_.push_back(s); }
vhdl_wait_type_t get_type() const { return type_; }
void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write);
private:
vhdl_wait_type_t type_;
vhdl_expr *expr_;
@ -431,6 +449,7 @@ private:
class vhdl_null_stmt : public vhdl_seq_stmt {
public:
void emit(std::ostream &of, int level) const;
void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write) {}
};
@ -440,6 +459,7 @@ public:
: reason_(reason) {}
void emit(std::ostream &of, int level) const;
void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write) {}
private:
std::string reason_;
};
@ -454,6 +474,7 @@ public:
stmt_container *get_else_container() { return &else_part_; }
stmt_container *add_elsif(vhdl_expr *test);
void emit(std::ostream &of, int level) const;
void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write);
private:
struct elsif {
vhdl_expr *test;
@ -471,6 +492,7 @@ private:
* expression part and a statement container.
*/
class vhdl_case_branch : public vhdl_element {
friend class vhdl_case_stmt;
public:
vhdl_case_branch(vhdl_expr *when) : when_(when) {}
~vhdl_case_branch();
@ -491,6 +513,7 @@ public:
void add_branch(vhdl_case_branch *b) { branches_.push_back(b); }
void emit(std::ostream &of, int level) const;
void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write);
private:
vhdl_expr *test_;
case_branch_list_t branches_;
@ -503,6 +526,8 @@ public:
stmt_container *get_container() { return &stmts_; }
void emit(std::ostream &of, int level) const;
virtual void find_vars(vhdl_var_set_t& read,
vhdl_var_set_t& write);
private:
stmt_container stmts_;
};
@ -514,6 +539,7 @@ public:
~vhdl_while_stmt();
void emit(std::ostream &of, int level) const;
void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write);
private:
vhdl_expr *test_;
};
@ -526,6 +552,7 @@ public:
~vhdl_for_stmt();
void emit(std::ostream &of, int level) const;
void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write);
private:
const char *lname_;
vhdl_expr *from_, *to_;
@ -542,6 +569,7 @@ public:
void emit(std::ostream &of, int level) const;
void add_expr(vhdl_expr *e) { exprs_.add_expr(e); }
void find_vars(vhdl_var_set_t& read, vhdl_var_set_t& write);
private:
std::string name_;
vhdl_expr_list exprs_;