// Different kinds of abstract storage locations: Constants, Global and Local Storage, Temporaries, ... #pragma once #include "data.h" #include #include #include namespace FlowGraph { // Parameter to Data class, defining where the data is stored // Explicitely not including size // But including label/data/pointer // -> includes identity of certain data point class Storage { public: virtual ~Storage() {} // force class to be polymorphic, for smart pointers }; class Constant: public Storage { public: Constant(std::vector& value): m_value(value) {} // little endian data const std::vector& value() const { return m_value; } private: std::vector m_value; }; class GlobalStorage : public Storage { public: GlobalStorage(const std::string& name): m_name(name) {} const std::string& name() const { return m_name; } private: std::string m_name; }; class LocalStorage : public Storage { public: LocalStorage(const std::string& name): m_name(name) {} const std::string& name() const { return m_name; } private: std::string m_name; }; // Provide a context for local temporaries name generation class LocalScope { public: LocalScope() = default; size_t getNewIndex() { return m_index++; } private: size_t m_index{ 0 }; }; // intermediate results, anonymous values // use generated name class TemporaryStorage : public Storage { public: TemporaryStorage(LocalScope& scope); const std::string& name() const { return m_name; } private: std::string m_name; }; // dereferenced pointer class PointeeStorage : public Storage { public: PointeeStorage(const Data& pointer, const Data& offset): m_pointer(pointer), m_offset(offset) { if (pointer.type() != DataType::Pointer) throw std::runtime_error("Pointer argument must be a DataType::Pointer"); if (offset.type() != DataType::Size) throw std::runtime_error("Offset argument must be a DataType::Size"); } Data pointer() { return m_pointer; } Data offset() { return m_offset; } private: Data m_pointer; Data m_offset; }; }