2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-06-07 09:12:37 +00:00

fix: various wrong alignment values (#823)

* fix: alignment mistakes on various games

* chore: reduce overhead of zcg definition with members fields

* fix: make sure Material alloc alignment is 4
This commit is contained in:
Jan
2026-06-07 03:14:37 +02:00
committed by GitHub
parent 036b27568c
commit ab7d8f5670
24 changed files with 62 additions and 50 deletions
+2 -1
View File
@@ -55,6 +55,7 @@ namespace IW3
struct StringTable; struct StringTable;
typedef unsigned short ScriptString; typedef unsigned short ScriptString;
typedef tdef_align32(16) char raw_byte16;
union XAssetHeader union XAssetHeader
{ {
@@ -2382,7 +2383,7 @@ namespace IW3
unsigned int dynEntClientWordCount[2]; unsigned int dynEntClientWordCount[2];
unsigned int dynEntClientCount[2]; unsigned int dynEntClientCount[2];
unsigned int* dynEntCellBits[2]; unsigned int* dynEntCellBits[2];
char* dynEntVisData[2][3]; raw_byte16* dynEntVisData[2][3];
}; };
struct GfxWorldStreamInfo struct GfxWorldStreamInfo
+1 -1
View File
@@ -3124,7 +3124,7 @@ namespace T5
unsigned int dynEntClientWordCount[2]; unsigned int dynEntClientWordCount[2];
unsigned int dynEntClientCount[2]; unsigned int dynEntClientCount[2];
unsigned int* dynEntCellBits[2]; unsigned int* dynEntCellBits[2];
char* dynEntVisData[2][3]; raw_byte16* dynEntVisData[2][3];
}; };
struct GfxWorldLodChain struct GfxWorldLodChain
+1 -3
View File
@@ -1296,8 +1296,6 @@ namespace T6
vec3_t sunFxPosition; vec3_t sunFxPosition;
}; };
typedef tdef_align32(4) GfxDrawSurf GfxDrawSurf_align4;
struct GfxWorldDpvsStatic struct GfxWorldDpvsStatic
{ {
unsigned int smodelCount; unsigned int smodelCount;
@@ -1320,7 +1318,7 @@ namespace T6
GfxStaticModelInst* smodelInsts; GfxStaticModelInst* smodelInsts;
GfxSurface* surfaces; GfxSurface* surfaces;
GfxStaticModelDrawInst* smodelDrawInsts; GfxStaticModelDrawInst* smodelDrawInsts;
GfxDrawSurf_align4* surfaceMaterials; GfxDrawSurf* surfaceMaterials;
raw_byte128* surfaceCastsSunShadow; raw_byte128* surfaceCastsSunShadow;
raw_byte128* surfaceCastsShadow; raw_byte128* surfaceCastsShadow;
raw_byte128* smodelCastsShadow; raw_byte128* smodelCastsShadow;
@@ -109,6 +109,7 @@ set count cullGroups GfxWorld::cullGroupCount;
set count smodelDrawInsts smodelCount; set count smodelDrawInsts smodelCount;
set block surfaceMaterials XFILE_BLOCK_RUNTIME; set block surfaceMaterials XFILE_BLOCK_RUNTIME;
set count surfaceMaterials staticSurfaceCount; set count surfaceMaterials staticSurfaceCount;
set allocalign surfaceMaterials 4;
set block surfaceCastsSunShadow XFILE_BLOCK_RUNTIME; set block surfaceCastsSunShadow XFILE_BLOCK_RUNTIME;
set count surfaceCastsSunShadow surfaceVisDataCount; set count surfaceCastsSunShadow surfaceVisDataCount;
@@ -3,6 +3,7 @@
// ========================================= // =========================================
use Material; use Material;
set block XFILE_BLOCK_TEMP; set block XFILE_BLOCK_TEMP;
set allocalign Material 4;
set string info::name; set string info::name;
set reusable textureTable; set reusable textureTable;
set count textureTable textureCount; set count textureTable textureCount;
@@ -3,6 +3,7 @@
// ========================================= // =========================================
use Material; use Material;
set block XFILE_BLOCK_TEMP; set block XFILE_BLOCK_TEMP;
set allocalign Material 4;
set string info::name; set string info::name;
set reusable textureTable; set reusable textureTable;
set count textureTable textureCount; set count textureTable textureCount;
@@ -3,6 +3,7 @@
// ========================================= // =========================================
use Material; use Material;
set block XFILE_BLOCK_TEMP; set block XFILE_BLOCK_TEMP;
set allocalign Material 4;
set string info::name; set string info::name;
set reusable textureTable; set reusable textureTable;
set count textureTable textureCount; set count textureTable textureCount;
@@ -137,6 +137,7 @@ set count cullGroups GfxWorld::cullGroupCount;
set count smodelDrawInsts smodelCount; set count smodelDrawInsts smodelCount;
set block surfaceMaterials XFILE_BLOCK_RUNTIME; set block surfaceMaterials XFILE_BLOCK_RUNTIME;
set count surfaceMaterials staticSurfaceCount; set count surfaceMaterials staticSurfaceCount;
set allocalign surfaceMaterials 4;
set block surfaceCastsSunShadow XFILE_BLOCK_RUNTIME; set block surfaceCastsSunShadow XFILE_BLOCK_RUNTIME;
set count surfaceCastsSunShadow surfaceVisDataCount; set count surfaceCastsSunShadow surfaceVisDataCount;
@@ -3,6 +3,7 @@
// ========================================= // =========================================
use Material; use Material;
set block XFILE_BLOCK_TEMP; set block XFILE_BLOCK_TEMP;
set allocalign Material 4;
set string info::name; set string info::name;
set reusable textureTable; set reusable textureTable;
set count textureTable textureCount; set count textureTable textureCount;
@@ -162,6 +162,7 @@ set count surfaces GfxWorld::surfaceCount;
set count smodelDrawInsts smodelCount; set count smodelDrawInsts smodelCount;
set block surfaceMaterials XFILE_BLOCK_RUNTIME_VIRTUAL; set block surfaceMaterials XFILE_BLOCK_RUNTIME_VIRTUAL;
set count surfaceMaterials staticSurfaceCount; set count surfaceMaterials staticSurfaceCount;
set allocalign surfaceMaterials 4;
reorder: reorder:
smodelVisData smodelVisData
surfaceVisData surfaceVisData
@@ -3,6 +3,7 @@
// ========================================= // =========================================
use Material; use Material;
set block XFILE_BLOCK_TEMP; set block XFILE_BLOCK_TEMP;
set allocalign Material 4;
set string info::name; set string info::name;
set reusable textureTable; set reusable textureTable;
set count textureTable textureCount; set count textureTable textureCount;
@@ -7,10 +7,7 @@ DefinitionWithMembers::DefinitionWithMembers(std::string _namespace, std::string
m_flags(0), m_flags(0),
m_size(0), m_size(0),
m_alignment(0), m_alignment(0),
m_has_alignment_override(false), m_pack(pack)
m_anonymous(false),
m_pack(pack),
m_alignment_override(0)
{ {
} }
@@ -23,8 +20,6 @@ unsigned DefinitionWithMembers::GetAlignment() const
bool DefinitionWithMembers::GetForceAlignment() const bool DefinitionWithMembers::GetForceAlignment() const
{ {
assert(m_flags & FLAG_FIELDS_CALCULATED);
return m_flags & FLAG_ALIGNMENT_FORCED; return m_flags & FLAG_ALIGNMENT_FORCED;
} }
@@ -34,3 +29,8 @@ unsigned DefinitionWithMembers::GetSize() const
return m_size; return m_size;
} }
bool DefinitionWithMembers::IsAnonymous() const
{
return m_flags & FLAG_ANONYMOUS;
}
@@ -12,22 +12,19 @@ public:
static constexpr int FLAG_FIELDS_CALCULATED = 1 << 0; static constexpr int FLAG_FIELDS_CALCULATED = 1 << 0;
static constexpr int FLAG_FIELDS_CALCULATING = 1 << 1; static constexpr int FLAG_FIELDS_CALCULATING = 1 << 1;
static constexpr int FLAG_ALIGNMENT_FORCED = 1 << 2; static constexpr int FLAG_ALIGNMENT_FORCED = 1 << 2;
static constexpr int FLAG_ANONYMOUS = 1 << 3;
DefinitionWithMembers(std::string _namespace, std::string name, unsigned pack); DefinitionWithMembers(std::string _namespace, std::string name, unsigned pack);
[[nodiscard]] unsigned GetAlignment() const override; [[nodiscard]] unsigned GetAlignment() const override;
[[nodiscard]] bool GetForceAlignment() const override; [[nodiscard]] bool GetForceAlignment() const override;
[[nodiscard]] unsigned GetSize() const override; [[nodiscard]] unsigned GetSize() const override;
[[nodiscard]] bool IsAnonymous() const;
unsigned m_flags; unsigned m_flags;
unsigned m_size; unsigned m_size;
unsigned m_alignment; unsigned m_alignment;
unsigned m_pack;
bool m_has_alignment_override;
bool m_anonymous;
const unsigned m_pack;
unsigned m_alignment_override;
std::vector<std::shared_ptr<Variable>> m_members; std::vector<std::shared_ptr<Variable>> m_members;
}; };
@@ -21,6 +21,7 @@ public:
TypeInformation* m_type_info; TypeInformation* m_type_info;
std::string m_asset_name; std::string m_asset_name;
std::unique_ptr<IEvaluation> m_alloc_alignment;
std::vector<StructureInformation*> m_usages; std::vector<StructureInformation*> m_usages;
std::vector<std::unique_ptr<MemberInformation>> m_ordered_members; std::vector<std::unique_ptr<MemberInformation>> m_ordered_members;
@@ -42,7 +42,7 @@ namespace
for (const auto* structure : m_env.m_used_structures) for (const auto* structure : m_env.m_used_structures)
{ {
StructureComputations computations(structure->m_info); StructureComputations computations(structure->m_info);
if (!structure->m_info->m_definition->m_anonymous && !computations.IsAsset() && structure->m_info->m_has_matching_cross_platform_structure) if (!structure->m_info->m_definition->IsAnonymous() && !computations.IsAsset() && structure->m_info->m_has_matching_cross_platform_structure)
TestMethod(structure->m_info); TestMethod(structure->m_info);
} }
@@ -256,6 +256,14 @@ void BaseTemplate::MakeEvaluationInternal(const IEvaluation* evaluation, std::os
MakeOperandDynamic(dynamic_cast<const OperandDynamic*>(evaluation), str); MakeOperandDynamic(dynamic_cast<const OperandDynamic*>(evaluation), str);
} }
std::string BaseTemplate::MakeAllocAlignment(const StructureInformation& info)
{
if (info.m_alloc_alignment)
return MakeEvaluation(info.m_alloc_alignment.get());
return std::to_string(info.m_definition->GetAlignment());
}
std::string BaseTemplate::MakeEvaluation(const IEvaluation* evaluation) std::string BaseTemplate::MakeEvaluation(const IEvaluation* evaluation)
{ {
std::ostringstream str; std::ostringstream str;
@@ -33,6 +33,7 @@ protected:
static std::string MakeArrayIndices(const DeclarationModifierComputations& modifierComputations); static std::string MakeArrayIndices(const DeclarationModifierComputations& modifierComputations);
static std::string MakeCustomActionCall(const CustomAction* action); static std::string MakeCustomActionCall(const CustomAction* action);
static std::string MakeArrayCount(const ArrayDeclarationModifier* arrayModifier); static std::string MakeArrayCount(const ArrayDeclarationModifier* arrayModifier);
static std::string MakeAllocAlignment(const StructureInformation& info);
static std::string MakeEvaluation(const IEvaluation* evaluation); static std::string MakeEvaluation(const IEvaluation* evaluation);
static bool ShouldGenerateFillMethod(const RenderingUsedType& type); static bool ShouldGenerateFillMethod(const RenderingUsedType& type);
@@ -138,7 +138,7 @@ namespace
// Variable Declarations: type varType; // Variable Declarations: type varType;
for (const auto* type : m_env.m_used_types) for (const auto* type : m_env.m_used_types)
{ {
if (type->m_info && !type->m_info->m_definition->m_anonymous if (type->m_info && !type->m_info->m_definition->IsAnonymous()
&& (!type->m_info->m_is_leaf || !type->m_info->m_has_matching_cross_platform_structure) && !StructureComputations(type->m_info).IsAsset()) && (!type->m_info->m_is_leaf || !type->m_info->m_has_matching_cross_platform_structure) && !StructureComputations(type->m_info).IsAsset())
{ {
LINE(VariableDecl(type->m_type)) LINE(VariableDecl(type->m_type))
@@ -345,7 +345,7 @@ namespace
for (const auto* type : m_env.m_used_types) for (const auto* type : m_env.m_used_types)
{ {
if (type->m_info && !type->m_info->m_definition->m_anonymous if (type->m_info && !type->m_info->m_definition->IsAnonymous()
&& (!type->m_info->m_is_leaf || !type->m_info->m_has_matching_cross_platform_structure) && !StructureComputations(type->m_info).IsAsset()) && (!type->m_info->m_is_leaf || !type->m_info->m_has_matching_cross_platform_structure) && !StructureComputations(type->m_info).IsAsset())
{ {
PrintVariableInitialization(type->m_type); PrintVariableInitialization(type->m_type);
@@ -480,7 +480,7 @@ namespace
const DeclarationModifierComputations& modifier, const DeclarationModifierComputations& modifier,
const size_t nestedBaseOffset) const size_t nestedBaseOffset)
{ {
const auto hasAnonymousType = memberInfo.m_type && memberInfo.m_type->m_definition->m_anonymous; const auto hasAnonymousType = memberInfo.m_type && memberInfo.m_type->m_definition->IsAnonymous();
if (!hasAnonymousType) if (!hasAnonymousType)
{ {
@@ -888,10 +888,12 @@ namespace
void PrintLoadPtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info) const void PrintLoadPtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info) const
{ {
const auto alignment = info && def == info->m_definition ? MakeAllocAlignment(*info) : std::to_string(def->GetAlignment());
if (info && !info->m_has_matching_cross_platform_structure && StructureComputations(info).GetDynamicMember()) if (info && !info->m_has_matching_cross_platform_structure && StructureComputations(info).GetDynamicMember())
{ {
assert(def == info->m_definition);
LINE("// Alloc first for alignment, then proceed to read as game does") LINE("// Alloc first for alignment, then proceed to read as game does")
LINEF("m_stream.Alloc({0});", def->GetAlignment()) LINEF("m_stream.Alloc({0});", alignment)
LINEF("const auto allocSize = LoadDynamicFill_{0}(m_stream.LoadWithFill(0));", MakeSafeTypeName(def)) LINEF("const auto allocSize = LoadDynamicFill_{0}(m_stream.LoadWithFill(0));", MakeSafeTypeName(def))
LINEF("*{0} = static_cast<{1}*>(m_stream.AllocOutOfBlock(0, allocSize));", MakeTypePtrVarName(def), def->GetFullName()) LINEF("*{0} = static_cast<{1}*>(m_stream.AllocOutOfBlock(0, allocSize));", MakeTypePtrVarName(def), def->GetFullName())
} }
@@ -901,7 +903,7 @@ namespace
MakeTypePtrVarName(def), MakeTypePtrVarName(def),
m_env.m_word_size_mismatch ? "AllocOutOfBlock" : "Alloc", m_env.m_word_size_mismatch ? "AllocOutOfBlock" : "Alloc",
def->GetFullName(), def->GetFullName(),
def->GetAlignment()) alignment)
} }
if (info && !info->m_is_leaf) if (info && !info->m_is_leaf)
@@ -1989,7 +1991,7 @@ namespace
MakeTypePtrVarName(info->m_definition), MakeTypePtrVarName(info->m_definition),
m_env.m_word_size_mismatch ? "AllocOutOfBlock" : "Alloc", m_env.m_word_size_mismatch ? "AllocOutOfBlock" : "Alloc",
info->m_definition->GetFullName(), info->m_definition->GetFullName(),
info->m_definition->GetAlignment()) MakeAllocAlignment(*info))
if (inTemp) if (inTemp)
{ {
@@ -114,7 +114,7 @@ namespace
// Variable Declarations: type varType; // Variable Declarations: type varType;
for (const auto* type : m_env.m_used_types) for (const auto* type : m_env.m_used_types)
{ {
if (type->m_info && !type->m_info->m_definition->m_anonymous && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset()) if (type->m_info && !type->m_info->m_definition->IsAnonymous() && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset())
{ {
LINE(VariableDecl(type->m_type)) LINE(VariableDecl(type->m_type))
} }
@@ -267,7 +267,7 @@ namespace
for (const auto* type : m_env.m_used_types) for (const auto* type : m_env.m_used_types)
{ {
if (type->m_info && !type->m_info->m_definition->m_anonymous && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset()) if (type->m_info && !type->m_info->m_definition->IsAnonymous() && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset())
{ {
PrintVariableInitialization(type->m_type); PrintVariableInitialization(type->m_type);
} }
@@ -124,7 +124,7 @@ namespace
// Variable Declarations: type varType; // Variable Declarations: type varType;
for (const auto* type : m_env.m_used_types) for (const auto* type : m_env.m_used_types)
{ {
if (type->m_info && !type->m_info->m_definition->m_anonymous if (type->m_info && !type->m_info->m_definition->IsAnonymous()
&& (!type->m_info->m_is_leaf || !type->m_info->m_has_matching_cross_platform_structure) && !StructureComputations(type->m_info).IsAsset()) && (!type->m_info->m_is_leaf || !type->m_info->m_has_matching_cross_platform_structure) && !StructureComputations(type->m_info).IsAsset())
LINE(VariableDecl(type->m_type)) LINE(VariableDecl(type->m_type))
} }
@@ -138,7 +138,7 @@ namespace
for (const auto* type : m_env.m_used_types) for (const auto* type : m_env.m_used_types)
{ {
if (type->m_info && !type->m_info->m_definition->m_anonymous && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset()) if (type->m_info && !type->m_info->m_definition->IsAnonymous() && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset())
LINE(WrittenVariableDecl(type->m_type)) LINE(WrittenVariableDecl(type->m_type))
} }
for (const auto* type : m_env.m_used_types) for (const auto* type : m_env.m_used_types)
@@ -370,7 +370,7 @@ namespace
for (const auto* type : m_env.m_used_types) for (const auto* type : m_env.m_used_types)
{ {
if (type->m_info && !type->m_info->m_definition->m_anonymous if (type->m_info && !type->m_info->m_definition->IsAnonymous()
&& (!type->m_info->m_is_leaf || !type->m_info->m_has_matching_cross_platform_structure) && !StructureComputations(type->m_info).IsAsset()) && (!type->m_info->m_is_leaf || !type->m_info->m_has_matching_cross_platform_structure) && !StructureComputations(type->m_info).IsAsset())
PrintVariableInitialization(type->m_type); PrintVariableInitialization(type->m_type);
} }
@@ -1201,7 +1201,7 @@ namespace
LINE("{") LINE("{")
m_intendation++; m_intendation++;
LINEF("m_stream->Align({0});", info->m_definition->GetAlignment()) LINEF("m_stream->Align({0});", MakeAllocAlignment(*info))
LINEF("m_stream->ReusableAddOffset(*{0});", MakeTypePtrVarName(info->m_definition)) LINEF("m_stream->ReusableAddOffset(*{0});", MakeTypePtrVarName(info->m_definition))
LINE("") LINE("")
if (!info->m_is_leaf) if (!info->m_is_leaf)
@@ -1282,7 +1282,7 @@ namespace
const DeclarationModifierComputations& modifier, const DeclarationModifierComputations& modifier,
const size_t nestedBaseOffset) const size_t nestedBaseOffset)
{ {
const auto hasAnonymousType = memberInfo.m_type && memberInfo.m_type->m_definition->m_anonymous; const auto hasAnonymousType = memberInfo.m_type && memberInfo.m_type->m_definition->IsAnonymous();
if (!hasAnonymousType) if (!hasAnonymousType)
{ {
@@ -1478,7 +1478,8 @@ namespace
void PrintWritePtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info, const bool reusable) const void PrintWritePtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info, const bool reusable) const
{ {
LINEF("m_stream->Align({0});", def->GetAlignment()) const auto alignment = info && def == info->m_definition ? MakeAllocAlignment(*info) : std::to_string(def->GetAlignment());
LINEF("m_stream->Align({0});", alignment)
if (reusable) if (reusable)
{ {
@@ -31,9 +31,9 @@ void SequenceAllocAlign::ProcessMatch(CommandsParserState* state, SequenceResult
if (!state->GetTypenameAndMembersFromTypename(typeNameToken.TypeNameValue(), type, memberChain)) if (!state->GetTypenameAndMembersFromTypename(typeNameToken.TypeNameValue(), type, memberChain))
throw ParsingException(typeNameToken.GetPos(), "Unknown type"); throw ParsingException(typeNameToken.GetPos(), "Unknown type");
if (memberChain.empty())
throw ParsingException(typeNameToken.GetPos(), "Need to specify a member");
auto allocAlignEvaluation = CommandsCommonMatchers::ProcessEvaluation(state, result, type); auto allocAlignEvaluation = CommandsCommonMatchers::ProcessEvaluation(state, result, type);
if (memberChain.empty())
type->m_alloc_alignment = std::move(allocAlignEvaluation);
else
memberChain.back()->m_alloc_alignment = std::move(allocAlignEvaluation); memberChain.back()->m_alloc_alignment = std::move(allocAlignEvaluation);
} }
@@ -61,15 +61,15 @@ void HeaderBlockStruct::OnClose(HeaderParserState* state)
m_struct_definition = structDefinition.get(); m_struct_definition = structDefinition.get();
if (m_is_anonymous) if (m_is_anonymous)
structDefinition->m_anonymous = true; structDefinition->m_flags |= DefinitionWithMembers::FLAG_ANONYMOUS;
for (auto& member : m_members) for (auto& member : m_members)
structDefinition->m_members.emplace_back(std::move(member)); structDefinition->m_members.emplace_back(std::move(member));
if (m_has_custom_align) if (m_has_custom_align)
{ {
structDefinition->m_alignment_override = static_cast<unsigned>(m_custom_alignment); structDefinition->m_alignment = static_cast<unsigned>(m_custom_alignment);
structDefinition->m_has_alignment_override = true; structDefinition->m_flags |= DefinitionWithMembers::FLAG_ALIGNMENT_FORCED;
} }
state->AddDataType(std::move(structDefinition)); state->AddDataType(std::move(structDefinition));
@@ -61,15 +61,15 @@ void HeaderBlockUnion::OnClose(HeaderParserState* state)
m_union_definition = unionDefinition.get(); m_union_definition = unionDefinition.get();
if (m_is_anonymous) if (m_is_anonymous)
unionDefinition->m_anonymous = true; unionDefinition->m_flags |= DefinitionWithMembers::FLAG_ANONYMOUS;
for (auto& member : m_members) for (auto& member : m_members)
unionDefinition->m_members.emplace_back(std::move(member)); unionDefinition->m_members.emplace_back(std::move(member));
if (m_has_custom_align) if (m_has_custom_align)
{ {
unionDefinition->m_alignment_override = static_cast<unsigned>(m_custom_alignment); unionDefinition->m_alignment = static_cast<unsigned>(m_custom_alignment);
unionDefinition->m_has_alignment_override = true; unionDefinition->m_flags |= DefinitionWithMembers::FLAG_ALIGNMENT_FORCED;
} }
state->AddDataType(std::move(unionDefinition)); state->AddDataType(std::move(unionDefinition));
@@ -4,6 +4,7 @@
#include "Utils/Alignment.h" #include "Utils/Alignment.h"
#include "Utils/Logging/Log.h" #include "Utils/Logging/Log.h"
#include <algorithm>
#include <cassert> #include <cassert>
#include <cstdint> #include <cstdint>
#include <iostream> #include <iostream>
@@ -43,12 +44,7 @@ namespace
bool CalculateAlign(IDataRepository* repository, DefinitionWithMembers* definition) bool CalculateAlign(IDataRepository* repository, DefinitionWithMembers* definition)
{ {
if (definition->m_has_alignment_override) if (!definition->GetForceAlignment())
{
definition->m_flags |= DefinitionWithMembers::FLAG_ALIGNMENT_FORCED;
definition->m_alignment = definition->m_alignment_override;
}
else
{ {
definition->m_alignment = 0; definition->m_alignment = 0;
for (const auto& member : definition->m_members) for (const auto& member : definition->m_members)
@@ -57,8 +53,7 @@ namespace
return false; return false;
const auto memberAlignment = member->GetAlignment(); const auto memberAlignment = member->GetAlignment();
if (memberAlignment > definition->m_alignment) definition->m_alignment = std::max(memberAlignment, definition->m_alignment);
definition->m_alignment = memberAlignment;
} }
} }