diff --git a/vhdlpp/expression.h b/vhdlpp/expression.h index 0206e1e88..b8f962534 100644 --- a/vhdlpp/expression.h +++ b/vhdlpp/expression.h @@ -369,6 +369,7 @@ class ExpInteger : public Expression { ExpInteger(int64_t val); ~ExpInteger(); + const VType*probe_type(Entity*ent, Architecture*arc) const; int elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype); int emit(ostream&out, Entity*ent, Architecture*arc); bool is_primary(void) const; diff --git a/vhdlpp/expression_elaborate.cc b/vhdlpp/expression_elaborate.cc index 73a67f988..ba73f4765 100644 --- a/vhdlpp/expression_elaborate.cc +++ b/vhdlpp/expression_elaborate.cc @@ -24,7 +24,7 @@ # include "vsignal.h" # include # include -# include +# include "ivl_assert.h" using namespace std; @@ -89,9 +89,9 @@ int ExpName::elaborate_lval(Entity*ent, Architecture*arc, bool is_sequ) bool flag; flag = index_->evaluate(arc, use_msb); - assert(flag); + ivl_assert(*this, flag); flag = lsb_->evaluate(arc, use_lsb); - assert(flag); + ivl_assert(*this, flag); vector use_dims (1); use_dims[0] = VTypeArray::range_t(use_msb, use_lsb); @@ -220,7 +220,7 @@ int ExpAggregate::elaborate_expr_array_(Entity*ent, Architecture*arc, const VTyp cdx += ecur->count_choices(); } - assert(cdx == choice_count); + ivl_assert(*this, cdx == choice_count); for (size_t idx = 0 ; idx < aggregate_.size() ; idx += 1) { if (aggregate_[idx].alias_flag) @@ -251,7 +251,7 @@ int ExpArithmetic::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltyp ltype = probe_type(ent, arc); } - assert(ltype != 0); + ivl_assert(*this, ltype != 0); errors += elaborate_exprs(ent, arc, ltype); return errors; } @@ -272,7 +272,7 @@ int ExpBitstring::elaborate_expr(Entity*, Architecture*, const VType*) int ExpCharacter::elaborate_expr(Entity*, Architecture*, const VType*ltype) { - assert(ltype != 0); + ivl_assert(*this, ltype != 0); set_type(ltype); return 0; } @@ -289,7 +289,7 @@ int ExpConditional::elaborate_expr(Entity*ent, Architecture*arc, const VType*lty if (ltype == 0) ltype = probe_type(ent, arc); - assert(ltype); + ivl_assert(*this, ltype); set_type(ltype); @@ -322,6 +322,11 @@ int ExpFunc::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype) return errors; } +const VType* ExpInteger::probe_type(Entity*, Architecture*) const +{ + return primitive_INTEGER; +} + int ExpInteger::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype) { int errors = 0; @@ -330,7 +335,7 @@ int ExpInteger::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype) ltype = probe_type(ent, arc); } - assert(ltype != 0); + ivl_assert(*this, ltype != 0); return errors; } @@ -343,7 +348,7 @@ int ExpLogical::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype) ltype = probe_type(ent, arc); } - assert(ltype != 0); + ivl_assert(*this, ltype != 0); errors += elaborate_exprs(ent, arc, ltype); return errors; } @@ -371,7 +376,7 @@ const VType* ExpName::probe_type(Entity*ent, Architecture*arc) const int ExpName::elaborate_expr(Entity*, Architecture*, const VType*ltype) { - assert(ltype != 0); + ivl_assert(*this, ltype != 0); return 0; } @@ -414,14 +419,14 @@ int ExpRelation::elaborate_expr(Entity*ent, Architecture*arc, const VType*ltype) ltype = probe_type(ent, arc); } - assert(ltype != 0); + ivl_assert(*this, ltype != 0); errors += elaborate_exprs(ent, arc, ltype); return errors; } int ExpString::elaborate_expr(Entity*, Architecture*, const VType*ltype) { - assert(ltype != 0); + ivl_assert(*this, ltype != 0); set_type(ltype); return 0; } diff --git a/vhdlpp/ivl_assert.h b/vhdlpp/ivl_assert.h new file mode 100644 index 000000000..ebf473754 --- /dev/null +++ b/vhdlpp/ivl_assert.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2007-2010 Stephen Williams (steve@icarus.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef __ivl_assert_h +#define __ivl_assert_h + +# include + +#define ivl_assert(tok, expression) \ + do { \ + if (! (expression)) { \ + cerr << (tok).get_fileline() << ": assert: " \ + << __FILE__ << ":" << __LINE__ \ + << ": failed assertion " << #expression << endl; \ + abort(); \ + } \ + } while (0) + +#endif diff --git a/vhdlpp/parse.y b/vhdlpp/parse.y index f4c14c316..cbe5d1cf1 100644 --- a/vhdlpp/parse.y +++ b/vhdlpp/parse.y @@ -284,27 +284,20 @@ design_file : { yylloc.text = file_path; } design_units ; architecture_body : architecture_body_start K_of IDENTIFIER + { bind_entity_to_active_scope($3, active_scope) } K_is block_declarative_items_opt K_begin architecture_statement_part K_end K_architecture_opt identifier_opt ';' { Architecture*tmp = new Architecture(lex_strings.make($1), - *active_scope, *$7); + *active_scope, *$8); FILE_NAME(tmp, @1); bind_architecture_to_entity($3, tmp); - if ($10 && tmp->get_name() != $10) + if ($11 && tmp->get_name() != $11) errormsg(@1, "Architecture name doesn't match closing name.\n"); delete[]$1; delete[]$3; - delete $7; - pop_scope(); - if ($10) delete[]$10; - } - | architecture_body_start - K_of IDENTIFIER - K_is block_declarative_items_opt - K_begin error K_end K_architecture_opt identifier_opt ';' - { errormsg(@8, "Errors in architecture statements.\n"); - yyerrok; + delete $8; pop_scope(); + if ($11) delete[]$11; } ; diff --git a/vhdlpp/parse_misc.cc b/vhdlpp/parse_misc.cc index 4bf8368cd..7b4c49e36 100644 --- a/vhdlpp/parse_misc.cc +++ b/vhdlpp/parse_misc.cc @@ -30,6 +30,17 @@ using namespace std; +void bind_entity_to_active_scope(const char*ename, ActiveScope*scope) +{ + perm_string ekey = lex_strings.make(ename); + std::map::const_iterator idx = design_entities.find(ekey); + if (idx == design_entities.end()) { + return; + } + + scope->bind(idx->second); +} + void bind_architecture_to_entity(const char*ename, Architecture*arch) { perm_string ekey = lex_strings.make(ename); diff --git a/vhdlpp/parse_misc.h b/vhdlpp/parse_misc.h index 94c3fa4a7..d62c3e92c 100644 --- a/vhdlpp/parse_misc.h +++ b/vhdlpp/parse_misc.h @@ -28,6 +28,7 @@ class Package; class ScopeBase; class VType; +extern void bind_entity_to_active_scope(const char*ename, ActiveScope*scope); extern void bind_architecture_to_entity(const char*ename, Architecture*arch); extern const VType* calculate_subtype_array(const YYLTYPE&loc, const char*base_name, diff --git a/vhdlpp/scope.cc b/vhdlpp/scope.cc index d1e6a3112..a0c51bb2e 100644 --- a/vhdlpp/scope.cc +++ b/vhdlpp/scope.cc @@ -177,6 +177,9 @@ bool ActiveScope::is_vector_name(perm_string name) const if (find_variable(name)) return true; + if (context_entity_ && context_entity_->find_port(name)) + return true; + return false; } diff --git a/vhdlpp/scope.h b/vhdlpp/scope.h index 10a096186..d2127674f 100644 --- a/vhdlpp/scope.h +++ b/vhdlpp/scope.h @@ -119,7 +119,7 @@ class ActiveScope : public ScopeBase { public: ActiveScope() { } - ActiveScope(ActiveScope*par) : ScopeBase(*par) { } + ActiveScope(ActiveScope*par) : ScopeBase(*par), context_entity_(0) { } ~ActiveScope() { } @@ -171,10 +171,16 @@ class ActiveScope : public ScopeBase { new_constants_[name] = new const_t(obj, val); } + void bind(Entity*ent) + { context_entity_ = ent; } + void destroy_global_scope() { cleanup(); } + + private: + Entity*context_entity_; }; #endif