Handle prefix expressions that include array index expressions.

This commit is contained in:
Stephen Williams 2012-09-01 14:51:04 -07:00
parent 7fad717a1e
commit 85e000ed0c
7 changed files with 94 additions and 2 deletions

View File

@ -20,12 +20,16 @@
*/
# include "StringHeap.h"
# include <fstream>
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;

View File

@ -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;
}

View File

@ -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_;

View File

@ -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 <iostream>
# include <typeinfo>
# 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<const VTypeDef*> (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<const VTypeArray*> (found_type)) {
found_type = array->element_type();
while (const VTypeDef*tdef = dynamic_cast<const VTypeDef*> (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<const VTypeRecord*> (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) {

View File

@ -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;
}

View File

@ -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 <path>.
*
* elaboration=<path>
* Enable debugging of elaboratin by dumping elaboration
* process information to the file named <path>.
*
* entities=<path>
* Enable debugging of elaborated entities by writing the
* elaboration results to the file named <path>.
@ -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);

View File

@ -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);