Handle prefix expressions that include array index expressions.
This commit is contained in:
parent
7fad717a1e
commit
85e000ed0c
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue