1 //===- unittest/Format/FormatTestVerilog.cpp ------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "FormatTestUtils.h"
10 #include "clang/Format/Format.h"
11 #include "llvm/Support/Debug.h"
12 #include "gtest/gtest.h"
13 
14 #define DEBUG_TYPE "format-test"
15 
16 namespace clang {
17 namespace format {
18 
19 class FormatTestVerilog : public ::testing::Test {
20 protected:
format(llvm::StringRef Code,unsigned Offset,unsigned Length,const FormatStyle & Style)21   static std::string format(llvm::StringRef Code, unsigned Offset,
22                             unsigned Length, const FormatStyle &Style) {
23     LLVM_DEBUG(llvm::errs() << "---\n");
24     LLVM_DEBUG(llvm::errs() << Code << "\n\n");
25     std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
26     tooling::Replacements Replaces = reformat(Style, Code, Ranges);
27     auto Result = applyAllReplacements(Code, Replaces);
28     EXPECT_TRUE(static_cast<bool>(Result));
29     LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
30     return *Result;
31   }
32 
33   static std::string
format(llvm::StringRef Code,const FormatStyle & Style=getLLVMStyle (FormatStyle::LK_Verilog))34   format(llvm::StringRef Code,
35          const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Verilog)) {
36     return format(Code, 0, Code.size(), Style);
37   }
38 
verifyFormat(llvm::StringRef Code,const FormatStyle & Style=getLLVMStyle (FormatStyle::LK_Verilog))39   static void verifyFormat(
40       llvm::StringRef Code,
41       const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Verilog)) {
42     EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
43     EXPECT_EQ(Code.str(),
44               format(test::messUp(Code, /*HandleHash=*/false), Style));
45   }
46 };
47 
TEST_F(FormatTestVerilog,Delay)48 TEST_F(FormatTestVerilog, Delay) {
49   // Delay by the default unit.
50   verifyFormat("#0;");
51   verifyFormat("#1;");
52   verifyFormat("#10;");
53   verifyFormat("#1.5;");
54   // Explicit unit.
55   verifyFormat("#1fs;");
56   verifyFormat("#1.5fs;");
57   verifyFormat("#1ns;");
58   verifyFormat("#1.5ns;");
59   verifyFormat("#1us;");
60   verifyFormat("#1.5us;");
61   verifyFormat("#1ms;");
62   verifyFormat("#1.5ms;");
63   verifyFormat("#1s;");
64   verifyFormat("#1.5s;");
65   // The following expression should be on the same line.
66   verifyFormat("#1 x = x;");
67   EXPECT_EQ("#1 x = x;", format("#1\n"
68                                 "x = x;"));
69 }
70 
TEST_F(FormatTestVerilog,If)71 TEST_F(FormatTestVerilog, If) {
72   verifyFormat("if (x)\n"
73                "  x = x;");
74   verifyFormat("if (x)\n"
75                "  x = x;\n"
76                "x = x;");
77 
78   // Test else
79   verifyFormat("if (x)\n"
80                "  x = x;\n"
81                "else if (x)\n"
82                "  x = x;\n"
83                "else\n"
84                "  x = x;");
85   verifyFormat("if (x) begin\n"
86                "  x = x;\n"
87                "end else if (x) begin\n"
88                "  x = x;\n"
89                "end else begin\n"
90                "  x = x;\n"
91                "end");
92   verifyFormat("if (x) begin : x\n"
93                "  x = x;\n"
94                "end : x else if (x) begin : x\n"
95                "  x = x;\n"
96                "end : x else begin : x\n"
97                "  x = x;\n"
98                "end : x");
99 
100   // Test block keywords.
101   verifyFormat("if (x) begin\n"
102                "  x = x;\n"
103                "end");
104   verifyFormat("if (x) begin : x\n"
105                "  x = x;\n"
106                "end : x");
107   verifyFormat("if (x) begin\n"
108                "  x = x;\n"
109                "  x = x;\n"
110                "end");
111   verifyFormat("disable fork;\n"
112                "x = x;");
113   verifyFormat("rand join x x;\n"
114                "x = x;");
115   verifyFormat("if (x) fork\n"
116                "  x = x;\n"
117                "join");
118   verifyFormat("if (x) fork\n"
119                "  x = x;\n"
120                "join_any");
121   verifyFormat("if (x) fork\n"
122                "  x = x;\n"
123                "join_none");
124   verifyFormat("if (x) generate\n"
125                "  x = x;\n"
126                "endgenerate");
127   verifyFormat("if (x) generate : x\n"
128                "  x = x;\n"
129                "endgenerate : x");
130 
131   // Test that concatenation braces don't get regarded as blocks.
132   verifyFormat("if (x)\n"
133                "  {x} = x;");
134   verifyFormat("if (x)\n"
135                "  x = {x};");
136   verifyFormat("if (x)\n"
137                "  x = {x};\n"
138                "else\n"
139                "  {x} = {x};");
140 }
141 
TEST_F(FormatTestVerilog,Preprocessor)142 TEST_F(FormatTestVerilog, Preprocessor) {
143   auto Style = getLLVMStyle(FormatStyle::LK_Verilog);
144   Style.ColumnLimit = 20;
145 
146   // Macro definitions.
147   EXPECT_EQ("`define X          \\\n"
148             "  if (x)           \\\n"
149             "    x = x;",
150             format("`define X if(x)x=x;", Style));
151   EXPECT_EQ("`define X(x)       \\\n"
152             "  if (x)           \\\n"
153             "    x = x;",
154             format("`define X(x) if(x)x=x;", Style));
155   EXPECT_EQ("`define X          \\\n"
156             "  x = x;           \\\n"
157             "  x = x;",
158             format("`define X x=x;x=x;", Style));
159   // Macro definitions with invocations inside.
160   EXPECT_EQ("`define LIST       \\\n"
161             "  `ENTRY           \\\n"
162             "  `ENTRY",
163             format("`define LIST \\\n"
164                    "`ENTRY \\\n"
165                    "`ENTRY",
166                    Style));
167   EXPECT_EQ("`define LIST       \\\n"
168             "  `x = `x;         \\\n"
169             "  `x = `x;",
170             format("`define LIST \\\n"
171                    "`x = `x; \\\n"
172                    "`x = `x;",
173                    Style));
174   EXPECT_EQ("`define LIST       \\\n"
175             "  `x = `x;         \\\n"
176             "  `x = `x;",
177             format("`define LIST `x=`x;`x=`x;", Style));
178   // Macro invocations.
179   verifyFormat("`x = (`x1 + `x2 + x);");
180   // Lines starting with a preprocessor directive should not be indented.
181   std::string Directives[] = {
182       "begin_keywords",
183       "celldefine",
184       "default_nettype",
185       "define",
186       "else",
187       "elsif",
188       "end_keywords",
189       "endcelldefine",
190       "endif",
191       "ifdef",
192       "ifndef",
193       "include",
194       "line",
195       "nounconnected_drive",
196       "pragma",
197       "resetall",
198       "timescale",
199       "unconnected_drive",
200       "undef",
201       "undefineall",
202   };
203   for (auto &Name : Directives) {
204     EXPECT_EQ("if (x)\n"
205               "`" +
206                   Name +
207                   "\n"
208                   "  ;",
209               format("if (x)\n"
210                      "`" +
211                          Name +
212                          "\n"
213                          ";",
214                      Style));
215   }
216   // Lines starting with a regular macro invocation should be indented as a
217   // normal line.
218   EXPECT_EQ("if (x)\n"
219             "  `x = `x;\n"
220             "`timescale 1ns / 1ps",
221             format("if (x)\n"
222                    "`x = `x;\n"
223                    "`timescale 1ns / 1ps",
224                    Style));
225   EXPECT_EQ("if (x)\n"
226             "`timescale 1ns / 1ps\n"
227             "  `x = `x;",
228             format("if (x)\n"
229                    "`timescale 1ns / 1ps\n"
230                    "`x = `x;",
231                    Style));
232   std::string NonDirectives[] = {
233       // For `__FILE__` and `__LINE__`, although the standard classifies them as
234       // preprocessor directives, they are used like regular macros.
235       "__FILE__", "__LINE__", "elif", "foo", "x",
236   };
237   for (auto &Name : NonDirectives) {
238     EXPECT_EQ("if (x)\n"
239               "  `" +
240                   Name + ";",
241               format("if (x)\n"
242                      "`" +
243                          Name +
244                          "\n"
245                          ";",
246                      Style));
247   }
248 }
249 
250 } // namespace format
251 } // end namespace clang
252