From 85e000ed0c990675920d89baba4779318d875ce9 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sat, 1 Sep 2012 14:51:04 -0700 Subject: [PATCH] Handle prefix expressions that include array index expressions. --- vhdlpp/compiler.h | 4 +++ vhdlpp/debug.cc | 12 +++++++++ vhdlpp/expression.h | 7 ++++++ vhdlpp/expression_elaborate.cc | 46 ++++++++++++++++++++++++++++++++++ vhdlpp/expression_emit.cc | 7 +++++- vhdlpp/main.cc | 18 ++++++++++++- vhdlpp/vtype.h | 2 ++ 7 files changed, 94 insertions(+), 2 deletions(-) diff --git a/vhdlpp/compiler.h b/vhdlpp/compiler.h index dc4117de5..f0ae81ad5 100644 --- a/vhdlpp/compiler.h +++ b/vhdlpp/compiler.h @@ -20,12 +20,16 @@ */ # include "StringHeap.h" +# include const int GN_KEYWORD_2008 = 0x0001; // TRUE if processing is supposed to dump progress to stderr. extern bool verbose_flag; +extern bool debug_elaboration; +extern std::ofstream debug_log_file; + extern StringHeapLex lex_strings; extern StringHeapLex filename_strings; diff --git a/vhdlpp/debug.cc b/vhdlpp/debug.cc index 5eba2793d..972150778 100644 --- a/vhdlpp/debug.cc +++ b/vhdlpp/debug.cc @@ -424,3 +424,15 @@ void prange_t::dump(ostream&out, int indent) const out << setw(indent) << "" << (direction_ ? "downto" : "to"); right_->dump(out, indent); } + +ostream& Expression::dump_inline(ostream&out) const +{ + out << typeid(*this).name(); + return out; +} + +ostream& ExpInteger::dump_inline(ostream&out) const +{ + out << value_; + return out; +} diff --git a/vhdlpp/expression.h b/vhdlpp/expression.h index 7831bdeb7..628f234ab 100644 --- a/vhdlpp/expression.h +++ b/vhdlpp/expression.h @@ -111,6 +111,7 @@ class Expression : public LineInfo { // Debug dump of the expression. virtual void dump(ostream&out, int indent = 0) const =0; + virtual ostream& dump_inline(ostream&out) const; protected: // This function is called by the derived class during @@ -131,6 +132,11 @@ static inline void FILE_NAME(Expression*tgt, const LineInfo*src) tgt->set_line(*src); } +static inline ostream& operator <<(ostream&out, const Expression&exp) +{ + return exp.dump_inline(out); +} + class ExpUnary : public Expression { public: @@ -473,6 +479,7 @@ class ExpInteger : public Expression { bool is_primary(void) const; bool evaluate(ScopeBase*scope, int64_t&val) const; void dump(ostream&out, int indent = 0) const; + virtual ostream& dump_inline(ostream&out) const; private: int64_t value_; diff --git a/vhdlpp/expression_elaborate.cc b/vhdlpp/expression_elaborate.cc index 156510957..465e3b743 100644 --- a/vhdlpp/expression_elaborate.cc +++ b/vhdlpp/expression_elaborate.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2012 Stephen Williams (steve@icarus.com) + * Copyright CERN 2012 / 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 @@ -25,6 +26,7 @@ # include # include # include "parse_types.h" +# include "compiler.h" # include "ivl_assert.h" using namespace std; @@ -87,6 +89,17 @@ int ExpName::elaborate_lval_(Entity*ent, Architecture*arc, bool is_sequ, ExpName { int errors = 0; + if (debug_elaboration) { + debug_log_file << get_fileline() << ": ExpName::elaborate_lval_: " + << "name_=" << name_ + << ", suffix->name()=" << suffix->name(); + if (index_) + debug_log_file << ", index_=" << *index_; + if (lsb_) + debug_log_file << ", lsb_=" << *lsb_; + debug_log_file << endl; + } + if (prefix_.get()) { cerr << get_fileline() << ": sorry: I don't know how to elaborate " << "ExpName prefix of " << name_ @@ -128,8 +141,40 @@ int ExpName::elaborate_lval_(Entity*ent, Architecture*arc, bool is_sequ, ExpName found_type = var->peek_type(); } + // Resolve type definition to get an actual type. + while (const VTypeDef*tdef = dynamic_cast (found_type)) { + found_type = tdef->peek_definition(); + + if (debug_elaboration) { + debug_log_file << get_fileline() << ": ExpName::elaborate_lval_: " + << "Resolve typedef " << tdef->peek_name() + << " to defined type=" << typeid(*found_type).name() + << endl; + } + } + ivl_assert(*this, found_type); + // If the prefix type is an array, then we may actually have a + // case of an array of structs. For example: + // foo(n).bar + // where foo is an array, (n) is an array index and foo(n) is + // something that takes a suffix. For the purpose of our + // expression type calculations, we need the element type. + if (const VTypeArray*array = dynamic_cast (found_type)) { + found_type = array->element_type(); + + while (const VTypeDef*tdef = dynamic_cast (found_type)) { + found_type = tdef->peek_definition(); + } + + if (debug_elaboration) { + debug_log_file << get_fileline() << ": ExpName::elaborate_lval_: " + << "Extract array element type=" << typeid(*found_type).name() + << endl; + } + } + const VType*suffix_type = 0; if (const VTypeRecord*record = dynamic_cast (found_type)) { @@ -140,6 +185,7 @@ int ExpName::elaborate_lval_(Entity*ent, Architecture*arc, bool is_sequ, ExpName ivl_assert(*this, element_type); suffix_type = element_type; + } if (suffix_type == 0) { diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index fda8c8c45..c4ba78ed3 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -610,7 +610,12 @@ int ExpName::emit_as_prefix_(ostream&out, Entity*ent, Architecture*arc) } out << "\\" << name_ << " "; - ivl_assert(*this, index_ == 0); + if (index_) { + out << "["; + errors += index_->emit(out, ent, arc); + out << "]"; + ivl_assert(*this, lsb_ == 0); + } out << "."; return errors; } diff --git a/vhdlpp/main.cc b/vhdlpp/main.cc index d5c765954..ce3fa2df6 100644 --- a/vhdlpp/main.cc +++ b/vhdlpp/main.cc @@ -1,6 +1,7 @@ const char COPYRIGHT[] = - "Copyright (c) 2011 Stephen Williams (steve@icarus.com)"; + "Copyright (c) 2011-2012 Stephen Williams (steve@icarus.com)\n" + "Copyright CERN 2012 / 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 @@ -36,6 +37,10 @@ const char COPYRIGHT[] = * Enable debugging of library support by dumping library * information to the file named . * + * elaboration= + * Enable debugging of elaboratin by dumping elaboration + * process information to the file named . + * * entities= * Enable debugging of elaborated entities by writing the * elaboration results to the file named . @@ -94,7 +99,10 @@ bool verbose_flag = false; // Where to dump design entities const char*dump_design_entities_path = 0; const char*dump_libraries_path = 0; +const char*debug_log_path = 0; +bool debug_elaboration = false; +ofstream debug_log_file; extern void dump_libraries(ostream&file); extern void parser_cleanup(); @@ -109,6 +117,10 @@ static void process_debug_token(const char*word) dump_design_entities_path = strdup(word+9); } else if (strncmp(word, "libraries=", 10) == 0) { dump_libraries_path = strdup(word+10); + } else if (strncmp(word, "log=", 4) == 0) { + debug_log_path = strdup(word+4); + } else if (strcmp(word, "elaboration") == 0) { + debug_elaboration = true; } } @@ -148,6 +160,10 @@ int main(int argc, char*argv[]) break; } + if (debug_log_path) { + debug_log_file.open(debug_log_path); + } + if ( (rc = mkdir(work_path, 0777)) < 0 ) { if (errno != EEXIST) { fprintf(stderr, "Icarus Verilog VHDL unable to create work directory %s, errno=%d\n", work_path, errno); diff --git a/vhdlpp/vtype.h b/vhdlpp/vtype.h index 16fcd7e6a..047b89528 100644 --- a/vhdlpp/vtype.h +++ b/vhdlpp/vtype.h @@ -246,6 +246,8 @@ class VTypeDef : public VType { explicit VTypeDef(perm_string name, const VType*is); ~VTypeDef(); + inline perm_string peek_name() const { return name_; } + // If the type is not given a definition in the constructor, // then this must be used to set the definition later. void set_definition(const VType*is);