2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-09-05 00:07:25 +00:00

Add information and computations to ZCG cpp

This commit is contained in:
Jan
2021-02-08 14:33:57 +01:00
parent 65cf1ef9c2
commit 3b716965a5
33 changed files with 876 additions and 54 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;
};