Skip to content

Commit

Permalink
Support union type
Browse files Browse the repository at this point in the history
  • Loading branch information
mingzheTerapines committed Aug 2, 2024
1 parent c4ccda7 commit 732a412
Showing 1 changed file with 43 additions and 52 deletions.
95 changes: 43 additions & 52 deletions lib/Dialect/Moore/MooreOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,11 @@ static std::optional<uint32_t> getStructFieldIndex(Type type, StringAttr name) {
return structType.getFieldIndex(name);
if (auto structType = dyn_cast<UnpackedStructType>(type))
return structType.getFieldIndex(name);
assert(0 && "expected StructType or UnpackedStructType");
if (auto unionType = dyn_cast<UnionType>(type))
return unionType.getFieldIndex(name);
if (auto unionType = dyn_cast<UnpackedUnionType>(type))
return unionType.getFieldIndex(name);
assert(0 && "expected Struct-Like Type");
return {};
}

Expand All @@ -563,6 +567,10 @@ static ArrayRef<StructLikeMember> getStructMembers(Type type) {
return structType.getMembers();
if (auto structType = dyn_cast<UnpackedStructType>(type))
return structType.getMembers();
if (auto unionType = dyn_cast<UnionType>(type))
return unionType.getMembers();
if (auto unionType = dyn_cast<UnpackedUnionType>(type))
return unionType.getMembers();
return {};
}

Expand Down Expand Up @@ -760,71 +768,54 @@ LogicalResult StructInjectOp::canonicalize(StructInjectOp op,
//===----------------------------------------------------------------------===//

LogicalResult UnionCreateOp::verify() {
/// checks if the types of the input is exactly equal to the union field
auto type = getStructFieldType(getType(), getFieldNameAttr());

/// checks if the type of the input is exactly equal to the union field
/// type
return TypeSwitch<Type, LogicalResult>(getType())
.Case<UnionType, UnpackedUnionType>([this](auto &type) {
auto members = type.getMembers();
auto resultType = getType();
auto fieldName = getFieldName();
for (const auto &member : members)
if (member.name == fieldName && member.type == resultType)
return success();
emitOpError("input type must match the union field type");
return failure();
})
.Default([this](auto &) {
emitOpError("input type must be UnionType or UnpackedUnionType");
return failure();
});

if (!type)
return emitOpError() << "union field " << getFieldNameAttr()
<< " which does not exist in " << getInput().getType();
if (type != getType())
return emitOpError() << "result type " << getType()
<< " must match union field type " << type;
return success();
}

//===----------------------------------------------------------------------===//
// UnionExtractOp
//===----------------------------------------------------------------------===//

LogicalResult UnionExtractOp::verify() {
/// checks if the types of the input is exactly equal to the one of the
/// types of the result union fields
return TypeSwitch<Type, LogicalResult>(getInput().getType())
.Case<UnionType, UnpackedUnionType>([this](auto &type) {
auto members = type.getMembers();
auto fieldName = getFieldName();
auto resultType = getType();
for (const auto &member : members)
if (member.name == fieldName && member.type == resultType)
return success();
emitOpError("result type must match the union field type");
return failure();
})
.Default([this](auto &) {
emitOpError("input type must be UnionType or UnpackedUnionType");
return failure();
});
auto type = getStructFieldType(getInput().getType(), getFieldNameAttr());

/// checks if the type of the input is exactly equal to the type of the result
/// union fields
if (!type)
return emitOpError() << "union field " << getFieldNameAttr()
<< " which does not exist in " << getInput().getType();
if (type != getType())
return emitOpError() << "result type " << getType()
<< " must match union field type " << type;
return success();
}

//===----------------------------------------------------------------------===//
// UnionExtractOp
// UnionExtractRefOp
//===----------------------------------------------------------------------===//

LogicalResult UnionExtractRefOp::verify() {
/// checks if the types of the result is exactly equal to the type of the
/// refe union field
return TypeSwitch<Type, LogicalResult>(getInput().getType().getNestedType())
.Case<UnionType, UnpackedUnionType>([this](auto &type) {
auto members = type.getMembers();
auto fieldName = getFieldName();
auto resultType = getType().getNestedType();
for (const auto &member : members)
if (member.name == fieldName && member.type == resultType)
return success();
emitOpError("result type must match the union field type");
return failure();
})
.Default([this](auto &) {
emitOpError("input type must be UnionType or UnpackedUnionType");
return failure();
});
auto type = getStructFieldType(getInput().getType().getNestedType(),
getFieldNameAttr());
/// checks if the type of the result is exactly equal to the type of the
/// referring union field
if (!type)
return emitOpError() << "union field " << getFieldNameAttr()
<< " which does not exist in " << getInput().getType();
if (type != getType())
return emitOpError() << "result type " << getType()
<< " must match union field type " << type;
return success();
}

//===----------------------------------------------------------------------===//
Expand Down

0 comments on commit 732a412

Please sign in to comment.