#pragma once
#include "engine/engine.h"
#include "engine/identifiers.h"
#include "engine/symlevel/definitions.h"
#include "engine/terms.h"
#include "engine/typeinfo_manager.h"
#include "utils/logger.h"
#include <cstdint>
#include <memory>
namespace Engine {
class FieldLayout {
public:
struct Entry {
Identifier<Symlevel::FieldDefinition> definition;
Term fieldType;
std::optional<uint32_t> offset;
};
struct SizeDesc {
std::optional<uint32_t> size{0};
uint8_t alignment{1};
};
struct Content {
std::vector<Entry> fields;
SizeDesc desc{};
};
FieldLayout(Content&& content);
std::shared_ptr<Content const> operator->() const;
Content const& operator*() const;
private:
std::shared_ptr<Content> content;
};
class FieldLayoutManager {
public:
static std::unique_ptr<FieldLayoutManager> New(Session& session);
static std::unique_ptr<FieldLayoutManager> New(Session& session, TypeInfoManager& typeInfoManager);
virtual std::optional<FieldLayout> GetLayout(Term term) = 0;
virtual std::optional<uint32_t> GetFlatSize(Term term) = 0;
virtual uint8_t GetFlatAlignment(Term term) = 0;
virtual void FillRefOffsets(Term term, std::vector<uint32_t>& offsets, uint32_t disp) = 0;
virtual ~FieldLayoutManager();
};
namespace Log {
extern Logging::Logger fields;
}
}