19ed2e68cSsstwcw //===- unittest/Format/FormatTestVerilog.cpp ------------------------------===//
29ed2e68cSsstwcw //
39ed2e68cSsstwcw // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
49ed2e68cSsstwcw // See https://llvm.org/LICENSE.txt for license information.
59ed2e68cSsstwcw // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69ed2e68cSsstwcw //
79ed2e68cSsstwcw //===----------------------------------------------------------------------===//
89ed2e68cSsstwcw 
99ed2e68cSsstwcw #include "FormatTestUtils.h"
109ed2e68cSsstwcw #include "clang/Format/Format.h"
119ed2e68cSsstwcw #include "llvm/Support/Debug.h"
129ed2e68cSsstwcw #include "gtest/gtest.h"
139ed2e68cSsstwcw 
149ed2e68cSsstwcw #define DEBUG_TYPE "format-test"
159ed2e68cSsstwcw 
169ed2e68cSsstwcw namespace clang {
179ed2e68cSsstwcw namespace format {
189ed2e68cSsstwcw 
199ed2e68cSsstwcw class FormatTestVerilog : public ::testing::Test {
209ed2e68cSsstwcw protected:
format(llvm::StringRef Code,unsigned Offset,unsigned Length,const FormatStyle & Style)219ed2e68cSsstwcw   static std::string format(llvm::StringRef Code, unsigned Offset,
229ed2e68cSsstwcw                             unsigned Length, const FormatStyle &Style) {
239ed2e68cSsstwcw     LLVM_DEBUG(llvm::errs() << "---\n");
249ed2e68cSsstwcw     LLVM_DEBUG(llvm::errs() << Code << "\n\n");
259ed2e68cSsstwcw     std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
269ed2e68cSsstwcw     tooling::Replacements Replaces = reformat(Style, Code, Ranges);
279ed2e68cSsstwcw     auto Result = applyAllReplacements(Code, Replaces);
289ed2e68cSsstwcw     EXPECT_TRUE(static_cast<bool>(Result));
299ed2e68cSsstwcw     LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
309ed2e68cSsstwcw     return *Result;
319ed2e68cSsstwcw   }
329ed2e68cSsstwcw 
33*2e32ff10Ssstwcw   static std::string
format(llvm::StringRef Code,const FormatStyle & Style=getLLVMStyle (FormatStyle::LK_Verilog))34*2e32ff10Ssstwcw   format(llvm::StringRef Code,
35*2e32ff10Ssstwcw          const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Verilog)) {
369ed2e68cSsstwcw     return format(Code, 0, Code.size(), Style);
379ed2e68cSsstwcw   }
389ed2e68cSsstwcw 
verifyFormat(llvm::StringRef Code,const FormatStyle & Style=getLLVMStyle (FormatStyle::LK_Verilog))399ed2e68cSsstwcw   static void verifyFormat(
409ed2e68cSsstwcw       llvm::StringRef Code,
419ed2e68cSsstwcw       const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Verilog)) {
429ed2e68cSsstwcw     EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
439ed2e68cSsstwcw     EXPECT_EQ(Code.str(),
449ed2e68cSsstwcw               format(test::messUp(Code, /*HandleHash=*/false), Style));
459ed2e68cSsstwcw   }
469ed2e68cSsstwcw };
479ed2e68cSsstwcw 
TEST_F(FormatTestVerilog,Delay)48*2e32ff10Ssstwcw TEST_F(FormatTestVerilog, Delay) {
49*2e32ff10Ssstwcw   // Delay by the default unit.
50*2e32ff10Ssstwcw   verifyFormat("#0;");
51*2e32ff10Ssstwcw   verifyFormat("#1;");
52*2e32ff10Ssstwcw   verifyFormat("#10;");
53*2e32ff10Ssstwcw   verifyFormat("#1.5;");
54*2e32ff10Ssstwcw   // Explicit unit.
55*2e32ff10Ssstwcw   verifyFormat("#1fs;");
56*2e32ff10Ssstwcw   verifyFormat("#1.5fs;");
57*2e32ff10Ssstwcw   verifyFormat("#1ns;");
58*2e32ff10Ssstwcw   verifyFormat("#1.5ns;");
59*2e32ff10Ssstwcw   verifyFormat("#1us;");
60*2e32ff10Ssstwcw   verifyFormat("#1.5us;");
61*2e32ff10Ssstwcw   verifyFormat("#1ms;");
62*2e32ff10Ssstwcw   verifyFormat("#1.5ms;");
63*2e32ff10Ssstwcw   verifyFormat("#1s;");
64*2e32ff10Ssstwcw   verifyFormat("#1.5s;");
65*2e32ff10Ssstwcw   // The following expression should be on the same line.
66*2e32ff10Ssstwcw   verifyFormat("#1 x = x;");
67*2e32ff10Ssstwcw   EXPECT_EQ("#1 x = x;", format("#1\n"
68*2e32ff10Ssstwcw                                 "x = x;"));
69*2e32ff10Ssstwcw }
70*2e32ff10Ssstwcw 
TEST_F(FormatTestVerilog,If)719ed2e68cSsstwcw TEST_F(FormatTestVerilog, If) {
729ed2e68cSsstwcw   verifyFormat("if (x)\n"
739ed2e68cSsstwcw                "  x = x;");
749ed2e68cSsstwcw   verifyFormat("if (x)\n"
759ed2e68cSsstwcw                "  x = x;\n"
769ed2e68cSsstwcw                "x = x;");
779ed2e68cSsstwcw 
789ed2e68cSsstwcw   // Test else
799ed2e68cSsstwcw   verifyFormat("if (x)\n"
809ed2e68cSsstwcw                "  x = x;\n"
819ed2e68cSsstwcw                "else if (x)\n"
829ed2e68cSsstwcw                "  x = x;\n"
839ed2e68cSsstwcw                "else\n"
849ed2e68cSsstwcw                "  x = x;");
859ed2e68cSsstwcw   verifyFormat("if (x) begin\n"
869ed2e68cSsstwcw                "  x = x;\n"
879ed2e68cSsstwcw                "end else if (x) begin\n"
889ed2e68cSsstwcw                "  x = x;\n"
899ed2e68cSsstwcw                "end else begin\n"
909ed2e68cSsstwcw                "  x = x;\n"
919ed2e68cSsstwcw                "end");
929ed2e68cSsstwcw   verifyFormat("if (x) begin : x\n"
939ed2e68cSsstwcw                "  x = x;\n"
949ed2e68cSsstwcw                "end : x else if (x) begin : x\n"
959ed2e68cSsstwcw                "  x = x;\n"
969ed2e68cSsstwcw                "end : x else begin : x\n"
979ed2e68cSsstwcw                "  x = x;\n"
989ed2e68cSsstwcw                "end : x");
999ed2e68cSsstwcw 
1009ed2e68cSsstwcw   // Test block keywords.
1019ed2e68cSsstwcw   verifyFormat("if (x) begin\n"
1029ed2e68cSsstwcw                "  x = x;\n"
1039ed2e68cSsstwcw                "end");
1049ed2e68cSsstwcw   verifyFormat("if (x) begin : x\n"
1059ed2e68cSsstwcw                "  x = x;\n"
1069ed2e68cSsstwcw                "end : x");
1079ed2e68cSsstwcw   verifyFormat("if (x) begin\n"
1089ed2e68cSsstwcw                "  x = x;\n"
1099ed2e68cSsstwcw                "  x = x;\n"
1109ed2e68cSsstwcw                "end");
1119ed2e68cSsstwcw   verifyFormat("disable fork;\n"
1129ed2e68cSsstwcw                "x = x;");
1139ed2e68cSsstwcw   verifyFormat("rand join x x;\n"
1149ed2e68cSsstwcw                "x = x;");
1159ed2e68cSsstwcw   verifyFormat("if (x) fork\n"
1169ed2e68cSsstwcw                "  x = x;\n"
1179ed2e68cSsstwcw                "join");
1189ed2e68cSsstwcw   verifyFormat("if (x) fork\n"
1199ed2e68cSsstwcw                "  x = x;\n"
1209ed2e68cSsstwcw                "join_any");
1219ed2e68cSsstwcw   verifyFormat("if (x) fork\n"
1229ed2e68cSsstwcw                "  x = x;\n"
1239ed2e68cSsstwcw                "join_none");
1249ed2e68cSsstwcw   verifyFormat("if (x) generate\n"
1259ed2e68cSsstwcw                "  x = x;\n"
1269ed2e68cSsstwcw                "endgenerate");
1279ed2e68cSsstwcw   verifyFormat("if (x) generate : x\n"
1289ed2e68cSsstwcw                "  x = x;\n"
1299ed2e68cSsstwcw                "endgenerate : x");
1309ed2e68cSsstwcw 
1319ed2e68cSsstwcw   // Test that concatenation braces don't get regarded as blocks.
1329ed2e68cSsstwcw   verifyFormat("if (x)\n"
1339ed2e68cSsstwcw                "  {x} = x;");
1349ed2e68cSsstwcw   verifyFormat("if (x)\n"
1359ed2e68cSsstwcw                "  x = {x};");
1369ed2e68cSsstwcw   verifyFormat("if (x)\n"
1379ed2e68cSsstwcw                "  x = {x};\n"
1389ed2e68cSsstwcw                "else\n"
1399ed2e68cSsstwcw                "  {x} = {x};");
1409ed2e68cSsstwcw }
1419ed2e68cSsstwcw 
TEST_F(FormatTestVerilog,Preprocessor)142*2e32ff10Ssstwcw TEST_F(FormatTestVerilog, Preprocessor) {
143*2e32ff10Ssstwcw   auto Style = getLLVMStyle(FormatStyle::LK_Verilog);
144*2e32ff10Ssstwcw   Style.ColumnLimit = 20;
145*2e32ff10Ssstwcw 
146*2e32ff10Ssstwcw   // Macro definitions.
147*2e32ff10Ssstwcw   EXPECT_EQ("`define X          \\\n"
148*2e32ff10Ssstwcw             "  if (x)           \\\n"
149*2e32ff10Ssstwcw             "    x = x;",
150*2e32ff10Ssstwcw             format("`define X if(x)x=x;", Style));
151*2e32ff10Ssstwcw   EXPECT_EQ("`define X(x)       \\\n"
152*2e32ff10Ssstwcw             "  if (x)           \\\n"
153*2e32ff10Ssstwcw             "    x = x;",
154*2e32ff10Ssstwcw             format("`define X(x) if(x)x=x;", Style));
155*2e32ff10Ssstwcw   EXPECT_EQ("`define X          \\\n"
156*2e32ff10Ssstwcw             "  x = x;           \\\n"
157*2e32ff10Ssstwcw             "  x = x;",
158*2e32ff10Ssstwcw             format("`define X x=x;x=x;", Style));
159*2e32ff10Ssstwcw   // Macro definitions with invocations inside.
160*2e32ff10Ssstwcw   EXPECT_EQ("`define LIST       \\\n"
161*2e32ff10Ssstwcw             "  `ENTRY           \\\n"
162*2e32ff10Ssstwcw             "  `ENTRY",
163*2e32ff10Ssstwcw             format("`define LIST \\\n"
164*2e32ff10Ssstwcw                    "`ENTRY \\\n"
165*2e32ff10Ssstwcw                    "`ENTRY",
166*2e32ff10Ssstwcw                    Style));
167*2e32ff10Ssstwcw   EXPECT_EQ("`define LIST       \\\n"
168*2e32ff10Ssstwcw             "  `x = `x;         \\\n"
169*2e32ff10Ssstwcw             "  `x = `x;",
170*2e32ff10Ssstwcw             format("`define LIST \\\n"
171*2e32ff10Ssstwcw                    "`x = `x; \\\n"
172*2e32ff10Ssstwcw                    "`x = `x;",
173*2e32ff10Ssstwcw                    Style));
174*2e32ff10Ssstwcw   EXPECT_EQ("`define LIST       \\\n"
175*2e32ff10Ssstwcw             "  `x = `x;         \\\n"
176*2e32ff10Ssstwcw             "  `x = `x;",
177*2e32ff10Ssstwcw             format("`define LIST `x=`x;`x=`x;", Style));
178*2e32ff10Ssstwcw   // Macro invocations.
179*2e32ff10Ssstwcw   verifyFormat("`x = (`x1 + `x2 + x);");
180*2e32ff10Ssstwcw   // Lines starting with a preprocessor directive should not be indented.
181*2e32ff10Ssstwcw   std::string Directives[] = {
182*2e32ff10Ssstwcw       "begin_keywords",
183*2e32ff10Ssstwcw       "celldefine",
184*2e32ff10Ssstwcw       "default_nettype",
185*2e32ff10Ssstwcw       "define",
186*2e32ff10Ssstwcw       "else",
187*2e32ff10Ssstwcw       "elsif",
188*2e32ff10Ssstwcw       "end_keywords",
189*2e32ff10Ssstwcw       "endcelldefine",
190*2e32ff10Ssstwcw       "endif",
191*2e32ff10Ssstwcw       "ifdef",
192*2e32ff10Ssstwcw       "ifndef",
193*2e32ff10Ssstwcw       "include",
194*2e32ff10Ssstwcw       "line",
195*2e32ff10Ssstwcw       "nounconnected_drive",
196*2e32ff10Ssstwcw       "pragma",
197*2e32ff10Ssstwcw       "resetall",
198*2e32ff10Ssstwcw       "timescale",
199*2e32ff10Ssstwcw       "unconnected_drive",
200*2e32ff10Ssstwcw       "undef",
201*2e32ff10Ssstwcw       "undefineall",
202*2e32ff10Ssstwcw   };
203*2e32ff10Ssstwcw   for (auto &Name : Directives) {
204*2e32ff10Ssstwcw     EXPECT_EQ("if (x)\n"
205*2e32ff10Ssstwcw               "`" +
206*2e32ff10Ssstwcw                   Name +
207*2e32ff10Ssstwcw                   "\n"
208*2e32ff10Ssstwcw                   "  ;",
209*2e32ff10Ssstwcw               format("if (x)\n"
210*2e32ff10Ssstwcw                      "`" +
211*2e32ff10Ssstwcw                          Name +
212*2e32ff10Ssstwcw                          "\n"
213*2e32ff10Ssstwcw                          ";",
214*2e32ff10Ssstwcw                      Style));
215*2e32ff10Ssstwcw   }
216*2e32ff10Ssstwcw   // Lines starting with a regular macro invocation should be indented as a
217*2e32ff10Ssstwcw   // normal line.
218*2e32ff10Ssstwcw   EXPECT_EQ("if (x)\n"
219*2e32ff10Ssstwcw             "  `x = `x;\n"
220*2e32ff10Ssstwcw             "`timescale 1ns / 1ps",
221*2e32ff10Ssstwcw             format("if (x)\n"
222*2e32ff10Ssstwcw                    "`x = `x;\n"
223*2e32ff10Ssstwcw                    "`timescale 1ns / 1ps",
224*2e32ff10Ssstwcw                    Style));
225*2e32ff10Ssstwcw   EXPECT_EQ("if (x)\n"
226*2e32ff10Ssstwcw             "`timescale 1ns / 1ps\n"
227*2e32ff10Ssstwcw             "  `x = `x;",
228*2e32ff10Ssstwcw             format("if (x)\n"
229*2e32ff10Ssstwcw                    "`timescale 1ns / 1ps\n"
230*2e32ff10Ssstwcw                    "`x = `x;",
231*2e32ff10Ssstwcw                    Style));
232*2e32ff10Ssstwcw   std::string NonDirectives[] = {
233*2e32ff10Ssstwcw       // For `__FILE__` and `__LINE__`, although the standard classifies them as
234*2e32ff10Ssstwcw       // preprocessor directives, they are used like regular macros.
235*2e32ff10Ssstwcw       "__FILE__", "__LINE__", "elif", "foo", "x",
236*2e32ff10Ssstwcw   };
237*2e32ff10Ssstwcw   for (auto &Name : NonDirectives) {
238*2e32ff10Ssstwcw     EXPECT_EQ("if (x)\n"
239*2e32ff10Ssstwcw               "  `" +
240*2e32ff10Ssstwcw                   Name + ";",
241*2e32ff10Ssstwcw               format("if (x)\n"
242*2e32ff10Ssstwcw                      "`" +
243*2e32ff10Ssstwcw                          Name +
244*2e32ff10Ssstwcw                          "\n"
245*2e32ff10Ssstwcw                          ";",
246*2e32ff10Ssstwcw                      Style));
247*2e32ff10Ssstwcw   }
248*2e32ff10Ssstwcw }
249*2e32ff10Ssstwcw 
2509ed2e68cSsstwcw } // namespace format
2519ed2e68cSsstwcw } // end namespace clang
252