#include "FormatTestUtils.h"
#include "clang/Format/Format.h"
#include "llvm/Support/Debug.h"
#include "gtest/gtest.h"
#define DEBUG_TYPE "format-test"
namespace clang {
namespace format {
class FormatTestVerilog : public ::testing::Test {
protected:
static std::string format(llvm::StringRef Code, unsigned Offset,
unsigned Length, const FormatStyle &Style) {
LLVM_DEBUG(llvm::errs() << "---\n");
LLVM_DEBUG(llvm::errs() << Code << "\n\n");
std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
tooling::Replacements Replaces = reformat(Style, Code, Ranges);
auto Result = applyAllReplacements(Code, Replaces);
EXPECT_TRUE(static_cast<bool>(Result));
LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
return *Result;
}
static std::string
format(llvm::StringRef Code,
const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Verilog)) {
return format(Code, 0, Code.size(), Style);
}
static void verifyFormat(
llvm::StringRef Code,
const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Verilog)) {
EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
EXPECT_EQ(Code.str(),
format(test::messUp(Code, false), Style));
}
};
TEST_F(FormatTestVerilog, Delay) {
verifyFormat("#0;");
verifyFormat("#1;");
verifyFormat("#10;");
verifyFormat("#1.5;");
verifyFormat("#1fs;");
verifyFormat("#1.5fs;");
verifyFormat("#1ns;");
verifyFormat("#1.5ns;");
verifyFormat("#1us;");
verifyFormat("#1.5us;");
verifyFormat("#1ms;");
verifyFormat("#1.5ms;");
verifyFormat("#1s;");
verifyFormat("#1.5s;");
verifyFormat("#1 x = x;");
EXPECT_EQ("#1 x = x;", format("#1\n"
"x = x;"));
}
TEST_F(FormatTestVerilog, If) {
verifyFormat("if (x)\n"
" x = x;");
verifyFormat("if (x)\n"
" x = x;\n"
"x = x;");
verifyFormat("if (x)\n"
" x = x;\n"
"else if (x)\n"
" x = x;\n"
"else\n"
" x = x;");
verifyFormat("if (x) begin\n"
" x = x;\n"
"end else if (x) begin\n"
" x = x;\n"
"end else begin\n"
" x = x;\n"
"end");
verifyFormat("if (x) begin : x\n"
" x = x;\n"
"end : x else if (x) begin : x\n"
" x = x;\n"
"end : x else begin : x\n"
" x = x;\n"
"end : x");
verifyFormat("if (x) begin\n"
" x = x;\n"
"end");
verifyFormat("if (x) begin : x\n"
" x = x;\n"
"end : x");
verifyFormat("if (x) begin\n"
" x = x;\n"
" x = x;\n"
"end");
verifyFormat("disable fork;\n"
"x = x;");
verifyFormat("rand join x x;\n"
"x = x;");
verifyFormat("if (x) fork\n"
" x = x;\n"
"join");
verifyFormat("if (x) fork\n"
" x = x;\n"
"join_any");
verifyFormat("if (x) fork\n"
" x = x;\n"
"join_none");
verifyFormat("if (x) generate\n"
" x = x;\n"
"endgenerate");
verifyFormat("if (x) generate : x\n"
" x = x;\n"
"endgenerate : x");
verifyFormat("if (x)\n"
" {x} = x;");
verifyFormat("if (x)\n"
" x = {x};");
verifyFormat("if (x)\n"
" x = {x};\n"
"else\n"
" {x} = {x};");
}
TEST_F(FormatTestVerilog, Preprocessor) {
auto Style = getLLVMStyle(FormatStyle::LK_Verilog);
Style.ColumnLimit = 20;
EXPECT_EQ("`define X \\\n"
" if (x) \\\n"
" x = x;",
format("`define X if(x)x=x;", Style));
EXPECT_EQ("`define X(x) \\\n"
" if (x) \\\n"
" x = x;",
format("`define X(x) if(x)x=x;", Style));
EXPECT_EQ("`define X \\\n"
" x = x; \\\n"
" x = x;",
format("`define X x=x;x=x;", Style));
EXPECT_EQ("`define LIST \\\n"
" `ENTRY \\\n"
" `ENTRY",
format("`define LIST \\\n"
"`ENTRY \\\n"
"`ENTRY",
Style));
EXPECT_EQ("`define LIST \\\n"
" `x = `x; \\\n"
" `x = `x;",
format("`define LIST \\\n"
"`x = `x; \\\n"
"`x = `x;",
Style));
EXPECT_EQ("`define LIST \\\n"
" `x = `x; \\\n"
" `x = `x;",
format("`define LIST `x=`x;`x=`x;", Style));
verifyFormat("`x = (`x1 + `x2 + x);");
std::string Directives[] = {
"begin_keywords",
"celldefine",
"default_nettype",
"define",
"else",
"elsif",
"end_keywords",
"endcelldefine",
"endif",
"ifdef",
"ifndef",
"include",
"line",
"nounconnected_drive",
"pragma",
"resetall",
"timescale",
"unconnected_drive",
"undef",
"undefineall",
};
for (auto &Name : Directives) {
EXPECT_EQ("if (x)\n"
"`" +
Name +
"\n"
" ;",
format("if (x)\n"
"`" +
Name +
"\n"
";",
Style));
}
EXPECT_EQ("if (x)\n"
" `x = `x;\n"
"`timescale 1ns / 1ps",
format("if (x)\n"
"`x = `x;\n"
"`timescale 1ns / 1ps",
Style));
EXPECT_EQ("if (x)\n"
"`timescale 1ns / 1ps\n"
" `x = `x;",
format("if (x)\n"
"`timescale 1ns / 1ps\n"
"`x = `x;",
Style));
std::string NonDirectives[] = {
"__FILE__", "__LINE__", "elif", "foo", "x",
};
for (auto &Name : NonDirectives) {
EXPECT_EQ("if (x)\n"
" `" +
Name + ";",
format("if (x)\n"
"`" +
Name +
"\n"
";",
Style));
}
}
} }