#pragma once
#include <libsolidity/codegen/ArrayUtils.h>
#include <libsolutil/Common.h>
#include <liblangutil/SourceLocation.h>
#include <memory>
#include <vector>
namespace solidity::frontend
{
class Declaration;
class Type;
class TupleType;
class ArrayType;
class CompilerContext;
class VariableDeclaration;
class LValue
{
protected:
explicit LValue(CompilerContext& _compilerContext, Type const* _dataType = nullptr):
m_context(_compilerContext), m_dataType(_dataType) {}
public:
virtual ~LValue() = default;
virtual unsigned sizeOnStack() const { return 1; }
virtual void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const = 0;
virtual void storeValue(Type const& _sourceType,
langutil::SourceLocation const& _location = {}, bool _move = false) const = 0;
virtual void setToZero(
langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const = 0;
protected:
CompilerContext& m_context;
Type const* m_dataType;
};
class StackVariable: public LValue
{
public:
StackVariable(CompilerContext& _compilerContext, VariableDeclaration const& _declaration);
unsigned sizeOnStack() const override { return 0; }
void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;
void storeValue(
Type const& _sourceType,
langutil::SourceLocation const& _location = {},
bool _move = false
) const override;
void setToZero(
langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const override;
private:
unsigned m_baseStackOffset;
unsigned m_size;
};
class MemoryItem: public LValue
{
public:
MemoryItem(CompilerContext& _compilerContext, Type const& _type, bool _padded = true);
unsigned sizeOnStack() const override { return 1; }
void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;
void storeValue(
Type const& _sourceType,
langutil::SourceLocation const& _location = {},
bool _move = false
) const override;
void setToZero(
langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const override;
private:
bool m_padded = false;
};
class ImmutableItem: public LValue
{
public:
ImmutableItem(CompilerContext& _compilerContext, VariableDeclaration const& _variable);
unsigned sizeOnStack() const override { return 0; }
void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;
void storeValue(
Type const& _sourceType,
langutil::SourceLocation const& _location = {},
bool _move = false
) const override;
void setToZero(
langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const override;
private:
VariableDeclaration const& m_variable;
};
class StorageItem: public LValue
{
public:
StorageItem(CompilerContext& _compilerContext, VariableDeclaration const& _declaration);
StorageItem(CompilerContext& _compilerContext, Type const& _type);
unsigned sizeOnStack() const override { return 2; }
void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;
void storeValue(
Type const& _sourceType,
langutil::SourceLocation const& _location = {},
bool _move = false
) const override;
void setToZero(
langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const override;
};
class StorageByteArrayElement: public LValue
{
public:
StorageByteArrayElement(CompilerContext& _compilerContext);
unsigned sizeOnStack() const override { return 2; }
void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;
void storeValue(
Type const& _sourceType,
langutil::SourceLocation const& _location = {},
bool _move = false
) const override;
void setToZero(
langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const override;
};
class TupleObject: public LValue
{
public:
TupleObject(CompilerContext& _compilerContext, std::vector<std::unique_ptr<LValue>>&& _lvalues);
unsigned sizeOnStack() const override;
void retrieveValue(langutil::SourceLocation const& _location, bool _remove = false) const override;
void storeValue(
Type const& _sourceType,
langutil::SourceLocation const& _location = {},
bool _move = false
) const override;
void setToZero(
langutil::SourceLocation const& _location = {},
bool _removeReference = true
) const override;
private:
std::vector<std::unique_ptr<LValue>> m_lvalues;
};
}