Merge pull request #1575 from antmicro/msrs/fix-kdpiexportitem
Add a size check before merging leaves in kDPIImportItem/kDPIExportItem
diff --git a/WORKSPACE b/WORKSPACE
index 8cea500..dcbc98d 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -126,10 +126,10 @@
# A version slightly beyond 21.5 as it fixes a warning
http_archive(
name = "com_google_protobuf",
- sha256 = "efcd93bb1a228d08b4b0fcda00e710592fdf17ce6d0f5c8a239c2db0ba268a3f",
- strip_prefix = "protobuf-4efbcc44605731dc31507b94f0b81d2bd5ec169b",
+ sha256 = "6a31b662deaeb0ac35e6287bda2f3369b19836e6c9f8828d4da444346f420298",
+ strip_prefix = "protobuf-21.12",
urls = [
- "https://github.com/protocolbuffers/protobuf/archive/4efbcc44605731dc31507b94f0b81d2bd5ec169b.zip",
+ "https://github.com/protocolbuffers/protobuf/archive/refs/tags/v21.12.zip",
],
)
diff --git a/verilog/CST/port.cc b/verilog/CST/port.cc
index a968523..eed3ea9 100644
--- a/verilog/CST/port.cc
+++ b/verilog/CST/port.cc
@@ -32,7 +32,7 @@
using verible::Symbol;
using verible::SyntaxTreeLeaf;
-std::vector<verible::TreeSearchMatch> FindAllModulePortDeclarations(
+std::vector<verible::TreeSearchMatch> FindAllPortDeclarations(
const Symbol& root) {
return SearchSyntaxTree(root, NodekPortDeclaration());
}
@@ -52,16 +52,14 @@
return SearchSyntaxTree(root, NodekPortItem());
}
-const SyntaxTreeLeaf* GetIdentifierFromModulePortDeclaration(
- const Symbol& symbol) {
+const SyntaxTreeLeaf* GetIdentifierFromPortDeclaration(const Symbol& symbol) {
const auto* identifier_symbol =
verible::GetSubtreeAsSymbol(symbol, NodeEnum::kPortDeclaration, 3);
if (!identifier_symbol) return nullptr;
return AutoUnwrapIdentifier(*identifier_symbol);
}
-const SyntaxTreeLeaf* GetDirectionFromModulePortDeclaration(
- const Symbol& symbol) {
+const SyntaxTreeLeaf* GetDirectionFromPortDeclaration(const Symbol& symbol) {
if (const auto* dir_symbol =
GetSubtreeAsSymbol(symbol, NodeEnum::kPortDeclaration, 0)) {
return &SymbolCastToLeaf(*dir_symbol);
@@ -69,6 +67,35 @@
return nullptr;
}
+std::vector<verible::TreeSearchMatch> FindAllModulePortDeclarations(
+ const verible::Symbol& root) {
+ return SearchSyntaxTree(root, NodekModulePortDeclaration());
+}
+
+const verible::SyntaxTreeLeaf* GetIdentifierFromModulePortDeclaration(
+ const verible::Symbol& symbol) {
+ auto& node = SymbolCastToNode(symbol);
+ if (!MatchNodeEnumOrNull(node, NodeEnum::kModulePortDeclaration))
+ return nullptr;
+ auto id_unpacked_dims = FindAllIdentifierUnpackedDimensions(symbol);
+ if (id_unpacked_dims.empty()) return nullptr;
+ if (id_unpacked_dims.size() > 1) {
+ LOG(ERROR) << "Expected one identifier node in port declaration, but got "
+ << id_unpacked_dims.size();
+ }
+ return GetSymbolIdentifierFromIdentifierUnpackedDimensions(
+ *id_unpacked_dims.front().match);
+}
+
+const verible::SyntaxTreeLeaf* GetDirectionFromModulePortDeclaration(
+ const verible::Symbol& symbol) {
+ if (const auto* dir_symbol =
+ GetSubtreeAsSymbol(symbol, NodeEnum::kModulePortDeclaration, 0)) {
+ return &SymbolCastToLeaf(*dir_symbol);
+ }
+ return nullptr;
+}
+
const verible::SyntaxTreeLeaf* GetIdentifierFromPortReference(
const verible::Symbol& port_reference) {
const auto* identifier_symbol =
diff --git a/verilog/CST/port.h b/verilog/CST/port.h
index ef1e3be..7ff13af 100644
--- a/verilog/CST/port.h
+++ b/verilog/CST/port.h
@@ -29,8 +29,8 @@
namespace verilog {
-// Find all individual module port declarations.
-std::vector<verible::TreeSearchMatch> FindAllModulePortDeclarations(
+// Find all individual port declarations.
+std::vector<verible::TreeSearchMatch> FindAllPortDeclarations(
const verible::Symbol&);
// Find all nodes tagged with kPort.
@@ -41,12 +41,24 @@
std::vector<verible::TreeSearchMatch> FindAllActualNamedPort(
const verible::Symbol&);
-// Extract the name of the module port identifier from a port declaration.
-const verible::SyntaxTreeLeaf* GetIdentifierFromModulePortDeclaration(
+// Extract the name of the port identifier from a port declaration.
+const verible::SyntaxTreeLeaf* GetIdentifierFromPortDeclaration(
const verible::Symbol&);
// Extract the direction from a port declaration.
// Can return nullptr if the direction is not explicitly specified.
+const verible::SyntaxTreeLeaf* GetDirectionFromPortDeclaration(
+ const verible::Symbol&);
+
+// Find all individual module port declarations.
+std::vector<verible::TreeSearchMatch> FindAllModulePortDeclarations(
+ const verible::Symbol&);
+
+// Extract the name of the module port identifier from a port declaration.
+const verible::SyntaxTreeLeaf* GetIdentifierFromModulePortDeclaration(
+ const verible::Symbol&);
+
+// Extract the direction from a module port declaration.
const verible::SyntaxTreeLeaf* GetDirectionFromModulePortDeclaration(
const verible::Symbol&);
diff --git a/verilog/CST/port_test.cc b/verilog/CST/port_test.cc
index 9cb7ab6..b4c9617 100644
--- a/verilog/CST/port_test.cc
+++ b/verilog/CST/port_test.cc
@@ -55,6 +55,135 @@
using verible::TreeSearchMatch;
// Tests that no ports are found from an empty source.
+TEST(FindAllPortDeclarationsTest, EmptySource) {
+ VerilogAnalyzer analyzer("", "");
+ ASSERT_OK(analyzer.Analyze());
+ const auto& root = analyzer.Data().SyntaxTree();
+ const auto port_declarations =
+ FindAllPortDeclarations(*ABSL_DIE_IF_NULL(root));
+ EXPECT_TRUE(port_declarations.empty());
+}
+
+// Tests that no ports are found in port-less module.
+TEST(FindAllPortDeclarationsTest, NonPort) {
+ VerilogAnalyzer analyzer("module foo; endmodule", "");
+ ASSERT_OK(analyzer.Analyze());
+ const auto& root = analyzer.Data().SyntaxTree();
+ const auto port_declarations =
+ FindAllPortDeclarations(*ABSL_DIE_IF_NULL(root));
+ EXPECT_TRUE(port_declarations.empty());
+}
+
+// Tests that a package-item net declaration is not a port.
+TEST(FindAllPortDeclarationsTest, OneWire) {
+ VerilogAnalyzer analyzer("wire w;", "");
+ ASSERT_OK(analyzer.Analyze());
+ const auto& root = analyzer.Data().SyntaxTree();
+ const auto port_declarations =
+ FindAllPortDeclarations(*ABSL_DIE_IF_NULL(root));
+ EXPECT_TRUE(port_declarations.empty());
+}
+
+// Tests that a local wire inside a module is not a port.
+TEST(FindAllPortDeclarationsTest, OneWireInModule) {
+ VerilogAnalyzer analyzer("module m; wire w; endmodule", "");
+ ASSERT_OK(analyzer.Analyze());
+ const auto& root = analyzer.Data().SyntaxTree();
+ const auto port_declarations =
+ FindAllPortDeclarations(*ABSL_DIE_IF_NULL(root));
+ EXPECT_TRUE(port_declarations.empty());
+}
+
+// Tests that a port wire inside a module is found.
+TEST(FindAllPortDeclarationsTest, OnePortInModule) {
+ const char* kTestCases[] = {
+ "logic l",
+ "wire w",
+ "input w",
+ "input [1:0] w",
+ "input w [0:1]",
+ "input w [6]",
+ "input [7:0] w [6]",
+ "input wire w",
+ "reg r",
+ "output r",
+ "output reg r",
+ "output reg [1:0] r",
+ "output reg r [0:3]",
+ "output reg [1:0] r [0:3]",
+ };
+ for (auto test : kTestCases) {
+ VerilogAnalyzer analyzer(absl::StrCat("module m(", test, "); endmodule"),
+ "");
+ ASSERT_OK(analyzer.Analyze());
+ const auto& root = analyzer.Data().SyntaxTree();
+ const auto port_declarations =
+ FindAllPortDeclarations(*ABSL_DIE_IF_NULL(root));
+ EXPECT_EQ(port_declarations.size(), 1);
+ const auto& decl = port_declarations.front();
+ EXPECT_TRUE(decl.context.IsInside(NodeEnum::kModuleDeclaration));
+ }
+}
+
+TEST(GetIdentifierFromPortDeclarationTest, VariousPorts) {
+ constexpr int kTag = 1; // don't care
+ const SyntaxTreeSearchTestCase kTestCases[] = {
+ {"module foo(input ", {kTag, "bar"}, "); endmodule"},
+ {"module foo(input logic ", {kTag, "b_a_r"}, "); endmodule"},
+ {"module foo(input wire ", {kTag, "hello_world"}, " = 1); endmodule"},
+ {"module foo(wire ", {kTag, "hello_world1"}, " = 1); endmodule"},
+ {"module foo(input logic [3:0] ", {kTag, "bar2"}, "); endmodule"},
+ {"module foo(input logic ", {kTag, "b_a_r"}, " [3:0]); endmodule"},
+ {"module foo(input logic ", {kTag, "bar"}, " [4]); endmodule"},
+ // multiple ports
+ {"module foo(input ",
+ {kTag, "bar"},
+ ", output ",
+ {kTag, "bar2"},
+ "); endmodule"},
+ {"module foo(input logic ",
+ {kTag, "bar"},
+ ", input wire ",
+ {kTag, "bar2"},
+ "); endmodule"},
+ {"module foo(input logic ",
+ {kTag, "bar"},
+ ", output ",
+ {kTag, "bar2"},
+ "); endmodule"},
+ {"module foo(wire ",
+ {kTag, "bar"},
+ ", wire ",
+ {kTag, "bar2"},
+ " = 1); endmodule"},
+ {"module foo(input logic [3:0] ",
+ {kTag, "bar"},
+ ", input logic ",
+ {kTag, "bar2"},
+ " [4]); endmodule"},
+ {"module foo(input logic ",
+ {kTag, "bar"},
+ " [3:0], input logic [3:0] ",
+ {kTag, "bar2"},
+ "); endmodule"},
+ };
+ for (const auto& test : kTestCases) {
+ TestVerilogSyntaxRangeMatches(
+ __FUNCTION__, test, [](const TextStructureView& text_structure) {
+ const auto& root = text_structure.SyntaxTree();
+ const auto port_declarations = FindAllPortDeclarations(*root);
+ std::vector<TreeSearchMatch> ids;
+ for (const auto& port : port_declarations) {
+ const auto* identifier_leaf =
+ GetIdentifierFromPortDeclaration(*port.match);
+ ids.push_back(TreeSearchMatch{identifier_leaf, /* no context */});
+ }
+ return ids;
+ });
+ }
+}
+
+// Tests that no ports are found from an empty source.
TEST(FindAllModulePortDeclarationsTest, EmptySource) {
VerilogAnalyzer analyzer("", "");
ASSERT_OK(analyzer.Analyze());
@@ -97,23 +226,12 @@
// Tests that a port wire inside a module is found.
TEST(FindAllModulePortDeclarationsTest, OnePortInModule) {
const char* kTestCases[] = {
- "logic l",
- "wire w",
- "input w",
- "input [1:0] w",
- "input w [0:1]",
- "input w [6]",
- "input [7:0] w [6]",
- "input wire w",
- "reg r",
- "output r",
- "output reg r",
- "output reg [1:0] r",
- "output reg r [0:3]",
- "output reg [1:0] r [0:3]",
+ "input p", "input [1:0] p", "input p [0:1]",
+ "input p [6]", "input [7:0] p [6]", "input wire p",
+ "output p", "output reg p", "output reg [1:0] p",
};
for (auto test : kTestCases) {
- VerilogAnalyzer analyzer(absl::StrCat("module m(", test, "); endmodule"),
+ VerilogAnalyzer analyzer(absl::StrCat("module m(p); ", test, "; endmodule"),
"");
ASSERT_OK(analyzer.Analyze());
const auto& root = analyzer.Data().SyntaxTree();
@@ -128,44 +246,37 @@
TEST(GetIdentifierFromModulePortDeclarationTest, VariousPorts) {
constexpr int kTag = 1; // don't care
const SyntaxTreeSearchTestCase kTestCases[] = {
- {"module foo(input ", {kTag, "bar"}, "); endmodule"},
- {"module foo(input logic ", {kTag, "b_a_r"}, "); endmodule"},
- {"module foo(input wire ", {kTag, "hello_world"}, " = 1); endmodule"},
- {"module foo(wire ", {kTag, "hello_world1"}, " = 1); endmodule"},
- {"module foo(input logic [3:0] ", {kTag, "bar2"}, "); endmodule"},
- {"module foo(input logic ", {kTag, "b_a_r"}, " [3:0]); endmodule"},
- {"module foo(input logic ", {kTag, "bar"}, " [4]); endmodule"},
+ {"module foo(bar); input ", {kTag, "bar"}, "; endmodule"},
+ {"module foo(b_a_r); input logic ", {kTag, "b_a_r"}, "; endmodule"},
+ {"module foo(bar2); input logic [3:0] ", {kTag, "bar2"}, "; endmodule"},
+ {"module foo(b_a_r); input logic ", {kTag, "b_a_r"}, " [3:0]; endmodule"},
+ {"module foo(bar); input logic ", {kTag, "bar"}, " [4]; endmodule"},
// multiple ports
- {"module foo(input ",
+ {"module foo(bar, bar2); input ",
{kTag, "bar"},
- ", output ",
+ "; output ",
{kTag, "bar2"},
- "); endmodule"},
- {"module foo(input logic ",
+ "; endmodule"},
+ {"module foo(bar, bar2); input logic ",
{kTag, "bar"},
- ", input wire ",
+ "; input wire ",
{kTag, "bar2"},
- "); endmodule"},
- {"module foo(input logic ",
+ "; endmodule"},
+ {"module foo(bar, bar2); input logic ",
{kTag, "bar"},
- ", output ",
+ "; output ",
{kTag, "bar2"},
- "); endmodule"},
- {"module foo(wire ",
+ "; endmodule"},
+ {"module foo(bar, bar2); input logic [3:0] ",
{kTag, "bar"},
- ", wire ",
+ "; input logic ",
{kTag, "bar2"},
- " = 1); endmodule"},
- {"module foo(input logic [3:0] ",
+ " [4]; endmodule"},
+ {"module foo(bar, bar2); input logic ",
{kTag, "bar"},
- ", input logic ",
+ " [3:0]; input logic [3:0] ",
{kTag, "bar2"},
- " [4]); endmodule"},
- {"module foo(input logic ",
- {kTag, "bar"},
- " [3:0], input logic [3:0] ",
- {kTag, "bar2"},
- "); endmodule"},
+ "; endmodule"},
};
for (const auto& test : kTestCases) {
TestVerilogSyntaxRangeMatches(
@@ -422,13 +533,12 @@
TestVerilogSyntaxRangeMatches(
__FUNCTION__, test, [](const TextStructureView& text_structure) {
const auto& root = text_structure.SyntaxTree();
- const auto& ports =
- FindAllModulePortDeclarations(*ABSL_DIE_IF_NULL(root));
+ const auto& ports = FindAllPortDeclarations(*ABSL_DIE_IF_NULL(root));
std::vector<TreeSearchMatch> directions;
for (const auto& port : ports) {
const auto* direction =
- GetDirectionFromModulePortDeclaration(*port.match);
+ GetDirectionFromPortDeclaration(*port.match);
directions.emplace_back(
TreeSearchMatch{(const verible::Symbol*)direction, {}});
}
diff --git a/verilog/analysis/checkers/port_name_suffix_rule.cc b/verilog/analysis/checkers/port_name_suffix_rule.cc
index 242c6e1..eb946e0 100644
--- a/verilog/analysis/checkers/port_name_suffix_rule.cc
+++ b/verilog/analysis/checkers/port_name_suffix_rule.cc
@@ -103,9 +103,8 @@
constexpr absl::string_view implicit_direction = "input";
verible::matcher::BoundSymbolManager manager;
if (PortMatcher().Matches(symbol, &manager)) {
- const auto* identifier_leaf =
- GetIdentifierFromModulePortDeclaration(symbol);
- const auto* direction_leaf = GetDirectionFromModulePortDeclaration(symbol);
+ const auto* identifier_leaf = GetIdentifierFromPortDeclaration(symbol);
+ const auto* direction_leaf = GetDirectionFromPortDeclaration(symbol);
const auto token = identifier_leaf->get();
const auto direction =
direction_leaf ? direction_leaf->get().text() : implicit_direction;
diff --git a/verilog/analysis/checkers/signal_name_style_rule.cc b/verilog/analysis/checkers/signal_name_style_rule.cc
index 04e5b48..2bb57d5 100644
--- a/verilog/analysis/checkers/signal_name_style_rule.cc
+++ b/verilog/analysis/checkers/signal_name_style_rule.cc
@@ -79,8 +79,7 @@
const SyntaxTreeContext& context) {
verible::matcher::BoundSymbolManager manager;
if (PortMatcher().Matches(symbol, &manager)) {
- const auto* identifier_leaf =
- GetIdentifierFromModulePortDeclaration(symbol);
+ const auto* identifier_leaf = GetIdentifierFromPortDeclaration(symbol);
const auto name = ABSL_DIE_IF_NULL(identifier_leaf)->get().text();
if (!verible::IsLowerSnakeCaseWithDigits(name))
violations_.insert(
diff --git a/verilog/formatting/formatter_test.cc b/verilog/formatting/formatter_test.cc
index 3898644..bf0d06b 100644
--- a/verilog/formatting/formatter_test.cc
+++ b/verilog/formatting/formatter_test.cc
@@ -5518,6 +5518,43 @@
" );\n"
"endmodule\n"},
+ {// comment following a delay in next line
+ "module t;\n"
+ "reg x;\n"
+ "initial begin\n"
+ "#20\n"
+ "//comment\n"
+ "x = 1;\n"
+ "x = 2;\n"
+ "end\n"
+ "endmodule\n",
+ "module t;\n"
+ " reg x;\n"
+ " initial begin\n"
+ " #20\n"
+ " //comment\n"
+ " x = 1;\n"
+ " x = 2;\n"
+ " end\n"
+ "endmodule\n"},
+ {// comment following a delay in the same line
+ "module t;\n"
+ "reg x;\n"
+ "initial begin\n"
+ "#20 //comment\n"
+ "x = 1;\n"
+ "x = 2;\n"
+ "end\n"
+ "endmodule\n",
+ "module t;\n"
+ " reg x;\n"
+ " initial begin\n"
+ " #20 //comment\n"
+ " x = 1;\n"
+ " x = 2;\n"
+ " end\n"
+ "endmodule\n"},
+
{
// test that alternate top-syntax mode works
"// verilog_syntax: parse-as-module-body\n"
diff --git a/verilog/formatting/tree_unwrapper.cc b/verilog/formatting/tree_unwrapper.cc
index a2b1f1e..d353806 100644
--- a/verilog/formatting/tree_unwrapper.cc
+++ b/verilog/formatting/tree_unwrapper.cc
@@ -971,9 +971,11 @@
{
// Single statements directly inside a flow-control construct
// should be properly indented one level.
- const int indent = ShouldIndentRelativeToDirectParent(Context())
- ? style_.indentation_spaces
- : 0;
+ const int indent = Context().IsInside(NodeEnum::kBlockItemStatementList)
+ ? 0
+ : ShouldIndentRelativeToDirectParent(Context())
+ ? style_.indentation_spaces
+ : 0;
VisitIndentedSection(node, indent,
PartitionPolicyEnum::kFitOnLineElseExpand);
break;
@@ -2876,7 +2878,8 @@
// RHS may have been further partitioned, e.g. a macro call.
auto& children = partition.Children();
if (children.size() == 2 &&
- verible::is_leaf(children.front()) /* left side */) {
+ verible::is_leaf(children.front()) /* left side */ &&
+ !PartitionIsForcedIntoNewLine(children.back())) {
verible::MergeLeafIntoNextLeaf(&children.front());
VLOG(4) << "after merge leaf (left-into-right):\n" << partition;
}
diff --git a/verilog/tools/kythe/indexing_facts_tree_extractor.cc b/verilog/tools/kythe/indexing_facts_tree_extractor.cc
index d325fd7..9dfb647 100644
--- a/verilog/tools/kythe/indexing_facts_tree_extractor.cc
+++ b/verilog/tools/kythe/indexing_facts_tree_extractor.cc
@@ -753,7 +753,7 @@
// module m(input a, input b);
if (tag == NodeEnum::kPortDeclaration) {
const SyntaxTreeLeaf* leaf =
- GetIdentifierFromModulePortDeclaration(module_port_node);
+ GetIdentifierFromPortDeclaration(module_port_node);
if (!leaf) return;
facts_tree_context_.top().Children().emplace_back(