#include "BaseTemplate.h" #include "Domain/Computations/MemberComputations.h" #include "Domain/Computations/StructureComputations.h" #include "Domain/Definition/ArrayDeclarationModifier.h" #include BaseTemplate::BaseTemplate(std::ostream& stream, const BaseRenderingContext& context) : m_out(stream), m_intendation(0u), m_env(context) { } void BaseTemplate::DoIntendation() const { for (auto i = 0u; i < m_intendation; i++) m_out << INTENDATION; } // clang-format off void BaseTemplate::AddGeneratedHint() const { LINE("// ====================================================================") LINE("// This file has been generated by ZoneCodeGenerator.") LINE("// Do not modify.") LINE("// Any changes will be discarded when regenerating.") LINE("// ====================================================================") LINE("") } // clang-format on std::string BaseTemplate::Upper(std::string str) { for (auto& c : str) c = static_cast(toupper(c)); return str; } std::string BaseTemplate::Lower(std::string str) { for (auto& c : str) c = static_cast(tolower(c)); return str; } void BaseTemplate::MakeSafeTypeNameInternal(const DataDefinition* def, std::ostringstream& str) { for (const auto& c : def->m_name) { if (isspace(c)) str << "_"; else str << c; } } void BaseTemplate::MakeTypeVarNameInternal(const DataDefinition* def, std::ostringstream& str) { str << "var"; MakeSafeTypeNameInternal(def, str); } void BaseTemplate::MakeTypePtrVarNameInternal(const DataDefinition* def, std::ostringstream& str) { str << "var"; MakeSafeTypeNameInternal(def, str); str << "Ptr"; } void BaseTemplate::MakeArrayIndicesInternal(const DeclarationModifierComputations& modifierComputations, std::ostringstream& str) { for (const auto index : modifierComputations.GetArrayIndices()) { str << "[" << index << "]"; } } std::string BaseTemplate::MakeTypeVarName(const DataDefinition* def) { std::ostringstream str; MakeTypeVarNameInternal(def, str); return str.str(); } std::string BaseTemplate::MakeTypePtrVarName(const DataDefinition* def) { std::ostringstream str; MakeTypePtrVarNameInternal(def, str); return str.str(); } std::string BaseTemplate::MakeSafeTypeName(const DataDefinition* def) { std::ostringstream str; MakeSafeTypeNameInternal(def, str); return str.str(); } std::string BaseTemplate::MakeMemberAccess(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier) { std::ostringstream str; MakeTypeVarNameInternal(info->m_definition, str); str << "->" << member->m_member->m_name; MakeArrayIndicesInternal(modifier, str); return str.str(); } std::string BaseTemplate::MakeTypeDecl(const TypeDeclaration* decl) { std::ostringstream str; if (decl->m_is_const) { str << "const "; } str << decl->m_type->GetFullName(); return str.str(); } std::string BaseTemplate::MakeFollowingReferences(const std::vector& modifiers) { std::ostringstream str; for (const auto* modifier : modifiers) { if (modifier->GetType() == DeclarationModifierType::ARRAY) { const auto* array = dynamic_cast(modifier); str << "[" << array->m_size << "]"; } else { str << "*"; } } return str.str(); } std::string BaseTemplate::MakeArrayIndices(const DeclarationModifierComputations& modifierComputations) { std::ostringstream str; MakeArrayIndicesInternal(modifierComputations, str); return str.str(); } std::string BaseTemplate::MakeCustomActionCall(const CustomAction* action) { std::ostringstream str; str << "m_actions." << action->m_action_name << "("; auto first = true; for (const auto* def : action->m_parameter_types) { if (first) { first = false; } else { str << ", "; } MakeTypeVarNameInternal(def, str); } str << ");"; return str.str(); } std::string BaseTemplate::MakeArrayCount(const ArrayDeclarationModifier* arrayModifier) { if (arrayModifier->m_dynamic_count_evaluation) { return MakeEvaluation(arrayModifier->m_dynamic_count_evaluation.get()); } return std::to_string(arrayModifier->m_size); } void BaseTemplate::MakeOperandStatic(const OperandStatic* op, std::ostringstream& str) { if (op->m_enum_member != nullptr) { str << op->m_enum_member->m_name; } else { str << op->m_value; } } void BaseTemplate::MakeOperandDynamic(const OperandDynamic* op, std::ostringstream& str) { MakeTypeVarNameInternal(op->m_structure->m_definition, str); if (!op->m_referenced_member_chain.empty()) { str << "->"; const auto lastEntry = op->m_referenced_member_chain.end() - 1; for (auto i = op->m_referenced_member_chain.begin(); i != lastEntry; ++i) { MemberComputations computations(*i); str << (*i)->m_member->m_name; if (computations.ContainsNonEmbeddedReference()) str << "->"; else str << "."; } str << (*lastEntry)->m_member->m_name; } for (const auto& arrayIndex : op->m_array_indices) { str << "["; MakeEvaluationInternal(arrayIndex.get(), str); str << "]"; } } void BaseTemplate::MakeOperation(const Operation* operation, std::ostringstream& str) { if (operation->Operand1NeedsParenthesis()) { str << "("; MakeEvaluationInternal(operation->m_operand1.get(), str); str << ")"; } else MakeEvaluationInternal(operation->m_operand1.get(), str); str << " " << operation->m_operation_type->m_syntax << " "; if (operation->Operand2NeedsParenthesis()) { str << "("; MakeEvaluationInternal(operation->m_operand2.get(), str); str << ")"; } else MakeEvaluationInternal(operation->m_operand2.get(), str); } void BaseTemplate::MakeEvaluationInternal(const IEvaluation* evaluation, std::ostringstream& str) { if (evaluation->GetType() == EvaluationType::OPERATION) MakeOperation(dynamic_cast(evaluation), str); else if (evaluation->GetType() == EvaluationType::OPERAND_STATIC) MakeOperandStatic(dynamic_cast(evaluation), str); else if (evaluation->GetType() == EvaluationType::OPERAND_DYNAMIC) MakeOperandDynamic(dynamic_cast(evaluation), str); } std::string BaseTemplate::MakeAllocAlignment(const StructureInformation& info) const { if (info.m_alloc_alignment) return MakeEvaluation(info.m_alloc_alignment.get()); return std::to_string(info.m_definition->GetAlignment(m_env.m_word_size)); } std::string BaseTemplate::MakeEvaluation(const IEvaluation* evaluation) { std::ostringstream str; MakeEvaluationInternal(evaluation, str); return str.str(); } bool BaseTemplate::ShouldGenerateFillMethod(const RenderingUsedType& type) { const auto isNotForeignAsset = type.m_is_context_asset || !type.m_info || !StructureComputations(type.m_info).IsAsset(); const auto hasMismatchingStructure = type.m_info && type.m_type == type.m_info->m_definition && !type.m_info->m_has_matching_cross_platform_memory_layout; const auto isEmbeddedDynamic = type.m_info && type.m_info->m_embedded_reference_exists && StructureComputations(type.m_info).GetDynamicMember(); return isNotForeignAsset && (hasMismatchingStructure || isEmbeddedDynamic); } size_t BaseTemplate::SizeForDeclModifierLevel(const MemberInformation& memberInfo, const size_t level) const { const auto& declModifiers = memberInfo.m_member->m_type_declaration->m_declaration_modifiers; if (declModifiers.empty()) return memberInfo.m_member->m_type_declaration->GetSize(m_env.m_word_size); if (level == 0) return memberInfo.m_member->m_type_declaration->GetSize(m_env.m_word_size); size_t currentSize = memberInfo.m_member->m_type_declaration->m_type->GetSize(m_env.m_word_size); const auto end = declModifiers.rbegin() + (declModifiers.size() - level); for (auto i = declModifiers.rbegin(); i != end; ++i) { if ((*i)->GetType() == DeclarationModifierType::POINTER) currentSize = m_env.m_pointer_size; else currentSize *= dynamic_cast(i->get())->m_size; } return currentSize; } size_t BaseTemplate::OffsetForMemberModifier(const MemberInformation& memberInfo, const DeclarationModifierComputations& modifier, const size_t nestedBaseOffset) const { size_t curOffset = memberInfo.m_member->m_offset; auto curLevel = 0u; for (const auto index : modifier.GetArrayIndices()) { if (index > 0) curOffset += index * SizeForDeclModifierLevel(memberInfo, curLevel + 1); curLevel++; } return curOffset + nestedBaseOffset; } bool BaseTemplate::MemoryLayoutMatches(const StructureInformation& structureInfo) const { return !m_env.m_word_size_mismatch || structureInfo.m_has_matching_cross_platform_memory_layout; }