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: 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 34 format(llvm::StringRef Code, 35 const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Verilog)) { 36 return format(Code, 0, Code.size(), Style); 37 } 38 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 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 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 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