Allow to attach additional information to typedefs
Currently typedefs are just a pointer to a data_type_t. Currently typedefs are implemented by setting the name field of a data_type_t when a typedef of the type is declared. This works mostly, but there are some corner cases that can't be supported. E.g. a typedef of a typedef does not work as it overwrites the name field of the same data_type_t multiple times. Forward typedefs can also not be supported since forward typedefs allow to reference a type before it has been declared. There are also some problems with type identifier references from a higher-level scope if there is a type identifier in the current scope with the same name, but it is declared after the type identifier has been referenced. E.g. in the following x should be a vector fo width 8, but it will be a vector of width 4, because while the right type is used it is elaborated in the wrong scope. ``` localparam A = 8; typedef logic [A-1:0] T; module M; localparam A = 4; T x; typedef int T; endmodule ``` Furthermore typedefs used for the type of ports are elaborated in the wrong scope. To handle these corner case issues introduce a data_type_t for typedefs. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
3bea115c51
commit
2e0d6d5af1
|
|
@ -51,8 +51,8 @@ PScope::PScope(perm_string n, LexicalScope*parent)
|
||||||
|
|
||||||
PScope::~PScope()
|
PScope::~PScope()
|
||||||
{
|
{
|
||||||
for(map<perm_string, data_type_t*>::iterator it = typedefs.begin();
|
for(typedef_map_t::iterator it = typedefs.begin(); it != typedefs.end();
|
||||||
it != typedefs.end(); ++it)
|
++it)
|
||||||
delete it->second;
|
delete it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
3
PScope.h
3
PScope.h
|
|
@ -120,7 +120,8 @@ class LexicalScope {
|
||||||
bool has_parameter_port_list;
|
bool has_parameter_port_list;
|
||||||
|
|
||||||
// Defined types in the scope.
|
// Defined types in the scope.
|
||||||
std::map<perm_string,data_type_t*>typedefs;
|
typedef std::map<perm_string,typedef_t*> typedef_map_t;
|
||||||
|
typedef_map_t typedefs;
|
||||||
|
|
||||||
// Named events in the scope.
|
// Named events in the scope.
|
||||||
std::map<perm_string,PEvent*>events;
|
std::map<perm_string,PEvent*>events;
|
||||||
|
|
|
||||||
35
elab_type.cc
35
elab_type.cc
|
|
@ -43,7 +43,6 @@ ivl_type_t data_type_t::elaborate_type(Design*des, NetScope*scope)
|
||||||
{
|
{
|
||||||
scope = find_scope(des, scope);
|
scope = find_scope(des, scope);
|
||||||
|
|
||||||
ivl_assert(*this, scope);
|
|
||||||
Definitions*use_definitions = scope;
|
Definitions*use_definitions = scope;
|
||||||
|
|
||||||
map<Definitions*,ivl_type_t>::iterator pos = cache_type_elaborate_.lower_bound(use_definitions);
|
map<Definitions*,ivl_type_t>::iterator pos = cache_type_elaborate_.lower_bound(use_definitions);
|
||||||
|
|
@ -172,13 +171,8 @@ ivl_type_t parray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||||
ivl_type_t etype = base_type->elaborate_type(des, scope);
|
ivl_type_t etype = base_type->elaborate_type(des, scope);
|
||||||
if (!etype->packed()) {
|
if (!etype->packed()) {
|
||||||
cerr << this->get_fileline() << " error: Packed array ";
|
cerr << this->get_fileline() << " error: Packed array ";
|
||||||
if (!name.nil())
|
|
||||||
cerr << "`" << name << "` ";
|
|
||||||
cerr << "base-type `";
|
cerr << "base-type `";
|
||||||
if (base_type->name.nil())
|
|
||||||
cerr << *base_type;
|
cerr << *base_type;
|
||||||
else
|
|
||||||
cerr << base_type->name;
|
|
||||||
cerr << "` is not packed." << endl;
|
cerr << "` is not packed." << endl;
|
||||||
des->errors++;
|
des->errors++;
|
||||||
}
|
}
|
||||||
|
|
@ -385,8 +379,31 @@ NetScope *typeref_t::find_scope(Design *des, NetScope *s) const
|
||||||
if (scope)
|
if (scope)
|
||||||
s = des->find_package(scope->pscope_name());
|
s = des->find_package(scope->pscope_name());
|
||||||
|
|
||||||
if (!type->name.nil())
|
|
||||||
s = s->find_typedef_scope(des, type);
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ivl_type_t typedef_t::elaborate_type(Design *des, NetScope *scope)
|
||||||
|
{
|
||||||
|
if (!data_type.get()) {
|
||||||
|
cerr << get_fileline() << ": error: Undefined type `" << name << "`."
|
||||||
|
<< endl;
|
||||||
|
des->errors++;
|
||||||
|
|
||||||
|
// Try to recover
|
||||||
|
return netvector_t::integer_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search upwards from where the type was referenced
|
||||||
|
scope = scope->find_typedef_scope(des, this);
|
||||||
|
if (!scope) {
|
||||||
|
cerr << get_fileline() << ": sorry: "
|
||||||
|
<< "Can not find the scope type defintion `" << name << "`."
|
||||||
|
<< endl;
|
||||||
|
des->errors++;
|
||||||
|
|
||||||
|
// Try to recover
|
||||||
|
return netvector_t::integer_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
return data_type->elaborate_type(des, scope);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -369,7 +369,7 @@ TU [munpf]
|
||||||
identifier here and interpret it in the package scope. */
|
identifier here and interpret it in the package scope. */
|
||||||
if (in_package_scope) {
|
if (in_package_scope) {
|
||||||
if (rc == IDENTIFIER) {
|
if (rc == IDENTIFIER) {
|
||||||
if (data_type_t*type = pform_test_type_identifier(in_package_scope, yylval.text)) {
|
if (typedef_t*type = pform_test_type_identifier(in_package_scope, yylval.text)) {
|
||||||
yylval.type_identifier.text = yylval.text;
|
yylval.type_identifier.text = yylval.text;
|
||||||
yylval.type_identifier.type = type;
|
yylval.type_identifier.type = type;
|
||||||
rc = TYPE_IDENTIFIER;
|
rc = TYPE_IDENTIFIER;
|
||||||
|
|
@ -405,7 +405,7 @@ TU [munpf]
|
||||||
/* If this identifier names a previously declared type, then
|
/* If this identifier names a previously declared type, then
|
||||||
return this as a TYPE_IDENTIFIER instead. */
|
return this as a TYPE_IDENTIFIER instead. */
|
||||||
if (rc == IDENTIFIER && gn_system_verilog()) {
|
if (rc == IDENTIFIER && gn_system_verilog()) {
|
||||||
if (data_type_t*type = pform_test_type_identifier(yylloc, yylval.text)) {
|
if (typedef_t*type = pform_test_type_identifier(yylloc, yylval.text)) {
|
||||||
yylval.type_identifier.text = yylval.text;
|
yylval.type_identifier.text = yylval.text;
|
||||||
yylval.type_identifier.type = type;
|
yylval.type_identifier.type = type;
|
||||||
rc = TYPE_IDENTIFIER;
|
rc = TYPE_IDENTIFIER;
|
||||||
|
|
@ -426,7 +426,7 @@ TU [munpf]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gn_system_verilog()) {
|
if (gn_system_verilog()) {
|
||||||
if (data_type_t*type = pform_test_type_identifier(yylloc, yylval.text)) {
|
if (typedef_t*type = pform_test_type_identifier(yylloc, yylval.text)) {
|
||||||
yylval.type_identifier.text = yylval.text;
|
yylval.type_identifier.text = yylval.text;
|
||||||
yylval.type_identifier.type = type;
|
yylval.type_identifier.type = type;
|
||||||
return TYPE_IDENTIFIER;
|
return TYPE_IDENTIFIER;
|
||||||
|
|
|
||||||
|
|
@ -232,19 +232,20 @@ NetScope*NetScope::find_import(const Design*des, perm_string name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetScope::add_typedefs(const map<perm_string,data_type_t*>*typedefs)
|
void NetScope::add_typedefs(const map<perm_string,typedef_t*>*typedefs)
|
||||||
{
|
{
|
||||||
if (!typedefs->empty())
|
if (!typedefs->empty())
|
||||||
typedefs_ = *typedefs;
|
typedefs_ = *typedefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetScope*NetScope::find_typedef_scope(const Design*des, data_type_t*type)
|
NetScope*NetScope::find_typedef_scope(const Design*des, const typedef_t*type)
|
||||||
{
|
{
|
||||||
assert(type);
|
assert(type);
|
||||||
|
|
||||||
NetScope *cur_scope = this;
|
NetScope *cur_scope = this;
|
||||||
while (cur_scope) {
|
while (cur_scope) {
|
||||||
if (cur_scope->typedefs_.find(type->name) != cur_scope->typedefs_.end())
|
auto it = cur_scope->typedefs_.find(type->name);
|
||||||
|
if (it != cur_scope->typedefs_.end() && it->second == type)
|
||||||
return cur_scope;
|
return cur_scope;
|
||||||
NetScope*import_scope = cur_scope->find_import(des, type->name);
|
NetScope*import_scope = cur_scope->find_import(des, type->name);
|
||||||
if (import_scope)
|
if (import_scope)
|
||||||
|
|
|
||||||
|
|
@ -940,10 +940,10 @@ class NetScope : public Definitions, public Attrib {
|
||||||
void add_imports(const std::map<perm_string,PPackage*>*imports);
|
void add_imports(const std::map<perm_string,PPackage*>*imports);
|
||||||
NetScope*find_import(const Design*des, perm_string name);
|
NetScope*find_import(const Design*des, perm_string name);
|
||||||
|
|
||||||
void add_typedefs(const std::map<perm_string,data_type_t*>*typedefs);
|
void add_typedefs(const std::map<perm_string,typedef_t*>*typedefs);
|
||||||
|
|
||||||
/* Search the scope hierarchy for the scope where 'type' was defined. */
|
/* Search the scope hierarchy for the scope where 'type' was defined. */
|
||||||
NetScope*find_typedef_scope(const Design*des, data_type_t*type);
|
NetScope*find_typedef_scope(const Design*des, const typedef_t*type);
|
||||||
|
|
||||||
/* Parameters exist within a scope, and these methods allow
|
/* Parameters exist within a scope, and these methods allow
|
||||||
one to manipulate the set. In these cases, the name is the
|
one to manipulate the set. In these cases, the name is the
|
||||||
|
|
@ -1268,7 +1268,7 @@ class NetScope : public Definitions, public Attrib {
|
||||||
|
|
||||||
const std::map<perm_string,PPackage*>*imports_;
|
const std::map<perm_string,PPackage*>*imports_;
|
||||||
|
|
||||||
std::map<perm_string,data_type_t*>typedefs_;
|
std::map<perm_string,typedef_t*>typedefs_;
|
||||||
|
|
||||||
NetEvent *events_;
|
NetEvent *events_;
|
||||||
|
|
||||||
|
|
|
||||||
19
parse.y
19
parse.y
|
|
@ -438,7 +438,7 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector<Statem
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
char*text;
|
char*text;
|
||||||
data_type_t*type;
|
typedef_t*type;
|
||||||
} type_identifier;
|
} type_identifier;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -810,12 +810,12 @@ class_identifier
|
||||||
perm_string name = lex_strings.make($1);
|
perm_string name = lex_strings.make($1);
|
||||||
class_type_t*tmp = new class_type_t(name);
|
class_type_t*tmp = new class_type_t(name);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
pform_set_typedef(name, tmp, NULL);
|
pform_set_typedef(@1, name, tmp, NULL);
|
||||||
delete[]$1;
|
delete[]$1;
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
| TYPE_IDENTIFIER
|
| TYPE_IDENTIFIER
|
||||||
{ class_type_t*tmp = dynamic_cast<class_type_t*>($1.type);
|
{ class_type_t*tmp = dynamic_cast<class_type_t*>($1.type->get_data_type());
|
||||||
if (tmp == 0) {
|
if (tmp == 0) {
|
||||||
yyerror(@1, "Type name \"%s\"is not a predeclared class name.", $1.text);
|
yyerror(@1, "Type name \"%s\"is not a predeclared class name.", $1.text);
|
||||||
}
|
}
|
||||||
|
|
@ -2656,7 +2656,7 @@ block_item_decls_opt
|
||||||
type_declaration
|
type_declaration
|
||||||
: K_typedef data_type IDENTIFIER dimensions_opt ';'
|
: K_typedef data_type IDENTIFIER dimensions_opt ';'
|
||||||
{ perm_string name = lex_strings.make($3);
|
{ perm_string name = lex_strings.make($3);
|
||||||
pform_set_typedef(name, $2, $4);
|
pform_set_typedef(@3, name, $2, $4);
|
||||||
delete[]$3;
|
delete[]$3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2665,12 +2665,7 @@ type_declaration
|
||||||
inherited from a different scope. */
|
inherited from a different scope. */
|
||||||
| K_typedef data_type TYPE_IDENTIFIER dimensions_opt ';'
|
| K_typedef data_type TYPE_IDENTIFIER dimensions_opt ';'
|
||||||
{ perm_string name = lex_strings.make($3.text);
|
{ perm_string name = lex_strings.make($3.text);
|
||||||
if (pform_test_type_identifier_local(name)) {
|
pform_set_typedef(@3, name, $2, $4);
|
||||||
yyerror(@3, "error: Typedef identifier \"%s\" is already a type name.", $3.text);
|
|
||||||
delete $4;
|
|
||||||
} else {
|
|
||||||
pform_set_typedef(name, $2, $4);
|
|
||||||
}
|
|
||||||
delete[]$3.text;
|
delete[]$3.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2682,7 +2677,7 @@ type_declaration
|
||||||
perm_string name = lex_strings.make($3);
|
perm_string name = lex_strings.make($3);
|
||||||
class_type_t*tmp = new class_type_t(name);
|
class_type_t*tmp = new class_type_t(name);
|
||||||
FILE_NAME(tmp, @3);
|
FILE_NAME(tmp, @3);
|
||||||
pform_set_typedef(name, tmp, NULL);
|
pform_set_typedef(@3, name, tmp, NULL);
|
||||||
delete[]$3;
|
delete[]$3;
|
||||||
}
|
}
|
||||||
| K_typedef K_enum IDENTIFIER ';'
|
| K_typedef K_enum IDENTIFIER ';'
|
||||||
|
|
@ -2697,7 +2692,7 @@ type_declaration
|
||||||
perm_string name = lex_strings.make($2);
|
perm_string name = lex_strings.make($2);
|
||||||
class_type_t*tmp = new class_type_t(name);
|
class_type_t*tmp = new class_type_t(name);
|
||||||
FILE_NAME(tmp, @2);
|
FILE_NAME(tmp, @2);
|
||||||
pform_set_typedef(name, tmp, NULL);
|
pform_set_typedef(@3, name, tmp, NULL);
|
||||||
delete[]$2;
|
delete[]$2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,10 +89,8 @@ extern void lex_in_package_scope(PPackage*pkg);
|
||||||
* parser detects typedefs and marks the typedef'ed identifiers as
|
* parser detects typedefs and marks the typedef'ed identifiers as
|
||||||
* type names.
|
* type names.
|
||||||
*/
|
*/
|
||||||
extern data_type_t* pform_test_type_identifier(const YYLTYPE&loc, const char*txt);
|
extern typedef_t* pform_test_type_identifier(const YYLTYPE&loc, const char*txt);
|
||||||
extern data_type_t* pform_test_type_identifier(PPackage*pkg, const char*txt);
|
extern typedef_t* pform_test_type_identifier(PPackage*pkg, const char*txt);
|
||||||
|
|
||||||
extern bool pform_test_type_identifier_local(perm_string txt);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test if this identifier is a package name. The pform needs to help
|
* Test if this identifier is a package name. The pform needs to help
|
||||||
|
|
|
||||||
46
pform.cc
46
pform.cc
|
|
@ -858,18 +858,28 @@ void pform_put_enum_type_in_scope(enum_type_t*enum_set)
|
||||||
lexical_scope->enum_sets.push_back(enum_set);
|
lexical_scope->enum_sets.push_back(enum_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_typedef(perm_string name, data_type_t*data_type, std::list<pform_range_t>*unp_ranges)
|
void pform_set_typedef(const struct vlltype&loc, perm_string name,
|
||||||
|
data_type_t*data_type,
|
||||||
|
std::list<pform_range_t>*unp_ranges)
|
||||||
{
|
{
|
||||||
if(unp_ranges)
|
if(unp_ranges)
|
||||||
data_type = new uarray_type_t(data_type, unp_ranges);
|
data_type = new uarray_type_t(data_type, unp_ranges);
|
||||||
|
|
||||||
add_local_symbol(lexical_scope, name, data_type);
|
typedef_t *&td = lexical_scope->typedefs[name];
|
||||||
|
if (!td) {
|
||||||
|
td = new typedef_t(name);
|
||||||
|
FILE_NAME(td, loc);
|
||||||
|
add_local_symbol(lexical_scope, name, td);
|
||||||
|
}
|
||||||
|
|
||||||
data_type_t*&ref = lexical_scope->typedefs[name];
|
if (!td->set_data_type(data_type)) {
|
||||||
|
cerr << loc << " error: Type identifier `" << name
|
||||||
ivl_assert(*data_type, ref == 0);
|
<< "` has already been declared in this scope at "
|
||||||
ref = data_type;
|
<< td->get_data_type()->get_fileline() << "."
|
||||||
ref->name = name;
|
<< endl;
|
||||||
|
error_count++;
|
||||||
|
delete data_type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pform_set_type_referenced(const struct vlltype&loc, const char*name)
|
void pform_set_type_referenced(const struct vlltype&loc, const char*name)
|
||||||
|
|
@ -878,13 +888,13 @@ void pform_set_type_referenced(const struct vlltype&loc, const char*name)
|
||||||
check_potential_imports(loc, lex_name, false);
|
check_potential_imports(loc, lex_name, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
data_type_t* pform_test_type_identifier(const struct vlltype&loc, const char*txt)
|
typedef_t* pform_test_type_identifier(const struct vlltype&loc, const char*txt)
|
||||||
{
|
{
|
||||||
perm_string name = lex_strings.make(txt);
|
perm_string name = lex_strings.make(txt);
|
||||||
|
|
||||||
LexicalScope*cur_scope = lexical_scope;
|
LexicalScope*cur_scope = lexical_scope;
|
||||||
do {
|
do {
|
||||||
map<perm_string,data_type_t*>::iterator cur;
|
LexicalScope::typedef_map_t::iterator cur;
|
||||||
|
|
||||||
// First look to see if this identifier is imported from
|
// First look to see if this identifier is imported from
|
||||||
// a package. If it is, see if it is a type in that
|
// a package. If it is, see if it is a type in that
|
||||||
|
|
@ -924,24 +934,6 @@ data_type_t* pform_test_type_identifier(const struct vlltype&loc, const char*txt
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The parser uses this function to test if the name is a typedef in
|
|
||||||
* the current scope. We use this to know if we can override the
|
|
||||||
* definition because it shadows a containing scope.
|
|
||||||
*/
|
|
||||||
bool pform_test_type_identifier_local(perm_string name)
|
|
||||||
{
|
|
||||||
LexicalScope*cur_scope = lexical_scope;
|
|
||||||
|
|
||||||
map<perm_string,data_type_t*>::iterator cur;
|
|
||||||
|
|
||||||
cur = cur_scope->typedefs.find(name);
|
|
||||||
if (cur != cur_scope->typedefs.end())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PECallFunction* pform_make_call_function(const struct vlltype&loc,
|
PECallFunction* pform_make_call_function(const struct vlltype&loc,
|
||||||
const pform_name_t&name,
|
const pform_name_t&name,
|
||||||
const list<PExpr*>&parms)
|
const list<PExpr*>&parms)
|
||||||
|
|
|
||||||
3
pform.h
3
pform.h
|
|
@ -303,7 +303,8 @@ extern void pform_make_elab_task(const struct vlltype&li,
|
||||||
perm_string name,
|
perm_string name,
|
||||||
const std::list<PExpr*>¶ms);
|
const std::list<PExpr*>¶ms);
|
||||||
|
|
||||||
extern void pform_set_typedef(perm_string name, data_type_t*data_type,
|
extern void pform_set_typedef(const struct vlltype&loc, perm_string name,
|
||||||
|
data_type_t*data_type,
|
||||||
std::list<pform_range_t>*unp_ranges);
|
std::list<pform_range_t>*unp_ranges);
|
||||||
|
|
||||||
extern void pform_set_type_referenced(const struct vlltype&loc, const char*name);
|
extern void pform_set_type_referenced(const struct vlltype&loc, const char*name);
|
||||||
|
|
|
||||||
|
|
@ -1502,10 +1502,10 @@ void PGenerate::dump(ostream&out, unsigned indent) const
|
||||||
|
|
||||||
void LexicalScope::dump_typedefs_(ostream&out, unsigned indent) const
|
void LexicalScope::dump_typedefs_(ostream&out, unsigned indent) const
|
||||||
{
|
{
|
||||||
typedef map<perm_string,data_type_t*>::const_iterator iter_t;
|
typedef typedef_map_t::const_iterator iter_t;
|
||||||
for (iter_t cur = typedefs.begin() ; cur != typedefs.end() ; ++ cur) {
|
for (iter_t cur = typedefs.begin() ; cur != typedefs.end() ; ++ cur) {
|
||||||
out << setw(indent) << "" << "typedef of " << cur->first << ":" << endl;
|
out << setw(indent) << "" << "typedef of " << cur->first << ":" << endl;
|
||||||
cur->second->pform_dump(out, indent+4);
|
cur->second->get_data_type()->pform_dump(out, indent+4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -143,10 +143,12 @@ PExpr* pform_package_ident(const struct vlltype&loc,
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
data_type_t* pform_test_type_identifier(PPackage*pkg, const char*txt)
|
typedef_t* pform_test_type_identifier(PPackage*pkg, const char*txt)
|
||||||
{
|
{
|
||||||
perm_string use_name = lex_strings.make(txt);
|
perm_string use_name = lex_strings.make(txt);
|
||||||
map<perm_string,data_type_t*>::const_iterator cur = pkg->typedefs.find(use_name);
|
LexicalScope::typedef_map_t::const_iterator cur;
|
||||||
|
|
||||||
|
cur = pkg->typedefs.find(use_name);
|
||||||
if (cur != pkg->typedefs.end())
|
if (cur != pkg->typedefs.end())
|
||||||
return cur->second;
|
return cur->second;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,3 +44,13 @@ PNamedItem::SymbolType class_type_t::symbol_type() const
|
||||||
{
|
{
|
||||||
return CLASS;
|
return CLASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool typedef_t::set_data_type(data_type_t *t)
|
||||||
|
{
|
||||||
|
if (data_type.get())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
data_type.reset(t);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -162,20 +162,31 @@ class data_type_t : public PNamedItem {
|
||||||
|
|
||||||
virtual SymbolType symbol_type() const;
|
virtual SymbolType symbol_type() const;
|
||||||
|
|
||||||
virtual NetScope *find_scope(Design* des, NetScope *scope) const;
|
|
||||||
|
|
||||||
perm_string name;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Elaborate the type to an ivl_type_s type.
|
// Elaborate the type to an ivl_type_s type.
|
||||||
virtual ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const;
|
virtual ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const;
|
||||||
|
virtual NetScope *find_scope(Design* des, NetScope *scope) const;
|
||||||
|
|
||||||
// Keep per-scope elaboration results cached.
|
// Keep per-scope elaboration results cached.
|
||||||
std::map<Definitions*,ivl_type_t> cache_type_elaborate_;
|
std::map<Definitions*,ivl_type_t> cache_type_elaborate_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct typedef_t : public PNamedItem {
|
||||||
|
explicit typedef_t(perm_string n) : name(n) { };
|
||||||
|
|
||||||
|
ivl_type_t elaborate_type(Design*des, NetScope*scope);
|
||||||
|
|
||||||
|
bool set_data_type(data_type_t *t);
|
||||||
|
const data_type_t *get_data_type() const { return data_type.get(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<data_type_t> data_type;
|
||||||
|
public:
|
||||||
|
perm_string name;
|
||||||
|
};
|
||||||
|
|
||||||
struct typeref_t : public data_type_t {
|
struct typeref_t : public data_type_t {
|
||||||
explicit typeref_t(data_type_t *t, PScope *s = 0) : scope(s), type(t) {}
|
explicit typeref_t(typedef_t *t, PScope *s = 0) : scope(s), type(t) {}
|
||||||
|
|
||||||
ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const;
|
ivl_type_t elaborate_type_raw(Design*des, NetScope*scope) const;
|
||||||
NetScope *find_scope(Design* des, NetScope *scope) const;
|
NetScope *find_scope(Design* des, NetScope *scope) const;
|
||||||
|
|
@ -184,7 +195,7 @@ struct typeref_t : public data_type_t {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PScope *scope;
|
PScope *scope;
|
||||||
data_type_t *type;
|
typedef_t *type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct void_type_t : public data_type_t {
|
struct void_type_t : public data_type_t {
|
||||||
|
|
@ -335,7 +346,7 @@ struct string_type_t : public data_type_t {
|
||||||
|
|
||||||
struct class_type_t : public data_type_t {
|
struct class_type_t : public data_type_t {
|
||||||
|
|
||||||
inline explicit class_type_t(perm_string n) { name = n; }
|
inline explicit class_type_t(perm_string n) : name(n) { }
|
||||||
|
|
||||||
void pform_dump(std::ostream&out, unsigned indent) const;
|
void pform_dump(std::ostream&out, unsigned indent) const;
|
||||||
void pform_dump_init(std::ostream&out, unsigned indent) const;
|
void pform_dump_init(std::ostream&out, unsigned indent) const;
|
||||||
|
|
@ -370,6 +381,8 @@ struct class_type_t : public data_type_t {
|
||||||
|
|
||||||
ivl_type_t elaborate_type_raw(Design*, NetScope*) const;
|
ivl_type_t elaborate_type_raw(Design*, NetScope*) const;
|
||||||
|
|
||||||
|
perm_string name;
|
||||||
|
|
||||||
virtual SymbolType symbol_type() const;
|
virtual SymbolType symbol_type() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue