Skip to content

Commit

Permalink
Handle missing test case for integer underlying an enum.
Browse files Browse the repository at this point in the history
  • Loading branch information
cdleary committed Nov 15, 2024
1 parent ccbb8cc commit e56d590
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 18 deletions.
43 changes: 25 additions & 18 deletions xls/codegen/vast/vast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,25 @@ bool CannotStripWhitespace(std::string_view s) {
return stripped.size() == s.size();
}

// Helper that combines DataKind and DataType strings -- since either of these
// can be empty under certain circumstances we consolidate the handling of
// inserting spaces appropriately in this routine.
std::string CombineKindAndDataType(std::string_view kind_str,
std::string_view data_type_str) {
CHECK(CannotStripWhitespace(kind_str));
CHECK(CannotStripWhitespace(data_type_str));

std::string result;
if (kind_str.empty()) {
result = data_type_str;
} else if (data_type_str.empty()) {
result = kind_str;
} else {
result = absl::StrCat(kind_str, " ", data_type_str);
}
return result;
}

} // namespace

int Precedence(OperatorKind kind) {
Expand Down Expand Up @@ -923,18 +942,8 @@ std::string Def::EmitNoSemi(LineInfo* line_info) const {
std::string kind_str = DataKindToString(data_kind());
std::string data_type_str =
data_type()->EmitWithIdentifier(line_info, GetName());
std::string result = CombineKindAndDataType(kind_str, data_type_str);

CHECK(CannotStripWhitespace(kind_str));
CHECK(CannotStripWhitespace(data_type_str));

std::string result;
if (kind_str.empty()) {
result = data_type_str;
} else if (data_type_str.empty()) {
result = kind_str;
} else {
result = absl::StrCat(kind_str, " ", data_type_str);
}
LineInfoEnd(line_info, this);
return result;
}
Expand Down Expand Up @@ -1362,13 +1371,11 @@ std::string Enum::Emit(LineInfo* line_info) const {
LineInfoStart(line_info, this);
std::string result = "enum {\n";
if (kind_ != DataKind::kUntypedEnum) {
std::string underlying_type_string = DataKindToString(kind_);
if (!underlying_type_string.empty()) {
absl::StrAppend(&underlying_type_string, " ");
}
absl::StrAppend(&underlying_type_string, BaseType()->Emit(line_info));

result = absl::StrFormat("enum %s {\n", underlying_type_string);
std::string kind_str = DataKindToString(kind_);
std::string data_type_str = BaseType()->Emit(line_info);
std::string underlying_type_str =
CombineKindAndDataType(kind_str, data_type_str);
result = absl::StrFormat("enum %s {\n", underlying_type_str);
}
LineInfoIncrease(line_info, 1);
for (int i = 0; i < members_.size(); i++) {
Expand Down
34 changes: 34 additions & 0 deletions xls/codegen/vast/vast_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,40 @@ TEST_P(VastTest, EmitBitVectorLogicDef) {
EXPECT_EQ(logic_def->Emit(&line_info), "logic [41:0] foo;");
}

// Tests we can build and emit a construct of the following form:
// ```
// typedef enum integer {
// kElem0 = 0,
// kElem1 = 1,
// kElem2 = 2,
// kElem3 = 3,
// } enum_t;
// ```
TEST_P(VastTest, EmitTypedefOfEnumWithUnderlyingInteger) {
VerilogFile f(GetFileType());
const SourceInfo si;
DataType* data_type = f.IntegerType(si);
Enum* enum_def = f.Make<Enum>(si, DataKind::kInteger, data_type);
EnumMemberRef* elem0 =
enum_def->AddMember("kElem0", f.PlainLiteral(0, si), si);
EnumMemberRef* elem1 =
enum_def->AddMember("kElem1", f.PlainLiteral(1, si), si);
EnumMemberRef* elem2 =
enum_def->AddMember("kElem2", f.PlainLiteral(2, si), si);
EnumMemberRef* elem3 =
enum_def->AddMember("kElem3", f.PlainLiteral(3, si), si);
Typedef* enum_typedef =
f.Make<Typedef>(si, f.Make<Def>(si, "enum_t", DataKind::kUser, enum_def));
LineInfo line_info;
EXPECT_EQ(enum_typedef->Emit(&line_info),
R"(typedef enum integer {
kElem0 = 0,
kElem1 = 1,
kElem2 = 2,
kElem3 = 3
} enum_t;)");
}

TEST_P(VastTest, DataTypes) {
VerilogFile f(GetFileType());

Expand Down

0 comments on commit e56d590

Please sign in to comment.