Add Tests for ZCG cpp

This commit is contained in:
Jan
2021-02-10 18:03:50 +01:00
parent 31497d804c
commit f9ef7cc35b
102 changed files with 502 additions and 21 deletions

View File

@ -0,0 +1,228 @@
#include "MemberComputations.h"
#include <algorithm>
#include <cassert>
#include "StructureComputations.h"
#include "Domain/Definition/ArrayDeclarationModifier.h"
#include "Domain/Definition/PointerDeclarationModifier.h"
MemberComputations::MemberComputations(const MemberInformation* member)
: m_info(member)
{
assert(m_info != nullptr);
}
bool MemberComputations::ShouldIgnore() const
{
return m_info->m_condition && m_info->m_condition->IsStatic() && m_info->m_condition->EvaluateNumeric() == 0;
}
bool MemberComputations::ContainsNonEmbeddedReference() const
{
const auto& declarationModifiers = m_info->m_member->m_type_declaration->m_declaration_modifiers;
return std::any_of(declarationModifiers.begin(), declarationModifiers.end(), [](const std::unique_ptr<DeclarationModifier>& modifier)
{
return modifier->GetType() == DeclarationModifierType::POINTER;
});
}
bool MemberComputations::ContainsSinglePointerReference() const
{
const auto& declarationModifiers = m_info->m_member->m_type_declaration->m_declaration_modifiers;
if (declarationModifiers.empty())
return false;
const auto* lastModifier = declarationModifiers[declarationModifiers.size() - 1].get();
if (lastModifier->GetType() != DeclarationModifierType::POINTER)
return false;
return !dynamic_cast<const PointerDeclarationModifier*>(lastModifier)->AnyCountEvaluationIsArray();
}
bool MemberComputations::ContainsArrayPointerReference() const
{
const auto& declarationModifiers = m_info->m_member->m_type_declaration->m_declaration_modifiers;
if (declarationModifiers.empty())
return false;
const auto* lastModifier = declarationModifiers[declarationModifiers.size() - 1].get();
if (lastModifier->GetType() != DeclarationModifierType::POINTER)
return false;
return dynamic_cast<const PointerDeclarationModifier*>(lastModifier)->AnyCountEvaluationIsArray();
}
bool MemberComputations::ContainsPointerArrayReference() const
{
if (!ContainsSinglePointerReference())
return false;
const auto pointerDepth = GetPointerDepth();
const auto isArray = IsArray();
return isArray && pointerDepth == 1 || !isArray && pointerDepth == 2;
}
bool MemberComputations::ContainsArrayReference() const
{
const auto& declarationModifiers = m_info->m_member->m_type_declaration->m_declaration_modifiers;
if (declarationModifiers.empty())
return false;
const auto* lastModifier = declarationModifiers[declarationModifiers.size() - 1].get();
return lastModifier->GetType() == DeclarationModifierType::ARRAY;
}
const IEvaluation* MemberComputations::GetArrayPointerCountEvaluation() const
{
const auto& declarationModifiers = m_info->m_member->m_type_declaration->m_declaration_modifiers;
if (declarationModifiers.empty())
return nullptr;
const auto* lastModifier = declarationModifiers[declarationModifiers.size() - 1].get();
return lastModifier->GetType() == DeclarationModifierType::POINTER
? dynamic_cast<const PointerDeclarationModifier*>(lastModifier)->GetCountEvaluation()
: nullptr;
}
bool MemberComputations::IsArray() const
{
const auto& declarationModifiers = m_info->m_member->m_type_declaration->m_declaration_modifiers;
if (declarationModifiers.empty())
return false;
return declarationModifiers[0]->GetType() == DeclarationModifierType::ARRAY;
}
std::vector<int> MemberComputations::GetArraySizes() const
{
std::vector<int> sizes;
const auto& declarationModifiers = m_info->m_member->m_type_declaration->m_declaration_modifiers;
for (const auto& declarationModifier : declarationModifiers)
{
if (declarationModifier->GetType() != DeclarationModifierType::ARRAY)
break;
sizes.push_back(dynamic_cast<const ArrayDeclarationModifier*>(declarationModifier.get())->m_size);
}
return sizes;
}
int MemberComputations::GetArrayDimension() const
{
auto dimension = 0;
const auto& declarationModifiers = m_info->m_member->m_type_declaration->m_declaration_modifiers;
for (const auto& declarationModifier : declarationModifiers)
{
if (declarationModifier->GetType() != DeclarationModifierType::ARRAY)
break;
dimension++;
}
return dimension;
}
bool MemberComputations::IsPointerToArray() const
{
const auto& declarationModifiers = m_info->m_member->m_type_declaration->m_declaration_modifiers;
if (declarationModifiers.empty())
return false;
const auto* lastModifier = declarationModifiers[declarationModifiers.size() - 1].get();
if (lastModifier->GetType() != DeclarationModifierType::ARRAY)
return false;
return std::any_of(declarationModifiers.begin(), declarationModifiers.end(), [](const std::unique_ptr<DeclarationModifier>& modifier)
{
return modifier->GetType() == DeclarationModifierType::POINTER;
});
}
std::vector<int> MemberComputations::GetPointerToArraySizes() const
{
std::vector<int> sizes;
const auto& declarationModifiers = m_info->m_member->m_type_declaration->m_declaration_modifiers;
for (const auto& declarationModifier : declarationModifiers)
{
if (declarationModifier->GetType() == DeclarationModifierType::ARRAY)
{
sizes.push_back(dynamic_cast<ArrayDeclarationModifier*>(declarationModifier.get())->m_size);
}
else
{
sizes.clear();
}
}
return sizes;
}
int MemberComputations::GetPointerDepth() const
{
auto depth = 0;
const auto& declarationModifiers = m_info->m_member->m_type_declaration->m_declaration_modifiers;
for(const auto& declarationModifier : declarationModifiers)
{
if (declarationModifier->GetType() == DeclarationModifierType::POINTER)
depth++;
}
return depth;
}
bool MemberComputations::IsNotInDefaultNormalBlock() const
{
return m_info->m_fast_file_block != nullptr && !(m_info->m_fast_file_block->m_type == FastFileBlockType::NORMAL && m_info->m_fast_file_block->m_is_default);
}
bool MemberComputations::IsInTempBlock() const
{
return m_info->m_fast_file_block != nullptr && m_info->m_fast_file_block->m_type == FastFileBlockType::TEMP;
}
bool MemberComputations::IsInRuntimeBlock() const
{
return m_info->m_fast_file_block != nullptr && m_info->m_fast_file_block->m_type == FastFileBlockType::RUNTIME;
}
bool MemberComputations::IsFirstMember() const
{
const auto parentUsedMembers = StructureComputations(m_info->m_parent).GetUsedMembers();
return !parentUsedMembers.empty() && parentUsedMembers[0] == m_info;
}
bool MemberComputations::IsLastMember() const
{
const auto parentUsedMembers = StructureComputations(m_info->m_parent).GetUsedMembers();
return !parentUsedMembers.empty() && parentUsedMembers[parentUsedMembers.size() - 1] == m_info;
}
bool MemberComputations::HasDynamicArraySize() const
{
const auto& declarationModifiers = m_info->m_member->m_type_declaration->m_declaration_modifiers;
return std::any_of(declarationModifiers.begin(), declarationModifiers.end(), [](const std::unique_ptr<DeclarationModifier>& declarationModifier)
{
return declarationModifier->GetType() == DeclarationModifierType::ARRAY
&& dynamic_cast<ArrayDeclarationModifier*>(declarationModifier.get())->m_dynamic_size_evaluation;
});
}
bool MemberComputations::IsDynamicMember() const
{
if (HasDynamicArraySize())
return true;
return !ContainsNonEmbeddedReference() && m_info->m_type && StructureComputations(m_info->m_type).GetDynamicMember() != nullptr;
}
bool MemberComputations::IsAfterPartialLoad() const
{
if (IsDynamicMember())
return true;
return m_info->m_parent->m_definition->GetType() == DataDefinitionType::UNION && StructureComputations(m_info->m_parent).GetDynamicMember() != nullptr;
}

View File

@ -0,0 +1,33 @@
#pragma once
#include "Domain/Information/MemberInformation.h"
class MemberComputations
{
const MemberInformation* const m_info;
public:
explicit MemberComputations(const MemberInformation* member);
_NODISCARD bool ShouldIgnore() const;
_NODISCARD bool ContainsNonEmbeddedReference() const;
_NODISCARD bool ContainsSinglePointerReference() const;
_NODISCARD bool ContainsArrayPointerReference() const;
_NODISCARD bool ContainsPointerArrayReference() const;
_NODISCARD bool ContainsArrayReference() const;
_NODISCARD const IEvaluation* GetArrayPointerCountEvaluation() const;
_NODISCARD bool IsArray() const;
_NODISCARD std::vector<int> GetArraySizes() const;
_NODISCARD int GetArrayDimension() const;
_NODISCARD bool IsPointerToArray() const;
_NODISCARD std::vector<int> GetPointerToArraySizes() const;
_NODISCARD int GetPointerDepth() const;
_NODISCARD bool IsNotInDefaultNormalBlock() const;
_NODISCARD bool IsInTempBlock() const;
_NODISCARD bool IsInRuntimeBlock() const;
_NODISCARD bool IsFirstMember() const;
_NODISCARD bool IsLastMember() const;
_NODISCARD bool HasDynamicArraySize() const;
_NODISCARD bool IsDynamicMember() const;
_NODISCARD bool IsAfterPartialLoad() const;
};

View File

@ -0,0 +1,243 @@
#include "MemberDeclarationModifierComputations.h"
#include <algorithm>
#include <cassert>
#include "MemberComputations.h"
#include "Domain/Definition/ArrayDeclarationModifier.h"
#include "Domain/Definition/PointerDeclarationModifier.h"
DeclarationModifierComputations::DeclarationModifierComputations(const MemberInformation* member, std::vector<int> modifierIndices)
: m_information(member),
m_modifier_indices(std::move(modifierIndices))
{
auto combinedIndex = 0;
auto arraySizes = MemberComputations(m_information).GetArraySizes();
std::vector<int> sizePerDepth(arraySizes.size());
auto currentDepthSize = 1;
for (int i = arraySizes.size(); i > 0; i--)
{
sizePerDepth[i - 1] = currentDepthSize;
currentDepthSize *= arraySizes[i - 1];
}
auto currentDepth = 0;
for (auto modifierIndex : m_modifier_indices)
{
combinedIndex += sizePerDepth[currentDepth++] * modifierIndex;
}
m_combined_index = combinedIndex;
}
DeclarationModifierComputations::DeclarationModifierComputations(const MemberInformation* member)
: m_information(member),
m_combined_index(0)
{
}
DeclarationModifier* DeclarationModifierComputations::GetDeclarationModifier() const
{
const auto& declarationModifiers = m_information->m_member->m_type_declaration->m_declaration_modifiers;
if (m_modifier_indices.size() < declarationModifiers.size())
return declarationModifiers[m_modifier_indices.size()].get();
return nullptr;
}
DeclarationModifier* DeclarationModifierComputations::GetNextDeclarationModifier() const
{
const auto& declarationModifiers = m_information->m_member->m_type_declaration->m_declaration_modifiers;
if (m_modifier_indices.size() + 1 < declarationModifiers.size())
return declarationModifiers[m_modifier_indices.size() + 1].get();
return nullptr;
}
std::vector<DeclarationModifier*> DeclarationModifierComputations::GetFollowingDeclarationModifiers() const
{
std::vector<DeclarationModifier*> following;
const auto& declarationModifiers = m_information->m_member->m_type_declaration->m_declaration_modifiers;
if (m_modifier_indices.size() + 1 < declarationModifiers.size())
{
for (auto i = declarationModifiers.begin() + m_modifier_indices.size() + 1; i != declarationModifiers.end(); ++i)
{
following.push_back(i->get());
}
}
return following;
}
std::vector<int> DeclarationModifierComputations::GetArrayIndices() const
{
return m_modifier_indices;
}
bool DeclarationModifierComputations::IsArray() const
{
auto* declarationModifier = GetDeclarationModifier();
return declarationModifier != nullptr && declarationModifier->GetType() == DeclarationModifierType::ARRAY;
}
int DeclarationModifierComputations::GetArraySize() const
{
auto* declarationModifier = GetDeclarationModifier();
if (declarationModifier != nullptr && declarationModifier->GetType() == DeclarationModifierType::ARRAY)
{
return dynamic_cast<ArrayDeclarationModifier*>(declarationModifier)->m_size;
}
return 0;
}
bool DeclarationModifierComputations::HasDynamicArrayCount() const
{
auto* declarationModifier = GetDeclarationModifier();
if (declarationModifier != nullptr && declarationModifier->GetType() == DeclarationModifierType::ARRAY)
{
return dynamic_cast<ArrayDeclarationModifier*>(declarationModifier)->m_dynamic_count_evaluation != nullptr;
}
return false;
}
const IEvaluation* DeclarationModifierComputations::GetDynamicArrayCountEvaluation() const
{
auto* declarationModifier = GetDeclarationModifier();
if (declarationModifier != nullptr && declarationModifier->GetType() == DeclarationModifierType::ARRAY)
{
return dynamic_cast<ArrayDeclarationModifier*>(declarationModifier)->m_dynamic_count_evaluation.get();
}
return nullptr;
}
std::vector<DeclarationModifierComputations> DeclarationModifierComputations::GetArrayEntries() const
{
std::vector<DeclarationModifierComputations> arrayEntries;
const auto arraySize = GetArraySize();
for (auto i = 0; i < arraySize; i++)
{
std::vector<int> childModifierIndices(m_modifier_indices.size() + 1);
std::copy(m_modifier_indices.begin(), m_modifier_indices.end(), childModifierIndices.begin());
childModifierIndices[childModifierIndices.size() - 1] = i;
arrayEntries.push_back(DeclarationModifierComputations(m_information, std::move(childModifierIndices)));
}
return arrayEntries;
}
bool DeclarationModifierComputations::IsSinglePointer() const
{
auto* declarationModifier = GetDeclarationModifier();
if (declarationModifier != nullptr
&& declarationModifier->GetType() == DeclarationModifierType::POINTER
&& !dynamic_cast<PointerDeclarationModifier*>(declarationModifier)->CountEvaluationIsArray(m_combined_index))
{
const auto following = GetFollowingDeclarationModifiers();
return !std::any_of(following.begin(), following.end(), [](const DeclarationModifier* modifier)
{
return modifier->GetType() == DeclarationModifierType::POINTER;
});
}
return false;
}
bool DeclarationModifierComputations::IsArrayPointer() const
{
auto* declarationModifier = GetDeclarationModifier();
if (declarationModifier != nullptr
&& declarationModifier->GetType() == DeclarationModifierType::POINTER
&& dynamic_cast<PointerDeclarationModifier*>(declarationModifier)->CountEvaluationIsArray(m_combined_index))
{
const auto following = GetFollowingDeclarationModifiers();
return !std::any_of(following.begin(), following.end(), [](const DeclarationModifier* modifier)
{
return modifier->GetType() == DeclarationModifierType::POINTER;
});
}
return false;
}
const IEvaluation* DeclarationModifierComputations::GetArrayPointerCountEvaluation() const
{
auto* declarationModifier = GetDeclarationModifier();
if (declarationModifier == nullptr || declarationModifier->GetType() != DeclarationModifierType::POINTER)
return nullptr;
return dynamic_cast<PointerDeclarationModifier*>(declarationModifier)->GetCountEvaluationForArrayIndex(m_combined_index);
}
bool DeclarationModifierComputations::IsPointerArray() const
{
auto* declarationModifier = GetDeclarationModifier();
if (declarationModifier == nullptr)
return false;
auto* nextDeclarationModifier = GetNextDeclarationModifier();
if (nextDeclarationModifier == nullptr)
return false;
const auto thisDeclModIsArray = declarationModifier->GetType() == DeclarationModifierType::POINTER
&& dynamic_cast<PointerDeclarationModifier*>(declarationModifier)->CountEvaluationIsArray(m_combined_index)
|| declarationModifier->GetType() == DeclarationModifierType::ARRAY;
if (!thisDeclModIsArray)
return false;
const auto nextDeclModIsSinglePointer = nextDeclarationModifier->GetType() == DeclarationModifierType::POINTER
&& !dynamic_cast<PointerDeclarationModifier*>(nextDeclarationModifier)->AnyCountEvaluationIsArray();
return nextDeclModIsSinglePointer;
}
const IEvaluation* DeclarationModifierComputations::GetPointerArrayCountEvaluation() const
{
auto* declarationModifier = GetDeclarationModifier();
if (declarationModifier == nullptr)
return nullptr;
if (declarationModifier->GetType() == DeclarationModifierType::POINTER)
{
return dynamic_cast<PointerDeclarationModifier*>(declarationModifier)->GetCountEvaluationForArrayIndex(m_combined_index);
}
if (declarationModifier->GetType() == DeclarationModifierType::ARRAY)
{
auto* arrayDeclarationModifier = dynamic_cast<ArrayDeclarationModifier*>(declarationModifier);
return arrayDeclarationModifier->m_dynamic_count_evaluation.get(); // This might be null in which case there is no evaluation but a static size
}
assert(false);
return nullptr;
}
bool DeclarationModifierComputations::IsDynamicArray() const
{
auto* declarationModifier = GetDeclarationModifier();
if (declarationModifier == nullptr)
return false;
return declarationModifier->GetType() == DeclarationModifierType::ARRAY
&& dynamic_cast<ArrayDeclarationModifier*>(declarationModifier)->m_dynamic_size_evaluation != nullptr;
}
const IEvaluation* DeclarationModifierComputations::GetDynamicArraySizeEvaluation() const
{
auto* declarationModifier = GetDeclarationModifier();
if (declarationModifier == nullptr
|| declarationModifier->GetType() != DeclarationModifierType::ARRAY)
return nullptr;
return dynamic_cast<ArrayDeclarationModifier*>(declarationModifier)->m_dynamic_size_evaluation.get();
}

View File

@ -0,0 +1,34 @@
#pragma once
#include "Utils/ClassUtils.h"
#include "Domain/Information/MemberInformation.h"
#include "Domain/Evaluation/IEvaluation.h"
class DeclarationModifierComputations
{
const MemberInformation* const m_information;
std::vector<int> m_modifier_indices;
int m_combined_index;
DeclarationModifierComputations(const MemberInformation* member, std::vector<int> modifierIndices);
public:
explicit DeclarationModifierComputations(const MemberInformation* member);
_NODISCARD DeclarationModifier* GetDeclarationModifier() const;
_NODISCARD DeclarationModifier* GetNextDeclarationModifier() const;
_NODISCARD std::vector<DeclarationModifier*> GetFollowingDeclarationModifiers() const;
_NODISCARD std::vector<int> GetArrayIndices() const;
_NODISCARD bool IsArray() const;
_NODISCARD int GetArraySize() const;
_NODISCARD bool HasDynamicArrayCount() const;
_NODISCARD const IEvaluation* GetDynamicArrayCountEvaluation() const;
_NODISCARD std::vector<DeclarationModifierComputations> GetArrayEntries() const;
_NODISCARD bool IsSinglePointer() const;
_NODISCARD bool IsArrayPointer() const;
_NODISCARD const IEvaluation* GetArrayPointerCountEvaluation() const;
_NODISCARD bool IsPointerArray() const;
_NODISCARD const IEvaluation* GetPointerArrayCountEvaluation() const;
_NODISCARD bool IsDynamicArray() const;
_NODISCARD const IEvaluation* GetDynamicArraySizeEvaluation() const;
};

View File

@ -0,0 +1,51 @@
#include "StructureComputations.h"
#include <cassert>
#include "MemberComputations.h"
StructureComputations::StructureComputations(const StructureInformation* structure)
: m_info(structure)
{
assert(m_info != nullptr);
}
bool StructureComputations::IsAsset() const
{
return m_info->m_asset_enum_entry != nullptr;
}
MemberInformation* StructureComputations::GetDynamicMember() const
{
for (const auto& member : m_info->m_ordered_members)
{
if (MemberComputations(member.get()).IsDynamicMember())
return member.get();
}
return nullptr;
}
std::vector<MemberInformation*> StructureComputations::GetUsedMembers() const
{
std::vector<MemberInformation*> members;
if (m_info->m_definition->GetType() == DataDefinitionType::UNION && GetDynamicMember() != nullptr)
{
for (const auto& member : m_info->m_ordered_members)
{
if (!MemberComputations(member.get()).ShouldIgnore())
members.push_back(member.get());
}
}
else
{
for (const auto& member : m_info->m_ordered_members)
{
if (!member->m_is_leaf && !MemberComputations(member.get()).ShouldIgnore())
members.push_back(member.get());
}
}
return members;
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "Domain/Information/StructureInformation.h"
class StructureComputations
{
const StructureInformation* const m_info;
public:
explicit StructureComputations(const StructureInformation* structure);
_NODISCARD bool IsAsset() const;
_NODISCARD MemberInformation* GetDynamicMember() const;
_NODISCARD std::vector<MemberInformation*> GetUsedMembers() const;
};

View File

@ -0,0 +1,6 @@
#include "ArrayDeclarationModifier.h"
DeclarationModifierType ArrayDeclarationModifier::GetType() const
{
return DeclarationModifierType::ARRAY;
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <memory>
#include "DeclarationModifier.h"
#include "Domain/Evaluation/IEvaluation.h"
class ArrayDeclarationModifier final : public DeclarationModifier
{
public:
int m_size;
/**
* \brief The array size is not actually given by \c m_size but instead is dynamic.
*/
std::unique_ptr<IEvaluation> m_dynamic_size_evaluation;
/**
* \brief The array has a size that is given by \c m_size but only a certain dynamic amount is handled by generated count.
*/
std::unique_ptr<IEvaluation> m_dynamic_count_evaluation;
DeclarationModifierType GetType() const override;
};

View File

@ -0,0 +1,75 @@
#include "BaseTypeDefinition.h"
BaseTypeDefinition::BaseTypeDefinition(std::string name, const unsigned size)
: DataDefinition("", std::move(name)),
m_size(size)
{
}
DataDefinitionType BaseTypeDefinition::GetType() const
{
return DataDefinitionType::BASE_TYPE;
}
unsigned BaseTypeDefinition::GetAlignment()
{
// Since this type has no members the alignment is always equal to the size.
return m_size;
}
unsigned BaseTypeDefinition::GetAlignment() const
{
return m_size;
}
bool BaseTypeDefinition::GetForceAlignment()
{
return false;
}
bool BaseTypeDefinition::GetForceAlignment() const
{
return false;
}
unsigned BaseTypeDefinition::GetSize()
{
return m_size;
}
unsigned BaseTypeDefinition::GetSize() const
{
return m_size;
}
const BaseTypeDefinition* const BaseTypeDefinition::FLOAT = new BaseTypeDefinition("float", 4);
const BaseTypeDefinition* const BaseTypeDefinition::DOUBLE = new BaseTypeDefinition("double", 8);
const BaseTypeDefinition* const BaseTypeDefinition::BOOL = new BaseTypeDefinition("bool", 1);
const BaseTypeDefinition* const BaseTypeDefinition::CHAR = new BaseTypeDefinition("char", 1);
const BaseTypeDefinition* const BaseTypeDefinition::UNSIGNED_CHAR = new BaseTypeDefinition("unsigned char", 1);
const BaseTypeDefinition* const BaseTypeDefinition::SHORT = new BaseTypeDefinition("short", 2);
const BaseTypeDefinition* const BaseTypeDefinition::UNSIGNED_SHORT = new BaseTypeDefinition("unsigned short", 2);
const BaseTypeDefinition* const BaseTypeDefinition::INT = new BaseTypeDefinition("int", 4);
const BaseTypeDefinition* const BaseTypeDefinition::UNSIGNED_INT = new BaseTypeDefinition("unsigned int", 4);
const BaseTypeDefinition* const BaseTypeDefinition::LONG = new BaseTypeDefinition("long", 4);
const BaseTypeDefinition* const BaseTypeDefinition::UNSIGNED_LONG = new BaseTypeDefinition("unsigned long", 4);
const BaseTypeDefinition* const BaseTypeDefinition::LONG_LONG = new BaseTypeDefinition("long long", 8);
const BaseTypeDefinition* const BaseTypeDefinition::UNSIGNED_LONG_LONG = new BaseTypeDefinition("unsigned long long", 8);
const BaseTypeDefinition* const BaseTypeDefinition::VOID = new BaseTypeDefinition("void", 0);
const BaseTypeDefinition* const BaseTypeDefinition::ALL_BASE_TYPES[]
{
FLOAT,
DOUBLE,
BOOL,
CHAR,
UNSIGNED_CHAR,
SHORT,
UNSIGNED_SHORT,
INT,
UNSIGNED_INT,
LONG,
UNSIGNED_LONG,
LONG_LONG,
UNSIGNED_LONG_LONG,
VOID
};

View File

@ -0,0 +1,37 @@
#pragma once
#include "DataDefinition.h"
class BaseTypeDefinition final : public DataDefinition
{
public:
const unsigned m_size;
private:
BaseTypeDefinition(std::string name, unsigned size);
public:
_NODISCARD DataDefinitionType GetType() const override;
_NODISCARD unsigned GetAlignment() override;
_NODISCARD unsigned GetAlignment() const;
_NODISCARD bool GetForceAlignment() override;
_NODISCARD bool GetForceAlignment() const;
_NODISCARD unsigned GetSize() override;
_NODISCARD unsigned GetSize() const;
static const BaseTypeDefinition* const FLOAT;
static const BaseTypeDefinition* const DOUBLE;
static const BaseTypeDefinition* const BOOL;
static const BaseTypeDefinition* const CHAR;
static const BaseTypeDefinition* const UNSIGNED_CHAR;
static const BaseTypeDefinition* const SHORT;
static const BaseTypeDefinition* const UNSIGNED_SHORT;
static const BaseTypeDefinition* const INT;
static const BaseTypeDefinition* const UNSIGNED_INT;
static const BaseTypeDefinition* const LONG;
static const BaseTypeDefinition* const UNSIGNED_LONG;
static const BaseTypeDefinition* const LONG_LONG;
static const BaseTypeDefinition* const UNSIGNED_LONG_LONG;
static const BaseTypeDefinition* const VOID;
static const BaseTypeDefinition* const ALL_BASE_TYPES[];
};

View File

@ -0,0 +1,19 @@
#include "DataDefinition.h"
#include <cassert>
#include <sstream>
#include "Utils/NamespaceBuilder.h"
DataDefinition::DataDefinition(std::string _namespace, std::string name)
: m_namespace(std::move(_namespace)),
m_name(std::move(name))
{
assert(!m_name.empty());
}
std::string DataDefinition::GetFullName() const
{
return NamespaceBuilder::Combine(m_namespace, m_name);
}

View File

@ -0,0 +1,37 @@
#pragma once
#include <string>
#include "Utils/ClassUtils.h"
enum class DataDefinitionType
{
STRUCT,
UNION,
ENUM,
TYPEDEF,
BASE_TYPE,
FORWARD_DECLARATION
};
class DataDefinition
{
public:
DataDefinition() = default;
DataDefinition(std::string _namespace, std::string name);
virtual ~DataDefinition() = default;
DataDefinition(const DataDefinition& other) = default;
DataDefinition(DataDefinition&& other) noexcept = default;
DataDefinition& operator=(const DataDefinition& other) = default;
DataDefinition& operator=(DataDefinition&& other) noexcept = default;
std::string m_namespace;
std::string m_name;
_NODISCARD virtual DataDefinitionType GetType() const = 0;
_NODISCARD virtual unsigned GetAlignment() = 0;
_NODISCARD virtual bool GetForceAlignment() = 0;
_NODISCARD virtual unsigned GetSize() = 0;
_NODISCARD std::string GetFullName() const;
};

View File

@ -0,0 +1,18 @@
#pragma once
#include "Utils/ClassUtils.h"
enum class DeclarationModifierType
{
POINTER,
ARRAY
};
class DeclarationModifier
{
public:
DeclarationModifier() = default;
virtual ~DeclarationModifier() = default;
_NODISCARD virtual DeclarationModifierType GetType() const = 0;
};

View File

@ -0,0 +1,57 @@
#include "DefinitionWithMembers.h"
DefinitionWithMembers::DefinitionWithMembers(std::string _namespace, std::string name, const unsigned pack)
: DataDefinition(std::move(_namespace), std::move(name)),
m_flags(0),
m_size(0),
m_alignment(0),
m_has_alignment_override(false),
m_anonymous(false),
m_pack(pack),
m_alignment_override(0)
{
}
void DefinitionWithMembers::CalculateAlignment()
{
if (m_has_alignment_override)
{
m_flags |= FLAG_ALIGNMENT_FORCED;
m_alignment = m_alignment_override;
}
else
{
m_alignment = 0;
for (const auto& member : m_members)
{
const auto memberAlignment = member->GetAlignment();
if (memberAlignment > m_alignment)
m_alignment = memberAlignment;
}
}
m_flags |= FLAG_ALIGNMENT_CALCULATED;
}
unsigned DefinitionWithMembers::GetAlignment()
{
if ((m_flags & FLAG_ALIGNMENT_CALCULATED) == 0)
CalculateAlignment();
return m_alignment;
}
bool DefinitionWithMembers::GetForceAlignment()
{
if ((m_flags & FLAG_ALIGNMENT_CALCULATED) == 0)
CalculateAlignment();
return m_flags & FLAG_ALIGNMENT_FORCED;
}
unsigned DefinitionWithMembers::GetSize()
{
if ((m_flags & FLAG_SIZE_CALCULATED) == 0)
CalculateSize();
return m_size;
}

View File

@ -0,0 +1,37 @@
#pragma once
#include <memory>
#include <vector>
#include "DataDefinition.h"
#include "Variable.h"
class DefinitionWithMembers : public DataDefinition
{
protected:
static constexpr int FLAG_SIZE_CALCULATED = 1 << 0;
static constexpr int FLAG_ALIGNMENT_CALCULATED = 1 << 1;
static constexpr int FLAG_ALIGNMENT_FORCED = 1 << 2;
unsigned m_flags;
unsigned m_size;
unsigned m_alignment;
virtual void CalculateSize() = 0;
void CalculateAlignment();
public:
bool m_has_alignment_override;
bool m_anonymous;
const unsigned m_pack;
unsigned m_alignment_override;
std::vector<std::unique_ptr<Variable>> m_members;
DefinitionWithMembers(std::string _namespace, std::string name, unsigned pack);
_NODISCARD unsigned GetAlignment() override;
_NODISCARD bool GetForceAlignment() override;
_NODISCARD unsigned GetSize() override;
};

View File

@ -0,0 +1,35 @@
#include "EnumDefinition.h"
#include <cassert>
EnumDefinition::EnumDefinition(std::string _namespace, std::string name, const BaseTypeDefinition* parentType)
: DataDefinition(std::move(_namespace), std::move(name)),
m_parent_type(parentType)
{
assert(parentType != nullptr);
}
DataDefinitionType EnumDefinition::GetType() const
{
return DataDefinitionType::ENUM;
}
unsigned EnumDefinition::GetAlignment()
{
return m_parent_type->GetAlignment();
}
bool EnumDefinition::GetForceAlignment()
{
return m_parent_type->GetForceAlignment();
}
unsigned EnumDefinition::GetSize()
{
return m_parent_type->GetSize();
}
void EnumDefinition::AddEnumMember(EnumMember enumMember)
{
m_members.emplace_back(std::make_unique<EnumMember>(std::move(enumMember)));
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <memory>
#include <vector>
#include "BaseTypeDefinition.h"
#include "DataDefinition.h"
#include "EnumMember.h"
class EnumDefinition final : public DataDefinition
{
public:
const BaseTypeDefinition* m_parent_type;
std::vector<std::unique_ptr<EnumMember>> m_members;
EnumDefinition(std::string _namespace, std::string name, const BaseTypeDefinition* parentType);
_NODISCARD DataDefinitionType GetType() const override;
_NODISCARD unsigned GetAlignment() override;
_NODISCARD bool GetForceAlignment() override;
_NODISCARD unsigned GetSize() override;
void AddEnumMember(EnumMember enumMember);
};

View File

@ -0,0 +1,12 @@
#include "EnumMember.h"
EnumMember::EnumMember()
: m_value(0)
{
}
EnumMember::EnumMember(std::string name, const long long value)
: m_name(std::move(name)),
m_value(value)
{
}

View File

@ -0,0 +1,13 @@
#pragma once
#include <string>
class EnumMember
{
public:
std::string m_name;
long long m_value;
EnumMember();
EnumMember(std::string name, long long value);
};

View File

@ -0,0 +1,28 @@
#include "ForwardDeclaration.h"
ForwardDeclaration::ForwardDeclaration(std::string _namespace, std::string name, DataDefinitionType type)
: DataDefinition(std::move(_namespace), std::move(name)),
m_forwarded_type(type),
m_definition(nullptr)
{
}
DataDefinitionType ForwardDeclaration::GetType() const
{
return DataDefinitionType::FORWARD_DECLARATION;
}
unsigned ForwardDeclaration::GetAlignment()
{
return 0;
}
bool ForwardDeclaration::GetForceAlignment()
{
return false;
}
unsigned ForwardDeclaration::GetSize()
{
return 0;
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "DataDefinition.h"
class ForwardDeclaration final : public DataDefinition
{
public:
const DataDefinitionType m_forwarded_type;
DataDefinition* m_definition;
ForwardDeclaration(std::string _namespace, std::string name, DataDefinitionType type);
_NODISCARD DataDefinitionType GetType() const override;
_NODISCARD unsigned GetAlignment() override;
_NODISCARD bool GetForceAlignment() override;
_NODISCARD unsigned GetSize() override;
};

View File

@ -0,0 +1,72 @@
#include "PointerDeclarationModifier.h"
#include "Domain/Evaluation/OperandStatic.h"
const IEvaluation* const PointerDeclarationModifier::DEFAULT_COUNT = new OperandStatic(1);
DeclarationModifierType PointerDeclarationModifier::GetType() const
{
return DeclarationModifierType::POINTER;
}
const IEvaluation* PointerDeclarationModifier::GetCountEvaluation() const
{
if (m_count_evaluation)
return m_count_evaluation.get();
return DEFAULT_COUNT;
}
const IEvaluation* PointerDeclarationModifier::GetCountEvaluationForArrayIndex(const int index)
{
if (index >= 0 && m_count_evaluation_by_array_index.size() > static_cast<unsigned>(index))
{
return m_count_evaluation_by_array_index[index].get();
}
if (m_count_evaluation)
{
return m_count_evaluation.get();
}
return DEFAULT_COUNT;
}
bool PointerDeclarationModifier::EvaluationIsArray(const IEvaluation* evaluation)
{
return !evaluation->IsStatic() || evaluation->EvaluateNumeric() > 1;
}
bool PointerDeclarationModifier::CountEvaluationIsArray() const
{
if (m_count_evaluation)
{
return EvaluationIsArray(m_count_evaluation.get());
}
return EvaluationIsArray(DEFAULT_COUNT);
}
bool PointerDeclarationModifier::CountEvaluationIsArray(const int index) const
{
if(index >= 0 && m_count_evaluation_by_array_index.size() > static_cast<unsigned>(index))
{
return EvaluationIsArray(m_count_evaluation_by_array_index[index].get());
}
return CountEvaluationIsArray();
}
bool PointerDeclarationModifier::AnyCountEvaluationIsArray() const
{
if (m_count_evaluation && EvaluationIsArray(m_count_evaluation.get()))
return true;
for(const auto& arrayCountEvaluation : m_count_evaluation_by_array_index)
{
if (EvaluationIsArray(arrayCountEvaluation.get()))
return true;
}
return EvaluationIsArray(DEFAULT_COUNT);
}

View File

@ -0,0 +1,26 @@
#pragma once
#include <memory>
#include <vector>
#include "DeclarationModifier.h"
#include "Domain/Evaluation/IEvaluation.h"
class PointerDeclarationModifier final : public DeclarationModifier
{
static const IEvaluation* const DEFAULT_COUNT;
static bool EvaluationIsArray(const IEvaluation* evaluation);
public:
std::unique_ptr<IEvaluation> m_count_evaluation;
std::vector<std::unique_ptr<IEvaluation>> m_count_evaluation_by_array_index;
_NODISCARD DeclarationModifierType GetType() const override;
_NODISCARD const IEvaluation* GetCountEvaluation() const;
_NODISCARD const IEvaluation* GetCountEvaluationForArrayIndex(int index);
_NODISCARD bool CountEvaluationIsArray() const;
_NODISCARD bool CountEvaluationIsArray(int index) const;
_NODISCARD bool AnyCountEvaluationIsArray() const;
};

View File

@ -0,0 +1,49 @@
#include "StructDefinition.h"
#include "Utils/AlignmentUtils.h"
void StructDefinition::CalculateSize()
{
m_size = 0;
auto currentBitOffset = 0u;
for(const auto& member : m_members)
{
if(member->m_type_declaration->m_has_custom_bit_size)
{
currentBitOffset += member->m_type_declaration->m_custom_bit_size;
}
else
{
if (currentBitOffset > 0)
{
currentBitOffset = AlignmentUtils::Align(currentBitOffset, 8u);
m_size += currentBitOffset / 8;
currentBitOffset = 0;
}
m_size = AlignmentUtils::Align(m_size, member->GetForceAlignment() ? member->GetAlignment() : std::min(member->GetAlignment(), m_pack));
m_size += member->m_type_declaration->GetSize();
}
}
if (currentBitOffset > 0)
{
currentBitOffset = AlignmentUtils::Align(currentBitOffset, 8u);
m_size += currentBitOffset / 8;
}
m_size = AlignmentUtils::Align(m_size, GetAlignment());
m_flags |= FLAG_SIZE_CALCULATED;
}
StructDefinition::StructDefinition(std::string _namespace, std::string name, const int pack)
: DefinitionWithMembers(std::move(_namespace), std::move(name), pack)
{
}
DataDefinitionType StructDefinition::GetType() const
{
return DataDefinitionType::STRUCT;
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "DefinitionWithMembers.h"
class StructDefinition final : public DefinitionWithMembers
{
protected:
void CalculateSize() override;
public:
StructDefinition(std::string _namespace, std::string name, int pack);
_NODISCARD DataDefinitionType GetType() const override;
};

View File

@ -0,0 +1,90 @@
#include "TypeDeclaration.h"
#include <cassert>
#include "ArrayDeclarationModifier.h"
TypeDeclaration::TypeDeclaration(DataDefinition* type)
: m_flags(0),
m_size(0),
m_alignment(0),
m_is_const(false),
m_has_custom_bit_size(false),
m_type(type),
m_custom_bit_size(0)
{
assert(m_type != nullptr);
}
void TypeDeclaration::CalculateSize()
{
auto currentSize = m_type->GetSize();
for(auto i = m_declaration_modifiers.size(); i > 0; i--)
{
const auto& declarationModifier = m_declaration_modifiers[i - 1];
switch(declarationModifier->GetType())
{
case DeclarationModifierType::POINTER:
currentSize = POINTER_SIZE;
break;
case DeclarationModifierType::ARRAY:
currentSize *= dynamic_cast<ArrayDeclarationModifier*>(declarationModifier.get())->m_size;
break;
}
}
m_flags |= FLAG_SIZE_CALCULATED;
}
void TypeDeclaration::CalculateAlignment()
{
auto hasPointerModifier = false;
for (const auto& declarationModifier : m_declaration_modifiers)
{
if (declarationModifier->GetType() == DeclarationModifierType::POINTER)
{
hasPointerModifier = true;
break;
}
}
if (hasPointerModifier)
{
m_alignment = POINTER_SIZE;
}
else
{
m_alignment = m_type->GetAlignment();
if (m_type->GetForceAlignment())
m_flags |= FLAG_ALIGNMENT_FORCED;
}
m_flags |= FLAG_ALIGNMENT_CALCULATED;
}
unsigned TypeDeclaration::GetSize()
{
if ((m_flags & FLAG_SIZE_CALCULATED) == 0)
CalculateSize();
return m_size;
}
unsigned TypeDeclaration::GetAlignment()
{
if ((m_flags & FLAG_ALIGNMENT_CALCULATED) == 0)
CalculateAlignment();
return m_alignment;
}
bool TypeDeclaration::GetForceAlignment()
{
if ((m_flags & FLAG_ALIGNMENT_CALCULATED) == 0)
CalculateAlignment();
return m_flags & FLAG_ALIGNMENT_FORCED;
}

View File

@ -0,0 +1,37 @@
#pragma once
#include <memory>
#include <vector>
#include <cstdint>
#include "DataDefinition.h"
#include "DeclarationModifier.h"
class TypeDeclaration
{
static constexpr unsigned POINTER_SIZE = sizeof(uint32_t); // TODO: Change this to support 64bit
static constexpr int FLAG_SIZE_CALCULATED = 1 << 0;
static constexpr int FLAG_ALIGNMENT_CALCULATED = 1 << 1;
static constexpr int FLAG_ALIGNMENT_FORCED = 1 << 2;
unsigned m_flags;
unsigned m_size;
unsigned m_alignment;
void CalculateSize();
void CalculateAlignment();
public:
explicit TypeDeclaration(DataDefinition* type);
bool m_is_const;
bool m_has_custom_bit_size;
DataDefinition* m_type;
unsigned m_custom_bit_size;
std::vector<std::unique_ptr<DeclarationModifier>> m_declaration_modifiers;
unsigned GetSize();
unsigned GetAlignment();
bool GetForceAlignment();
};

View File

@ -0,0 +1,33 @@
#include "TypedefDefinition.h"
TypedefDefinition::TypedefDefinition(std::string _namespace, std::string name, std::unique_ptr<TypeDeclaration> typeDeclaration)
: DataDefinition(std::move(_namespace), std::move(name)),
m_has_alignment_override(false),
m_alignment_override(0),
m_type_declaration(std::move(typeDeclaration))
{
}
DataDefinitionType TypedefDefinition::GetType() const
{
return DataDefinitionType::TYPEDEF;
}
unsigned TypedefDefinition::GetAlignment()
{
if (m_has_alignment_override)
{
return m_alignment_override;
}
return m_type_declaration->GetAlignment();
}
bool TypedefDefinition::GetForceAlignment()
{
return m_has_alignment_override || m_type_declaration->GetForceAlignment();
}
unsigned TypedefDefinition::GetSize()
{
return m_type_declaration->GetSize();
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "DataDefinition.h"
#include "TypeDeclaration.h"
class TypedefDefinition final : public DataDefinition
{
public:
bool m_has_alignment_override;
unsigned m_alignment_override;
std::unique_ptr<TypeDeclaration> m_type_declaration;
TypedefDefinition(std::string _namespace, std::string name, std::unique_ptr<TypeDeclaration> typeDeclaration);
_NODISCARD DataDefinitionType GetType() const override;
_NODISCARD unsigned GetAlignment() override;
_NODISCARD bool GetForceAlignment() override;
_NODISCARD unsigned GetSize() override;
};

View File

@ -0,0 +1,29 @@
#include "UnionDefinition.h"
#include "Utils/AlignmentUtils.h"
void UnionDefinition::CalculateSize()
{
m_size = 0;
for(const auto& member : m_members)
{
const auto memberSize = member->m_type_declaration->GetSize();
if (memberSize > m_size)
m_size = memberSize;
}
m_size = AlignmentUtils::Align(m_size, GetAlignment());
m_flags |= FLAG_SIZE_CALCULATED;
}
UnionDefinition::UnionDefinition(std::string _namespace, std::string name, const int pack)
: DefinitionWithMembers(std::move(_namespace), std::move(name), pack)
{
}
DataDefinitionType UnionDefinition::GetType() const
{
return DataDefinitionType::UNION;
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "DefinitionWithMembers.h"
class UnionDefinition final : public DefinitionWithMembers
{
protected:
void CalculateSize() override;
public:
UnionDefinition(std::string _namespace, std::string name, int pack);
_NODISCARD DataDefinitionType GetType() const override;
};

View File

@ -0,0 +1,14 @@
#include "Variable.h"
unsigned Variable::GetAlignment()
{
if (m_has_alignment_override)
return m_alignment_override;
return m_type_declaration->GetAlignment();
}
bool Variable::GetForceAlignment()
{
return m_has_alignment_override || m_type_declaration->GetForceAlignment();
}

View File

@ -0,0 +1,18 @@
#pragma once
#include <memory>
#include <string>
#include "TypeDeclaration.h"
class Variable
{
public:
std::string m_name;
bool m_has_alignment_override;
unsigned m_alignment_override;
std::unique_ptr<TypeDeclaration> m_type_declaration;
unsigned GetAlignment();
bool GetForceAlignment();
};

View File

@ -0,0 +1,26 @@
#pragma once
#include "Utils/ClassUtils.h"
enum class EvaluationType
{
OPERAND_DYNAMIC,
OPERAND_STATIC,
OPERATION
};
class IEvaluation
{
public:
IEvaluation() = default;
virtual ~IEvaluation() = default;
IEvaluation(const IEvaluation& other) = default;
IEvaluation(IEvaluation&& other) noexcept = default;
IEvaluation& operator=(const IEvaluation& other) = default;
IEvaluation& operator=(IEvaluation&& other) noexcept = default;
_NODISCARD virtual EvaluationType GetType() const = 0;
_NODISCARD virtual bool IsStatic() const = 0;
_NODISCARD virtual int EvaluateNumeric() const = 0;
};

View File

@ -0,0 +1,24 @@
#include "OperandDynamic.h"
#include <cassert>
OperandDynamic::OperandDynamic(StructureInformation* structure)
: m_structure(structure)
{
}
EvaluationType OperandDynamic::GetType() const
{
return EvaluationType::OPERAND_DYNAMIC;
}
bool OperandDynamic::IsStatic() const
{
return false;
}
int OperandDynamic::EvaluateNumeric() const
{
assert(false);
return 0;
}

View File

@ -0,0 +1,21 @@
#pragma once
#include <memory>
#include <vector>
#include "IEvaluation.h"
#include "Domain/Information/MemberInformation.h"
#include "Domain/Information/StructureInformation.h"
class OperandDynamic final : public IEvaluation
{
public:
StructureInformation* const m_structure;
std::vector<MemberInformation*> m_referenced_member_chain;
std::vector<std::unique_ptr<IEvaluation>> m_array_indices;
explicit OperandDynamic(StructureInformation* structure);
_NODISCARD EvaluationType GetType() const override;
_NODISCARD bool IsStatic() const override;
_NODISCARD int EvaluateNumeric() const override;
};

View File

@ -0,0 +1,28 @@
#include "OperandStatic.h"
OperandStatic::OperandStatic(const int value)
: m_value(value),
m_enum_member(nullptr)
{
}
OperandStatic::OperandStatic(const int value, EnumMember* enumMember)
: m_value(value),
m_enum_member(enumMember)
{
}
EvaluationType OperandStatic::GetType() const
{
return EvaluationType::OPERAND_STATIC;
}
bool OperandStatic::IsStatic() const
{
return true;
}
int OperandStatic::EvaluateNumeric() const
{
return m_value;
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "IEvaluation.h"
#include "Domain/Definition/EnumMember.h"
class OperandStatic final : public IEvaluation
{
public:
const int m_value;
EnumMember* const m_enum_member;
explicit OperandStatic(int value);
OperandStatic(int value, EnumMember* enumMember);
_NODISCARD EvaluationType GetType() const override;
_NODISCARD bool IsStatic() const override;
_NODISCARD int EvaluateNumeric() const override;
};

View File

@ -0,0 +1,33 @@
#include "Operation.h"
Operation::Operation(const OperationType* type)
: m_operation_type(type)
{
}
EvaluationType Operation::GetType() const
{
return EvaluationType::OPERATION;
}
bool Operation::IsStatic() const
{
return m_operand1->IsStatic() && m_operand2->IsStatic();
}
int Operation::EvaluateNumeric() const
{
return m_operation_type->m_evaluation_function(m_operand1->EvaluateNumeric(), m_operand2->EvaluateNumeric());
}
bool Operation::Operand1NeedsParenthesis() const
{
return m_operand1->GetType() == EvaluationType::OPERATION
&& dynamic_cast<Operation*>(m_operand1.get())->m_operation_type->m_precedence > m_operation_type->m_precedence;
}
bool Operation::Operand2NeedsParenthesis() const
{
return m_operand2->GetType() == EvaluationType::OPERATION
&& dynamic_cast<Operation*>(m_operand2.get())->m_operation_type->m_precedence > m_operation_type->m_precedence;
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <memory>
#include "Utils/ClassUtils.h"
#include "IEvaluation.h"
#include "OperationType.h"
class Operation final : public IEvaluation
{
public:
const OperationType* const m_operation_type;
std::unique_ptr<IEvaluation> m_operand1;
std::unique_ptr<IEvaluation> m_operand2;
explicit Operation(const OperationType* type);
_NODISCARD EvaluationType GetType() const override;
_NODISCARD bool IsStatic() const override;
_NODISCARD int EvaluateNumeric() const override;
_NODISCARD bool Operand1NeedsParenthesis() const;
_NODISCARD bool Operand2NeedsParenthesis() const;
};

View File

@ -0,0 +1,139 @@
#include "OperationType.h"
OperationType::OperationType(std::string syntax, const OperationPrecedence precedence, std::function<int(int, int)> evaluationFunction)
: m_syntax(std::move(syntax)),
m_precedence(precedence),
m_evaluation_function(std::move(evaluationFunction))
{
}
const OperationType* const OperationType::OPERATION_ADD
= new OperationType("+", OperationPrecedence::ADDITION_SUBTRACTION, [](auto op1, auto op2)
{
return op1 + op2;
});
const OperationType* const OperationType::OPERATION_SUBTRACT
= new OperationType("-", OperationPrecedence::ADDITION_SUBTRACTION, [](auto op1, auto op2)
{
return op1 - op2;
});
const OperationType* const OperationType::OPERATION_MULTIPLY
= new OperationType("*", OperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER, [](auto op1, auto op2)
{
return op1 * op2;
});
const OperationType* const OperationType::OPERATION_DIVIDE
= new OperationType("/", OperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER, [](auto op1, auto op2)
{
return op1 / op2;
});
const OperationType* const OperationType::OPERATION_REMAINDER
= new OperationType("%", OperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER, [](auto op1, auto op2)
{
return op1 % op2;
});
const OperationType* const OperationType::OPERATION_BITWISE_AND
= new OperationType("&", OperationPrecedence::BITWISE_AND, [](auto op1, auto op2)
{
return op1 & op2;
});
const OperationType* const OperationType::OPERATION_BITWISE_XOR
= new OperationType("^", OperationPrecedence::BITWISE_XOR, [](auto op1, auto op2)
{
return op1 ^ op2;
});
const OperationType* const OperationType::OPERATION_BITWISE_OR
= new OperationType("|", OperationPrecedence::BITWISE_OR, [](auto op1, auto op2)
{
return op1 | op2;
});
const OperationType* const OperationType::OPERATION_SHIFT_LEFT
= new OperationType("<<", OperationPrecedence::BITWISE_SHIFT, [](auto op1, auto op2)
{
return op1 << op2;
});
const OperationType* const OperationType::OPERATION_SHIFT_RIGHT
= new OperationType(">>", OperationPrecedence::BITWISE_SHIFT, [](auto op1, auto op2)
{
return op1 >> op2;
});
const OperationType* const OperationType::OPERATION_GREATER_THAN
= new OperationType(">", OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, [](auto op1, auto op2)
{
return op1 > op2 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_GREATER_EQUALS_THAN
= new OperationType(">=", OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, [](auto op1, auto op2)
{
return op1 >= op2 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_LESS_THAN
= new OperationType("<", OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, [](auto op1, auto op2)
{
return op1 < op2 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_LESS_EQUALS_THAN
= new OperationType("<=", OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, [](auto op1, auto op2)
{
return op1 <= op2 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_EQUALS
= new OperationType("==", OperationPrecedence::RELATIONAL_EQUALS, [](auto op1, auto op2)
{
return op1 == op2 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_NOT_EQUALS
= new OperationType("!=", OperationPrecedence::RELATIONAL_EQUALS, [](auto op1, auto op2)
{
return op1 != op2 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_AND
= new OperationType("&&", OperationPrecedence::LOGICAL_AND, [](auto op1, auto op2)
{
return op1 > 0 && op2 > 0 ? 1 : 0;
});
const OperationType* const OperationType::OPERATION_OR
= new OperationType("||", OperationPrecedence::LOGICAL_OR, [](auto op1, auto op2)
{
return op1 > 0 || op2 > 0 ? 1 : 0;
});
const OperationType* const OperationType::ALL_OPERATION_TYPES[]
{
OPERATION_ADD,
OPERATION_SUBTRACT,
OPERATION_MULTIPLY,
OPERATION_DIVIDE,
OPERATION_REMAINDER,
OPERATION_BITWISE_AND,
OPERATION_BITWISE_XOR,
OPERATION_BITWISE_OR,
OPERATION_SHIFT_LEFT,
OPERATION_SHIFT_RIGHT,
OPERATION_GREATER_THAN,
OPERATION_GREATER_EQUALS_THAN,
OPERATION_LESS_THAN,
OPERATION_LESS_EQUALS_THAN,
OPERATION_EQUALS,
OPERATION_NOT_EQUALS,
OPERATION_AND,
OPERATION_OR
};

View File

@ -0,0 +1,52 @@
#pragma once
#include <functional>
#include <string>
// https://en.cppreference.com/w/cpp/language/operator_precedence
enum class OperationPrecedence
{
MULTIPLICATION_DIVISION_REMAINDER = 1,
ADDITION_SUBTRACTION = 2,
BITWISE_SHIFT = 3,
RELATIONAL_GREATER_LESS_THAN = 4,
RELATIONAL_EQUALS = 5,
BITWISE_AND = 6,
BITWISE_XOR = 7,
BITWISE_OR = 8,
LOGICAL_AND = 9,
LOGICAL_OR = 10
};
class OperationType
{
public:
std::string m_syntax;
OperationPrecedence m_precedence;
std::function<int(int operand1, int operand2)> m_evaluation_function;
private:
OperationType(std::string syntax, OperationPrecedence precedence, std::function<int(int, int)> evaluationFunction);
public:
static const OperationType* const OPERATION_ADD;
static const OperationType* const OPERATION_SUBTRACT;
static const OperationType* const OPERATION_MULTIPLY;
static const OperationType* const OPERATION_DIVIDE;
static const OperationType* const OPERATION_REMAINDER;
static const OperationType* const OPERATION_BITWISE_AND;
static const OperationType* const OPERATION_BITWISE_XOR;
static const OperationType* const OPERATION_BITWISE_OR;
static const OperationType* const OPERATION_SHIFT_LEFT;
static const OperationType* const OPERATION_SHIFT_RIGHT;
static const OperationType* const OPERATION_GREATER_THAN;
static const OperationType* const OPERATION_GREATER_EQUALS_THAN;
static const OperationType* const OPERATION_LESS_THAN;
static const OperationType* const OPERATION_LESS_EQUALS_THAN;
static const OperationType* const OPERATION_EQUALS;
static const OperationType* const OPERATION_NOT_EQUALS;
static const OperationType* const OPERATION_AND;
static const OperationType* const OPERATION_OR;
static const OperationType* const ALL_OPERATION_TYPES[];
};

View File

@ -0,0 +1,6 @@
#include "CustomAction.h"
CustomAction::CustomAction(std::string actionName)
: m_action_name(std::move(actionName))
{
}

View File

@ -0,0 +1,15 @@
#pragma once
#include <string>
#include <vector>
#include "Domain/Definition/DataDefinition.h"
class CustomAction
{
public:
std::string m_action_name;
std::vector<DataDefinition*> m_parameter_types;
explicit CustomAction(std::string actionName);
};

View File

@ -0,0 +1,9 @@
#include "FastFileBlock.h"
FastFileBlock::FastFileBlock(std::string name, const unsigned index, const FastFileBlockType type, const bool isDefault)
: m_name(std::move(name)),
m_index(index),
m_type(type),
m_is_default(isDefault)
{
}

View File

@ -0,0 +1,22 @@
#pragma once
#include <string>
enum class FastFileBlockType
{
TEMP,
RUNTIME,
DELAY,
NORMAL
};
class FastFileBlock
{
public:
std::string m_name;
unsigned m_index;
FastFileBlockType m_type;
bool m_is_default;
FastFileBlock(std::string name, unsigned index, FastFileBlockType type, bool isDefault);
};

View File

@ -0,0 +1,13 @@
#include "MemberInformation.h"
MemberInformation::MemberInformation(StructureInformation* parent, StructureInformation* type, Variable* member)
: m_parent(parent),
m_type(type),
m_member(member),
m_is_string(false),
m_is_script_string(false),
m_is_reusable(false),
m_is_leaf(false),
m_fast_file_block(nullptr)
{
}

View File

@ -0,0 +1,26 @@
#pragma once
#include <memory>
#include "Utils/ClassUtils.h"
#include "StructureInformation.h"
#include "Domain/Definition/Variable.h"
#include "Domain/FastFile/FastFileBlock.h"
#include "Domain/Evaluation/IEvaluation.h"
class StructureInformation;
class MemberInformation
{
public:
StructureInformation* m_parent;
StructureInformation* m_type;
Variable* m_member;
bool m_is_string;
bool m_is_script_string;
bool m_is_reusable;
bool m_is_leaf;
std::unique_ptr<IEvaluation> m_condition;
FastFileBlock* m_fast_file_block;
MemberInformation(StructureInformation* parent, StructureInformation* type, Variable* member);
};

View File

@ -0,0 +1,17 @@
#include "StructureInformation.h"
StructureInformation::StructureInformation(DefinitionWithMembers* definition)
: m_has_non_default_fast_file_align(false),
m_custom_fast_file_align(0),
m_definition(definition),
m_asset_enum_entry(nullptr),
m_is_leaf(false),
m_non_embedded_reference_exists(false),
m_single_pointer_reference_exists(false),
m_array_pointer_reference_exists(false),
m_array_reference_exists(false),
m_reference_from_non_default_normal_block_exists(false),
m_post_load_action(nullptr),
m_block(nullptr)
{
}

View File

@ -0,0 +1,36 @@
#pragma once
#include "Utils/ClassUtils.h"
#include "MemberInformation.h"
#include "Domain/Definition/DefinitionWithMembers.h"
#include "Domain/Definition/EnumMember.h"
#include "Domain/Extension/CustomAction.h"
#include "Domain/FastFile/FastFileBlock.h"
class MemberInformation;
class StructureInformation
{
public:
bool m_has_non_default_fast_file_align;
unsigned m_custom_fast_file_align;
DefinitionWithMembers* const m_definition;
EnumMember* m_asset_enum_entry;
std::vector<StructureInformation*> m_usages;
std::vector<std::unique_ptr<MemberInformation>> m_ordered_members;
bool m_is_leaf;
bool m_non_embedded_reference_exists;
bool m_single_pointer_reference_exists;
bool m_array_pointer_reference_exists;
bool m_array_reference_exists;
bool m_reference_from_non_default_normal_block_exists;
std::unique_ptr<CustomAction> m_post_load_action;
FastFileBlock* m_block;
std::vector<MemberInformation*> m_name_chain;
explicit StructureInformation(DefinitionWithMembers* definition);
};