From 4a45806176647b9968ee550434484bab5bc43377 Mon Sep 17 00:00:00 2001 From: Daniel Kroening Date: Tue, 5 Mar 2024 09:28:05 -0800 Subject: [PATCH] Verilog: parse tree now stores package_items SystemVerilog allows any package_item at the top level of the file. This extends the parse tree to store these, generalising from typedefs, which are package_items. --- src/verilog/parser.y | 1 + src/verilog/verilog_language.cpp | 9 +++++ src/verilog/verilog_language.h | 1 + src/verilog/verilog_parse_tree.cpp | 11 +++--- src/verilog/verilog_parse_tree.h | 41 +++++++++------------ src/verilog/verilog_typecheck.cpp | 57 ++++++++++++++++++++++++++++++ src/verilog/verilog_typecheck.h | 5 +++ 7 files changed, 95 insertions(+), 30 deletions(-) diff --git a/src/verilog/parser.y b/src/verilog/parser.y index 8ebb813d..82e1a423 100644 --- a/src/verilog/parser.y +++ b/src/verilog/parser.y @@ -643,6 +643,7 @@ description: | program_declaration | package_declaration | attribute_instance_brace package_item + { PARSER.parse_tree.create_package_item(stack_expr($2)); } | attribute_instance_brace bind_directive | config_declaration ; diff --git a/src/verilog/verilog_language.cpp b/src/verilog/verilog_language.cpp index d22bd412..92d5f2ab 100644 --- a/src/verilog/verilog_language.cpp +++ b/src/verilog/verilog_language.cpp @@ -159,6 +159,15 @@ bool verilog_languaget::typecheck( { if(module=="") return false; + if(!top_scope_package_items_done) + { + // Verilog allows 'package items' at the top-level scope, + // outside of a module. These only need to be done once. + top_scope_package_items_done = true; + if(verilog_typecheck_package_items(parse_tree, symbol_table, message_handler)) + return true; + } + if(verilog_typecheck(parse_tree, symbol_table, module, message_handler)) return true; diff --git a/src/verilog/verilog_language.h b/src/verilog/verilog_language.h index ed7464a1..965fff34 100644 --- a/src/verilog/verilog_language.h +++ b/src/verilog/verilog_language.h @@ -93,6 +93,7 @@ class verilog_languaget:public languaget protected: verilog_parse_treet parse_tree; + bool top_scope_package_items_done = false; }; std::unique_ptr new_verilog_language(); diff --git a/src/verilog/verilog_parse_tree.cpp b/src/verilog/verilog_parse_tree.cpp index 5e6f719b..8a9eb1cf 100644 --- a/src/verilog/verilog_parse_tree.cpp +++ b/src/verilog/verilog_parse_tree.cpp @@ -29,10 +29,8 @@ void verilog_parse_treet::create_module( exprt &ports, exprt &module_items) { - items.push_back(itemt()); + items.push_back(itemt(itemt::MODULE)); itemt &item=items.back(); - - item.type=itemt::MODULE; verilog_modulet &new_module=item.verilog_module; @@ -135,9 +133,10 @@ void verilog_parse_treet::itemt::show(std::ostream &out) const case itemt::MODULE: verilog_module.show(out); break; - - case itemt::TYPEDEF: - verilog_typedef.show(out); + + case itemt::PACKAGE_ITEM: + out << "Package item:\n"; + out << verilog_package_item.pretty() << '\n'; break; default: diff --git a/src/verilog/verilog_parse_tree.h b/src/verilog/verilog_parse_tree.h index 2e134e2b..3d3fd3d4 100644 --- a/src/verilog/verilog_parse_tree.h +++ b/src/verilog/verilog_parse_tree.h @@ -19,37 +19,32 @@ Author: Daniel Kroening, kroening@kroening.com class verilog_parse_treet { public: - class verilog_typedeft + struct itemt { public: - typet symbol; - typet type; - - void show(std::ostream &out) const + typedef enum + { + MODULE, + PACKAGE_ITEM + } item_typet; + item_typet type; + + explicit itemt(item_typet __type) : type(__type) { - out << "Typedef:\n"; - out << "\n"; } - }; - struct itemt - { - public: - typedef enum { MODULE, TYPEDEF } item_typet; - item_typet type; - verilog_modulet verilog_module; - - verilog_typedeft verilog_typedef; - + + exprt verilog_package_item; + bool is_module() const { return type==MODULE; } - bool is_typedef() const + bool is_package_item() const { - return type==TYPEDEF; + return type == PACKAGE_ITEM; } void show(std::ostream &out) const; @@ -80,12 +75,10 @@ class verilog_parse_treet exprt &ports, exprt &statements); - void create_typedef(irept &declaration) + void create_package_item(exprt package_item) { - items.push_back(itemt()); - items.back().type=itemt::TYPEDEF; - items.back().verilog_typedef.symbol.swap(declaration.get_sub()[0]); - items.back().verilog_typedef.type.swap(declaration.add(ID_type)); + items.push_back(itemt(itemt::PACKAGE_ITEM)); + items.back().verilog_package_item = std::move(package_item); } void swap(verilog_parse_treet &parse_tree) diff --git a/src/verilog/verilog_typecheck.cpp b/src/verilog/verilog_typecheck.cpp index bbf34095..35682c91 100644 --- a/src/verilog/verilog_typecheck.cpp +++ b/src/verilog/verilog_typecheck.cpp @@ -1753,3 +1753,60 @@ bool verilog_typecheck( verilog_typecheckt verilog_typecheck(*new_symbol, symbol_table, message_handler); return verilog_typecheck.typecheck_main(); } + +/*******************************************************************\ + +Function: verilog_typecheck + + Inputs: + + Outputs: + + Purpose: + +\*******************************************************************/ + +bool verilog_typecheck_package_items( + const verilog_parse_treet &parse_tree, + symbol_table_baset &symbol_table, + message_handlert &message_handler) +{ + for(auto &item : parse_tree.items) + if(item.is_package_item()) + { + // These might be typedefs, with enums + +#if 0 + // create symbol + symbolt symbol; + + symbol.mode=ID_Verilog; + symbol.base_name=verilog_module.name; + symbol.type=module_typet(); + symbol.name=verilog_module_symbol(verilog_module.name); + symbol.base_name=verilog_module.name; + symbol.pretty_name=verilog_module.name; + symbol.module=symbol.name; + symbol.location=verilog_module.location; + + symbol.type.add(ID_module_source)=verilog_module.to_irep(); + + // put symbol into symbol_table + symbolt *new_symbol; + + if(symbol_table.move(symbol, new_symbol)) + { + messaget message(message_handler); + message.error() << "duplicate definition of " + << symbol.base_name << messaget::eom; + return true; + } + + verilog_typecheckt verilog_typecheck(*new_symbol, symbol_table, message_handler); + + return verilog_typecheck.typecheck_main(); +#endif + } + + return false; +} diff --git a/src/verilog/verilog_typecheck.h b/src/verilog/verilog_typecheck.h index 253b32c3..5279f812 100644 --- a/src/verilog/verilog_typecheck.h +++ b/src/verilog/verilog_typecheck.h @@ -19,6 +19,11 @@ Author: Daniel Kroening, kroening@kroening.com #include "verilog_symbol_table.h" #include "verilog_typecheck_expr.h" +bool verilog_typecheck_package_items( + const verilog_parse_treet &, + symbol_table_baset &, + message_handlert &); + bool verilog_typecheck( const verilog_parse_treet &parse_tree, symbol_table_baset &,