Skip to content

Commit

Permalink
Update offset overload function and union initialize logic
Browse files Browse the repository at this point in the history
  • Loading branch information
leewei05 committed Jun 20, 2024
1 parent 93b4b97 commit b2d9886
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 8 deletions.
12 changes: 9 additions & 3 deletions include/type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ class RecordType : public Type {
const noexcept = 0;
/// @return The type offset in the record.
virtual std::size_t offset( // NOLINT(readability-identifier-naming)
const std::string& id) const noexcept = 0;
const std::string& id) const = 0;
virtual std::size_t offset( // NOLINT(readability-identifier-naming)
const std::size_t id) const = 0;
/// @brief Checks if `id` is a member of the record type.
virtual bool IsMember(const std::string& id) const noexcept = 0;
/// @return The type of a member in struct or union. The unknown type if the
Expand All @@ -209,7 +211,9 @@ class StructType : public RecordType {
std::string id() // NOLINT(readability-identifier-naming)
const noexcept override;
std::size_t offset( // NOLINT(readability-identifier-naming)
const std::string& id) const noexcept override;
const std::string& id) const override;
std::size_t offset( // NOLINT(readability-identifier-naming)
const std::size_t index) const override;
bool IsMember(const std::string& id) const noexcept override;
std::unique_ptr<Type> MemberType(
const std::string& id) const noexcept override;
Expand Down Expand Up @@ -238,7 +242,9 @@ class UnionType : public RecordType {
std::string id() // NOLINT(readability-identifier-naming)
const noexcept override;
std::size_t offset( // NOLINT(readability-identifier-naming)
const std::string& id) const noexcept override;
const std::string& id) const override;
std::size_t offset( // NOLINT(readability-identifier-naming)
const std::size_t index) const override;
bool IsMember(const std::string& id) const noexcept override;
std::unique_ptr<Type> MemberType(
const std::string& id) const noexcept override;
Expand Down
10 changes: 9 additions & 1 deletion src/qbe_ir_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,18 @@ void QbeIrGenerator::Visit(const RecordVarDeclNode& record_var_decl) {
init->Accept(*this);
const auto init_num = num_recorder.NumOfPrevExpr();

// NOTE: Every member shares the same starting memory location in union.
// Abort if initializing more than one element.
if (record_var_decl.type->IsUnion() && i > 0) {
break;
}

// res_addr = base_addr + offset
const int res_addr_num = NextLocalNum();
auto* record_type = dynamic_cast<RecordType*>(record_var_decl.type.get());
assert(record_type);
WriteInstr_("{} =l add {}, {}", FuncScopeTemp{res_addr_num},
FuncScopeTemp{base_addr}, i * init->type->size());
FuncScopeTemp{base_addr}, record_type->offset(i));
WriteInstr_("storew {}, {}", FuncScopeTemp{init_num},
FuncScopeTemp{res_addr_num});
}
Expand Down
30 changes: 26 additions & 4 deletions src/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,32 @@ std::string StructType::id() const noexcept {
return id_;
}

std::size_t StructType::offset(const std::string& id) const noexcept {
std::size_t StructType::offset(const std::string& id) const {
std::size_t offset = 0;
for (auto i = std::size_t{0}, e = fields_.size(); i < e; ++i) {
const auto& field = fields_.at(i);
if (field->id == id) {
return i * field->type->size();
return offset;
}

offset += field->type->size();
}

return -1;
throw "member not found in struct!";
}

std::size_t StructType::offset(const std::size_t index) const {
std::size_t offset = 0;
for (auto i = std::size_t{0}, e = fields_.size(); i < e; ++i) {
const auto& field = fields_.at(i);
if (i == index) {
return offset;
}

offset += field->type->size();
}

throw "member not found in struct!";
}

bool StructType::IsMember(const std::string& id) const noexcept {
Expand Down Expand Up @@ -231,7 +248,12 @@ std::unique_ptr<Type> StructType::Clone() const {
return std::make_unique<StructType>(id_, std::move(cloned_fields));
}

std::size_t UnionType::offset(const std::string& id) const noexcept {
std::size_t UnionType::offset(const std::string& id) const {
// Every member in union shares the same starting location.
return 0;
}

std::size_t UnionType::offset(const std::size_t index) const {
// Every member in union shares the same starting location.
return 0;
}
Expand Down

0 comments on commit b2d9886

Please sign in to comment.